diff options
author | root <root@lamia.panaceas.james.local> | 2015-06-13 13:08:23 +0100 |
---|---|---|
committer | root <root@lamia.panaceas.james.local> | 2015-06-13 13:08:23 +0100 |
commit | cd568297a41e5a6f2e130de82c07b6b789d34f4b (patch) | |
tree | a8ac2021e11d8a33d178fa521bde323c819e4c8d /app/atkbd.c | |
parent | 162fcd3f8d879615dc39181daea95ef6fcb83752 (diff) | |
download | tims_keyboard-cd568297a41e5a6f2e130de82c07b6b789d34f4b.tar.gz tims_keyboard-cd568297a41e5a6f2e130de82c07b6b789d34f4b.tar.bz2 tims_keyboard-cd568297a41e5a6f2e130de82c07b6b789d34f4b.zip |
add usb wakeup support, all keys up on bad data, and resend for parity errors
Diffstat (limited to 'app/atkbd.c')
-rw-r--r-- | app/atkbd.c | 127 |
1 files changed, 85 insertions, 42 deletions
diff --git a/app/atkbd.c b/app/atkbd.c index d450bc2..c12f70e 100644 --- a/app/atkbd.c +++ b/app/atkbd.c @@ -10,11 +10,11 @@ /*Cope with lost sync */ /*If we've had no bits for this long, it's definately the start of a new word, 72MHz units */ -#define RESYNC_GAP (7200000) /* 100ms */ +#define RESYNC_GAP (100 * MS) -#define ATKBD_TIMEOUT 1000 /*how long to wait for the keyboard to respond to a command in ms */ +#define ATKBD_TIMEOUT (1000 * MS) /*how long to wait for the keyboard to respond to a command in ms */ -#define ATKBD_CLOCK_SEIZE_DELAY 200 /* how many us from pulling clock low to pulling data low, when we xmit */ +#define ATKBD_CLOCK_SEIZE_DELAY 200 /* how many us from pulling clock low to pulling data low, when we xmit*/ #define ATKBD_BIT_DELAY 10 /* how many us we allow from the KBD to pull clock back up */ @@ -96,11 +96,22 @@ cycle_diff (uint32_t a, uint32_t b) return b - a; } + +static int fake_ctrl, pause_down; + +void +atkbd_dispatch_error (void) +{ + pause_down = 0; + fake_ctrl = 0; + scancode_error (); +} + + static void atkbd_dispatch (int key, int updown) { /* the logic here is batshit, consult scancode.doc in the DOCS dir */ - static int fake_ctrl, pause_down; switch (key) { @@ -150,7 +161,7 @@ atkbd_data_dispatch (uint8_t byte) static int emul; #ifdef DEBUG - printf ("ATKBD < 0x%02x\r\n", byte); + printf ("ATKBD_RX < 0x%02x\r\n", byte); #endif switch (byte) @@ -162,6 +173,7 @@ atkbd_data_dispatch (uint8_t byte) atkbd_nack++; break; case ATKBD_RET_BAT: + atkbd_dispatch_error (); atkbd_bat++; break; case ATKBD_RET_ECHO: @@ -219,7 +231,16 @@ exti0_isr (void) atkbd_byte = 0; parity = 0; if (!d) - state++; + { + state++; + } + else + { + atkbd_dispatch_error (); +#ifdef DEBUG + printf ("ATKBD_ISR ! start bit non-zero\r\n"); +#endif + } break; case STATE_BIT0: case STATE_BIT1: @@ -236,8 +257,28 @@ exti0_isr (void) state++; break; case STATE_STOP: - if (d && parity) - atkbd_data_dispatch (atkbd_byte); + if (d) + { + if (parity) + atkbd_data_dispatch (atkbd_byte); + + if (!parity) + { + atkbd_dispatch_error (); +#ifdef DEBUG + printf ("ATKBD_ISR ! bad parity - issuing resend\r\n"); +#endif + atkbd_send (ATKBD_CMD_RESEND); + } + } + else + { + atkbd_dispatch_error (); +#ifdef DEBUG + printf ("ATKBD_ISR ! stop bit zero\r\n"); +#endif + } + state = STATE_START; break; } @@ -275,7 +316,7 @@ atkbd_set (int clk, int dat) int atkbd_send (uint8_t d) { - uint32_t then = ticks; + uint32_t then = dwt_read_cycle_counter ();; int parity = 1; uint32_t c; @@ -293,46 +334,46 @@ atkbd_send (uint8_t d) for (c = 1; c < 0x100; c <<= 1) { while (GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; atkbd_set (1, c & d); parity ^= ! !(c & d); while (!GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; } /* A parity bit */ while (GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; atkbd_set (1, parity); while (!GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; /* two stop bits */ while (GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; atkbd_set (1, 1); while (!GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; while (GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; atkbd_set (1, 1); while (!GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; while (!GET (KBDAT)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; while (!GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; atkbd_unmask_flush_irq (); @@ -346,10 +387,10 @@ atkbd_send (uint8_t d) err: atkbd_set (1, 1); while (!GET (KBDAT)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; while (!GET (KBCLK)) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) goto err; atkbd_unmask_flush_irq (); @@ -363,18 +404,18 @@ err: static int atkbd_reset (void) { - uint32_t then = ticks; + uint32_t then = dwt_read_cycle_counter ();; atkbd_bat = 0; atkbd_send (ATKBD_CMD_RESET_BAT); while (!atkbd_bat) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; - then = ticks; + then = dwt_read_cycle_counter ();; atkbd_ack = 0; atkbd_send (ATKBD_CMD_SETALL_MBR); while (!atkbd_ack) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; @@ -384,11 +425,11 @@ atkbd_reset (void) int atkbd_request_echo (void) { - uint32_t then = ticks; + uint32_t then = dwt_read_cycle_counter ();; atkbd_ack = 0; atkbd_send (ATKBD_CMD_ECHO); while (!atkbd_echo) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; return 0; @@ -405,18 +446,18 @@ atkbd_set_leds (uint8_t leds) if (!ready) return 0; - then = ticks; + then = dwt_read_cycle_counter ();; atkbd_ack = 0; atkbd_send (ATKBD_CMD_SETLEDS); while (!atkbd_ack) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; - then = ticks; + then = dwt_read_cycle_counter ();; atkbd_ack = 0; atkbd_send (leds); while (!atkbd_ack) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; return 0; @@ -426,18 +467,18 @@ atkbd_set_leds (uint8_t leds) int atkbd_set_scanset (uint8_t scanset) { - uint32_t then = ticks; + uint32_t then = dwt_read_cycle_counter ();; atkbd_ack = 0; atkbd_send (ATKBD_CMD_SSCANSET); while (!atkbd_ack) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; - then = ticks; + then = dwt_read_cycle_counter ();; atkbd_ack = 0; atkbd_send (scanset); while (!atkbd_ack) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; return 0; @@ -446,11 +487,11 @@ atkbd_set_scanset (uint8_t scanset) int atkbd_set_mb (void) { - uint32_t then = ticks; + uint32_t then = dwt_read_cycle_counter ();; atkbd_ack = 0; atkbd_send (ATKBD_CMD_SETALL_MB); while (!atkbd_ack) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; return 0; @@ -459,11 +500,11 @@ atkbd_set_mb (void) int atkbd_set_mbr (void) { - uint32_t then = ticks; + uint32_t then = dwt_read_cycle_counter ();; atkbd_ack = 0; atkbd_send (ATKBD_CMD_SETALL_MBR); while (!atkbd_ack) - if (timed_out (then, ATKBD_TIMEOUT)) + if (timed_out_cycles (then, ATKBD_TIMEOUT)) return -1; return 0; @@ -477,9 +518,11 @@ atkbd_init (void) atkbd_set (1, 1); } -void atkbd_start(void) +void +atkbd_start (void) { - if (ready) return; + if (ready) + return; nvic_enable_irq (NVIC_EXTI0_IRQ); @@ -491,7 +534,7 @@ void atkbd_start(void) exti_reset_request (KBCLK); nvic_enable_irq (KBCLK_IRQ); - delay_ms(AT_KBD_INIT_TIME); + delay_ms (AT_KBD_INIT_TIME); atkbd_reset (); |