summaryrefslogtreecommitdiff
path: root/kbc.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2011-03-04 00:29:47 +0100
committerDavid Lamparter <equinox@diac24.net>2011-03-04 00:29:47 +0100
commitfb92f1bb096bdf7bddb6bb66c931d4212fbc5588 (patch)
tree6c77034c01482df832cff0bc10bfb6de73de9552 /kbc.c
parentd6be96c302ea4ce09d5abc64242ea5329fd28e3b (diff)
intermediate version
Diffstat (limited to 'kbc.c')
-rw-r--r--kbc.c166
1 files changed, 126 insertions, 40 deletions
diff --git a/kbc.c b/kbc.c
index b7bce72..c560326 100644
--- a/kbc.c
+++ b/kbc.c
@@ -50,2 +50,5 @@ enum state {
STATE_IDLEBLINK,
+ STATE_INPUT,
+ STATE_ACCEPT,
+ STATE_REJECT
};
@@ -116,11 +119,24 @@ static void dbg_init(void)
-
-
-
static volatile uint8_t statecntr = 0;
-#define mayabort if (TIFR0 & (1 << TOV0)) return 0;
-#define wait_CLKlo while (PIND & D_CLK) { __asm__ volatile ("nop\n"); mayabort; }
-#define wait_CLKhi while (!(PIND & D_CLK)) { __asm__ volatile ("nop\n"); mayabort; }
-#define wait_CLK wait_CLKhi; wait_CLKlo; _delay_us(5)
+#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)
+#define wait_CLKhi _wait_CLK(!(PIND /* & p0 & p1 & p2 */ & D_CLK))
+#define wait_CLK wait_CLKhi; wait_CLKlo; _delay_us(15)
+#define wait_CLKb
+
+#define wait_CLK_set wait_CLKlo
+#define wait_CLK_samp wait_CLKhi
@@ -129,3 +145,3 @@ static void timer_return(void)
TCNT0 = 0;
- TIFR0 |= (1 << TOV0);
+ TIFR0 = (1 << TOV0);
__asm__ volatile("nop\n");
@@ -134,5 +150,13 @@ static void timer_return(void)
-static uint8_t do_send_byte(uint8_t byte)
+static void timer_clear(void)
+{
+ TCNT0 = 0;
+ __asm__ volatile("nop\n");
+ TIFR0 = (1 << TOV0);
+}
+
+static uint16_t do_send_byte(uint8_t byte)
{
uint8_t bit = 0, parity = 1, rv, usarts;
+ uint8_t p2, p1, p0;
@@ -140,2 +164,4 @@ static uint8_t do_send_byte(uint8_t byte)
+ _delay_us(5);
+
/* make clock low, request clock from keyboard */
@@ -144,3 +170,3 @@ static uint8_t do_send_byte(uint8_t byte)
- _delay_us(250);
+ _delay_us(166);
@@ -149,3 +175,3 @@ static uint8_t do_send_byte(uint8_t byte)
- _delay_us(25);
+ // _delay_us(3);
@@ -154,5 +180,7 @@ static uint8_t do_send_byte(uint8_t byte)
+ wait_CLK_samp;
+
/* data bits */
for (bit = 0; bit < 8; bit++) {
- wait_CLK;
+ wait_CLK_set;
if (byte & 1) {
@@ -164,5 +192,10 @@ static uint8_t do_send_byte(uint8_t byte)
byte >>= 1;
+ wait_CLK_samp;
}
+
+ timer_clear();
+
+ bit = 0x10;
/* parity */
- wait_CLK;
+ wait_CLK_set;
if (parity)
@@ -171,14 +204,24 @@ static uint8_t do_send_byte(uint8_t byte)
PORTD &= ~D_DATA;
+ wait_CLK_samp;
+ bit = 0x11;
/* stop bit */
- wait_CLK;
+ wait_CLK_set;
PORTD |= D_DATA;
+ wait_CLK_samp;
+ DDRD &= ~D_DATA;
+#if 0
+ bit = 0x12;
/* ACK from keyboard */
- wait_CLKhi;
- DDRD &= ~D_DATA;
+ wait_CLK_set;
+ wait_CLK_samp;
+#endif
+
+ bit = 0x14;
+ while (PIND & D_DATA) { mayabort; }
+ bit = 0x15;
+ while (!(PIND & D_DATA)) { mayabort; }
- wait_CLKlo;
wait_CLKhi;
- while (!(PIND & D_DATA)) { __asm__ volatile ("nop\n"); mayabort; }
@@ -186,2 +229,4 @@ static uint8_t do_send_byte(uint8_t byte)
+ timer_clear();
+ bit = 0x16;
usart_rxpoll();
@@ -192,3 +237,7 @@ static uint8_t do_send_byte(uint8_t byte)
usarts = UCSR0A;
- mayabort;
+ if (TIFR0 & (1 << TOV0)) {
+ TIFR0 = (1 << TOV0);
+ if (++bit == 0x27)
+ return bit;
+ };
}
@@ -196,3 +245,3 @@ static uint8_t do_send_byte(uint8_t byte)
rv = UDR0;
- return rv;
+ return rv | 0x100;
}
@@ -201,3 +250,4 @@ static uint8_t send_byte(uint8_t byte)
{
- uint8_t rv, attempts;
+ uint16_t rv;
+ uint8_t attempts;
@@ -208,5 +258,7 @@ static uint8_t send_byte(uint8_t byte)
TCNT0 = 0;
- TIFR0 |= (1 << TOV0);
+ __asm__ volatile("nop\n");
+ TIFR0 = (1 << TOV0);
- if ((rv = do_send_byte(byte)) == 0xfa) {
+ rv = do_send_byte(byte);
+ if (rv == 0x1fa) {
dbg_wr(0x14);
@@ -217,3 +269,2 @@ static uint8_t send_byte(uint8_t byte)
}
-
/* clear state, wait, retry */
@@ -221,3 +272,11 @@ static uint8_t send_byte(uint8_t byte)
PORTD |= D_DATA | D_CLK;
- _delay_us(50);
+
+ if (rv == 0x1fe) {
+ dbg_wr(0xfe);
+ _delay_ms(33);
+ } else {
+ dbg_wr(0x08);
+ dbg_wr(0x80 | (rv & 0x7f));
+ dbg_wr(0x80 | (rv >> 7));
+ }
}
@@ -289,3 +348,5 @@ static uint8_t wait_byte(void)
-#define WAIT_ENTRY 15
+#define WAIT_INPUT 5
+#define WAIT_ACCEPT 5
+#define WAIT_REJECT 10
@@ -355,3 +416,3 @@ static void state_enter(void)
break;
- if (send_byte(0x01) != 0xfa)
+ if (send_byte(KBLED_STATE) != 0xfa)
break;
@@ -360,2 +421,23 @@ static void state_enter(void)
break;
+ case STATE_INPUT:
+ statecntr = WAIT_INPUT;
+ if (send_byte(0xed) != 0xfa)
+ break;
+ if (send_byte(KBLED_STATE) != 0xfa)
+ break;
+ break;
+ case STATE_ACCEPT:
+ statecntr = WAIT_ACCEPT;
+ if (send_byte(0xed) != 0xfa)
+ break;
+ if (send_byte(KBLED_OK) != 0xfa)
+ break;
+ break;
+ case STATE_REJECT:
+ statecntr = WAIT_REJECT;
+ if (send_byte(0xed) != 0xfa)
+ break;
+ if (send_byte(KBLED_ERROR) != 0xfa)
+ break;
+ break;
}
@@ -380,3 +462,7 @@ static void state_timeout(void)
break;
+ case STATE_INPUT:
+ memset(&code, 0, sizeof(code));
case STATE_IDLEBLINK:
+ case STATE_ACCEPT:
+ case STATE_REJECT:
state = STATE_IDLE;
@@ -396,4 +482,3 @@ ISR(SIG_OVERFLOW0)
-static const char kbc_60[48] = {
- '_', '_', '_', '_', '_', '_', '_', '_', /* 60 - 67 */
+static const char kbc_60[24] = {
'_', '1', '_', '4', '7', '_', '_', '_', /* 68 - 6f */
@@ -421,8 +506,7 @@ static void handle_keypress(uint8_t data)
if (code[0] || memcmp(passwd, code + 1, sizeof(passwd) - 1)) {
-
dbg_wr(0x20);
- /* state = BLOCK; */
+ nextstate = STATE_REJECT;
} else {
dbg_wr(lock ? 0x21 : 0x22);
- /* state = OPENING; */
+ nextstate = STATE_ACCEPT;
}
@@ -432,4 +516,4 @@ static void handle_keypress(uint8_t data)
- if (data >= 0x60 && data < 0x80)
- ascii = kbc_60[data - 0x60];
+ if (data >= 0x68 && data < 0x80)
+ ascii = kbc_60[data - 0x68];
@@ -439,3 +523,4 @@ static void handle_keypress(uint8_t data)
- /* statecntr = WAIT_ENTRY; */
+ statecntr = WAIT_INPUT;
+ nextstate = STATE_INPUT;
@@ -467,2 +552,3 @@ ISR(SIG_USART_RECV)
case STATE_IDLEBLINK:
+ case STATE_INPUT:
if (data < 0x90)
@@ -483,3 +569,3 @@ int main()
TIMSK0 = (1 << TOIE0);
- TCCR0B = (1 << CS02);
+ TCCR0B = (1 << CS02);
@@ -494,2 +580,6 @@ int main()
+ for (int i = 0; i < 5000; i++) {
+ __asm__ volatile("nop\nnop\n");
+ }
+
sei();
@@ -500,8 +590,4 @@ int main()
state_enter();
-
- dbg_wr(0x0e);
} else if (!statecntr) {
state_timeout();
-
- dbg_wr(0x0e);
}