From 75ff498d410a42b4cce52409f2abcfa9e3856143 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 6 Mar 2011 06:37:14 +0100 Subject: intermediate version --- kbc.c | 164 ++++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 100 insertions(+), 64 deletions(-) (limited to 'kbc.c') diff --git a/kbc.c b/kbc.c index c560326..6a04e4a 100644 --- a/kbc.c +++ b/kbc.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #ifndef PIN @@ -50,7 +51,10 @@ enum state { STATE_IDLEBLINK, STATE_INPUT, STATE_ACCEPT, - STATE_REJECT + STATE_REJECT, +#ifdef KILLSWITCH + STATE_ERROR, +#endif }; static volatile enum state state, nextstate; @@ -120,18 +124,7 @@ static void dbg_init(void) 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) #define wait_CLKhi _wait_CLK(!(PIND /* & p0 & p1 & p2 */ & D_CLK)) #define wait_CLK wait_CLKhi; wait_CLKlo; _delay_us(15) @@ -158,7 +151,6 @@ static void timer_clear(void) static uint16_t do_send_byte(uint8_t byte) { uint8_t bit = 0, parity = 1, rv, usarts; - uint8_t p2, p1, p0; usart_dis(); @@ -260,25 +252,15 @@ static uint8_t send_byte(uint8_t byte) TIFR0 = (1 << TOV0); 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 */ DDRD &= ~(D_DATA | D_CLK); PORTD |= D_DATA | D_CLK; - 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)); - } } dbg_wr(0x01); @@ -309,7 +291,6 @@ static uint8_t wait_byte(void) timer_return(); usart_rx(); - dbg_wr(0x02); return 0; } @@ -321,13 +302,6 @@ static uint8_t wait_byte(void) timer_return(); usart_rx(); - 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; } @@ -345,6 +319,7 @@ static uint8_t wait_byte(void) #define WAIT_IDLEBLINK 1 /* no full cycle */ #define CNTR_BLINK 6 +#define CNTR_ERROR 61 #define WAIT_INPUT 5 #define WAIT_ACCEPT 5 @@ -352,14 +327,15 @@ static uint8_t wait_byte(void) 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)]; static void state_enter(void) { - dbg_wr(0x11); - dbg_wr(state); - switch (state) { case STATE_NONE: case STATE_FAILURE: @@ -390,6 +366,7 @@ static void state_enter(void) break; if (wait_byte() != 0x83) break; +#if 0 /* scan code set 3 */ if (send_byte(0xf0) != 0xfa) break; @@ -398,6 +375,7 @@ static void state_enter(void) /* make codes only */ if (send_byte(0xf9) != 0xfa) break; +#endif nextstate = STATE_IDLE; break; case STATE_IDLE: @@ -440,6 +418,17 @@ static void state_enter(void) if (send_byte(KBLED_ERROR) != 0xfa) break; 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 } } @@ -467,6 +456,11 @@ static void state_timeout(void) case STATE_REJECT: state = STATE_IDLE; break; +#ifdef KILLSWITCH + case STATE_ERROR: + state = STATE_ERROR; + break; +#endif } state_enter(); } @@ -480,15 +474,33 @@ 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; static void handle_keypress(uint8_t data) { @@ -496,14 +508,52 @@ static void handle_keypress(uint8_t data) uint8_t ascii = '_'; uint8_t c; - 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); nextstate = STATE_REJECT; } else { @@ -514,25 +564,12 @@ static void handle_keypress(uint8_t data) return; } - if (data >= 0x68 && data < 0x80) - ascii = kbc_60[data - 0x68]; - for (c = 0; c < sizeof(code) - 1; c++) code[c] = code[c + 1]; code[c] = ascii; statecntr = WAIT_INPUT; nextstate = STATE_INPUT; - -#if 0 - TCNT0 = 0; - state = 1; - send_byte(0xed); - send_byte(0x00); - DDRD = DDRD_BEEP; - cntr = 0; - TIFR0 = (1 << TOV0); -#endif } ISR(SIG_USART_RECV) @@ -551,8 +588,7 @@ ISR(SIG_USART_RECV) case STATE_IDLE: case STATE_IDLEBLINK: case STATE_INPUT: - if (data < 0x90) - handle_keypress(data); + handle_keypress(data); default: break; } -- cgit v1.2.1