/*************************************************************
Nome: VANESSA FERNANDES SANTOS MACHADO
Janeiro/2025
EmbarcaTech
*************************************************************/

// Tarefa 2: Elabore um programa para acionar um LED utilizando o temporizador como contador
// a) Quando o botão A for pressionado 5 vezes o LED deve piscar por 10 segundos na frequência de 10 Hz.
// b) Implemente o botão B para mudar a frequência do LED para 1 Hz.

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/timer.h"

// Definição dos pinos utilizados
const uint LED_PIN = 2;
const uint BUTTON_A_PIN = 6;
const uint BUTTON_B_PIN = 13;

// Variáveis globais para controle do LED e dos botões
volatile int button_press_count = 0; // Contador de pressões do botão A
volatile bool led_active = false;    // Indica se o LED está ativo
volatile int led_frequency = 10;     // Frequência inicial do LED (10 Hz)
bool led_state = false;              // Estado do LED (aceso/apagado)
struct repeating_timer timer_led;    // Estrutura para controle do temporizador

// Função chamada periodicamente para piscar o LED
bool led_callback(struct repeating_timer *t) {
    if (led_active) {
        gpio_put(LED_PIN, led_state); // Atualiza o estado do LED
        led_state = !led_state;       // Alterna o estado do LED
        return true;                  // Mantém o temporizador ativo
    } else {
        gpio_put(LED_PIN, 0);          // Garante que o LED fique apagado
        return false; // Para o timer se o LED não estiver ativo
    }
}

// Callback acionado quando o botão A é pressionado
void button_A_callback(uint gpio, uint32_t events) {
    sleep_ms(50); // Reduz múltiplas detecções por ruído

    if (gpio_get(BUTTON_A_PIN) == 0) { // Confirma se o botão ainda está pressionado
        button_press_count++;
        printf("Botão pressionado %dX\n", button_press_count);
        
        if (button_press_count == 5) { // Quando pressionado 5x
            button_press_count = 0;  // Reseta contador
            led_active = true;

            // Inicia o temporizador para piscar o LED na frequência atual
            add_repeating_timer_ms(1000 / (led_frequency * 2), led_callback, NULL, &timer_led);
            printf("LED acionado!\n");

            // Aguarda 10 segundos sem bloquear interrupções
            uint64_t start_time = time_us_64(); 
            while ((time_us_64() - start_time) < 10000000) {
                sleep_ms(10);  // Pequeno atraso para evitar alto consumo
            }

            led_active = false; // Desativa o LED após 10 segundos
            cancel_repeating_timer(&timer_led); // Cancela o temporizador
            gpio_put(LED_PIN, 0); // Garante que o LED seja desligado
            printf("LED desligado após 10 segundos\n");
        }
    }
}

// Callback acionado quando o botão B é pressionado (altera a frequência do LED)
void button_B_callback(uint gpio, uint32_t events) {
    sleep_ms(50); // Debounce para evitar leituras incorretas

    if (gpio_get(BUTTON_B_PIN) == 0) {
        if (led_frequency == 10) {
            led_frequency = 1; // Muda a frequência para 1 Hz
        } else {
            led_frequency = 10; // Muda a frequência para 10 Hz
        }
        printf("Frequência alterada para %d Hz!\n", led_frequency);

        // Atualiza a frequência do temporizador se o LED ainda estiver ativo
        if (led_active) {
            cancel_repeating_timer(&timer_led); // Cancela o temporizador atual
            add_repeating_timer_ms(1000 / (led_frequency * 2), led_callback, NULL, &timer_led); // Reinicia o temporizador com a nova frequência
        }
    }
}

int main() {
    stdio_init_all();  // Inicializa a comunicação para printf
    printf("Pressione o botão A 5x para acender o LED\n");

    // Configuração do LED como saída
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    gpio_put(LED_PIN, 0); // Garante que o LED inicie apagado

    // Configuração dos botões como entrada com pull-down ativado
    gpio_init(BUTTON_A_PIN);
    gpio_set_dir(BUTTON_A_PIN, GPIO_IN);
    gpio_pull_down(BUTTON_A_PIN);

    gpio_init(BUTTON_B_PIN);
    gpio_set_dir(BUTTON_B_PIN, GPIO_IN);
    gpio_pull_down(BUTTON_B_PIN);

    // Configura interrupções para os botões
    gpio_set_irq_enabled_with_callback(BUTTON_A_PIN, GPIO_IRQ_EDGE_FALL, true, &button_A_callback);
    gpio_set_irq_enabled_with_callback(BUTTON_B_PIN, GPIO_IRQ_EDGE_FALL, true, &button_B_callback);

    // Loop principal (mantém o programa rodando indefinidamente)
    while (true) {
        tight_loop_contents(); // Otimiza o consumo de energia enquanto espera eventos
    }

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