// ALUNO: JOSICLEYTON AZEVEDO DOS SANTOS
// CAPACITAÇÃO EM SISTEMAS EMBARCADOS
// POLO NATAL
// TAREFA DA UNIDADE III
// LINGUAGENS E AMBIENTES DE PROGRAMAÇÃO


////////////////////////////////////////////////////////
// BIBLIOTECAS UTILIZADAS
////////////////////////////////////////////////////////
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"


// Definições de GPIOs
#define BUZZER 0
#define LED_PEDESTRE_VERDE 1
#define BOTAO_PEDESTRE 2
#define LED_VERMELHO 9
#define LED_AMARELO 10
#define LED_CARRO_VERDE 12

// Definição da frequência
#define FREQUENCIA_BUZZER 400

////////////////////////////////////////////////////////
// VARIÁVEIS GLOBAIS
////////////////////////////////////////////////////////
uint slice_buzzer;
volatile bool pedestre_esperando = false; // Flag para indicar solicitação de pedestres

////////////////////////////////////////////////////////
// FUNÇÕES AUXILIARES
////////////////////////////////////////////////////////

// (1)) Inicializa um botão configurado como entrada
void inicializar_botao(int gpio) {
    gpio_init(gpio);
    gpio_set_dir(gpio, GPIO_IN);
    gpio_pull_down(gpio);
}

// (2) Inicializa um LED configurado como saída
void inicializar_led(int gpio) {
    gpio_init(gpio);
    gpio_set_dir(gpio, GPIO_OUT);
    gpio_put(gpio, 0);
    gpio_set_slew_rate(gpio, GPIO_SLEW_RATE_SLOW);
}

// (3) Inicializa o PWM para o buzzer
void inicializar_pwm_buzzer(int gpio) {
    uint32_t clock = 125000000;

    gpio_set_function(gpio, GPIO_FUNC_PWM);
    slice_buzzer = pwm_gpio_to_slice_num(gpio);

    uint32_t wrap_value = clock / FREQUENCIA_BUZZER - 1; // Calcula o valor de wrap
    pwm_set_wrap(slice_buzzer, wrap_value);             // Define o valor máximo do contador
    pwm_set_chan_level(slice_buzzer, PWM_CHAN_A, wrap_value / 2); // 50% de duty cycle
}

// (4) Callback da interrupção do botão de pedestres
void botao_pedestre_callback(uint gpio, uint32_t events) {
    pedestre_esperando = true; // Define a flag quando o botão é pressionado
}

// (5) Controla o sistema de pedestres
void ativar_sistema_pedestre() {
    // Liga o LED verde para pedestres e o vermelho para carros
    gpio_put(LED_AMARELO, 0);
    gpio_put(LED_PEDESTRE_VERDE, 1);
    gpio_put(LED_VERMELHO, 1);
    pwm_set_enabled(slice_buzzer, true);

    sleep_ms(15000); // 15 segundos para pedestres atravessarem

    // Desliga os LEDs e buzzer
    gpio_put(LED_PEDESTRE_VERDE, 0);
    gpio_put(LED_VERMELHO, 0);
    pwm_set_enabled(slice_buzzer, false);

    pedestre_esperando = false; // Reseta a flag
}

// (6) Controla o ciclo automático do semáforo
void executar_ciclo_semaforo() {

    // (A) Fase verde para carros
    gpio_put(LED_CARRO_VERDE, 1);
    gpio_put(LED_AMARELO, 0);
    gpio_put(LED_VERMELHO, 0);

    for (int i = 0; i < 80; i++) { // 8 segundos (80 x 100ms)
        sleep_ms(100);
        if (pedestre_esperando) {
            gpio_put(LED_CARRO_VERDE, 0);
            gpio_put(LED_AMARELO, 1);
            sleep_ms(5000); // Amarelo por 5 segundos
            ativar_sistema_pedestre();
            return;
        }
    }
    gpio_put(LED_CARRO_VERDE, 0);

    // (B) Fase amarela
    gpio_put(LED_AMARELO, 1);
    for (int i = 0; i < 20; i++) { // 2 segundos (20 x 100ms)
        sleep_ms(100);
        if (pedestre_esperando) {
            // Prolonga o amarelo por mais 3 segundos caso o pedestre
            // acione o botão (para ter um ciclo total de 5 segundos)
            sleep_ms(3000);
            gpio_put(LED_AMARELO, 0);
            ativar_sistema_pedestre();
            return;
        }
    }
    gpio_put(LED_AMARELO, 0);

    // (C) Fase vermelha para carros
    gpio_put(LED_VERMELHO, 1);
    for (int i = 0; i < 100; i++) { // 10 segundos (100 x 100ms)
        sleep_ms(100);
        if (pedestre_esperando) {
            ativar_sistema_pedestre();
            return;
        }
    }
    gpio_put(LED_VERMELHO, 0);
}

////////////////////////////////////////////////////////
// FUNÇÃO PRINCIPAL
////////////////////////////////////////////////////////

int main() {
    stdio_init_all();

    // Inicializa os componentes
    inicializar_pwm_buzzer(BUZZER);
    inicializar_botao(BOTAO_PEDESTRE);
    inicializar_led(LED_PEDESTRE_VERDE);
    inicializar_led(LED_CARRO_VERDE);
    inicializar_led(LED_AMARELO);
    inicializar_led(LED_VERMELHO);

    // Configura a interrupção do botão
    gpio_set_irq_enabled_with_callback(BOTAO_PEDESTRE, GPIO_IRQ_EDGE_RISE, true, &botao_pedestre_callback);

    while (true) {
        executar_ciclo_semaforo(); // Executa o ciclo do semáforo continuamente
    }

    return 0;
}
$abcdeabcde151015202530fghijfghij
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT