]>
git.gir.st - tmk_keyboard.git/blob - protocol/ibm4704.c
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