2 #include <avr/interrupt.h>
4 #include <util/delay.h>
8 static uint16_t button_start[N_BUTTONS];
9 static unsigned char prev_pin;
11 static unsigned char user_params[MAX_USER_PARAMS] = { 0, 0, 0 };
12 static unsigned char user_params_max[MAX_USER_PARAMS] = { 3, 2, 2 };
14 static unsigned char user_params_state = 0;
16 * Here 0 means "no setup currently in progress",
17 * 1 .. MAX_USER_PARAMS means "now short presses increase or decrease
18 * the value of user_params[user_params_state-1]"
21 static uint16_t user_params_starttime;
23 static void inline set_status_led(unsigned char n, pattern_t *pattern)
25 led_set_pattern(n + N_PWMLEDS, pattern);
28 pattern_t *status_pattern_select(unsigned char n)
30 if (user_params_state) // Setup in progress
31 return number_pattern(n == 0
33 : 1 + user_params[user_params_state-1]
35 else if (!(prev_pin & _BV(PA3)) || !(prev_pin & _BV(PA4)))
36 // at least one button is pressed
38 // otherwise, an ordinary state
41 return number_pattern(1 + ambient_zone);
43 return off_pattern; // for now
47 static void toggle_bright_mode()
52 static void set_panic_mode()
57 unsigned char get_user_param(unsigned char param)
59 if (param < MAX_USER_PARAMS)
60 return user_params[param];
61 return 0; // FIXME: internal error?
64 static inline void short_press(unsigned char button)
68 if (user_params_state == 0) {
76 param = user_params_state-1;
79 if (user_params[param])
82 user_params[param] = user_params_max[param];
86 if (user_params[param] >= user_params_max[param])
87 user_params[param] = 0;
89 // FIXME: notify somebody about user_params change?
91 set_status_led(1, status_pattern_select(1));
93 user_params_starttime = jiffies;
96 static inline void long_press(unsigned char button)
103 // button 1 - cycle through states
106 if (user_params_state >= MAX_USER_PARAMS)
107 user_params_state = 1;
109 set_status_led(0, status_pattern_select(0));
110 set_status_led(1, status_pattern_select(1));
111 user_params_starttime = jiffies;
116 DDRA &= ~(_BV(PA3) | _BV(PA4));
117 PORTA |= _BV(PA3) | _BV(PA4);
121 prev_pin = _BV(PA3) | _BV(PA4);
122 user_params_state = 0;
125 static void handle_button(unsigned char button, unsigned char cur,
128 // BEWARE: pins are at _zero_ when pressed!
129 if (!cur && prev) { // --- just pressed ---
130 button_start[button] = jiffies;
131 set_status_led(button, off_pattern);
133 } else if (!cur && !prev) { // --- is still pressed ---
134 uint16_t duration = jiffies - button_start[button];
137 set_status_led(button, on_pattern);
138 // acknowledge long press
140 } else if (cur && !prev) { // --- just released ---
141 uint16_t duration = jiffies - button_start[button];
143 if (duration > 6 && duration < 30) {
145 } else if (duration > 80) {
146 set_status_led(button, off_pattern);
149 // ignore other button-press durations
153 void timer_check_buttons()
155 unsigned char pin = PINA & (_BV(PA3) | _BV(PA4));
157 handle_button(0, pin & _BV(PA3), prev_pin & _BV(PA3));
158 handle_button(1, pin & _BV(PA4), prev_pin & _BV(PA4));
162 if (user_params_state && jiffies - user_params_starttime > 500) {
163 user_params_state = 0;
164 set_status_led(0, status_pattern_select(0));
165 set_status_led(1, status_pattern_select(1));