2 Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
5 #include <util/delay.h>
7 #include "ring_buffer.h"
11 #define WAIT(stat, us, err) do { \
12 if (!wait_##stat(us)) { \
13 ibm4704_error = err; \
19 uint8_t ibm4704_error = 0;
22 void ibm4704_init(void)
32 Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
34 ____ __ __ __ __ __ __ __ __ __ ________
35 Clock \______/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
36 ^ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___
37 Data ____|__/ X____X____X____X____X____X____X____X____X____X \___
38 | Start 0 1 2 3 4 5 6 7 P Stop
41 Start bit: can be long as 300-350us.
42 Request: Host pulls Clock line down to request to send a command.
43 Timing: After Request keyboard pull up Data and down Clock line to low for start bit.
44 After request host release Clock line once Data line becomes hi.
45 Host writes a bit while Clock is hi and Keyboard reads while low.
46 Stop bit: Host releases or pulls up Data line to hi after 9th clock and waits for keyboard pull down the line to lo.
48 uint8_t ibm4704_send(uint8_t data)
50 bool parity = true; // odd parity
59 /* wait for Start bit(Clock:lo/Data:hi) */
60 WAIT(data_hi, 300, 0x30);
63 for (uint8_t i = 0; i < 8; i++) {
64 WAIT(clock_hi, 100, 0x40+i);
71 WAIT(clock_lo, 100, 0x48+i);
75 WAIT(clock_hi, 100, 0x34);
76 if (parity) { data_hi(); } else { data_lo(); }
77 WAIT(clock_lo, 100, 0x35);
80 WAIT(clock_hi, 100, 0x34);
84 WAIT(data_lo, 100, 0x36);
91 if (ibm4704_error > 0x30) {
92 xprintf("S:%02X ", ibm4704_error);
98 /* wait forever to receive data */
99 uint8_t ibm4704_recv_response(void)
101 while (!rbuf_has_data()) {
104 return rbuf_dequeue();
110 Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
112 ____ __ __ __ __ __ __ __ __ __ ________
113 Clock \____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
114 ____ ____ ____ ____ ____ ____ ____ ____ ____ ____
115 Data ____/ X____X____X____X____X____X____X____X____X____X________
116 Start 0 1 2 3 4 5 6 7 P Stop
118 Start bit: can be long as 300-350us.
119 Inhibit: Pull Data line down to inhibit keyboard to send.
120 Timing: Host reads bit while Clock is hi.
121 Stop bit: Keyboard pulls down Data line to lo after 9th clock.
123 uint8_t ibm4704_recv(void)
125 if (rbuf_has_data()) {
126 return rbuf_dequeue();
132 ISR(IBM4704_INT_VECT)
135 INIT, START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY,
138 static uint8_t data = 0;
140 static uint8_t parity = false;
143 // return unless falling edge
144 if (clock_in()) { goto RETURN; } // why this occurs?
150 WAIT(data_hi, 10, state);
173 ibm4704_error = IBM4704_ERR_NONE;
181 ibm4704_error = state;
182 while (ibm4704_send(0xFE)) _delay_ms(1); // resend
183 xprintf("R:%02X%02X\n", state, data);