2 * The Sphinx -- A Device for Asking Riddles at the Entrance to the Garage
4 * (c) 2017 Martin Mares <mj@ucw.cz>
8 * Pin assignment (component side view; "*" marks inverted signals)
10 * +-------------------+
12 * button* | PB3 PB2=SCK |
13 * output | PB4 PB1=MISO |
14 * | GND PB0=MOSI | diagnostic LED*
15 * +-------------------+
17 * Note that MOSI is used for programming, so the LED is connected
18 * via jumper, which must be open during programming.
21 #define F_CPU 1200000UL
23 #include <avr/interrupt.h>
25 #include <avr/sleep.h>
26 #include <util/delay.h>
31 #define B(x) (1U<<(x))
33 static void sleep(uint16_t millisec)
41 static byte out_pulse;
42 #define OUT_PULSE_WIDTH 100
44 #define DEBOUNCE_THRESHOLD 3
46 static u16 press_timer;
47 #define LONG_PRESS 150
48 static byte second_timer;
50 #define UNLOCK_SECONDS 60
74 if (debounce < DEBOUNCE_THRESHOLD)
81 if (!(second_timer & 7))
87 unlocked = UNLOCK_SECONDS;
95 if (press_timer < LONG_PRESS) {
97 if (press_timer == LONG_PRESS) {
98 out_pulse = OUT_PULSE_WIDTH;
100 unlocked = UNLOCK_SECONDS;
109 // PB0: output for diagnostic LED
112 // PB3: button input, needs pull up
115 // PB4: output to control the gate
119 for (byte i=0; i<5; i++) {
140 // Set up timer interrupt
141 TCCR0A = 0x02; // No OC pins, clear on compare
142 TCCR0B = 0x05; // Run at CLK_IO / 1024
143 OCR0A = 11; // Approximately once in 10ms
144 TIMSK0 = B(OCIE0A); // Interrupt on compare
147 // Sleep well, my little sphinx
149 set_sleep_mode(SLEEP_MODE_IDLE);