#include #include #include #include "lights.h" static uint16_t button_start[N_BUTTONS]; static unsigned char button_pressed[N_BUTTONS]; static unsigned char sleep_after_release; void init_buttons() { DDRB &= ~(_BV(PB6) | _BV(PB0)); PORTB |= _BV(PB6) | _BV(PB0); sleep_after_release = 0; // log_byte(PORTB); } static void inline long_press(unsigned char n) { sleep_after_release = 1; gpio_set(1, 1); } static void do_sleep() { // led_set_status(2); // MCUCR |= _BV(ISC00); // any edge generates IRQ log_byte(0xb0); log_flush(); set_sleep_mode(SLEEP_MODE_PWR_DOWN); PORTA = 0; PORTB = 0; DDRA = 0; DDRB = 0; GIMSK |= _BV(INT0); // enable INT0 sleep_enable(); sei(); sleep_cpu(); sleep_disable(); cli(); GIMSK &= ~_BV(INT0); // disable INT0 hw_setup(); } static void inline short_press(unsigned char n) { led_set_status(1); } void timer_check_buttons() { unsigned char pinb = PINB; unsigned char i; unsigned char port_states[N_BUTTONS] = { pinb & _BV(PB6), pinb & _BV(PB0), }; for (i = 0; i < N_BUTTONS; i++) { if (!port_states[i]) { // is pressed if (button_pressed[i] == 0) { // begin of button press button_pressed[i] = 1; button_start[i] = jiffies; #if 0 // log_byte(0xC0); // log_word(jiffies); #endif } else if (button_pressed[i] == 1) { // been already pressed uint16_t duration = jiffies - button_start[i]; if (duration > 80) { // long button press button_pressed[i] = 2; long_press(i); } } } else { // is not pressed if (button_pressed[i]) { // just depressed uint16_t duration = jiffies - button_start[i]; #if 1 log_byte(0xC1); log_word(duration); log_flush(); #endif button_pressed[i] = 0; if (duration > 6 && duration < 30) short_press(i); if (sleep_after_release) do_sleep(); } } } } ISR(INT0_vect) { hw_setup(); log_byte(0xbb); log_flush(); }