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.
+#define WAKEUP_LIMIT 5 // times 100 ms
static uint16_t button_start[N_BUTTONS];
static unsigned char prev_pin;
static uint16_t button_start[N_BUTTONS];
static unsigned char prev_pin;
- 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;
button_start[0] = 0;
button_start[1] = 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)
{
static void handle_button(unsigned char button, unsigned char cur,
unsigned char prev)
{
+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
+}
+
/* buttons.c */
#define MAX_USER_PARAMS 3
void init_buttons();
/* buttons.c */
#define MAX_USER_PARAMS 3
void init_buttons();
void timer_check_buttons();
unsigned char get_user_param(unsigned char param);
pattern_t *status_pattern_select(unsigned char n);
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;
/* battery.c */
extern volatile unsigned char battery_100mv;
static void hw_setup()
{
wdt_enable(WDTO_1S);
static void hw_setup()
{
wdt_enable(WDTO_1S);
init_battery();
init_pwm();
init_adc();
init_battery();
init_pwm();
init_adc();
susp_adc();
susp_tmr();
susp_gpio();
susp_adc();
susp_tmr();
susp_gpio();
- uint16_t wake_count = 0;
- unsigned char btn;
-
-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();
+ // 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();