]> www.fi.muni.cz Git - bike-lights.git/commitdiff
buttons, wakeup rework
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 30 Nov 2012 09:58:31 +0000 (10:58 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 30 Nov 2012 10:02:42 +0000 (11:02 +0100)
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.

firmware/buttons.c
firmware/lights.h
firmware/main.c

index 679d958cbec7e1585ae0e661a0140a740d0f3370..0742f927fb668a17d83d4ca3698e475f5f5a89f5 100644 (file)
@@ -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
+}
+
index d51e977322da11d3660dac200dd0d09c2808c37a..0f18a7875d6f2a15ec0eeff01b2c8374e8d855d6 100644 (file)
@@ -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;
index ea3bb69d1384dd5840c5e6a90066dda0807a229c..8166771478bd207e8cced92f6bf9f11eaef4a754 100644 (file)
@@ -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)