]> www.fi.muni.cz Git - bike-lights.git/blobdiff - firmware/buttons.c
ambient light: consistent init function naming
[bike-lights.git] / firmware / buttons.c
index 2419e89e86dd83b2d1091094193e52dc797f0f78..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;
 
@@ -40,7 +41,7 @@ pattern_t *status_pattern_select(unsigned char n)
                // error led
                return number_pattern(1 + ambient_zone);
        } else {
-               return off_pattern; // for now
+               return jiffies > 500 ? number_pattern(2) : zero_pattern; // for now
        }
 }
 
@@ -79,7 +80,7 @@ static inline void short_press(unsigned char button)
                if (user_params[param])
                        user_params[param]--;
                else
-                       user_params[param] = user_params_max[param];
+                       user_params[param] = user_params_max[param]-1;
        } else {
                user_params[param]++;
 
@@ -103,7 +104,7 @@ static inline void long_press(unsigned char button)
        // button 1 - cycle through states
        user_params_state++;
 
-       if (user_params_state >= MAX_USER_PARAMS)
+       if (user_params_state > MAX_USER_PARAMS)
                user_params_state = 1;
 
        set_status_led(0, status_pattern_select(0));
@@ -113,12 +114,30 @@ 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;
        prev_pin = _BV(PA3) | _BV(PA4);
+       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,
@@ -158,10 +177,35 @@ void timer_check_buttons()
 
        prev_pin = pin;
 
-       if (jiffies - user_params_starttime > 500) {
+       if (user_params_state && jiffies - user_params_starttime > 1000) {
                user_params_state = 0;
                set_status_led(0, status_pattern_select(0));
                set_status_led(1, status_pattern_select(1));
        }
 }
 
+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
+}
+