aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2012-04-21 11:07:51 +0900
committertmk <nobody@nowhere>2012-04-21 11:07:51 +0900
commit0a4fa89548e8c098c65c289865ebbf1e1c29adf4 (patch)
treeb60bf72ed05f1231503917af6b68fdef4d9ec170
parent38d61ee1b191d40bcccbc252fdddba47e5bb8f36 (diff)
downloadqmk_firmware-0a4fa89548e8c098c65c289865ebbf1e1c29adf4.tar.gz
qmk_firmware-0a4fa89548e8c098c65c289865ebbf1e1c29adf4.zip
M0110: Fixed timing of signal handling.
-rw-r--r--m0110.c98
-rw-r--r--m0110.h15
2 files changed, 87 insertions, 26 deletions
diff --git a/m0110.c b/m0110.c
index f4f5223dd..522c3ec0d 100644
--- a/m0110.c
+++ b/m0110.c
@@ -66,7 +66,7 @@ Signaling
66--------- 66---------
67CLOCK is always from KEYBOARD. DATA are sent with MSB first. 67CLOCK is always from KEYBOARD. DATA are sent with MSB first.
68 68
691) IDLE: both line is high. 691) IDLE: both lines are high.
70 CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71 DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 71 DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72 72
@@ -79,7 +79,7 @@ CLOCK is always from KEYBOARD. DATA are sent with MSB first.
793) HOST->KEYBOARD: HOST asserts bit on falling edge. 793) HOST->KEYBOARD: HOST asserts bit on falling edge.
80 CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ 80 CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
81 DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ 81 DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
82 <----> 840us(request to send by host) <-> 80us(hold DATA) 82 <----> 840us(request to send by host) <---> 80us(hold DATA)
83 <--> 180us(clock low) 83 <--> 180us(clock low)
84 <---> 220us(clock high) 84 <---> 220us(clock high)
85 85
@@ -98,11 +98,18 @@ COMMAND:
98 98
99KEY EVENT: 99KEY EVENT:
100 bit 7 key state(0:press 1:release) 100 bit 7 key state(0:press 1:release)
101 bit 6-1 scan code 101 bit 6-1 scan code(see below)
102 bit 0 always 1 102 bit 0 always 1
103 To get scan code, use ((bits&(1<<7)) | ((bits&7F))>>1). 103 To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1).
104
105 Note: On the M0110A, the numpad keys and the arrow keys are preceded by 0x79.
106 Moreover, the numpad keys =, /, * and + are preceded by shift-down 0x71 on press and shift-up 0xF1 on release.
107 So, the data transferred by nupmad 5 is "79 2F" whereas for numpad + it's "71 79 0D".
104 108
105SCAN CODE: 109SCAN CODE:
110 m0111_recv_key() function returns follwing scan codes instead of raw key events.
111 Scan codes are 1 byte long and bit7 is set when key is released.
112
106 M0110 113 M0110
107 ,---------------------------------------------------------. 114 ,---------------------------------------------------------.
108 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| 115 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs|
@@ -127,29 +134,74 @@ SCAN CODE:
127 | 3A| 37| 31 | 34| 3A| 134 | 3A| 37| 31 | 34| 3A|
128 `------------------------------------------------' 135 `------------------------------------------------'
129 136
137 M0110A
138 ,---------------------------------------------------------. ,---------------.
139 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *|
140 |---------------------------------------------------------| |---------------|
141 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
142 |-----------------------------------------------------' | |---------------|
143 |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
144 |---------------------------------------------------------| |---------------|
145 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
146 |---------------------------------------------------------' |-----------|Ent|
147 |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| |
148 `---------------------------------------------------------' `---------------'
149 ,---------------------------------------------------------. ,---------------.
150 | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62|
151 |---------------------------------------------------------| |---------------|
152 | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E|
153 |-----------------------------------------------------' | |---------------|
154 | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66|
155 |---------------------------------------------------------| |---------------|
156 | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| |
157 |---------------------------------------------------------' |-----------| 4C|
158 | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| |
159 `---------------------------------------------------------' `---------------'
160
130 161
131References 162References
132---------- 163----------
164Technical Info for 128K/512K and Plus
165 ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf
166 ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf
133Protocol: 167Protocol:
168 Page 20 of Tech Info for 128K/512K
134 http://www.mac.linux-m68k.org/devel/plushw.php 169 http://www.mac.linux-m68k.org/devel/plushw.php
135Connector: 170Connector:
171 Page 20 of Tech Info for 128K/512K
136 http://www.kbdbabel.org/conn/kbd_connector_macplus.png 172 http://www.kbdbabel.org/conn/kbd_connector_macplus.png
137Signaling: 173Signaling:
138 http://www.kbdbabel.org/signaling/kbd_signaling_mac.png 174 http://www.kbdbabel.org/signaling/kbd_signaling_mac.png
139 http://typematic.blog.shinobi.jp/Entry/14/ 175 http://typematic.blog.shinobi.jp/Entry/14/
140Scan Codes: 176Scan Codes:
177 Page 22 of Tech Info for 128K/512K
178 Page 07 of Tech Info for Plus
141 http://m0115.web.fc2.com/m0110.jpg 179 http://m0115.web.fc2.com/m0110.jpg
142 http://m0115.web.fc2.com/m0110a.jpg 180 http://m0115.web.fc2.com/m0110a.jpg
143*/ 181*/
144 182
145 183
146#define WAIT(stat, us, err) do { \ 184#define WAIT_US(stat, us, err) do { \
147 if (!wait_##stat(us)) { \ 185 if (!wait_##stat(us)) { \
148 m0110_error = err; \ 186 m0110_error = err; \
149 goto ERROR; \ 187 goto ERROR; \
150 } \ 188 } \
151} while (0) 189} while (0)
152 190
191#define WAIT_MS(stat, ms, err) do { \
192 uint16_t _ms = ms; \
193 while (_ms) { \
194 if (wait_##stat(1000)) { \
195 break; \
196 } \
197 _ms--; \
198 } \
199 if (_ms == 0) { \
200 m0110_error = err; \
201 goto ERROR; \
202 } \
203} while (0)
204
153 205
154uint8_t m0110_error = 0; 206uint8_t m0110_error = 0;
155 207
@@ -158,9 +210,13 @@ void m0110_init(void)
158{ 210{
159 uint8_t data; 211 uint8_t data;
160 idle(); 212 idle();
161 _delay_ms(255); 213 _delay_ms(1000);
162 214
163 m0110_send(M0110_MODLE); 215 // Model Number
216 // M0110 : 0x09 00001001 : model number 4 (100)
217 // M0110A: 0x0B 00001011 : model number 5 (101)
218 // M0110 & M0120: ???
219 m0110_send(M0110_MODEL);
164 data = m0110_recv(); 220 data = m0110_recv();
165 print("m0110_init model: "); phex(data); print("\n"); 221 print("m0110_init model: "); phex(data); print("\n");
166 222
@@ -174,24 +230,22 @@ uint8_t m0110_send(uint8_t data)
174 m0110_error = 0; 230 m0110_error = 0;
175 231
176 request(); 232 request();
177 WAIT(clock_lo, 1000, 0); 233 WAIT_MS(clock_lo, 250, 1); // keyboard may block long time
178 for (uint8_t bit = 0x80; bit; bit >>= 1) { 234 for (uint8_t bit = 0x80; bit; bit >>= 1) {
179 WAIT(clock_lo, 250, 3); 235 WAIT_US(clock_lo, 250, 3);
180 _delay_us(15);
181 if (data&bit) { 236 if (data&bit) {
182 data_hi(); 237 data_hi();
183 } else { 238 } else {
184 data_lo(); 239 data_lo();
185 } 240 }
186 WAIT(clock_hi, 200, 4); 241 WAIT_US(clock_hi, 200, 4);
187 } 242 }
188 _delay_us(100); // hold last bit for 80us 243 _delay_us(100); // hold last bit for 80us
189 idle(); 244 idle();
190 return 1; 245 return 1;
191ERROR: 246ERROR:
192 if (m0110_error) { 247 print("m0110_send err: "); phex(m0110_error); print("\n");
193 print("m0110_send err: "); phex(m0110_error); print("\n"); 248 _delay_ms(500);
194 }
195 idle(); 249 idle();
196 return 0; 250 return 0;
197} 251}
@@ -201,24 +255,20 @@ uint8_t m0110_recv(void)
201 uint8_t data = 0; 255 uint8_t data = 0;
202 m0110_error = 0; 256 m0110_error = 0;
203 257
204 WAIT(clock_lo, -1, 0); // need 250ms? insted 0xffff(16bit max)us 258 WAIT_MS(clock_lo, 250, 1); // keyboard may block long time
205 for (uint8_t i = 0; i < 8; i++) { 259 for (uint8_t i = 0; i < 8; i++) {
206 data <<= 1; 260 data <<= 1;
207 WAIT(clock_lo, 200, 2); 261 WAIT_US(clock_lo, 200, 2);
208 WAIT(clock_hi, 200, 3); 262 WAIT_US(clock_hi, 200, 3);
209 if (data_in()) { 263 if (data_in()) {
210 data |= 1; 264 data |= 1;
211 } 265 }
212 } 266 }
213 idle(); 267 idle();
214 if (data != M0110_NULL) {
215 print("m0110_recv data: "); phex(data); print("\n");
216 }
217 return data; 268 return data;
218ERROR: 269ERROR:
219 if (m0110_error) { 270 print("m0110_recv err: "); phex(m0110_error); print("\n");
220 print("m0110_recv err: "); phex(m0110_error); print("\n"); 271 _delay_ms(500);
221 }
222 idle(); 272 idle();
223 return 0xFF; 273 return 0xFF;
224} 274}
@@ -231,7 +281,7 @@ uint8_t m0110_recv_key(void)
231 if (key == 0xFF || key == M0110_NULL) 281 if (key == 0xFF || key == M0110_NULL)
232 return M0110_NULL; 282 return M0110_NULL;
233 else 283 else
234 return ((key&(1<<7)) | ((key&0x7F)>>1)); 284 return M0110_RAW2SCAN(key);
235} 285}
236 286
237 287
diff --git a/m0110.h b/m0110.h
index f5c1e21bd..287c45b54 100644
--- a/m0110.h
+++ b/m0110.h
@@ -55,11 +55,22 @@ POSSIBILITY OF SUCH DAMAGE.
55#endif 55#endif
56 56
57#define M0110_INQUIRY 0x10 57#define M0110_INQUIRY 0x10
58#define M0110_INSTNAT 0x14 58#define M0110_INSTANT 0x14
59#define M0110_MODLE 0x16 59#define M0110_MODEL 0x16
60#define M0110_TEST 0x36 60#define M0110_TEST 0x36
61 61
62#define M0110_PAD 0x79
62#define M0110_NULL 0x7B 63#define M0110_NULL 0x7B
64#define M0110_TEST_ACK 0x7D
65#define M0110_TEST_NAK 0x77
66
67
68/* scan code offset for keypad and arrow keys */
69#define M0110_KEYPAD_OFFSET 0x40
70#define M0110_ARROW_OFFSET 0x60
71
72/* convert key event raw response into scan code */
73#define M0110_RAW2SCAN(key) ((key&(1<<7)) | ((key&0x7F)>>1))
63 74
64 75
65extern uint8_t m0110_error; 76extern uint8_t m0110_error;