#include #include "button.h" #include "timers.h" #include "hal.h" #include #include "pm.h" // TODO: FOR DEBUGGING ONLY volatile enum BUTTON_EVENTS button_event_status = NONE; // User button interrupt ISR(INT1_vect) { _delay_ms(50); if (HAL_ASSERTED_N(BUTTON_N)) { // Button down event switch (button_event_status) { case NONE: // Start processing button from NONE, case EV_BOOT: // or drop boot event if not polled for, case EV_PRESS: // or drop current keypress to prevent unhandled keypresses from blocking other would-be-handled keypresses case EV_DOUBLEPRESS: case EV_LONGPRESS: case EV_DOUBLELONGPRESS: button_event_status = WAIT_FOR_RELEASE_1; timer_set(TIMER_BUTTON, timer_ms(500)); break; case WAIT_FOR_SECOND: button_event_status = WAIT_FOR_RELEASE_2; timer_set(TIMER_BUTTON, timer_ms(500)); break; default: break; } } else { // Button up event switch (button_event_status) { case WAIT_FOR_RELEASE_1: button_event_status = WAIT_FOR_SECOND; break; case WAIT_FOR_RELEASE_2: button_event_status = EV_DOUBLEPRESS; break; default: break; } } return; } void button_init() { HAL_INIT(BUTTON_N, INPUT, ON); // Pull-up for user button button_event_status = EV_BOOT; MCUCR = (1 << ISC10); // Any-edge interrupt GICR = (1 << INT1); // Turn on button interrupt } void button_systick_cb() { if (button_event_status != 0) { // TODO: we should not enter on pending EV? if (timer_expired(TIMER_BUTTON)) { switch (button_event_status) { case WAIT_FOR_RELEASE_1: button_event_status = EV_LONGPRESS; break; case WAIT_FOR_RELEASE_2: button_event_status = EV_DOUBLELONGPRESS; pm_reset(); // TODO: For debugging purposes only break; case WAIT_FOR_SECOND: button_event_status = EV_PRESS; break; default: break; } } } } int button_event(enum BUTTON_EVENTS ev) { if (button_event_status == ev) { button_event_status = NONE; // Mark as handled return 1; } return 0; }