diff --git a/lab_3/lab_3.c b/lab_3/lab_3.c index a2cc777..bd702e0 100644 --- a/lab_3/lab_3.c +++ b/lab_3/lab_3.c @@ -21,11 +21,13 @@ #define PSEUDO_BTN 15 // GPIO 15 is the pseudo-button #define DELAY_US 1000000 // 1-second delay for repeating timer -#define DEBOUNCE_MS 200 // Debounce delay +#define DEBOUNCE_US 100 // 100us debounce delay -unsigned long long time = 0; // Elapsed time +u_int64_t time = 0; // Elapsed time +u_int prev_state = 0; // Previous state of pseudo-button struct repeating_timer timer; // Repeating timer + /** * Callback function for repeating timer * This function will print the elapsed time every second as required by the @@ -33,13 +35,25 @@ struct repeating_timer timer; // Repeating timer * @param t The timer that triggered the callback * @return True to keep the timer running, false to stop it */ -bool repeating_timer_callback (struct repeating_timer *t) { +bool elapsed_time_callback (struct repeating_timer *t) { + time++; // Print elapsed time every second - printf("Elapsed Time: %llus\n", - (time_us_64() - time) / 1000000); + printf("Elapsed Time: %llus\n", time); return true; } +/** + * 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 + */ +int64_t debounce_callback(alarm_id_t id, void *new_event) { + printf("Debounce Callback\n"); + return (prev_state == *(uint32_t *)new_event); +} + /** * Interrupt callback function for pseudo-button (pull-up) * This function will start the timer on button press (falling edge) @@ -48,41 +62,53 @@ bool repeating_timer_callback (struct repeating_timer *t) { * @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; + + // 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) { - time = time_us_64(); - printf("Timer Started at %llu\n", time); + printf("\n====================================\n"); + printf("Timer Started\n"); + printf("====================================\n"); add_repeating_timer_us( DELAY_US, - repeating_timer_callback, + elapsed_time_callback, NULL, &timer ); } // Stop timer on button release - else + if (gpio == PSEUDO_BTN && events == GPIO_IRQ_EDGE_RISE) { - if (gpio == PSEUDO_BTN && events == GPIO_IRQ_EDGE_RISE) - { - printf("Timer Stopped at %llu\n", time_us_64()); - cancel_repeating_timer(&timer); + cancel_repeating_timer(&timer); - // Print elapsed time and reset - printf("Final Elapsed Time: %llus\n", - (time_us_64() - time) / 1000000); + // Print elapsed time and reset + printf("\n====================================\n"); + printf("Timer Stopped\n"); + printf("====================================\n"); + printf("Final Elapsed Time: %llus\n", time); + printf("====================================\n"); - time = 0; - } + time = 0; } } /** * Initialize the pseudo-button (pull-up) - * The pseudo-button is connected to GPIO 15 and is configured as an input - * with a pull-up resistor. - * The interrupt is configured to trigger on both rising and falling edges. + * The pseudo-button is connected to GPIO 15 and is configured as + * an input with a pull-up resistor. + * The interrupt is configured to trigger on both rising and + * falling edges. */ static void btn_init () { gpio_init(PSEUDO_BTN); @@ -104,8 +130,6 @@ int main () { while (true) { tight_loop_contents(); - // Debounce - sleep_ms(DEBOUNCE_MS); } }