88 lines
2.0 KiB
C
88 lines
2.0 KiB
C
|
#include <avr/interrupt.h>
|
||
|
#include "button.h"
|
||
|
#include "timers.h"
|
||
|
#include "hal.h"
|
||
|
#include <util/delay.h>
|
||
|
|
||
|
#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;
|
||
|
}
|