2 Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
5 #include <util/delay.h>
10 #define WAIT(stat, us, err) do { \
11 if (!wait_##stat(us)) { \
12 ibm4704_error = err; \
18 uint8_t ibm4704_error = 0;
21 void ibm4704_init(void)
29 Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
31 ____ __ __ __ __ __ __ __ __ __ ________
32 Clock \______/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
33 ^ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___
34 Data ____|__/ X____X____X____X____X____X____X____X____X____X \___
35 | Start 0 1 2 3 4 5 6 7 P Stop
38 Start bit: can be long as 300-350us.
39 Request: Host pulls Clock line down to request to send a command.
40 Timing: After Request keyboard pull up Data and down Clock line to low for start bit.
41 After request host release Clock line once Data line becomes hi.
42 Host writes a bit while Clock is hi and Keyboard reads while low.
43 Stop bit: Host releases or pulls up Data line to hi after 9th clock and waits for keyboard pull down the line to lo.
45 uint8_t ibm4704_send(uint8_t data)
47 bool parity = true; // odd parity
54 /* wait for Start bit(Clock:lo/Data:hi) */
55 WAIT(data_hi, 300, 0x30);
58 for (uint8_t i = 0; i < 8; i++) {
59 WAIT(clock_hi, 100, 0x40+i);
67 WAIT(clock_lo, 100, 0x48+i);
71 WAIT(clock_hi, 100, 0x34);
72 if (parity) { data_hi(); } else { data_lo(); }
73 WAIT(clock_lo, 100, 0x35);
76 WAIT(clock_hi, 100, 0x34);
80 WAIT(data_lo, 100, 0x36);
83 _delay_us(200); // wait to recover clock to hi
87 if (ibm4704_error >= 0x30) {
88 xprintf("x%02X ", ibm4704_error);
90 _delay_us(200); // wait to recover clock to hi
94 /* receive data when host want else inhibit communication */
95 uint8_t ibm4704_recv_response(void)
97 // 250 * 100us(wait start bit in ibm4704_recv)
101 data = ibm4704_recv();
102 } while (try-- && ibm4704_error);
109 Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
111 ____ __ __ __ __ __ __ __ __ __ ________
112 Clock \____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
113 ____ ____ ____ ____ ____ ____ ____ ____ ____ ____
114 Data ____/ X____X____X____X____X____X____X____X____X____X________
115 Start 0 1 2 3 4 5 6 7 P Stop
117 Start bit: can be long as 300-350us.
118 Inhibit: Pull Data line down to inhibit keyboard to send.
119 Timing: Host reads bit while Clock is hi.
120 Stop bit: Keyboard pulls down Data line to lo after 9th clock.
122 uint8_t ibm4704_recv(void)
125 bool parity = true; // odd parity
126 ibm4704_error = IBM4704_ERR_NONE;
129 _delay_us(5); // wait for line settles
132 WAIT(clock_lo, 100, 0x11); // wait for keyboard to send
133 WAIT(data_hi, 100, 0x12); // can be delayed that long
135 WAIT(clock_hi, 100, 0x13); // first rising edge which can take longer
137 for (uint8_t i = 0; i < 8; i++) {
138 WAIT(clock_hi, 100, 0x20+i);
144 WAIT(clock_lo, 150, 0x28+i);
148 WAIT(clock_hi, 100, 0x17);
149 if (data_in() != parity) {
150 ibm4704_error = IBM4704_ERR_PARITY;
153 WAIT(clock_lo, 150, 0x18);
156 WAIT(clock_hi, 100, 0x19);
157 WAIT(data_lo, 1, 0x19);
160 _delay_us(200); // wait to recover clock to hi
163 if (ibm4704_error > 0x12) {
164 xprintf("x%02X ", ibm4704_error);
167 _delay_us(200); // wait to recover clock to hi