]> www.fi.muni.cz Git - bike-lights.git/blob - firmware/buttons.c
mudflap for dual rearlights
[bike-lights.git] / firmware / buttons.c
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <avr/sleep.h>
4 #include <util/delay.h>
5
6 #include "lights.h"
7
8 static uint16_t button_start[N_BUTTONS];
9 static unsigned char button_pressed[N_BUTTONS];
10 static unsigned char just_waked_up;
11
12 void init_buttons()
13 {
14         unsigned char i;
15
16         DDRB &= ~(_BV(PB4) | _BV(PB6));
17         PORTB |=  _BV(PB4) | _BV(PB6);
18
19         for (i=0; i < N_BUTTONS; i++) {
20                 button_start[i] = 0;
21                 button_pressed[i] = 0;
22         }
23
24         just_waked_up = 1;
25
26         // log_byte(PORTB);
27 }
28
29 static void do_sleep()
30 {
31         log_byte(0xb0);
32         log_flush();
33
34         hw_suspend();
35         gpio_before_poweroff(); // Set the status LED on again
36
37         while((PINB & _BV(PB6)) == 0)
38                 ; // wait for button release
39
40         _delay_ms(100);
41
42         susp_gpio(); // disable the status LED
43
44         power_down();
45 }
46
47 static void inline long_press(unsigned char n)
48 {
49         if (n == 0)
50                 do_sleep();
51 }
52
53 static void inline short_press(unsigned char n)
54 {
55         if (n == 0)
56                 gpio_set(2,1);
57 }
58
59 void timer_check_buttons()
60 {
61         unsigned char pinb = PINB;
62         unsigned char i;
63         unsigned char port_states[N_BUTTONS] = {
64                 pinb & _BV(PB6),
65                 pinb & _BV(PB4),
66         };
67
68         for (i = 0; i < N_BUTTONS; i++) {
69                 if (!port_states[i]) { // is pressed
70                         if (i == 0 && just_waked_up)
71                                 continue;
72                         if (button_pressed[i] == 0) {
73                                 // begin of button press
74                                 button_pressed[i] = 1;
75                                 button_start[i] = jiffies;
76 #if 0
77                                 log_byte(0xC0);
78                                 log_word(jiffies);
79 #endif
80                         } else if (button_pressed[i] == 1) {
81                                 // been already pressed
82                                 uint16_t duration = jiffies - button_start[i];
83                                 if (duration > 80) {
84                                         // long button press
85                                         button_pressed[i] = 2;
86                                         long_press(i);
87                                 }
88                         }
89                 } else { // is not pressed
90                         if (i == 0)
91                                 just_waked_up = 0;
92                         if (button_pressed[i]) { // just depressed
93                                 uint16_t duration = jiffies - button_start[i];
94 #if 1
95                                 log_byte(0xC1);
96                                 log_word(duration);
97                                 log_flush();
98 #endif
99                                 button_pressed[i] = 0;
100                                 if (duration > 6 && duration < 30)
101                                         short_press(i);
102                         }
103                 }
104         }
105 }
106