summaryrefslogtreecommitdiffstats
path: root/app/atkbd.c
diff options
context:
space:
mode:
authorroot <root@lamia.panaceas.james.local>2015-06-13 13:08:23 +0100
committerroot <root@lamia.panaceas.james.local>2015-06-13 13:08:23 +0100
commitcd568297a41e5a6f2e130de82c07b6b789d34f4b (patch)
treea8ac2021e11d8a33d178fa521bde323c819e4c8d /app/atkbd.c
parent162fcd3f8d879615dc39181daea95ef6fcb83752 (diff)
downloadtims_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.c127
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 ();