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=d10a322bd34c721aca16d3bfbc63e12c2e4bb570;hp=90bea63dc60d300c3f3e6723d6f0718979167cbb;hb=HEAD;hpb=647f353f4d8c87c5cf18cae905e9d600cd0e6bcb diff --git a/firmware/main.c b/firmware/main.c index 90bea63..b3fcc65 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,10 +8,10 @@ #include "lights.h" +static unsigned char prev_jiffies_8; + static void hw_setup() { - wdt_enable(WDTO_1S); - init_battery(); init_pwm(); init_adc(); @@ -26,22 +27,24 @@ static void hw_setup() set_sleep_mode(SLEEP_MODE_IDLE); } -static void hw_suspend() +static void inline hw_suspend() { susp_pwm(); susp_adc(); susp_tmr(); susp_gpio(); + susp_ambient(); susp_buttons(); - - wdt_disable(); } -void power_down() +void power_down(unsigned char err) { hw_suspend(); do { + if (err) + gpio_set(0, 1); + // G'night set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); @@ -60,9 +63,20 @@ void power_down() hw_setup(); } -int main(void) +static void inline first_boot() { - init_log(); + 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); power_usi_disable(); // Once for lifetime ACSRA |= _BV(ACD); // disable analog comparator @@ -70,15 +84,78 @@ int main(void) log_set_state(3); hw_setup(); - power_down(); + power_down(mcusr_save & _BV(WDRF)); + + prev_jiffies_8 = jiffies; sei(); -#if 1 - while (1) { - wdt_reset(); - sleep_mode(); +} + +static void inline do_timer() +{ + // For now, we run them all in their own atomic blocks + ATOMIC_BLOCK(ATOMIC_FORCEON) { + timer_check_buttons(); } -#endif + ATOMIC_BLOCK(ATOMIC_FORCEON) { + patterns_next_tick(); + } + ATOMIC_BLOCK(ATOMIC_FORCEON) { + pwm_disable_if_not_needed(); + } + ATOMIC_BLOCK(ATOMIC_FORCEON) { + timer_start_slow_adcs(); + } + ATOMIC_BLOCK(ATOMIC_FORCEON) { + if ((jiffies & 0x7FF) == 0) + ambient_log_min_max(); + } +} + +static void inline main_loop_iteration() +{ + unsigned char jiffies_8; /* + * we use only lower 8-bits in order to + * avoid the need for locking of 16-bit + * accesses. + */ + + 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); + } + + sleep_enable(); + // keep BOD active, no sleep_bod_disable(); + sei(); + sleep_cpu(); + sleep_disable(); + + jiffies_8 = jiffies; + + if (jiffies_8 != prev_jiffies_8) { // was timer IRQ + if (jiffies_8 - prev_jiffies_8 > 1) { // overrun + log_byte(0xee); + log_byte(jiffies_8 - prev_jiffies_8); + log_flush(); + } + + prev_jiffies_8 = jiffies_8; + + do_timer(); + } +} + +int main(void) +{ + first_boot(); + + while (1) + main_loop_iteration(); #if 0 DDRB |= _BV(PB2);