diff options
| author | David Lamparter <equinox@diac24.net> | 2011-03-06 06:37:14 +0100 |
|---|---|---|
| committer | David Lamparter <equinox@diac24.net> | 2011-03-06 06:37:14 +0100 |
| commit | 75ff498d410a42b4cce52409f2abcfa9e3856143 (patch) | |
| tree | cbf465f82edf39e8097a9c1e70630f6df7df4ba7 | |
| parent | fb92f1bb096bdf7bddb6bb66c931d4212fbc5588 (diff) | |
intermediate version
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | kbc.c | 164 |
2 files changed, 104 insertions, 65 deletions
@@ -5,2 +5,3 @@ AOBJCOPY=avr-objcopy ALD=avr-ld +ASIZE=avr-size CFLAGS=-Wall -Wextra -Wno-unused-parameter -pedantic -std=c99 @@ -25,3 +26,4 @@ love: kbc.flash %.ld.o: %.o - $(ACC) $(ACFLAGS) $(ALDFLAGS) -o $@ $< + $(ACC) $(ACFLAGS) $(ALDFLAGS) -Wl,-Map,$(patsubst %.ld.o,%.map,$@) -o $@ $< + @$(ASIZE) $@ @@ -37,2 +39,3 @@ clean: .PHONY: love flash clean +.SECONDARY: @@ -6,2 +6,3 @@ #include <avr/sleep.h> +#include <avr/pgmspace.h> #include <util/delay.h> @@ -52,3 +53,6 @@ enum state { STATE_ACCEPT, - STATE_REJECT + STATE_REJECT, +#ifdef KILLSWITCH + STATE_ERROR, +#endif }; @@ -122,14 +126,3 @@ static volatile uint8_t statecntr = 0; #define mayabort if (TIFR0 & (1 << TOV0)) return bit; -#if 0 -#define _wait_CLK(cond) do { \ - p2 = p1 = p0 = PIND; \ - while (cond) { \ - p2 = p1; p1 = p0; p0 = PIND; \ - __asm__ volatile ("nop\n"); \ - mayabort; \ - } \ - } while (0) -#else #define _wait_CLK(cond) while(cond) { mayabort; } -#endif #define wait_CLKlo _wait_CLK( PIND /* & p0 & p1 & p2 */ & D_CLK) @@ -160,3 +153,2 @@ static uint16_t do_send_byte(uint8_t byte) uint8_t bit = 0, parity = 1, rv, usarts; - uint8_t p2, p1, p0; @@ -262,9 +254,5 @@ static uint8_t send_byte(uint8_t byte) rv = do_send_byte(byte); - if (rv == 0x1fa) { - dbg_wr(0x14); - dbg_wr(0x80 | (byte & 0x0f)); - dbg_wr(0x80 | (byte >> 4)); - dbg_wr(0x80 | attempts); + if (rv == 0x1fa) goto out; - } + /* clear state, wait, retry */ @@ -273,10 +261,4 @@ static uint8_t send_byte(uint8_t byte) - if (rv == 0x1fe) { - dbg_wr(0xfe); + if (rv == 0x1fe) _delay_ms(33); - } else { - dbg_wr(0x08); - dbg_wr(0x80 | (rv & 0x7f)); - dbg_wr(0x80 | (rv >> 7)); - } } @@ -311,3 +293,2 @@ static uint8_t wait_byte(void) - dbg_wr(0x02); return 0; @@ -323,9 +304,2 @@ static uint8_t wait_byte(void) - dbg_wr(0x19); - dbg_wr(0x80 | (state)); - dbg_wr(0x80 | (usarts & 0x0f)); - dbg_wr(0x80 | (usarts >> 4)); - dbg_wr(0x80 | (data & 0x0f)); - dbg_wr(0x80 | (data >> 4)); - return data; @@ -347,2 +321,3 @@ static uint8_t wait_byte(void) #define CNTR_BLINK 6 +#define CNTR_ERROR 61 @@ -354,3 +329,7 @@ static uint8_t cntr = 0; -static const char passwd[sizeof(PIN)] = PIN; +#ifdef KILLSWITCH +static uint8_t error; +#endif + +static const char passwd[sizeof(PIN) - 1] = PIN; static char code[sizeof(PIN)]; @@ -359,5 +338,2 @@ static void state_enter(void) { - dbg_wr(0x11); - dbg_wr(state); - switch (state) { @@ -392,2 +368,3 @@ static void state_enter(void) break; +#if 0 /* scan code set 3 */ @@ -400,2 +377,3 @@ static void state_enter(void) break; +#endif nextstate = STATE_IDLE; @@ -442,2 +420,13 @@ static void state_enter(void) break; +#ifdef KILLSWITCH + case STATE_ERROR: + statecntr = 1; + cntr = CNTR_ERROR; + error ^= KBLED_ERROR; + if (send_byte(0xed) != 0xfa) + break; + if (send_byte(error) != 0xfa) + break; + break; +#endif } @@ -469,2 +458,7 @@ static void state_timeout(void) break; +#ifdef KILLSWITCH + case STATE_ERROR: + state = STATE_ERROR; + break; +#endif } @@ -482,11 +476,29 @@ ISR(SIG_OVERFLOW0) -static const char kbc_60[24] = { +#define ESC 0x1b +#define ENT 0x0d + +#define KBC_BASE 0x16 +const PROGMEM char kbc[] = { +/* 0 1 2 3 4 5 6 7 + * 8 9 a b c d e f + */ + '1', '_', /* 10 - 17 */ + '_', '_', '_', '_', '_', '_', '2', '_', /* 18 - 1f */ + '_', '_', '_', '_', '_', '4', '3', '_', /* 20 - 27 */ + '_', '_', '_', '_', '_', '_', '5', '_', /* 28 - 2f */ + '_', '_', '_', '_', '_', '_', '6', '_', /* 30 - 37 */ + '_', '_', '_', '_', '_', '7', '8', '_', /* 38 - 3f */ + '_', '_', '_', '_', '_', '0', '9', '_', /* 40 - 47 */ + '_', '_', '_', '_', '_', '_', '_', '_', /* 48 - 4f */ + '_', '_', '_', '_', '_', '_', '_', '_', /* 50 - 57 */ + '_', '_', ENT, '_', '_', '_', '_', '_', /* 58 - 5f */ + '_', '_', '_', '_', '_', '_', '_', '_', /* 60 - 67 */ '_', '1', '_', '4', '7', '_', '_', '_', /* 68 - 6f */ - '0', '.', '2', '5', '6', '8', '_', '/', /* 70 - 77 */ - '_', '_', '3', '_', '+', '9', '*', '_' /* 78 - 7f */ + '0', '_', '2', '5', '6', '8', ESC, ESC, /* 70 - 77 */ + '_', '_', '3', '_', '_', '9' /* 78 - 7f */ }; -#define KC_ESC 0x08 -#define KC_ENTER 0x5a -#define KC_NUM 0x76 -#define KC_NP_ENTER 0x79 + +#define NUMPAD_ENTER 0xda /* e0 5a */ + +static uint8_t pressed = 0, e0 = 0, release = 0; @@ -498,10 +510,48 @@ static void handle_keypress(uint8_t data) - lock = data == KC_ESC || data == KC_NUM; - unlock = data == KC_ENTER || data == KC_NP_ENTER; + if (release) { + pressed = 0; + release = 0; + return; + } + if (data == pressed) + return; + + if (data == 0xe0) { + e0 = 0x80; + return; + } + if (data == 0xf0) { + release = 1; + return; + } + if (data >= 0x80) + return; + + pressed = data; + + data |= e0; + e0 = 0; + + if (data >= KBC_BASE && data < KBC_BASE + sizeof(kbc)) + ascii = pgm_read_byte(kbc + data - KBC_BASE); + + dbg_wr(0x03); + dbg_wr(0x80 | (ascii & 0xf)); + dbg_wr(0x80 | (ascii >> 4)); + + lock = ascii == ESC; + unlock = ascii == ENT || data == NUMPAD_ENTER; if (lock || unlock) { - /* passwd: a b c d \0 + /* passwd: a b c d * code: \0 a b c d */ - if (code[0] || memcmp(passwd, code + 1, sizeof(passwd) - 1)) { +#ifdef KILLSWITCH + if (code[0] || !memcmp("9164", code + 1, 4)) { + error = 0; + nextstate = STATE_ERROR; + return; + } +#endif + if (code[0] || memcmp(passwd, code + 1, sizeof(passwd))) { dbg_wr(0x20); @@ -516,5 +566,2 @@ static void handle_keypress(uint8_t data) - if (data >= 0x68 && data < 0x80) - ascii = kbc_60[data - 0x68]; - for (c = 0; c < sizeof(code) - 1; c++) @@ -525,12 +572,2 @@ static void handle_keypress(uint8_t data) nextstate = STATE_INPUT; - -#if 0 - TCNT0 = 0; - state = 1; - send_byte(0xed); - send_byte(0x00); - DDRD = DDRD_BEEP; - cntr = 0; - TIFR0 = (1 << TOV0); -#endif } @@ -553,4 +590,3 @@ ISR(SIG_USART_RECV) case STATE_INPUT: - if (data < 0x90) - handle_keypress(data); + handle_keypress(data); default: |
