#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
#include "hardware/gpio.h"


// Definição dos pinos dos LEDs e outros componentes
#define LED_VERDE_PEDESTRE 10      // LED Verde Pedestre
#define LED_VERDE 11               // LED Verde
#define LED_AMARELO 12             // LED Amarelo
#define LED_VERMELHO 13            // LED Vermelho
#define ALTO_FALANTE 21            // Configuração do pino do buzzer
#define BOTAO 27                   // Pino do botão
#define FREQUENCIA_ALTO_FALANTE 100 // Configuração da frequência do buzzer (em Hz)

// Inicializa os pinos dos leds
void inicializar_leds() {
    gpio_init(LED_VERDE_PEDESTRE);
    gpio_init(LED_VERDE);
    gpio_init(LED_AMARELO);
    gpio_init(LED_VERMELHO);

    gpio_set_slew_rate(LED_VERDE_PEDESTRE, GPIO_SLEW_RATE_SLOW);
    gpio_set_slew_rate(LED_VERDE, GPIO_SLEW_RATE_SLOW);
    gpio_set_slew_rate(LED_AMARELO, GPIO_SLEW_RATE_SLOW);
    gpio_set_slew_rate(LED_VERMELHO, GPIO_SLEW_RATE_SLOW);

    gpio_set_dir(LED_VERDE_PEDESTRE, true);
    gpio_set_dir(LED_VERDE, true);
    gpio_set_dir(LED_AMARELO, true);
    gpio_set_dir(LED_VERMELHO, true);
}

// Controla o estado dos LEDs do semáforo
void controlar_semaforo(bool verde, bool amarelo, bool vermelho) {
    gpio_put(LED_VERDE, verde);
    gpio_put(LED_AMARELO, amarelo);
    gpio_put(LED_VERMELHO, vermelho);
}

// Controla o estado do LED do pedestre
void controlar_led_pedestre(bool estado) {
    gpio_put(LED_VERDE_PEDESTRE, estado);
}

// Função para inicializar o PWM no pino do buzzer
void pwm_inicializar_alto_falante(uint pino) {
    gpio_set_function(pino, GPIO_FUNC_PWM); // Configurar o pino como saída de PWM
    uint slice_num = pwm_gpio_to_slice_num(pino); // Obter o slice do PWM associado ao pino
    pwm_config config = pwm_get_default_config(); // Configurar o PWM com frequência desejada
    pwm_config_set_clkdiv(&config, clock_get_hz(clk_sys) / (FREQUENCIA_ALTO_FALANTE * 4096)); // Divisor de clock
    pwm_init(slice_num, &config, true);
    pwm_set_gpio_level(pino, 0); // Iniciar o PWM no nível baixo
}

// Função para emitir um beep com duração especificada
void beep(uint pino, uint duracao_ms) {
    uint slice_num = pwm_gpio_to_slice_num(pino); // Obter o slice do PWM associado ao pino
    pwm_set_gpio_level(pino, 1024); // Configurar o duty cycle para 50% (ativo)
    sleep_ms(duracao_ms); // Temporização
    controlar_led_pedestre(true); // Acende o LED do pedestre
    pwm_set_gpio_level(pino, 0); // Desativar o sinal PWM (duty cycle 0)
    controlar_led_pedestre(false); // Apaga o LED do pedestre
    sleep_ms(100); // Temporização
}

// Função que verifica se o botão foi pressionado
int verificar_botao_pressionado(int tempo_ms) {
    for (int tempo_atual = 0; tempo_atual < tempo_ms; tempo_atual += 100) {
        if (gpio_get(BOTAO) == 0) {
            return 1;
        }
        sleep_ms(100);
    }
    return 0;
}

// Função para acender os LEDs e ligar o buzzer quando o botão for pressionado
void acionar_semaforo_pedestre_generico(bool incluir_amarelo) {
    controlar_semaforo(false, false, false);  // Desliga todos os LEDs do semáforo
    // Acende o LED Amarelo por 5 segundos
    if (incluir_amarelo) {
        controlar_semaforo(false, true, false);
        controlar_led_pedestre(false);
        sleep_ms(5000);
    }
    // Acende o LED Verde do pedestre e Vermelho do semáforo por 15 segundos
    controlar_semaforo(false, false, true);
    controlar_led_pedestre(true);
    // Beep
    beep(ALTO_FALANTE, 15000);
    sequenciar_semaforo();
}

// Função para acender os LEDs e ligar o buzzer quando o botão for pressionado no tempo vermelho do semáforo.
void acionar_semaforo_pedestre_vermelho() {
    acionar_semaforo_pedestre_generico(false); // Não inclui o LED amarelo
}

// Função para acender os LEDs e ligar o buzzer quando o botão for pressionado no tempo amarelo e verde do semáforo.
void acionar_semaforo_pedestre() {
    acionar_semaforo_pedestre_generico(true); // Inclui o LED amarelo
}

// Função para controlar o semáforo no ciclo normal
void sequenciar_semaforo() {
    while (true) {        
        controlar_semaforo(true, false, false);
        if (verificar_botao_pressionado(8000)) {
            acionar_semaforo_pedestre();     
        }
        controlar_semaforo(false, true, false);
        if (verificar_botao_pressionado(2000)) {
            acionar_semaforo_pedestre();  
        }
        controlar_semaforo(false, false, true);
        if (verificar_botao_pressionado(10000)) {
            acionar_semaforo_pedestre_vermelho();
        }
    }
}

int main() {
    stdio_init_all();   
    // Configuração do botão
    gpio_init(BOTAO);
    gpio_set_dir(BOTAO, GPIO_IN);
    gpio_pull_up(BOTAO);
    // Configuração do buzzer
    gpio_init(ALTO_FALANTE);
    gpio_set_dir(ALTO_FALANTE, GPIO_OUT);
    pwm_inicializar_alto_falante(ALTO_FALANTE);
      
    inicializar_leds(); // Inicia os leds
    sequenciar_semaforo(); // Inicia o ciclo do semáforo
    return 0;
}
$abcdeabcde151015202530fghijfghij
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT