X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=bike-lights.git;a=blobdiff_plain;f=firmware%2Fmain.c;h=e6f03b01fafa1156aeb86cc01cb7da7eabc62f1c;hp=02e75d9adfdc868d53aceede6cc9c0cd00f82f1d;hb=6ce11e298f73e160555e2bf4dd3d88f120fbdebd;hpb=47e678a90062fa2dbc6cb8f9e5efc81072f5dcc5 diff --git a/firmware/main.c b/firmware/main.c index 02e75d9..e6f03b0 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -9,99 +9,107 @@ static void hw_setup() { - wdt_enable(WDTO_1S); init_battery(); init_pwm(); init_adc(); init_tmr(); init_buttons(); - pwmled_init(); - gpio_init(); - ambient_init(); - pattern_init(); + init_pwmled(); + init_gpio(); + init_ambient(); + init_pattern(); + init_control(); set_sleep_mode(SLEEP_MODE_IDLE); } -static void hw_suspend() +static void inline hw_suspend() { susp_pwm(); susp_adc(); susp_tmr(); susp_gpio(); - wdt_disable(); + susp_ambient(); + susp_buttons(); } - -void power_down() +void power_down(unsigned char err) { - 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(); + do { + if (err) + gpio_set(0, 1); - // Disable PCINT14 - GIMSK &= ~_BV(PCIE1); - PCMSK1 &= ~_BV(PCINT14); + // G'night + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + sleep_enable(); + sleep_bod_disable(); + sei(); + sleep_cpu(); - // 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); - } + // G'morning + cli(); + sleep_disable(); - // ok, so I will wake up - log_byte(0xb1); - log_word(wake_count); - log_flush(); + // allow wakeup by long button-press only + } while (!buttons_wait_for_release()); + // ok, so I will wake up hw_setup(); } - -ISR(PCINT_vect) +static void inline first_boot() { - GIMSK &= ~_BV(PCIE1); - PCMSK1 &= ~_BV(PCINT14); -} + unsigned char mcusr_save; + + // disable the WDT if running + wdt_reset(); + mcusr_save = MCUSR; + MCUSR = 0; + wdt_disable(); + + if (mcusr_save & _BV(WDRF)) // was watchdog reset? + gpio_set(0, 1); + + init_log(mcusr_save); -int main(void) -{ - log_init(); power_usi_disable(); // Once for lifetime + ACSRA |= _BV(ACD); // disable analog comparator log_set_state(3); hw_setup(); - power_down(); + power_down(mcusr_save & _BV(WDRF)); sei(); -#if 1 - while (1) { - wdt_reset(); - sleep_mode(); +} + +static void inline main_loop_iteration() +{ + cli(); + if (TIMER1_IS_ON()) { + set_sleep_mode(SLEEP_MODE_IDLE); + } else if (adc_is_on) { + set_sleep_mode(SLEEP_MODE_ADC); + } else { + set_sleep_mode(SLEEP_MODE_PWR_DOWN); } -#endif + + sleep_enable(); + // keep BOD active, no sleep_bod_disable(); + sei(); + sleep_cpu(); + sleep_disable(); +} + +int main(void) +{ + first_boot(); + + while (1) + main_loop_iteration(); #if 0 DDRB |= _BV(PB2);