summaryrefslogtreecommitdiff
path: root/kbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kbc.c')
-rw-r--r--kbc.c128
1 files changed, 81 insertions, 47 deletions
diff --git a/kbc.c b/kbc.c
index 3568eda..45e3308 100644
--- a/kbc.c
+++ b/kbc.c
@@ -16,8 +16,8 @@
16 * 0 16 * 0
17 * 1 BEEP (OC1A) 17 * 1 BEEP (OC1A)
18 * 2 SS up:8 18 * 2 SS up:8
19 * 3 MOSI up:2 19 * 3 MOSI up:2 LOCK
20 * 4 MISO up:4 20 * 4 MISO up:4 UNLOCK
21 * 5 SCK up:7 21 * 5 SCK up:7
22 * port C 22 * port C
23 * 0-3 23 * 0-3
@@ -38,10 +38,14 @@
38#define D_PWR (1 << 5) 38#define D_PWR (1 << 5)
39 39
40#define B_BEEP (1 << 1) 40#define B_BEEP (1 << 1)
41#define B_OPEN 0 41#define B_FEEDBACK (1 << 2)
42#define B_CLOSE 0 42#define B_CLOSE (1 << 3)
43#define B_OPEN (1 << 4)
44
43#define B_MISO (1 << 4) 45#define B_MISO (1 << 4)
44 46
47#define MAXTRIES 3
48
45enum state { 49enum state {
46 STATE_NONE = 0, 50 STATE_NONE = 0,
47 STATE_FAILURE, 51 STATE_FAILURE,
@@ -53,11 +57,13 @@ enum state {
53 STATE_INPUT, 57 STATE_INPUT,
54 STATE_ACCEPT, 58 STATE_ACCEPT,
55 STATE_REJECT, 59 STATE_REJECT,
60 STATE_KEYMATIC_RECHECK,
61 STATE_KEYMATIC_RECLOSE,
56#ifdef KILLSWITCH 62#ifdef KILLSWITCH
57 STATE_ERROR, 63 STATE_ERROR,
58#endif 64#endif
59}; 65};
60static volatile enum state state, nextstate; 66static volatile enum state state, nextstate, toutstate;
61 67
62static void power_up() 68static void power_up()
63{ 69{
@@ -326,13 +332,19 @@ static uint8_t wait_byte(void)
326#define WAIT_IDLEBLINK 1 /* no full cycle */ 332#define WAIT_IDLEBLINK 1 /* no full cycle */
327#define CNTR_BLINK 6 333#define CNTR_BLINK 6
328#define CNTR_ERROR 61 334#define CNTR_ERROR 61
335#define CNTR_BEEP 10
336#define CNTR_BEEP_REJ 92
329 337
330#define WAIT_INPUT 5 338#define WAIT_INPUT 6
331#define WAIT_ACCEPT 5 339#define WAIT_ACCEPT 8
332#define WAIT_REJECT 10 340#define WAIT_REJECT 8
341#define WAIT_KEYMATIC_RETRY 9
333 342
334static uint8_t cntr = 0; 343#define CNTR_KEYMATIC 30
344/* CNTR_BEEP_ACC == CNTR_KEYMATIC */
335 345
346static uint8_t cntr = 0;
347static uint8_t close_try = 0;
336#ifdef KILLSWITCH 348#ifdef KILLSWITCH
337static uint8_t error; 349static uint8_t error;
338#endif 350#endif
@@ -345,21 +357,25 @@ static void state_enter(void)
345 switch (state) { 357 switch (state) {
346 case STATE_NONE: 358 case STATE_NONE:
347 case STATE_FAILURE: 359 case STATE_FAILURE:
360 toutstate = STATE_POWERUP;
348 statecntr = WAIT_FAIL; 361 statecntr = WAIT_FAIL;
349 usart_dis(); 362 usart_dis();
350 power_down(); 363 power_down();
351 break; 364 break;
352 case STATE_POWERUP: 365 case STATE_POWERUP:
366 toutstate = STATE_INITRESET;
353 statecntr = WAIT_POWERUP; 367 statecntr = WAIT_POWERUP;
354 power_up(); 368 power_up();
355 usart_rx(); 369 usart_rx();
356 break; 370 break;
357 case STATE_INITRESET: 371 case STATE_INITRESET:
372 toutstate = STATE_FAILURE;
358 statecntr = WAIT_INIT; 373 statecntr = WAIT_INIT;
359 send_byte(0xff); 374 send_byte(0xff);
360 break; 375 break;
361 case STATE_CONFIG: 376 case STATE_CONFIG:
362 /* statecntr not used */ 377 /* statecntr not used */
378 toutstate = STATE_FAILURE;
363 nextstate = STATE_FAILURE; 379 nextstate = STATE_FAILURE;
364 if (send_byte(0xed) != 0xfa) 380 if (send_byte(0xed) != 0xfa)
365 break; 381 break;
@@ -385,6 +401,8 @@ static void state_enter(void)
385 nextstate = STATE_IDLE; 401 nextstate = STATE_IDLE;
386 break; 402 break;
387 case STATE_IDLE: 403 case STATE_IDLE:
404 memset(&code, 0, sizeof(code));
405 toutstate = STATE_IDLEBLINK;
388 statecntr = WAIT_IDLE; 406 statecntr = WAIT_IDLE;
389 nextstate = STATE_FAILURE; 407 nextstate = STATE_FAILURE;
390 if (send_byte(0xed) != 0xfa) 408 if (send_byte(0xed) != 0xfa)
@@ -394,6 +412,7 @@ static void state_enter(void)
394 nextstate = STATE_NONE; 412 nextstate = STATE_NONE;
395 break; 413 break;
396 case STATE_IDLEBLINK: 414 case STATE_IDLEBLINK:
415 toutstate = STATE_IDLE;
397 statecntr = WAIT_IDLEBLINK; 416 statecntr = WAIT_IDLEBLINK;
398 nextstate = STATE_FAILURE; 417 nextstate = STATE_FAILURE;
399 if (send_byte(0xed) != 0xfa) 418 if (send_byte(0xed) != 0xfa)
@@ -404,6 +423,7 @@ static void state_enter(void)
404 cntr = CNTR_BLINK; 423 cntr = CNTR_BLINK;
405 break; 424 break;
406 case STATE_INPUT: 425 case STATE_INPUT:
426 toutstate = STATE_IDLE;
407 statecntr = WAIT_INPUT; 427 statecntr = WAIT_INPUT;
408 if (send_byte(0xed) != 0xfa) 428 if (send_byte(0xed) != 0xfa)
409 break; 429 break;
@@ -411,6 +431,7 @@ static void state_enter(void)
411 break; 431 break;
412 break; 432 break;
413 case STATE_ACCEPT: 433 case STATE_ACCEPT:
434 toutstate = close_try ? STATE_KEYMATIC_RECHECK : STATE_IDLE;
414 statecntr = WAIT_ACCEPT; 435 statecntr = WAIT_ACCEPT;
415 if (send_byte(0xed) != 0xfa) 436 if (send_byte(0xed) != 0xfa)
416 break; 437 break;
@@ -418,14 +439,42 @@ static void state_enter(void)
418 break; 439 break;
419 break; 440 break;
420 case STATE_REJECT: 441 case STATE_REJECT:
442 toutstate = STATE_IDLE;
421 statecntr = WAIT_REJECT; 443 statecntr = WAIT_REJECT;
422 if (send_byte(0xed) != 0xfa) 444 if (send_byte(0xed) != 0xfa)
423 break; 445 break;
424 if (send_byte(KBLED_ERROR) != 0xfa) 446 if (send_byte(KBLED_ERROR) != 0xfa)
425 break; 447 break;
426 break; 448 break;
449 case STATE_KEYMATIC_RECHECK:
450 if (!close_try || !(PINB & B_FEEDBACK)) {
451 close_try = 0;
452 nextstate = STATE_IDLE;
453 return;
454 }
455 if (send_byte(0xed) != 0xfa)
456 break;
457 if (send_byte(KBLED_OK | KBLED_ERROR) != 0xfa)
458 break;
459
460 close_try--;
461
462 cntr = CNTR_KEYMATIC;
463 statecntr = WAIT_KEYMATIC_RETRY;
464 toutstate = STATE_KEYMATIC_RECLOSE;
465
466 PORTB &= ~(B_OPEN | B_BEEP);
467 break;
468 case STATE_KEYMATIC_RECLOSE:
469 cntr = CNTR_KEYMATIC;
470 statecntr = WAIT_KEYMATIC_RETRY;
471 toutstate = STATE_KEYMATIC_RECHECK;
472
473 PORTB &= ~(B_CLOSE | B_BEEP);
474 break;
427#ifdef KILLSWITCH 475#ifdef KILLSWITCH
428 case STATE_ERROR: 476 case STATE_ERROR:
477 toutstate = STATE_ERROR;
429 statecntr = 1; 478 statecntr = 1;
430 cntr = CNTR_ERROR; 479 cntr = CNTR_ERROR;
431 error ^= KBLED_ERROR; 480 error ^= KBLED_ERROR;
@@ -438,43 +487,13 @@ static void state_enter(void)
438 } 487 }
439} 488}
440 489
441static void state_timeout(void)
442{
443 switch (state) {
444 case STATE_NONE:
445 case STATE_FAILURE:
446 state = STATE_POWERUP;
447 break;
448 case STATE_POWERUP:
449 state = STATE_INITRESET;
450 break;
451 case STATE_INITRESET:
452 case STATE_CONFIG:
453 state = STATE_FAILURE;
454 break;
455 case STATE_IDLE:
456 state = STATE_IDLEBLINK;
457 break;
458 case STATE_INPUT:
459 memset(&code, 0, sizeof(code));
460 case STATE_IDLEBLINK:
461 case STATE_ACCEPT:
462 case STATE_REJECT:
463 state = STATE_IDLE;
464 break;
465#ifdef KILLSWITCH
466 case STATE_ERROR:
467 state = STATE_ERROR;
468 break;
469#endif
470 }
471 state_enter();
472}
473
474ISR(SIG_OVERFLOW0) 490ISR(SIG_OVERFLOW0)
475{ 491{
476 if (!--cntr) { 492 if (!--cntr) {
477 cntr = CNTRTOP; 493 cntr = CNTRTOP;
494
495 PORTB = B_OPEN | B_CLOSE | B_BEEP;
496
478 if (statecntr) 497 if (statecntr)
479 statecntr--; 498 statecntr--;
480 } 499 }
@@ -549,7 +568,7 @@ static void handle_keypress(uint8_t data)
549 unlock = ascii == ENT || data == NUMPAD_ENTER; 568 unlock = ascii == ENT || data == NUMPAD_ENTER;
550 569
551 if (lock || unlock) { 570 if (lock || unlock) {
552 uint8_t eebyte, pos, ok = 1; 571 uint8_t pos, ok = 1;
553 572
554 /* passwd: a b c d 573 /* passwd: a b c d
555 * code: \0 a b c d 574 * code: \0 a b c d
@@ -569,10 +588,19 @@ static void handle_keypress(uint8_t data)
569 ok = 0; 588 ok = 0;
570 589
571 if (!ok) { 590 if (!ok) {
572 dbg_wr(0x20); 591 PORTB &= ~B_BEEP;
592
593 cntr = CNTR_BEEP_REJ;
573 nextstate = STATE_REJECT; 594 nextstate = STATE_REJECT;
574 } else { 595 } else {
575 dbg_wr(lock ? 0x21 : 0x22); 596 if (lock) {
597 PORTB &= ~(B_CLOSE | B_BEEP);
598 close_try = MAXTRIES;
599 } else {
600 PORTB &= ~(B_OPEN | B_BEEP);
601 }
602
603 cntr = CNTR_KEYMATIC;
576 nextstate = STATE_ACCEPT; 604 nextstate = STATE_ACCEPT;
577 } 605 }
578 memset(&code, 0, sizeof(code)); 606 memset(&code, 0, sizeof(code));
@@ -583,7 +611,8 @@ static void handle_keypress(uint8_t data)
583 code[c] = code[c + 1]; 611 code[c] = code[c + 1];
584 code[c] = ascii; 612 code[c] = ascii;
585 613
586 statecntr = WAIT_INPUT; 614 PORTB &= ~B_BEEP;
615 cntr = CNTR_BEEP;
587 nextstate = STATE_INPUT; 616 nextstate = STATE_INPUT;
588} 617}
589 618
@@ -613,6 +642,9 @@ int main()
613{ 642{
614 dbg_init(); 643 dbg_init();
615 644
645 PORTB = B_OPEN | B_CLOSE | B_BEEP;
646 DDRB = B_OPEN | B_CLOSE | B_BEEP;
647
616 /* /256 = 31'250 Hz = 32 µs per 1 unit 648 /* /256 = 31'250 Hz = 32 µs per 1 unit
617 * /256 = 122 Hz = 8'192 µs per for overflow 649 * /256 = 122 Hz = 8'192 µs per for overflow
618 * /122 = 1,0006 Hz = 1 s per CNTRTOP */ 650 * /122 = 1,0006 Hz = 1 s per CNTRTOP */
@@ -640,7 +672,9 @@ int main()
640 nextstate = STATE_NONE; 672 nextstate = STATE_NONE;
641 state_enter(); 673 state_enter();
642 } else if (!statecntr) { 674 } else if (!statecntr) {
643 state_timeout(); 675 state = toutstate;
676 nextstate = STATE_NONE;
677 state_enter();
644 } 678 }
645 } 679 }
646} 680}