2 #include <avr/interrupt.h>
4 #include <util/delay.h>
5 #include <stdlib.h> // for NULL
9 #define WAKEUP_LIMIT 5 // times 100 ms
10 #define SHORT_PRESS_MIN 10 // in jiffies (100 Hz ticks)
11 #define SHORT_PRESS_MAX 50
12 #define LONG_PRESS_MIN 100
13 static uint16_t button_start;
14 static unsigned char prev_state;
16 void status_led_on_off(unsigned char mode)
21 PORTB &= ~_BV(PORTB1);
28 PORTB |= _BV(PORTB0); // enable internal pull-up
29 PORTB &= ~_BV(PORTB1); // status led off
30 GIMSK &= ~_BV(PCIE); // disable pin-change IRQs
31 PCMSK = 0; // disable pin-change IRQs on all pins of port B
39 DDRB &= ~(_BV(DDB0)); // set as input
40 PORTB |= _BV(PORTB0); // enable internal pull-up
41 PORTB &= ~_BV(PORTB1); // set to zero
46 // disable pin-change IRQs on all pins except PB1
49 void timer_check_buttons()
51 unsigned char cur = !(PINB & _BV(PINB0));
52 unsigned char prev = prev_state;
56 if (cur && !prev) { // --- just pressed ---
57 button_start = jiffies;
58 // set_status_led(button, NULL);
60 } else if (cur && prev) { // --- is still pressed ---
61 uint16_t duration = jiffies - button_start;
63 if (duration > LONG_PRESS_MIN) {
65 // acknowledge long press
67 } else if (!cur && prev) { // --- just released ---
68 uint16_t duration = jiffies - button_start;
70 if (duration > SHORT_PRESS_MIN && duration < SHORT_PRESS_MAX) {
72 } else if (duration > LONG_PRESS_MIN) {
73 // set_status_led(button, NULL);
76 // ignore other button-press durations
81 static void handle_brake(unsigned char cur, unsigned char prev)
83 if (cur && !prev) { // --- just pressed ---
84 button_start[2] = jiffies;
85 } else if (!cur && prev) { // --- just released ---
86 button_start[2] = jiffies;
87 } else { // --- no change ---
88 uint16_t duration = jiffies - button_start[2];
92 if (button_state.brake_working
93 && !button_state.brake_reported) {
94 button_state.brake_reported = 1;
98 button_state.brake_working = 1;
99 if (button_state.brake_reported) {
100 button_state.brake_reported = 0;
104 button_start[2] = jiffies - 7; // avoid overflow
110 unsigned char buttons_wait_for_release()
112 uint16_t wake_count = 0;
116 if (wake_count++ > WAKEUP_LIMIT)
117 status_led_on_off(1); // inform the user
121 pin = PINB & _BV(PINB0);
122 } while (!(pin & _BV(PINB0)));
124 status_led_on_off(0);
126 return wake_count > WAKEUP_LIMIT;
131 // empty - let it wake us from sleep, but do nothing else