From: Jan "Yenya" Kasprzak Date: Fri, 30 Nov 2012 09:58:31 +0000 (+0100) Subject: buttons, wakeup rework X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=bike-lights.git;a=commitdiff_plain;h=fad6d0df251d09246816d5f6480543b8af588641 buttons, wakeup rework Set up all the pin-change interrupts even for shutdown, fix the old pins used in the code (main.c), factor out waiting for button release from main.c to buttons.c, fix the status LED notification during wake-up. --- diff --git a/firmware/buttons.c b/firmware/buttons.c index 679d958..0742f92 100644 --- a/firmware/buttons.c +++ b/firmware/buttons.c @@ -5,6 +5,7 @@ #include "lights.h" +#define WAKEUP_LIMIT 5 // times 100 ms static uint16_t button_start[N_BUTTONS]; static unsigned char prev_pin; @@ -113,8 +114,12 @@ static inline void long_press(unsigned char button) void init_buttons() { - DDRA &= ~(_BV(PA3) | _BV(PA4)); - PORTA |= _BV(PA3) | _BV(PA4); + DDRA &= ~(_BV(PA3) | _BV(PA4)); // set as input + PORTA |= _BV(PA3) | _BV(PA4); // enable internal pull-ups + + GIMSK &= ~(_BV(PCIE0) | _BV(PCIE1)); // disable pin-change IRQs + PCMSK0 = 0; // disable pin-change IRQs on all pins of port A + PCMSK1 = 0; // disable pin-change IRQs on all pins of port B button_start[0] = 0; button_start[1] = 0; @@ -122,6 +127,19 @@ void init_buttons() user_params_state = 0; } +void susp_buttons() +{ + DDRA &= ~(_BV(PA3) | _BV(PA4)); // set as input + PORTA |= _BV(PA3) | _BV(PA4); // enable internal pull-ups + + GIMSK &= ~_BV(PCIE1); // disable pin-change IRQ on port B + GIMSK |= _BV(PCIE0); + + PCMSK0 = _BV(PCINT3) | _BV(PCINT4); + // disable pin-change IRQs on all pins except PA3,PA4 + PCMSK1 = 0; // disable pin-change IRQs on all pins of port B +} + static void handle_button(unsigned char button, unsigned char cur, unsigned char prev) { @@ -166,3 +184,28 @@ void timer_check_buttons() } } +unsigned char buttons_wait_for_release() +{ + uint16_t wake_count = 0; + unsigned char pin; + + do { + if (wake_count++ > WAKEUP_LIMIT) + gpio_set(0, 1); // inform the user + + _delay_ms(100); + + pin = PINA & (_BV(PA3) | _BV(PA4)); + } while (!(pin & _BV(PA3)) || !(pin & _BV(PA4))); + + gpio_set(0, 0); + + return wake_count > WAKEUP_LIMIT; + +} + +ISR(PCINT_vect) +{ + // empty - let it wake us from sleep, but do nothing else +} + diff --git a/firmware/lights.h b/firmware/lights.h index d51e977..0f18a78 100644 --- a/firmware/lights.h +++ b/firmware/lights.h @@ -81,9 +81,11 @@ pattern_t *number_pattern(unsigned char num); /* buttons.c */ #define MAX_USER_PARAMS 3 void init_buttons(); +void susp_buttons(); void timer_check_buttons(); unsigned char get_user_param(unsigned char param); pattern_t *status_pattern_select(unsigned char n); +unsigned char buttons_wait_for_release(); /* battery.c */ extern volatile unsigned char battery_100mv; diff --git a/firmware/main.c b/firmware/main.c index ea3bb69..8166771 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -10,6 +10,7 @@ static void hw_setup() { wdt_enable(WDTO_1S); + init_battery(); init_pwm(); init_adc(); @@ -30,59 +31,32 @@ static void hw_suspend() susp_adc(); susp_tmr(); susp_gpio(); + susp_buttons(); + wdt_disable(); } - void power_down() { - uint16_t wake_count = 0; - unsigned char btn; - hw_suspend(); -sleep_again: - // enable PCINT14, so that user can wake up later - GIMSK |= _BV(PCIE1); - PCMSK1 |= _BV(PCINT14); - - // G'night - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - sleep_enable(); - sleep_bod_disable(); - sei(); - sleep_cpu(); - - // G'morning - cli(); - - sleep_disable(); - - // Disable PCINT14 - GIMSK &= ~_BV(PCIE1); - PCMSK1 &= ~_BV(PCINT14); - - // allow wakeup by long button-press only - for (btn = 0; btn < 5; btn++) { - if ((PINB & _BV(PB6)) != 0) { - wake_count++; - goto sleep_again;; - } - _delay_ms(100); - } - // ok, so I will wake up - log_byte(0xb1); - log_word(wake_count); - log_flush(); + do { + // G'night + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + sleep_enable(); + sleep_bod_disable(); + sei(); + sleep_cpu(); - hw_setup(); -} + // G'morning + cli(); + sleep_disable(); + // allow wakeup by long button-press only + } while (!buttons_wait_for_release()); -ISR(PCINT_vect) -{ - GIMSK &= ~_BV(PCIE1); - PCMSK1 &= ~_BV(PCINT14); + // ok, so I will wake up + hw_setup(); } int main(void)