diff --git a/lab_3/lab_3.c b/lab_3/lab_3.c index bd702e0..4c7426c 100644 --- a/lab_3/lab_3.c +++ b/lab_3/lab_3.c @@ -20,13 +20,21 @@ #include "hardware/gpio.h" #define PSEUDO_BTN 15 // GPIO 15 is the pseudo-button -#define DELAY_US 1000000 // 1-second delay for repeating timer -#define DEBOUNCE_US 100 // 100us debounce delay +#define TIMER_US 1000000 // 1-second delay for repeating timer +#define DEBOUNCE_US 100 // 100us debounce time -u_int64_t time = 0; // Elapsed time -u_int prev_state = 0; // Previous state of pseudo-button struct repeating_timer timer; // Repeating timer +u_int64_t time = 0; // Elapsed time +typedef enum btn_state { // Button state + PRESSED = 0, + RELEASED = 1 +} btn_state_t; + +struct btn_status { // Button status + uint btn_pressed; + uint btn_released; +} btn_status = {0, 0}; /** * Callback function for repeating timer @@ -43,15 +51,32 @@ bool elapsed_time_callback (struct repeating_timer *t) { } /** - * Debounce callback function to check if the current state - * is equal to the previous state. - * @param id The alarm ID - * @param new_event The previous state of the pseudo-button - * @return True if the current state is equal to the previous state + * Get the state of the pseudo-button (pull-up) + * This function will implement a debounce algorithm to + * get the state of the pseudo-button. (With added complexity) + * @return The state of the pseudo-button */ -int64_t debounce_callback(alarm_id_t id, void *new_event) { - printf("Debounce Callback\n"); - return (prev_state == *(uint32_t *)new_event); +btn_state_t get_btn_state () { + u_int64_t start_time = time_us_64(); + while (time_us_64() - start_time < DEBOUNCE_US) + { + if (gpio_get(PSEUDO_BTN)) + { + btn_status.btn_released += 1; + } + else + { + btn_status.btn_pressed += 1; + } + } + + btn_state_t state = (btn_status.btn_pressed > btn_status.btn_released) ? + PRESSED : RELEASED; + + btn_status.btn_pressed = 0; + btn_status.btn_released = 0; + + return state; } /** @@ -62,33 +87,24 @@ int64_t debounce_callback(alarm_id_t id, void *new_event) { * @param events The type of interrupt that triggered the callback */ void gpio_callback (uint gpio, uint32_t events) { - // Debounce algorithm - prev_state = prev_state == 0 ? events : prev_state; + btn_state_t btn_state = get_btn_state(); - // Create an alarm that will trigger after 10ms - add_alarm_in_us( - DEBOUNCE_US, - debounce_callback, - &events, - false - ); - - // Start timer on button press - if (gpio == PSEUDO_BTN && events == GPIO_IRQ_EDGE_FALL) + if (events == GPIO_IRQ_EDGE_FALL && btn_state == PRESSED) { printf("\n====================================\n"); printf("Timer Started\n"); printf("====================================\n"); add_repeating_timer_us( - DELAY_US, + TIMER_US, elapsed_time_callback, NULL, &timer ); + } - // Stop timer on button release - if (gpio == PSEUDO_BTN && events == GPIO_IRQ_EDGE_RISE) + + if (events == GPIO_IRQ_EDGE_RISE && btn_state == RELEASED) { cancel_repeating_timer(&timer); @@ -100,6 +116,7 @@ void gpio_callback (uint gpio, uint32_t events) { printf("====================================\n"); time = 0; + } }