]> git.donarmstrong.com Git - tmk_firmware.git/blob - protocol/adb.c
Change ADB scan delay 12ms
[tmk_firmware.git] / protocol / adb.c
1 /*
2 Copyright 2011 Jun WAKO <wakojun@gmail.com>
3
4 This software is licensed with a Modified BSD License.
5 All of this is supposed to be Free Software, Open Source, DFSG-free,
6 GPL-compatible, and OK to use in both free and proprietary applications.
7 Additions and corrections to this file are welcome.
8
9
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are met:
12
13 * Redistributions of source code must retain the above copyright
14   notice, this list of conditions and the following disclaimer.
15
16 * Redistributions in binary form must reproduce the above copyright
17   notice, this list of conditions and the following disclaimer in
18   the documentation and/or other materials provided with the
19   distribution.
20
21 * Neither the name of the copyright holders nor the names of
22   contributors may be used to endorse or promote products derived
23   from this software without specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #include <stdbool.h>
39 #include <util/delay.h>
40 #include <avr/io.h>
41 #include <avr/interrupt.h>
42 #include "adb.h"
43 #include "debug.h"
44
45
46 static inline void data_lo(void);
47 static inline void data_hi(void);
48 static inline bool data_in(void);
49 #ifdef ADB_PSW_BIT
50 static inline void psw_lo(void);
51 static inline void psw_hi(void);
52 static inline bool psw_in(void);
53 #endif
54
55 static inline void attention(void);
56 static inline void place_bit0(void);
57 static inline void place_bit1(void);
58 static inline void send_byte(uint8_t data);
59 static inline bool read_bit(void);
60 static inline uint8_t read_byte(void);
61 static inline uint8_t wait_data_lo(uint16_t us);
62 static inline uint8_t wait_data_hi(uint8_t us);
63
64
65 void adb_host_init(void)
66 {
67     data_hi();
68 #ifdef ADB_PSW_BIT
69     psw_hi();
70 #endif
71
72     // Enable keyboard left/right modifier distinction
73     // Addr:Keyboard(0010), Cmd:Listen(10), Register3(11)
74     // upper byte: reserved bits 0000, device address 0010
75     // lower byte: device handler 00000011
76     adb_host_listen(0x2B,0x02,0x03);
77 }
78
79 #ifdef ADB_PSW_BIT
80 bool adb_host_psw(void)
81 {
82     return psw_in();
83 }
84 #endif
85
86 /*
87  * Don't call this in a row without the delay, otherwise it makes some of poor controllers
88  * overloaded and misses strokes. Recommended interval is 12ms.
89  *
90  * Thanks a lot, blargg!
91  * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
92  * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
93  */
94 uint16_t adb_host_kbd_recv(void)
95 {
96     uint16_t data = 0;
97     attention();
98     send_byte(0x2C);            // Addr:Keyboard(0010), Cmd:Talk(11), Register0(00)
99     place_bit0();               // Stopbit(0)
100     if (!wait_data_lo(500)) {   // Tlt/Stop to Start(140-260us)
101         return 0;               // No data to send
102     }
103     if (!read_bit()) {          // Startbit(1)
104         // Service Request
105         dprintf("Startbit ERROR\n");
106         return -2;
107     }
108
109     // ad hoc fix: without block inerrupt read wrong bit occasionally and get keys stuck
110     cli();
111     data = read_byte();
112     data = (data<<8) | read_byte();
113     uint8_t stop = read_bit();  // Stopbit(0)
114     sei();
115
116     if (stop) {
117         dprintf("Stopbit ERROR\n");
118         return -3;
119     }
120     return data;
121 }
122
123 void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l)
124 {
125     attention();
126     send_byte(cmd);
127     place_bit0();               // Stopbit(0)
128     _delay_us(200);             // Tlt/Stop to Start
129     place_bit1();               // Startbit(1)
130     send_byte(data_h); 
131     send_byte(data_l);
132     place_bit0();               // Stopbit(0);
133 }
134
135 // send state of LEDs
136 void adb_host_kbd_led(uint8_t led)
137 {
138     // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10)
139     // send upper byte (not used)
140     // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0:
141     adb_host_listen(0x2A,0,led&0x07);
142 }
143
144
145 static inline void data_lo()
146 {
147     ADB_DDR  |=  (1<<ADB_DATA_BIT);
148     ADB_PORT &= ~(1<<ADB_DATA_BIT);
149 }
150 static inline void data_hi()
151 {
152     ADB_PORT |=  (1<<ADB_DATA_BIT);
153     ADB_DDR  &= ~(1<<ADB_DATA_BIT);
154 }
155 static inline bool data_in()
156 {
157     ADB_PORT |=  (1<<ADB_DATA_BIT);
158     ADB_DDR  &= ~(1<<ADB_DATA_BIT);
159     return ADB_PIN&(1<<ADB_DATA_BIT);
160 }
161
162 #ifdef ADB_PSW_BIT
163 static inline void psw_lo()
164 {
165     ADB_DDR  |=  (1<<ADB_PSW_BIT);
166     ADB_PORT &= ~(1<<ADB_PSW_BIT);
167 }
168 static inline void psw_hi()
169 {
170     ADB_PORT |=  (1<<ADB_PSW_BIT);
171     ADB_DDR  &= ~(1<<ADB_PSW_BIT);
172 }
173 static inline bool psw_in()
174 {
175     ADB_PORT |=  (1<<ADB_PSW_BIT);
176     ADB_DDR  &= ~(1<<ADB_PSW_BIT);
177     return ADB_PIN&(1<<ADB_PSW_BIT);
178 }
179 #endif
180
181 static inline void attention(void)
182 {
183     data_lo();
184     _delay_us(700);
185     place_bit1();
186 }
187
188 static inline void place_bit0(void)
189 {
190     data_lo();
191     _delay_us(65);
192     data_hi();
193     _delay_us(35);
194 }
195
196 static inline void place_bit1(void)
197 {
198     data_lo();
199     _delay_us(35);
200     data_hi();
201     _delay_us(65);
202 }
203
204 static inline void send_byte(uint8_t data)
205 {
206     for (int i = 0; i < 8; i++) {
207         if (data&(0x80>>i))
208             place_bit1();
209         else
210             place_bit0();
211     }
212 }
213
214 static inline bool read_bit(void)
215 {
216     // ADB Bit Cells
217     //
218     // bit cell time: 70-130us
219     // low part of bit0: 60-70% of bit cell
220     // low part of bit1: 30-40% of bit cell
221     //
222     //    bit cell time         70us        130us
223     //    --------------------------------------------
224     //    low  part of bit0     42-49       78-91
225     //    high part of bit0     21-28       39-52
226     //    low  part of bit1     21-28       39-52
227     //    high part of bit1     42-49       78-91
228     //
229     //
230     // bit0:
231     //    70us bit cell:
232     //      ____________~~~~~~
233     //      42-49        21-28  
234     //
235     //    130us bit cell:
236     //      ____________~~~~~~
237     //      78-91        39-52  
238     //
239     // bit1:
240     //    70us bit cell:
241     //      ______~~~~~~~~~~~~
242     //      21-28        42-49
243     //
244     //    130us bit cell:
245     //      ______~~~~~~~~~~~~
246     //      39-52        78-91
247     //
248     // read:
249     //      ________|~~~~~~~~~
250     //              55us
251     // Read data line after 55us. If data line is low/high then bit is 0/1.
252     // This method might not work at <90us bit cell time.
253     //
254     // [from Apple IIgs Hardware Reference Second Edition]
255     bool bit;
256     wait_data_lo(75);   // wait the start of bit cell at least 130ms(55+0+75)
257     _delay_us(55);
258     bit = data_in();
259     wait_data_hi(36);   // wait high part of bit cell at least 91ms(55+36)
260     return bit;
261 }
262
263 static inline uint8_t read_byte(void)
264 {
265     uint8_t data = 0;
266     for (int i = 0; i < 8; i++) {
267         data <<= 1;
268         if (read_bit())
269             data = data | 1;
270     }
271     return data;
272 }
273
274 static inline uint8_t wait_data_lo(uint16_t us)
275 {
276     while (data_in() && us) {
277         _delay_us(1);
278         us--;
279     }
280     return us;
281 }
282
283 static inline uint8_t wait_data_hi(uint8_t us)
284 {
285     while (!data_in() && us) {
286         _delay_us(1);
287         us--;
288     }
289     return us;
290 }
291
292
293 /*
294 ADB Protocol
295 ============
296
297 Resources
298 ---------
299 ADB - The Untold Story: Space Aliens Ate My Mouse
300     http://developer.apple.com/legacy/mac/library/#technotes/hw/hw_01.html
301 ADB Manager
302     http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Devices/ADB_Manager.pdf
303     Service request(5-17)
304 Apple IIgs Hardware Reference Second Edition [Chapter6 p121]
305     ftp://ftp.apple.asimov.net/pub/apple_II/documentation/Apple%20IIgs%20Hardware%20Reference.pdf
306 ADB Keycode
307     http://72.0.193.250/Documentation/macppc/adbkeycodes/
308     http://m0115.web.fc2.com/m0115.jpg
309     [Inside Macintosh volume V, pages 191-192]
310     http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-421.18.3/IOHIDFamily/Cosmo_USB2ADB.c
311 ADB Signaling
312     http://kbdbabel.sourceforge.net/doc/kbd_signaling_pcxt_ps2_adb.pdf
313 ADB Overview & History
314     http://en.wikipedia.org/wiki/Apple_Desktop_Bus
315 Microchip Application Note: ADB device(with code for PIC16C)
316     http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011062
317 AVR ATtiny2131 ADB to PS/2 converter(Japanese)
318     http://hp.vector.co.jp/authors/VA000177/html/KeyBoardA5DEA5CBA5A2II.html
319
320
321 Pinouts
322 -------
323     ADB female socket from the front:
324     __________
325     |        | <--- top
326     | 4o  o3 |
327     |2o    o1|
328     |   ==   |
329     |________| <--- bottom
330       |    |   <--- 4pins
331
332
333     ADB female socket from bottom:
334
335     ========== <--- front
336     |        |
337     |        |
338     |2o    o1|
339     |4o    o3|
340     ---------- <--- back
341
342     1: Data
343     2: Power SW(low when press Power key)
344     3: Vcc(5V)
345     4: GND
346
347
348 Commands
349 --------
350     ADB command is 1byte and consists of 4bit-address, 2bit-command
351     type and 2bit-register. The commands are always sent by Host.
352
353     Command format:
354     7 6 5 4 3 2 1 0
355     | | | |------------ address
356             | |-------- command type
357                 | |---- register
358
359     bits                commands
360     ------------------------------------------------------
361     - - - - 0 0 0 0     Send Request(reset all devices)
362     A A A A 0 0 0 1     Flush(reset a device)
363     - - - - 0 0 1 0     Reserved
364     - - - - 0 0 1 1     Reserved
365     - - - - 0 1 - -     Reserved
366     A A A A 1 0 R R     Listen(write to a device)
367     A A A A 1 1 R R     Talk(read from a device)
368
369     The command to read keycodes from keyboard is 0x2C which
370     consist of keyboard address 2 and Talk against register 0. 
371
372     Address:
373     2:  keyboard
374     3:  mice
375
376     Registers:
377     0: application(keyobard uses this to store its data.)
378     1: application
379     2: application(keyboard uses this for LEDs and state of modifiers)
380     3: status and command
381
382
383 Communication
384 -------------
385     This is a minimum information for keyboard communication.
386     See "Resources" for detail.
387
388     Signaling:
389
390     ~~~~____________~~||||||||||||__~~~~~_~~|||||||||||||||__~~~~
391
392         |800us     |  |7 Command 0|  |   |  |15-64  Data  0|Stopbit(0)
393         +Attention |              |  |   +Startbit(1)
394                    +Startbit(1)   |  +Tlt(140-260us)
395                                   +stopbit(0)
396
397     Bit cells:
398
399     bit0: ______~~~
400           65    :35us
401
402     bit1: ___~~~~~~
403           35 :65us
404
405     bit0 low time: 60-70% of bit cell(42-91us)
406     bit1 low time: 30-40% of bit cell(21-52us)
407     bit cell time: 70-130us
408     [from Apple IIgs Hardware Reference Second Edition]
409
410     Criterion for bit0/1:
411     After 55us if line is low/high then bit is 0/1.
412
413     Attention & start bit:
414     Host asserts low in 560-1040us then places start bit(1).
415
416     Tlt(Stop to Start):
417     Bus stays high in 140-260us then device places start bit(1).
418
419     Global reset:
420     Host asserts low in 2.8-5.2ms. All devices are forced to reset.
421
422     Service request from device(Srq):
423     Device can request to send at commad(Global only?) stop bit.
424     Requesting device keeps low for 140-260us at stop bit of command.
425
426
427 Keyboard Data(Register0)
428     This 16bit data can contains two keycodes and two released flags.
429     First keycode is palced in upper byte. When one keyocode is sent,
430     lower byte is 0xFF.
431     Release flag is 1 when key is released.
432
433     1514 . . . . . 8 7 6 . . . . . 0
434      | | | | | | | | | +-+-+-+-+-+-+-   Keycode2
435      | | | | | | | | +---------------   Released2(1 when the key is released)
436      | +-+-+-+-+-+-+-----------------   Keycode1
437      +-------------------------------   Released1(1 when the key is released)
438
439     Keycodes:
440     Scancode consists of 7bit keycode and 1bit release flag.
441     Device can send two keycodes at once. If just one keycode is sent
442     keycode1 contains it and keyocode2 is 0xFF.
443
444     Power switch:
445     You can read the state from PSW line(active low) however
446     the switch has a special scancode 0x7F7F, so you can
447     also read from Data line. It uses 0xFFFF for release scancode.
448
449 Keyboard LEDs & state of keys(Register2)
450     This register hold current state of three LEDs and nine keys.
451     The state of LEDs can be changed by sending Listen command.
452     
453     1514 . . . . . . 7 6 5 . 3 2 1 0
454      | | | | | | | | | | | | | | | +-   LED1(NumLock)
455      | | | | | | | | | | | | | | +---   LED2(CapsLock)
456      | | | | | | | | | | | | | +-----   LED3(ScrollLock)
457      | | | | | | | | | | +-+-+-------   Reserved
458      | | | | | | | | | +-------------   ScrollLock
459      | | | | | | | | +---------------   NumLock
460      | | | | | | | +-----------------   Apple/Command
461      | | | | | | +-------------------   Option
462      | | | | | +---------------------   Shift
463      | | | | +-----------------------   Control
464      | | | +-------------------------   Reset/Power
465      | | +---------------------------   CapsLock
466      | +-----------------------------   Delete
467      +-------------------------------   Reserved
468
469 END_OF_ADB
470 */