2 #include <util/delay.h>
3 #include <util/atomic.h>
5 #include <avr/interrupt.h>
11 static unsigned char prev_jiffies_8;
13 static void hw_setup()
27 set_sleep_mode(SLEEP_MODE_IDLE);
30 static void inline hw_suspend()
40 void power_down(unsigned char err)
49 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
59 // allow wakeup by long button-press only
60 } while (!buttons_wait_for_release());
62 // ok, so I will wake up
66 static void inline first_boot()
68 unsigned char mcusr_save;
70 // disable the WDT if running
76 if (mcusr_save & _BV(WDRF)) // was watchdog reset?
81 power_usi_disable(); // Once for lifetime
82 ACSRA |= _BV(ACD); // disable analog comparator
87 power_down(mcusr_save & _BV(WDRF));
89 prev_jiffies_8 = jiffies;
94 static void inline do_timer()
96 // For now, we run them all in their own atomic blocks
97 ATOMIC_BLOCK(ATOMIC_FORCEON) {
98 timer_check_buttons();
100 ATOMIC_BLOCK(ATOMIC_FORCEON) {
101 patterns_next_tick();
103 ATOMIC_BLOCK(ATOMIC_FORCEON) {
104 pwm_disable_if_not_needed();
106 ATOMIC_BLOCK(ATOMIC_FORCEON) {
107 timer_start_slow_adcs();
109 ATOMIC_BLOCK(ATOMIC_FORCEON) {
110 if ((jiffies & 0x1FF) == 0)
111 ambient_log_min_max();
115 static void inline main_loop_iteration()
117 unsigned char jiffies_8; /*
118 * we use only lower 8-bits in order to
119 * avoid the need for locking of 16-bit
124 if (TIMER1_IS_ON()) {
125 set_sleep_mode(SLEEP_MODE_IDLE);
126 } else if (adc_is_on) {
127 set_sleep_mode(SLEEP_MODE_ADC);
129 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
133 // keep BOD active, no sleep_bod_disable();
140 if (jiffies_8 != prev_jiffies_8) { // was timer IRQ
141 if (jiffies_8 - prev_jiffies_8 > 1) { // overrun
143 log_byte(jiffies_8 - prev_jiffies_8);
147 prev_jiffies_8 = jiffies_8;
158 main_loop_iteration();
165 PORTB &=~ _BV( PB2 );