#include <avr/io.h>
#include <util/delay.h>
+#include <util/atomic.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include "lights.h"
+static unsigned char prev_jiffies_8;
+
static void hw_setup()
{
init_battery();
hw_setup();
power_down(mcusr_save & _BV(WDRF));
+ prev_jiffies_8 = jiffies;
+
sei();
}
+static void inline do_timer()
+{
+ // For now, we run them all in their own atomic blocks
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ timer_check_buttons();
+ }
+ 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);
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)
}
ISR(WDT_vect) {
- ++jiffies;
-
- timer_check_buttons();
- patterns_next_tick();
- pwm_disable_if_not_needed();
- timer_start_slow_adcs();
-
- if ((jiffies & 0x7FF) == 0)
- ambient_log_min_max();
-
WDTCR |= _BV(WDIE); // avoid WDT reset next time
+ ++jiffies;
}