]> www.fi.muni.cz Git - bike-lights.git/blob - firmware/main.c
main.c: split up the main() function
[bike-lights.git] / firmware / main.c
1 #include <avr/io.h>
2 #include <util/delay.h>
3 #include <avr/sleep.h>
4 #include <avr/interrupt.h>
5 #include <avr/power.h>
6 #include <avr/wdt.h>
7
8 #include "lights.h"
9
10 static void hw_setup()
11 {
12         init_battery();
13         init_pwm();
14         init_adc();
15         init_tmr();
16         init_buttons();
17
18         init_pwmled();
19         init_gpio();
20         init_ambient();
21         init_pattern();
22         init_control();
23
24         set_sleep_mode(SLEEP_MODE_IDLE);
25 }
26
27 static void inline hw_suspend()
28 {
29         susp_pwm();
30         susp_adc();
31         susp_tmr();
32         susp_gpio();
33         susp_ambient();
34         susp_buttons();
35 }
36
37 void power_down(unsigned char err)
38 {
39         hw_suspend();
40
41         do {
42                 if (err)
43                         gpio_set(0, 1);
44
45                 // G'night
46                 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
47                 sleep_enable();
48                 sleep_bod_disable();
49                 sei();
50                 sleep_cpu();
51
52                 // G'morning
53                 cli();
54                 sleep_disable();
55
56                 // allow wakeup by long button-press only
57         } while (!buttons_wait_for_release());
58
59         // ok, so I will wake up
60         hw_setup();
61 }
62
63 static void inline first_boot()
64 {
65         unsigned char mcusr_save;
66
67         // disable the WDT if running
68         wdt_reset();
69         mcusr_save = MCUSR;
70         MCUSR = 0;
71         wdt_disable();
72
73         if (mcusr_save & _BV(WDRF)) // was watchdog reset?
74                 gpio_set(0, 1);
75
76         init_log(mcusr_save);
77
78         power_usi_disable(); // Once for lifetime
79         ACSRA |= _BV(ACD);   // disable analog comparator
80
81         log_set_state(3);
82
83         hw_setup();
84         power_down(mcusr_save & _BV(WDRF));
85
86         sei();
87 }
88
89 static void inline main_loop_iteration()
90 {
91         cli();
92         if (TIMER1_IS_ON()) {
93                 set_sleep_mode(SLEEP_MODE_IDLE);
94         } else if (adc_is_on) {
95                 set_sleep_mode(SLEEP_MODE_ADC);
96         } else {
97                 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
98         }
99
100         sleep_enable();
101         // keep BOD active, no sleep_bod_disable();
102         sei();
103         sleep_cpu();
104         sleep_disable();
105 }
106
107 int main(void)
108 {
109         first_boot();
110
111         while (1)
112                 main_loop_iteration();
113
114 #if 0
115         DDRB |= _BV(PB2);
116         while (1) {
117                 PORTB |=  _BV( PB2 );
118                 _delay_ms(200);
119                 PORTB &=~ _BV( PB2 );
120                 _delay_ms(200);
121         }
122 #endif
123 }