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
@@ -3,6 +3,7 @@ AVRDUDE=avrdude
3ACC=avr-gcc 3ACC=avr-gcc
4AOBJCOPY=avr-objcopy 4AOBJCOPY=avr-objcopy
5ALD=avr-ld 5ALD=avr-ld
6ASIZE=avr-size
6CFLAGS=-Wall -Wextra -Wno-unused-parameter -pedantic -std=c99 7CFLAGS=-Wall -Wextra -Wno-unused-parameter -pedantic -std=c99
7ifdef PIN 8ifdef PIN
8DPIN=-DPIN=\"$(PIN)\" 9DPIN=-DPIN=\"$(PIN)\"
@@ -23,7 +24,8 @@ love: kbc.flash
23 $(AOBJCOPY) -j .eeprom -O binary $^ $@ 24 $(AOBJCOPY) -j .eeprom -O binary $^ $@
24 25
25%.ld.o: %.o 26%.ld.o: %.o
26 $(ACC) $(ACFLAGS) $(ALDFLAGS) -o $@ $< 27 $(ACC) $(ACFLAGS) $(ALDFLAGS) -Wl,-Map,$(patsubst %.ld.o,%.map,$@) -o $@ $<
28 @$(ASIZE) $@
27 29
28%.o: %.c 30%.o: %.c
29 $(ACC) $(ACFLAGS) -c -o $@ $< 31 $(ACC) $(ACFLAGS) -c -o $@ $<
@@ -35,4 +37,5 @@ clean:
35 rm -f *.flash *.eeprom *.o 37 rm -f *.flash *.eeprom *.o
36 38
37.PHONY: love flash clean 39.PHONY: love flash clean
40.SECONDARY:
38 41
diff --git a/kbc.c b/kbc.c
index c560326..6a04e4a 100644
--- a/kbc.c
+++ b/kbc.c
@@ -4,6 +4,7 @@
4#include <avr/io.h> 4#include <avr/io.h>
5#include <avr/interrupt.h> 5#include <avr/interrupt.h>
6#include <avr/sleep.h> 6#include <avr/sleep.h>
7#include <avr/pgmspace.h>
7#include <util/delay.h> 8#include <util/delay.h>
8 9
9#ifndef PIN 10#ifndef PIN
@@ -50,7 +51,10 @@ enum state {
50 STATE_IDLEBLINK, 51 STATE_IDLEBLINK,
51 STATE_INPUT, 52 STATE_INPUT,
52 STATE_ACCEPT, 53 STATE_ACCEPT,
53 STATE_REJECT 54 STATE_REJECT,
55#ifdef KILLSWITCH
56 STATE_ERROR,
57#endif
54}; 58};
55static volatile enum state state, nextstate; 59static volatile enum state state, nextstate;
56 60
@@ -120,18 +124,7 @@ static void dbg_init(void)
120static volatile uint8_t statecntr = 0; 124static volatile uint8_t statecntr = 0;
121 125
122#define mayabort if (TIFR0 & (1 << TOV0)) return bit; 126#define mayabort if (TIFR0 & (1 << TOV0)) return bit;
123#if 0
124#define _wait_CLK(cond) do { \
125 p2 = p1 = p0 = PIND; \
126 while (cond) { \
127 p2 = p1; p1 = p0; p0 = PIND; \
128 __asm__ volatile ("nop\n"); \
129 mayabort; \
130 } \
131 } while (0)
132#else
133#define _wait_CLK(cond) while(cond) { mayabort; } 127#define _wait_CLK(cond) while(cond) { mayabort; }
134#endif
135#define wait_CLKlo _wait_CLK( PIND /* & p0 & p1 & p2 */ & D_CLK) 128#define wait_CLKlo _wait_CLK( PIND /* & p0 & p1 & p2 */ & D_CLK)
136#define wait_CLKhi _wait_CLK(!(PIND /* & p0 & p1 & p2 */ & D_CLK)) 129#define wait_CLKhi _wait_CLK(!(PIND /* & p0 & p1 & p2 */ & D_CLK))
137#define wait_CLK wait_CLKhi; wait_CLKlo; _delay_us(15) 130#define wait_CLK wait_CLKhi; wait_CLKlo; _delay_us(15)
@@ -158,7 +151,6 @@ static void timer_clear(void)
158static uint16_t do_send_byte(uint8_t byte) 151static uint16_t do_send_byte(uint8_t byte)
159{ 152{
160 uint8_t bit = 0, parity = 1, rv, usarts; 153 uint8_t bit = 0, parity = 1, rv, usarts;
161 uint8_t p2, p1, p0;
162 154
163 usart_dis(); 155 usart_dis();
164 156
@@ -260,25 +252,15 @@ static uint8_t send_byte(uint8_t byte)
260 TIFR0 = (1 << TOV0); 252 TIFR0 = (1 << TOV0);
261 253
262 rv = do_send_byte(byte); 254 rv = do_send_byte(byte);
263 if (rv == 0x1fa) { 255 if (rv == 0x1fa)
264 dbg_wr(0x14);
265 dbg_wr(0x80 | (byte & 0x0f));
266 dbg_wr(0x80 | (byte >> 4));
267 dbg_wr(0x80 | attempts);
268 goto out; 256 goto out;
269 } 257
270 /* clear state, wait, retry */ 258 /* clear state, wait, retry */
271 DDRD &= ~(D_DATA | D_CLK); 259 DDRD &= ~(D_DATA | D_CLK);
272 PORTD |= D_DATA | D_CLK; 260 PORTD |= D_DATA | D_CLK;
273 261
274 if (rv == 0x1fe) { 262 if (rv == 0x1fe)
275 dbg_wr(0xfe);
276 _delay_ms(33); 263 _delay_ms(33);
277 } else {
278 dbg_wr(0x08);
279 dbg_wr(0x80 | (rv & 0x7f));
280 dbg_wr(0x80 | (rv >> 7));
281 }
282 } 264 }
283 265
284 dbg_wr(0x01); 266 dbg_wr(0x01);
@@ -309,7 +291,6 @@ static uint8_t wait_byte(void)
309 timer_return(); 291 timer_return();
310 usart_rx(); 292 usart_rx();
311 293
312 dbg_wr(0x02);
313 return 0; 294 return 0;
314 } 295 }
315 296
@@ -321,13 +302,6 @@ static uint8_t wait_byte(void)
321 timer_return(); 302 timer_return();
322 usart_rx(); 303 usart_rx();
323 304
324 dbg_wr(0x19);
325 dbg_wr(0x80 | (state));
326 dbg_wr(0x80 | (usarts & 0x0f));
327 dbg_wr(0x80 | (usarts >> 4));
328 dbg_wr(0x80 | (data & 0x0f));
329 dbg_wr(0x80 | (data >> 4));
330
331 return data; 305 return data;
332} 306}
333 307
@@ -345,6 +319,7 @@ static uint8_t wait_byte(void)
345 319
346#define WAIT_IDLEBLINK 1 /* no full cycle */ 320#define WAIT_IDLEBLINK 1 /* no full cycle */
347#define CNTR_BLINK 6 321#define CNTR_BLINK 6
322#define CNTR_ERROR 61
348 323
349#define WAIT_INPUT 5 324#define WAIT_INPUT 5
350#define WAIT_ACCEPT 5 325#define WAIT_ACCEPT 5
@@ -352,14 +327,15 @@ static uint8_t wait_byte(void)
352 327
353static uint8_t cntr = 0; 328static uint8_t cntr = 0;
354 329
355static const char passwd[sizeof(PIN)] = PIN; 330#ifdef KILLSWITCH
331static uint8_t error;
332#endif
333
334static const char passwd[sizeof(PIN) - 1] = PIN;
356static char code[sizeof(PIN)]; 335static char code[sizeof(PIN)];
357 336
358static void state_enter(void) 337static void state_enter(void)
359{ 338{
360 dbg_wr(0x11);
361 dbg_wr(state);
362
363 switch (state) { 339 switch (state) {
364 case STATE_NONE: 340 case STATE_NONE:
365 case STATE_FAILURE: 341 case STATE_FAILURE:
@@ -390,6 +366,7 @@ static void state_enter(void)
390 break; 366 break;
391 if (wait_byte() != 0x83) 367 if (wait_byte() != 0x83)
392 break; 368 break;
369#if 0
393 /* scan code set 3 */ 370 /* scan code set 3 */
394 if (send_byte(0xf0) != 0xfa) 371 if (send_byte(0xf0) != 0xfa)
395 break; 372 break;
@@ -398,6 +375,7 @@ static void state_enter(void)
398 /* make codes only */ 375 /* make codes only */
399 if (send_byte(0xf9) != 0xfa) 376 if (send_byte(0xf9) != 0xfa)
400 break; 377 break;
378#endif
401 nextstate = STATE_IDLE; 379 nextstate = STATE_IDLE;
402 break; 380 break;
403 case STATE_IDLE: 381 case STATE_IDLE:
@@ -440,6 +418,17 @@ static void state_enter(void)
440 if (send_byte(KBLED_ERROR) != 0xfa) 418 if (send_byte(KBLED_ERROR) != 0xfa)
441 break; 419 break;
442 break; 420 break;
421#ifdef KILLSWITCH
422 case STATE_ERROR:
423 statecntr = 1;
424 cntr = CNTR_ERROR;
425 error ^= KBLED_ERROR;
426 if (send_byte(0xed) != 0xfa)
427 break;
428 if (send_byte(error) != 0xfa)
429 break;
430 break;
431#endif
443 } 432 }
444} 433}
445 434
@@ -467,6 +456,11 @@ static void state_timeout(void)
467 case STATE_REJECT: 456 case STATE_REJECT:
468 state = STATE_IDLE; 457 state = STATE_IDLE;
469 break; 458 break;
459#ifdef KILLSWITCH
460 case STATE_ERROR:
461 state = STATE_ERROR;
462 break;
463#endif
470 } 464 }
471 state_enter(); 465 state_enter();
472} 466}
@@ -480,15 +474,33 @@ ISR(SIG_OVERFLOW0)
480 } 474 }
481} 475}
482 476
483static const char kbc_60[24] = { 477#define ESC 0x1b
478#define ENT 0x0d
479
480#define KBC_BASE 0x16
481const PROGMEM char kbc[] = {
482/* 0 1 2 3 4 5 6 7
483 * 8 9 a b c d e f
484 */
485 '1', '_', /* 10 - 17 */
486 '_', '_', '_', '_', '_', '_', '2', '_', /* 18 - 1f */
487 '_', '_', '_', '_', '_', '4', '3', '_', /* 20 - 27 */
488 '_', '_', '_', '_', '_', '_', '5', '_', /* 28 - 2f */
489 '_', '_', '_', '_', '_', '_', '6', '_', /* 30 - 37 */
490 '_', '_', '_', '_', '_', '7', '8', '_', /* 38 - 3f */
491 '_', '_', '_', '_', '_', '0', '9', '_', /* 40 - 47 */
492 '_', '_', '_', '_', '_', '_', '_', '_', /* 48 - 4f */
493 '_', '_', '_', '_', '_', '_', '_', '_', /* 50 - 57 */
494 '_', '_', ENT, '_', '_', '_', '_', '_', /* 58 - 5f */
495 '_', '_', '_', '_', '_', '_', '_', '_', /* 60 - 67 */
484 '_', '1', '_', '4', '7', '_', '_', '_', /* 68 - 6f */ 496 '_', '1', '_', '4', '7', '_', '_', '_', /* 68 - 6f */
485 '0', '.', '2', '5', '6', '8', '_', '/', /* 70 - 77 */ 497 '0', '_', '2', '5', '6', '8', ESC, ESC, /* 70 - 77 */
486 '_', '_', '3', '_', '+', '9', '*', '_' /* 78 - 7f */ 498 '_', '_', '3', '_', '_', '9' /* 78 - 7f */
487}; 499};
488#define KC_ESC 0x08 500
489#define KC_ENTER 0x5a 501#define NUMPAD_ENTER 0xda /* e0 5a */
490#define KC_NUM 0x76 502
491#define KC_NP_ENTER 0x79 503static uint8_t pressed = 0, e0 = 0, release = 0;
492 504
493static void handle_keypress(uint8_t data) 505static void handle_keypress(uint8_t data)
494{ 506{
@@ -496,14 +508,52 @@ static void handle_keypress(uint8_t data)
496 uint8_t ascii = '_'; 508 uint8_t ascii = '_';
497 uint8_t c; 509 uint8_t c;
498 510
499 lock = data == KC_ESC || data == KC_NUM; 511 if (release) {
500 unlock = data == KC_ENTER || data == KC_NP_ENTER; 512 pressed = 0;
513 release = 0;
514 return;
515 }
516 if (data == pressed)
517 return;
518
519 if (data == 0xe0) {
520 e0 = 0x80;
521 return;
522 }
523 if (data == 0xf0) {
524 release = 1;
525 return;
526 }
527 if (data >= 0x80)
528 return;
529
530 pressed = data;
531
532 data |= e0;
533 e0 = 0;
534
535 if (data >= KBC_BASE && data < KBC_BASE + sizeof(kbc))
536 ascii = pgm_read_byte(kbc + data - KBC_BASE);
537
538 dbg_wr(0x03);
539 dbg_wr(0x80 | (ascii & 0xf));
540 dbg_wr(0x80 | (ascii >> 4));
541
542 lock = ascii == ESC;
543 unlock = ascii == ENT || data == NUMPAD_ENTER;
501 544
502 if (lock || unlock) { 545 if (lock || unlock) {
503 /* passwd: a b c d \0 546 /* passwd: a b c d
504 * code: \0 a b c d 547 * code: \0 a b c d
505 */ 548 */
506 if (code[0] || memcmp(passwd, code + 1, sizeof(passwd) - 1)) { 549#ifdef KILLSWITCH
550 if (code[0] || !memcmp("9164", code + 1, 4)) {
551 error = 0;
552 nextstate = STATE_ERROR;
553 return;
554 }
555#endif
556 if (code[0] || memcmp(passwd, code + 1, sizeof(passwd))) {
507 dbg_wr(0x20); 557 dbg_wr(0x20);
508 nextstate = STATE_REJECT; 558 nextstate = STATE_REJECT;
509 } else { 559 } else {
@@ -514,25 +564,12 @@ static void handle_keypress(uint8_t data)
514 return; 564 return;
515 } 565 }
516 566
517 if (data >= 0x68 && data < 0x80)
518 ascii = kbc_60[data - 0x68];
519
520 for (c = 0; c < sizeof(code) - 1; c++) 567 for (c = 0; c < sizeof(code) - 1; c++)
521 code[c] = code[c + 1]; 568 code[c] = code[c + 1];
522 code[c] = ascii; 569 code[c] = ascii;
523 570
524 statecntr = WAIT_INPUT; 571 statecntr = WAIT_INPUT;
525 nextstate = STATE_INPUT; 572 nextstate = STATE_INPUT;
526
527#if 0
528 TCNT0 = 0;
529 state = 1;
530 send_byte(0xed);
531 send_byte(0x00);
532 DDRD = DDRD_BEEP;
533 cntr = 0;
534 TIFR0 = (1 << TOV0);
535#endif
536} 573}
537 574
538ISR(SIG_USART_RECV) 575ISR(SIG_USART_RECV)
@@ -551,8 +588,7 @@ ISR(SIG_USART_RECV)
551 case STATE_IDLE: 588 case STATE_IDLE:
552 case STATE_IDLEBLINK: 589 case STATE_IDLEBLINK:
553 case STATE_INPUT: 590 case STATE_INPUT:
554 if (data < 0x90) 591 handle_keypress(data);
555 handle_keypress(data);
556 default: 592 default:
557 break; 593 break;
558 } 594 }