1 #include <avr/interrupt.h>
6 #include <util/delay.h>
10 static unsigned char pwm = 1;
12 static void timer_init()
14 power_timer1_enable();
18 TCCR1 = _BV(CS10); // clk/1 = 1 MHz
19 // TCCR1 = _BV(CS11) | _BV(CS13); // clk/512 = 2 kHz
20 GTCCR = _BV(COM1B1) | _BV(PWM1B);
25 static void adc_init()
29 ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0); // clk/8 = 125 kHz
30 ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0); // 1.1V ref., PB3 single-ended
34 static void status_led_init()
40 static void status_led_on()
45 static void status_led_off()
50 static void buttons_init()
52 DDRB &= ~(_BV(PB0) | _BV(PB1)); // set as input
53 PORTB |= _BV(PB0) | _BV(PB1); // internal pull-up
55 GIMSK &= ~_BV(PCIE); // disable pin-change IRQs
56 PCMSK = 0; // disable pin-change IRQs on all pins of port B
59 static void buttons_susp()
64 PCMSK |= _BV(PCINT0) | _BV(PCINT1);
67 static unsigned char buttons_pressed()
70 (PINB & _BV(PB0) ? 0 : 1)
72 (PINB & _BV(PB1) ? 0 : 2)
76 #define WAKEUP_POLL 100 // msec
77 #define WAKEUP_LIMIT 5 // times WAKEUP_POLL
79 static unsigned char buttons_wait_for_release()
81 uint16_t wake_count = 0;
84 if (++wake_count > WAKEUP_LIMIT)
85 status_led_on(); // inform the user
87 _delay_ms(WAKEUP_POLL);
88 } while (buttons_pressed());
92 return wake_count > WAKEUP_LIMIT;
97 // empty - let it wake us from sleep, but do nothing else
100 static void wdt_init()
102 WDTCR = _BV(WDIE) | _BV(WDP1); // interrupt mode, 64 ms
105 static void wdt_susp()
110 static void hw_setup()
120 static void hw_suspend()
122 ADCSRA &= ~_BV(ADEN); // disable ADC
123 TCCR1 = 0; // disable T/C 1
132 static volatile unsigned char wdt_timer_fired;
138 static void power_down()
144 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
154 // allow wakeup by long button-press only
155 } while (!buttons_wait_for_release());
161 static void button_one_pressed()
171 static void button_two_pressed()
179 static unsigned char button_state, button_state_time;
181 static void timer_check_buttons()
183 unsigned char newstate = buttons_pressed();
185 if (newstate == button_state) {
186 if (newstate && button_state_time < 4)
192 button_state = newstate;
193 button_state_time = 0;
198 switch (button_state) {
199 case 1: button_one_pressed();
201 case 2: button_two_pressed();
203 default: // ignore when both are preseed
207 button_state = newstate;
218 while (!(ADCSRA & _BV(ADIF)))
222 while (!(ADCSRA & _BV(ADIF)))
229 // we try to be completely IRQ-driven, so just wait for IRQs here
232 set_sleep_mode(SLEEP_MODE_IDLE);
234 // keep BOD active, no sleep_bod_disable();
239 if (wdt_timer_fired) {
241 timer_check_buttons();