]> www.fi.muni.cz Git - bike-lights.git/blob - firmware/main.c
main.c: allow only long keypress to wake us
[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 void hw_setup()
11 {
12         wdt_enable(WDTO_1S);
13         init_pwm();
14         init_adc();
15         init_tmr();
16         init_buttons();
17
18         pwmled_init();
19         gpio_init();
20         ambient_init();
21         pattern_init();
22
23         set_sleep_mode(SLEEP_MODE_IDLE);
24 }
25
26 void hw_suspend()
27 {
28         susp_pwm();
29         susp_adc();
30         susp_tmr();
31         susp_gpio();
32         wdt_disable();
33 }
34
35
36 void power_down()
37 {
38         uint16_t wake_count = 0;
39         unsigned char btn;
40
41 sleep_again:
42         // enable PCINT14, so that user can wake up later
43         GIMSK |= _BV(PCIE1);
44         PCMSK1 |= _BV(PCINT14);
45
46         // G'night
47         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
48         sleep_enable();
49         sleep_bod_disable();
50         sei();
51         sleep_cpu();
52
53         // G'morning
54         cli();
55
56         sleep_disable();
57
58         // Disable PCINT14
59         GIMSK &= ~_BV(PCIE1);
60         PCMSK1 &= ~_BV(PCINT14);
61
62         // allow wakeup by long button-press only
63         for (btn = 0; btn < 5; btn++) {
64                 if ((PINB & _BV(PB6)) != 0) {
65                         wake_count++;
66                         goto sleep_again;;
67                 }
68                 _delay_ms(100);
69         }
70
71         // ok, so I will wake up
72         log_byte(0xb1);
73         log_word(wake_count);
74         log_flush();
75
76         hw_setup();
77 }
78
79
80 ISR(PCINT_vect)
81 {
82         GIMSK &= ~_BV(PCIE1);
83         PCMSK1 &= ~_BV(PCINT14);
84 }
85
86 int main(void)
87 {
88         log_init();
89         power_usi_disable(); // Once for lifetime
90
91         log_set_state(3);
92
93         hw_setup();
94         hw_suspend();
95         power_down();
96
97         sei();
98 #if 1
99         while (1) {
100                 wdt_reset();
101                 sleep_mode();
102         }
103 #endif
104
105 #if 0
106         DDRB |= _BV(PB2);
107         while (1) {
108                 PORTB |=  _BV( PB2 );
109                 _delay_ms(200);
110                 PORTB &=~ _BV( PB2 );
111                 _delay_ms(200);
112         }
113 #endif
114 }