summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2011-03-06 06:37:14 +0100
committerDavid Lamparter <equinox@diac24.net>2011-03-06 06:37:14 +0100
commit75ff498d410a42b4cce52409f2abcfa9e3856143 (patch)
treecbf465f82edf39e8097a9c1e70630f6df7df4ba7
parentfb92f1bb096bdf7bddb6bb66c931d4212fbc5588 (diff)
intermediate version
-rw-r--r--Makefile5
-rw-r--r--kbc.c164
2 files changed, 104 insertions, 65 deletions
diff --git a/Makefile b/Makefile
index 642202a..581165c 100644
--- a/Makefile
+++ b/Makefile
@@ -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:
diff --git a/kbc.c b/kbc.c
index c560326..6a04e4a 100644
--- a/kbc.c
+++ b/kbc.c
@@ -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: