aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2021-10-07 23:14:26 +0100
committerGitHub <noreply@github.com>2021-10-07 23:14:26 +0100
commite0d688d4c8040302fcacb735350c95fe6be4dbde (patch)
tree0518f3ffea7851479c8169ba3bd9fd1d0308fa1d /tmk_core
parentc39170b7ef433ee86230caad6263c59bb727ed5a (diff)
downloadqmk_firmware-e0d688d4c8040302fcacb735350c95fe6be4dbde.tar.gz
qmk_firmware-e0d688d4c8040302fcacb735350c95fe6be4dbde.zip
Move converter specific tmk_core protocols (#14743)
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/protocol.mk9
-rw-r--r--tmk_core/protocol/adb.c535
-rw-r--r--tmk_core/protocol/adb.h106
-rw-r--r--tmk_core/protocol/m0110.c583
-rw-r--r--tmk_core/protocol/m0110.h81
-rw-r--r--tmk_core/protocol/xt.h73
-rw-r--r--tmk_core/protocol/xt_interrupt.c166
-rw-r--r--tmk_core/readme.md11
8 files changed, 3 insertions, 1561 deletions
diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk
index b61f2f546..30c87a0f1 100644
--- a/tmk_core/protocol.mk
+++ b/tmk_core/protocol.mk
@@ -45,15 +45,6 @@ ifeq ($(strip $(SERIAL_MOUSE_USE_UART)), yes)
45 SRC += $(PROTOCOL_DIR)/serial_uart.c 45 SRC += $(PROTOCOL_DIR)/serial_uart.c
46endif 46endif
47 47
48ifeq ($(strip $(ADB_MOUSE_ENABLE)), yes)
49 OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE
50endif
51
52ifeq ($(strip $(XT_ENABLE)), yes)
53 SRC += $(PROTOCOL_DIR)/xt_interrupt.c
54 OPT_DEFS += -DXT_ENABLE
55endif
56
57ifeq ($(strip $(USB_HID_ENABLE)), yes) 48ifeq ($(strip $(USB_HID_ENABLE)), yes)
58 include $(TMK_DIR)/protocol/usb_hid.mk 49 include $(TMK_DIR)/protocol/usb_hid.mk
59endif 50endif
diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c
deleted file mode 100644
index 367f1b09f..000000000
--- a/tmk_core/protocol/adb.c
+++ /dev/null
@@ -1,535 +0,0 @@
1/*
2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3Copyright 2013 Shay Green <gblargg@gmail.com>
4
5This software is licensed with a Modified BSD License.
6All of this is supposed to be Free Software, Open Source, DFSG-free,
7GPL-compatible, and OK to use in both free and proprietary applications.
8Additions and corrections to this file are welcome.
9
10
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions are met:
13
14* Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16
17* Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in
19 the documentation and/or other materials provided with the
20 distribution.
21
22* Neither the name of the copyright holders nor the names of
23 contributors may be used to endorse or promote products derived
24 from this software without specific prior written permission.
25
26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36POSSIBILITY OF SUCH DAMAGE.
37*/
38
39#include <stdbool.h>
40#include <util/delay.h>
41#include <avr/io.h>
42#include <avr/interrupt.h>
43#include "adb.h"
44#include "print.h"
45
46// GCC doesn't inline functions normally
47#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT))
48#define data_hi() (ADB_DDR &= ~(1 << ADB_DATA_BIT))
49#define data_in() (ADB_PIN & (1 << ADB_DATA_BIT))
50
51#ifdef ADB_PSW_BIT
52static inline void psw_lo(void);
53static inline void psw_hi(void);
54static inline bool psw_in(void);
55#endif
56
57static inline void attention(void);
58static inline void place_bit0(void);
59static inline void place_bit1(void);
60static inline void send_byte(uint8_t data);
61static inline uint16_t wait_data_lo(uint16_t us);
62static inline uint16_t wait_data_hi(uint16_t us);
63
64void adb_host_init(void) {
65 ADB_PORT &= ~(1 << ADB_DATA_BIT);
66 data_hi();
67#ifdef ADB_PSW_BIT
68 psw_hi();
69#endif
70}
71
72#ifdef ADB_PSW_BIT
73bool adb_host_psw(void) { return psw_in(); }
74#endif
75
76/*
77 * Don't call this in a row without the delay, otherwise it makes some of poor controllers
78 * overloaded and misses strokes. Recommended interval is 12ms.
79 *
80 * Thanks a lot, blargg!
81 * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
82 * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
83 */
84uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); }
85
86#ifdef ADB_MOUSE_ENABLE
87__attribute__((weak)) void adb_mouse_init(void) { return; }
88
89__attribute__((weak)) void adb_mouse_task(void) { return; }
90
91uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }
92#endif
93
94// This sends Talk command to read data from register and returns length of the data.
95uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
96 for (int8_t i = 0; i < len; i++) buf[i] = 0;
97
98 cli();
99 attention();
100 send_byte((addr << 4) | ADB_CMD_TALK | reg);
101 place_bit0(); // Stopbit(0)
102 // TODO: Service Request(Srq):
103 // Device holds low part of comannd stopbit for 140-260us
104 //
105 // Command:
106 // ......._ ______________________ ___ ............_ -------
107 // | | | | | | |
108 // Command | | | | | Data bytes | |
109 // ........|___| | 140-260 |__| |_............|___|
110 // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
111 //
112 // Command without data:
113 // ......._ __________________________
114 // | |
115 // Command | |
116 // ........|___| | 140-260 |
117 // |stop0 | Tlt Stop-to-Start |
118 //
119 // Service Request:
120 // ......._ ______ ___ ............_ -------
121 // | 140-260 | | | | | |
122 // Command | Service Request | | | | Data bytes | |
123 // ........|___________________| |__| |_............|___|
124 // |stop0 | |start1| |stop0 |
125 // ......._ __________
126 // | 140-260 |
127 // Command | Service Request |
128 // ........|___________________|
129 // |stop0 |
130 // This can be happened?
131 // ......._ ______________________ ___ ............_ -----
132 // | | | | | | 140-260 |
133 // Command | | | | | Data bytes | Service Request |
134 // ........|___| | 140-260 |__| |_............|_________________|
135 // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
136 //
137 // "Service requests are issued by the devices during a very specific time at the
138 // end of the reception of the command packet.
139 // If a device in need of service issues a service request, it must do so within
140 // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."
141 //
142 // "A device sends a Service Request signal by holding the bus low during the low
143 // portion of the stop bit of any command or data transaction. The device must lengthen
144 // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
145 // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
146 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
147 xprintf("R");
148 sei();
149 return 0;
150 }
151 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
152 sei();
153 return 0; // No data from device(not error);
154 }
155
156 // start bit(1)
157 if (!wait_data_hi(40)) {
158 xprintf("S");
159 sei();
160 return 0;
161 }
162 if (!wait_data_lo(100)) {
163 xprintf("s");
164 sei();
165 return 0;
166 }
167
168 uint8_t n = 0; // bit count
169 do {
170 //
171 // |<- bit_cell_max(130) ->|
172 // | |<- lo ->|
173 // | | |<-hi->|
174 // _______
175 // | | |
176 // | 130-lo | lo-hi |
177 // |________| |
178 //
179 uint8_t lo = (uint8_t)wait_data_hi(130);
180 if (!lo) goto error; // no more bit or after stop bit
181
182 uint8_t hi = (uint8_t)wait_data_lo(lo);
183 if (!hi) goto error; // stop bit extedned by Srq?
184
185 if (n / 8 >= len) continue; // can't store in buf
186
187 buf[n / 8] <<= 1;
188 if ((130 - lo) < (lo - hi)) {
189 buf[n / 8] |= 1;
190 }
191 } while (++n);
192
193error:
194 sei();
195 return n / 8;
196}
197
198uint16_t adb_host_talk(uint8_t addr, uint8_t reg) {
199 uint8_t len;
200 uint8_t buf[8];
201 len = adb_host_talk_buf(addr, reg, buf, 8);
202 if (len != 2) return 0;
203 return (buf[0] << 8 | buf[1]);
204}
205
206void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
207 cli();
208 attention();
209 send_byte((addr << 4) | ADB_CMD_LISTEN | reg);
210 place_bit0(); // Stopbit(0)
211 // TODO: Service Request
212 _delay_us(200); // Tlt/Stop to Start
213 place_bit1(); // Startbit(1)
214 for (int8_t i = 0; i < len; i++) {
215 send_byte(buf[i]);
216 // xprintf("%02X ", buf[i]);
217 }
218 place_bit0(); // Stopbit(0);
219 sei();
220}
221
222void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) {
223 uint8_t buf[2] = {data_h, data_l};
224 adb_host_listen_buf(addr, reg, buf, 2);
225}
226
227void adb_host_flush(uint8_t addr) {
228 cli();
229 attention();
230 send_byte((addr << 4) | ADB_CMD_FLUSH);
231 place_bit0(); // Stopbit(0)
232 _delay_us(200); // Tlt/Stop to Start
233 sei();
234}
235
236// send state of LEDs
237void adb_host_kbd_led(uint8_t led) {
238 // Listen Register2
239 // upper byte: not used
240 // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
241 adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);
242}
243
244#ifdef ADB_PSW_BIT
245static inline void psw_lo() {
246 ADB_DDR |= (1 << ADB_PSW_BIT);
247 ADB_PORT &= ~(1 << ADB_PSW_BIT);
248}
249static inline void psw_hi() {
250 ADB_PORT |= (1 << ADB_PSW_BIT);
251 ADB_DDR &= ~(1 << ADB_PSW_BIT);
252}
253static inline bool psw_in() {
254 ADB_PORT |= (1 << ADB_PSW_BIT);
255 ADB_DDR &= ~(1 << ADB_PSW_BIT);
256 return ADB_PIN & (1 << ADB_PSW_BIT);
257}
258#endif
259
260static inline void attention(void) {
261 data_lo();
262 _delay_us(800 - 35); // bit1 holds lo for 35 more
263 place_bit1();
264}
265
266static inline void place_bit0(void) {
267 data_lo();
268 _delay_us(65);
269 data_hi();
270 _delay_us(35);
271}
272
273static inline void place_bit1(void) {
274 data_lo();
275 _delay_us(35);
276 data_hi();
277 _delay_us(65);
278}
279
280static inline void send_byte(uint8_t data) {
281 for (int i = 0; i < 8; i++) {
282 if (data & (0x80 >> i))
283 place_bit1();
284 else
285 place_bit0();
286 }
287}
288
289// These are carefully coded to take 6 cycles of overhead.
290// inline asm approach became too convoluted
291static inline uint16_t wait_data_lo(uint16_t us) {
292 do {
293 if (!data_in()) break;
294 _delay_us(1 - (6 * 1000000.0 / F_CPU));
295 } while (--us);
296 return us;
297}
298
299static inline uint16_t wait_data_hi(uint16_t us) {
300 do {
301 if (data_in()) break;
302 _delay_us(1 - (6 * 1000000.0 / F_CPU));
303 } while (--us);
304 return us;
305}
306
307/*
308ADB Protocol
309============
310
311Resources
312---------
313ADB - The Untold Story: Space Aliens Ate My Mouse
314 http://developer.apple.com/legacy/mac/library/#technotes/hw/hw_01.html
315ADB Manager
316 http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Devices/ADB_Manager.pdf
317 Service request(5-17)
318Apple IIgs Hardware Reference Second Edition [Chapter6 p121]
319 ftp://ftp.apple.asimov.net/pub/apple_II/documentation/Apple%20IIgs%20Hardware%20Reference.pdf
320ADB Keycode
321 http://72.0.193.250/Documentation/macppc/adbkeycodes/
322 http://m0115.web.fc2.com/m0115.jpg
323 [Inside Macintosh volume V, pages 191-192]
324 http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-421.18.3/IOHIDFamily/Cosmo_USB2ADB.c
325ADB Signaling
326 http://kbdbabel.sourceforge.net/doc/kbd_signaling_pcxt_ps2_adb.pdf
327ADB Overview & History
328 http://en.wikipedia.org/wiki/Apple_Desktop_Bus
329Microchip Application Note: ADB device(with code for PIC16C)
330 http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011062
331AVR ATtiny2131 ADB to PS/2 converter(Japanese)
332 http://hp.vector.co.jp/authors/VA000177/html/KeyBoardA5DEA5CBA5A2II.html
333
334
335Pinouts
336-------
337 ADB female socket from the front:
338 __________
339 | | <--- top
340 | 4o o3 |
341 |2o o1|
342 | == |
343 |________| <--- bottom
344 | | <--- 4pins
345
346
347 ADB female socket from bottom:
348
349 ========== <--- front
350 | |
351 | |
352 |2o o1|
353 |4o o3|
354 ---------- <--- back
355
356 1: Data
357 2: Power SW(low when press Power key)
358 3: Vcc(5V)
359 4: GND
360
361
362Commands
363--------
364 ADB command is 1byte and consists of 4bit-address, 2bit-command
365 type and 2bit-register. The commands are always sent by Host.
366
367 Command format:
368 7 6 5 4 3 2 1 0
369 | | | |------------ address
370 | |-------- command type
371 | |---- register
372
373 bits commands
374 ------------------------------------------------------
375 - - - - 0 0 0 0 Send Reset(reset all devices)
376 A A A A 0 0 0 1 Flush(reset a device)
377 - - - - 0 0 1 0 Reserved
378 - - - - 0 0 1 1 Reserved
379 - - - - 0 1 - - Reserved
380 A A A A 1 0 R R Listen(write to a device)
381 A A A A 1 1 R R Talk(read from a device)
382
383 The command to read keycodes from keyboard is 0x2C which
384 consist of keyboard address 2 and Talk against register 0.
385
386 Address:
387 2: keyboard
388 3: mice
389
390 Registers:
391 0: application(keyboard uses this to store its data.)
392 1: application
393 2: application(keyboard uses this for LEDs and state of modifiers)
394 3: status and command
395
396
397Communication
398-------------
399 This is a minimum information for keyboard communication.
400 See "Resources" for detail.
401
402 Signaling:
403
404 ~~~~____________~~||||||||||||__~~~~~_~~|||||||||||||||__~~~~
405
406 |800us | |7 Command 0| | | |15-64 Data 0|Stopbit(0)
407 +Attention | | | +Startbit(1)
408 +Startbit(1) | +Tlt(140-260us)
409 +stopbit(0)
410
411 Bit cells:
412
413 bit0: ______~~~
414 65 :35us
415
416 bit1: ___~~~~~~
417 35 :65us
418
419 bit0 low time: 60-70% of bit cell(42-91us)
420 bit1 low time: 30-40% of bit cell(21-52us)
421 bit cell time: 70-130us
422 [from Apple IIgs Hardware Reference Second Edition]
423
424 Criterion for bit0/1:
425 After 55us if line is low/high then bit is 0/1.
426
427 Attention & start bit:
428 Host asserts low in 560-1040us then places start bit(1).
429
430 Tlt(Stop to Start):
431 Bus stays high in 140-260us then device places start bit(1).
432
433 Global reset:
434 Host asserts low in 2.8-5.2ms. All devices are forced to reset.
435
436 Service request from device(Srq):
437 Device can request to send at commad(Global only?) stop bit.
438 Requesting device keeps low for 140-260us at stop bit of command.
439
440
441Keyboard Data(Register0)
442 This 16bit data can contains two keycodes and two released flags.
443 First keycode is palced in upper byte. When one keyocode is sent,
444 lower byte is 0xFF.
445 Release flag is 1 when key is released.
446
447 1514 . . . . . 8 7 6 . . . . . 0
448 | | | | | | | | | +-+-+-+-+-+-+- Keycode2
449 | | | | | | | | +--------------- Released2(1 when the key is released)
450 | +-+-+-+-+-+-+----------------- Keycode1
451 +------------------------------- Released1(1 when the key is released)
452
453 Keycodes:
454 Scancode consists of 7bit keycode and 1bit release flag.
455 Device can send two keycodes at once. If just one keycode is sent
456 keycode1 contains it and keyocode2 is 0xFF.
457
458 Power switch:
459 You can read the state from PSW line(active low) however
460 the switch has a special scancode 0x7F7F, so you can
461 also read from Data line. It uses 0xFFFF for release scancode.
462
463Keyboard LEDs & state of keys(Register2)
464 This register hold current state of three LEDs and nine keys.
465 The state of LEDs can be changed by sending Listen command.
466
467 1514 . . . . . . 7 6 5 . 3 2 1 0
468 | | | | | | | | | | | | | | | +- LED1(NumLock)
469 | | | | | | | | | | | | | | +--- LED2(CapsLock)
470 | | | | | | | | | | | | | +----- LED3(ScrollLock)
471 | | | | | | | | | | +-+-+------- Reserved
472 | | | | | | | | | +------------- ScrollLock
473 | | | | | | | | +--------------- NumLock
474 | | | | | | | +----------------- Apple/Command
475 | | | | | | +------------------- Option
476 | | | | | +--------------------- Shift
477 | | | | +----------------------- Control
478 | | | +------------------------- Reset/Power
479 | | +--------------------------- CapsLock
480 | +----------------------------- Delete
481 +------------------------------- Reserved
482
483Address, Handler ID and bits(Register3)
484 1514131211 . . 8 7 . . . . . . 0
485 | | | | | | | | | | | | | | | |
486 | | | | | | | | +-+-+-+-+-+-+-+- Handler ID
487 | | | | +-+-+-+----------------- Address
488 | | | +------------------------- 0
489 | | +--------------------------- Service request enable(1 = enabled)
490 | +----------------------------- Exceptional event(alwyas 1 if not used)
491 +------------------------------- 0
492
493ADB Bit Cells
494 bit cell time: 70-130us
495 low part of bit0: 60-70% of bit cell
496 low part of bit1: 30-40% of bit cell
497
498 bit cell time 70us 130us
499 --------------------------------------------
500 low part of bit0 42-49 78-91
501 high part of bit0 21-28 39-52
502 low part of bit1 21-28 39-52
503 high part of bit1 42-49 78-91
504
505
506 bit0:
507 70us bit cell:
508 ____________~~~~~~
509 42-49 21-28
510
511 130us bit cell:
512 ____________~~~~~~
513 78-91 39-52
514
515 bit1:
516 70us bit cell:
517 ______~~~~~~~~~~~~
518 21-28 42-49
519
520 130us bit cell:
521 ______~~~~~~~~~~~~
522 39-52 78-91
523
524 [from Apple IIgs Hardware Reference Second Edition]
525
526Keyboard Handle ID
527 Apple Standard Keyboard M0116: 0x01
528 Apple Extended Keyboard M0115: 0x02
529 Apple Extended Keyboard II M3501: 0x02
530 Apple Adjustable Keybaord: 0x10
531
532 http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
533
534END_OF_ADB
535*/
diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h
deleted file mode 100644
index fe8becc2d..000000000
--- a/tmk_core/protocol/adb.h
+++ /dev/null
@@ -1,106 +0,0 @@
1/*
2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3
4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free,
6GPL-compatible, and OK to use in both free and proprietary applications.
7Additions and corrections to this file are welcome.
8
9
10Redistribution and use in source and binary forms, with or without
11modification, 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
25THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35POSSIBILITY OF SUCH DAMAGE.
36*/
37
38#pragma once
39
40#include <stdint.h>
41#include <stdbool.h>
42
43#if !(defined(ADB_PORT) && defined(ADB_PIN) && defined(ADB_DDR) && defined(ADB_DATA_BIT))
44# error "ADB port setting is required in config.h"
45#endif
46
47#define ADB_POWER 0x7F
48#define ADB_CAPS 0x39
49
50/* ADB commands */
51// Default Address
52#define ADB_ADDR_0 0
53#define ADB_ADDR_DONGLE 1
54#define ADB_ADDR_KEYBOARD 2
55#define ADB_ADDR_MOUSE 3
56#define ADB_ADDR_TABLET 4
57#define ADB_ADDR_APPLIANCE 7
58#define ADB_ADDR_8 8
59#define ADB_ADDR_9 9
60#define ADB_ADDR_10 10
61#define ADB_ADDR_11 11
62#define ADB_ADDR_12 12
63#define ADB_ADDR_13 13
64#define ADB_ADDR_14 14
65#define ADB_ADDR_15 15
66// for temporary purpose, do not use for polling
67#define ADB_ADDR_TMP 15
68#define ADB_ADDR_MOUSE_POLL 10
69// Command Type
70#define ADB_CMD_RESET 0
71#define ADB_CMD_FLUSH 1
72#define ADB_CMD_LISTEN 8
73#define ADB_CMD_TALK 12
74// Register
75#define ADB_REG_0 0
76#define ADB_REG_1 1
77#define ADB_REG_2 2
78#define ADB_REG_3 3
79
80/* ADB keyboard handler id */
81#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */
82#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */
83#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */
84#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */
85#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */
86#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */
87#define ADB_HANDLER_CLASSIC1_MOUSE 0x01
88#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
89#define ADB_HANDLER_EXTENDED_MOUSE 0x04
90#define ADB_HANDLER_TURBO_MOUSE 0x32
91
92// ADB host
93void adb_host_init(void);
94bool adb_host_psw(void);
95uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
96uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
97void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
98void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
99void adb_host_flush(uint8_t addr);
100void adb_host_kbd_led(uint8_t led);
101uint16_t adb_host_kbd_recv(void);
102uint16_t adb_host_mouse_recv(void);
103
104// ADB Mouse
105void adb_mouse_task(void);
106void adb_mouse_init(void);
diff --git a/tmk_core/protocol/m0110.c b/tmk_core/protocol/m0110.c
deleted file mode 100644
index 64f2fa50a..000000000
--- a/tmk_core/protocol/m0110.c
+++ /dev/null
@@ -1,583 +0,0 @@
1/*
2Copyright 2011,2012 Jun WAKO <wakojun@gmail.com>
3
4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free,
6GPL-compatible, and OK to use in both free and proprietary applications.
7Additions and corrections to this file are welcome.
8
9
10Redistribution and use in source and binary forms, with or without
11modification, 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
25THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35POSSIBILITY OF SUCH DAMAGE.
36*/
37/* M0110A Support was contributed by skagon@github */
38
39#include <stdbool.h>
40#include <avr/io.h>
41#include <avr/interrupt.h>
42#include <util/delay.h>
43#include "m0110.h"
44#include "debug.h"
45
46static inline uint8_t raw2scan(uint8_t raw);
47static inline uint8_t inquiry(void);
48static inline uint8_t instant(void);
49static inline void clock_lo(void);
50static inline void clock_hi(void);
51static inline bool clock_in(void);
52static inline void data_lo(void);
53static inline void data_hi(void);
54static inline bool data_in(void);
55static inline uint16_t wait_clock_lo(uint16_t us);
56static inline uint16_t wait_clock_hi(uint16_t us);
57static inline uint16_t wait_data_lo(uint16_t us);
58static inline uint16_t wait_data_hi(uint16_t us);
59static inline void idle(void);
60static inline void request(void);
61
62#define WAIT_US(stat, us, err) \
63 do { \
64 if (!wait_##stat(us)) { \
65 m0110_error = err; \
66 goto ERROR; \
67 } \
68 } while (0)
69
70#define WAIT_MS(stat, ms, err) \
71 do { \
72 uint16_t _ms = ms; \
73 while (_ms) { \
74 if (wait_##stat(1000)) { \
75 break; \
76 } \
77 _ms--; \
78 } \
79 if (_ms == 0) { \
80 m0110_error = err; \
81 goto ERROR; \
82 } \
83 } while (0)
84
85#define KEY(raw) ((raw)&0x7f)
86#define IS_BREAK(raw) (((raw)&0x80) == 0x80)
87
88uint8_t m0110_error = 0;
89
90void m0110_init(void) {
91 idle();
92 _delay_ms(1000);
93
94 /* Not needed to initialize in fact.
95 uint8_t data;
96 m0110_send(M0110_MODEL);
97 data = m0110_recv();
98 print("m0110_init model: "); print_hex8(data); print("\n");
99
100 m0110_send(M0110_TEST);
101 data = m0110_recv();
102 print("m0110_init test: "); print_hex8(data); print("\n");
103 */
104}
105
106uint8_t m0110_send(uint8_t data) {
107 m0110_error = 0;
108
109 request();
110 WAIT_MS(clock_lo, 250, 1); // keyboard may block long time
111 for (uint8_t bit = 0x80; bit; bit >>= 1) {
112 WAIT_US(clock_lo, 250, 3);
113 if (data & bit) {
114 data_hi();
115 } else {
116 data_lo();
117 }
118 WAIT_US(clock_hi, 200, 4);
119 }
120 _delay_us(100); // hold last bit for 80us
121 idle();
122 return 1;
123ERROR:
124 print("m0110_send err: ");
125 print_hex8(m0110_error);
126 print("\n");
127 _delay_ms(500);
128 idle();
129 return 0;
130}
131
132uint8_t m0110_recv(void) {
133 uint8_t data = 0;
134 m0110_error = 0;
135
136 WAIT_MS(clock_lo, 250, 1); // keyboard may block long time
137 for (uint8_t i = 0; i < 8; i++) {
138 data <<= 1;
139 WAIT_US(clock_lo, 200, 2);
140 WAIT_US(clock_hi, 200, 3);
141 if (data_in()) {
142 data |= 1;
143 }
144 }
145 idle();
146 return data;
147ERROR:
148 print("m0110_recv err: ");
149 print_hex8(m0110_error);
150 print("\n");
151 _delay_ms(500);
152 idle();
153 return 0xFF;
154}
155
156/*
157Handling for exceptional case of key combinations for M0110A
158
159Shift and Calc/Arrow key could be operated simultaneously:
160
161 Case Shift Arrow Events Interpret
162 -------------------------------------------------------------------
163 1 Down Down 71, 79, DD Calc(d)*a *b
164 2 Down Up 71, 79, UU Arrow&Calc(u)*a
165 3 Up Down F1, 79, DD Shift(u) *c
166 4 Up Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a
167
168 Case Shift Calc Events Interpret
169 -------------------------------------------------------------------
170 5(1) Down Down 71, 71, 79, DD Shift(d) and Cacl(d)
171 6(2) Down Up F1, 71, 79, UU Shift(u) and Arrow&Calc(u)*a
172 7(1) Up Down F1, 71, 79, DD Shift(u) and Calc(d)
173 8(4) Up Up F1, F1, 79, UU Shift(ux2) and Arrow&Calc(u)*a
174
175During Calc key is hold:
176 Case Shift Arrow Events Interpret
177 -------------------------------------------------------------------
178 A(3) ---- Down F1, 79, DD Shift(u) *c
179 B ---- Up 79, UU Arrow&Calc(u)*a
180 C Down ---- F1, 71 Shift(u) and Shift(d)
181 D Up ---- F1 Shift(u)
182 E Hold Down 79, DD Normal
183 F Hold Up 79, UU Arrow&Calc(u)*a
184 G(1) Down Down F1, 71, 79, DD Shift(u)*b and Calc(d)*a
185 H(2) Down Up F1, 71, 79, UU Shift(u) and Arrow&Calc(u)*a
186 I(3) Up Down F1, F1, 79, DD Shift(ux2) *c
187 J(4) Up Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a
188
189 Case Shift Calc Events Interpret
190 -------------------------------------------------------------------
191 K(1) ---- Down 71, 79, DD Calc(d)*a
192 L(4) ---- Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a
193 M(1) Hold Down 71, 79, DD Calc(d)*a
194 N Hold Up 79, UU Arrow&Calc(u)*a
195
196 Where DD/UU indicates part of Keypad Down/Up event.
197 *a: Impossible to distinguish btween Arrow and Calc event.
198 *b: Shift(d) event is ignored.
199 *c: Arrow/Calc(d) event is ignored.
200*/
201uint8_t m0110_recv_key(void) {
202 static uint8_t keybuf = 0x00;
203 static uint8_t keybuf2 = 0x00;
204 static uint8_t rawbuf = 0x00;
205 uint8_t raw, raw2, raw3;
206
207 if (keybuf) {
208 raw = keybuf;
209 keybuf = 0x00;
210 return raw;
211 }
212 if (keybuf2) {
213 raw = keybuf2;
214 keybuf2 = 0x00;
215 return raw;
216 }
217
218 if (rawbuf) {
219 raw = rawbuf;
220 rawbuf = 0x00;
221 } else {
222 raw = instant(); // Use INSTANT for better response. Should be INQUIRY ?
223 }
224 switch (KEY(raw)) {
225 case M0110_KEYPAD:
226 raw2 = instant();
227 switch (KEY(raw2)) {
228 case M0110_ARROW_UP:
229 case M0110_ARROW_DOWN:
230 case M0110_ARROW_LEFT:
231 case M0110_ARROW_RIGHT:
232 if (IS_BREAK(raw2)) {
233 // Case B,F,N:
234 keybuf = (raw2scan(raw2) | M0110_CALC_OFFSET); // Calc(u)
235 return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); // Arrow(u)
236 }
237 break;
238 }
239 // Keypad or Arrow
240 return (raw2scan(raw2) | M0110_KEYPAD_OFFSET);
241 break;
242 case M0110_SHIFT:
243 raw2 = instant();
244 switch (KEY(raw2)) {
245 case M0110_SHIFT:
246 // Case: 5-8,C,G,H
247 rawbuf = raw2;
248 return raw2scan(raw); // Shift(d/u)
249 break;
250 case M0110_KEYPAD:
251 // Shift + Arrow, Calc, or etc.
252 raw3 = instant();
253 switch (KEY(raw3)) {
254 case M0110_ARROW_UP:
255 case M0110_ARROW_DOWN:
256 case M0110_ARROW_LEFT:
257 case M0110_ARROW_RIGHT:
258 if (IS_BREAK(raw)) {
259 if (IS_BREAK(raw3)) {
260 // Case 4:
261 print("(4)\n");
262 keybuf2 = raw2scan(raw); // Shift(u)
263 keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u)
264 return (raw2scan(raw3) | M0110_KEYPAD_OFFSET); // Arrow(u)
265 } else {
266 // Case 3:
267 print("(3)\n");
268 return (raw2scan(raw)); // Shift(u)
269 }
270 } else {
271 if (IS_BREAK(raw3)) {
272 // Case 2:
273 print("(2)\n");
274 keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u)
275 return (raw2scan(raw3) | M0110_KEYPAD_OFFSET); // Arrow(u)
276 } else {
277 // Case 1:
278 print("(1)\n");
279 return (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(d)
280 }
281 }
282 break;
283 default:
284 // Shift + Keypad
285 keybuf = (raw2scan(raw3) | M0110_KEYPAD_OFFSET);
286 return raw2scan(raw); // Shift(d/u)
287 break;
288 }
289 break;
290 default:
291 // Shift + Normal keys
292 keybuf = raw2scan(raw2);
293 return raw2scan(raw); // Shift(d/u)
294 break;
295 }
296 break;
297 default:
298 // Normal keys
299 return raw2scan(raw);
300 break;
301 }
302}
303
304static inline uint8_t raw2scan(uint8_t raw) { return (raw == M0110_NULL) ? M0110_NULL : ((raw == M0110_ERROR) ? M0110_ERROR : (((raw & 0x80) | ((raw & 0x7F) >> 1)))); }
305
306static inline uint8_t inquiry(void) {
307 m0110_send(M0110_INQUIRY);
308 return m0110_recv();
309}
310
311static inline uint8_t instant(void) {
312 m0110_send(M0110_INSTANT);
313 uint8_t data = m0110_recv();
314 if (data != M0110_NULL) {
315 debug_hex(data);
316 debug(" ");
317 }
318 return data;
319}
320
321static inline void clock_lo() {
322 M0110_CLOCK_PORT &= ~(1 << M0110_CLOCK_BIT);
323 M0110_CLOCK_DDR |= (1 << M0110_CLOCK_BIT);
324}
325static inline void clock_hi() {
326 /* input with pull up */
327 M0110_CLOCK_DDR &= ~(1 << M0110_CLOCK_BIT);
328 M0110_CLOCK_PORT |= (1 << M0110_CLOCK_BIT);
329}
330static inline bool clock_in() {
331 M0110_CLOCK_DDR &= ~(1 << M0110_CLOCK_BIT);
332 M0110_CLOCK_PORT |= (1 << M0110_CLOCK_BIT);
333 _delay_us(1);
334 return M0110_CLOCK_PIN & (1 << M0110_CLOCK_BIT);
335}
336static inline void data_lo() {
337 M0110_DATA_PORT &= ~(1 << M0110_DATA_BIT);
338 M0110_DATA_DDR |= (1 << M0110_DATA_BIT);
339}
340static inline void data_hi() {
341 /* input with pull up */
342 M0110_DATA_DDR &= ~(1 << M0110_DATA_BIT);
343 M0110_DATA_PORT |= (1 << M0110_DATA_BIT);
344}
345static inline bool data_in() {
346 M0110_DATA_DDR &= ~(1 << M0110_DATA_BIT);
347 M0110_DATA_PORT |= (1 << M0110_DATA_BIT);
348 _delay_us(1);
349 return M0110_DATA_PIN & (1 << M0110_DATA_BIT);
350}
351
352static inline uint16_t wait_clock_lo(uint16_t us) {
353 while (clock_in() && us) {
354 asm("");
355 _delay_us(1);
356 us--;
357 }
358 return us;
359}
360static inline uint16_t wait_clock_hi(uint16_t us) {
361 while (!clock_in() && us) {
362 asm("");
363 _delay_us(1);
364 us--;
365 }
366 return us;
367}
368static inline uint16_t wait_data_lo(uint16_t us) {
369 while (data_in() && us) {
370 asm("");
371 _delay_us(1);
372 us--;
373 }
374 return us;
375}
376static inline uint16_t wait_data_hi(uint16_t us) {
377 while (!data_in() && us) {
378 asm("");
379 _delay_us(1);
380 us--;
381 }
382 return us;
383}
384
385static inline void idle(void) {
386 clock_hi();
387 data_hi();
388}
389
390static inline void request(void) {
391 clock_hi();
392 data_lo();
393}
394
395/*
396Primitive M0110 Library for AVR
397==============================
398
399
400Signaling
401---------
402CLOCK is always from KEYBOARD. DATA are sent with MSB first.
403
4041) IDLE: both lines are high.
405 CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
406 DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
407
4082) KEYBOARD->HOST: HOST reads bit on rising edge.
409 CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
410 DATA ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
411 <--> 160us(clock low)
412 <---> 180us(clock high)
413
4143) HOST->KEYBOARD: HOST asserts bit on falling edge.
415 CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
416 DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
417 <----> 840us(request to send by host) <---> 80us(hold DATA)
418 <--> 180us(clock low)
419 <---> 220us(clock high)
420
421
422Protocol
423--------
424COMMAND:
425 Inquiry 0x10 get key event with block
426 Instant 0x12 get key event
427 Model 0x14 get model number(M0110 responds with 0x09)
428 bit 7 1 if another device connected(used when keypad exists?)
429 bit4-6 next device model number
430 bit1-3 keyboard model number
431 bit 0 always 1
432 Test 0x16 test(ACK:0x7D/NAK:0x77)
433
434KEY EVENT:
435 bit 7 key state(0:press 1:release)
436 bit 6-1 scan code(see below)
437 bit 0 always 1
438 To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1).
439
440 Note: On the M0110A, Keypad keys and Arrow keys are preceded by 0x79.
441 Moreover, some Keypad keys(=, /, * and +) are preceded by 0x71 on press and 0xF1 on release.
442
443ARROW KEYS:
444 Arrow keys and Calc keys(+,*,/,= on keypad) share same byte sequence and preceding byte of
445 Calc keys(0x71 and 0xF1) means press and release event of SHIFT. This causes a very confusing situation,
446 it is difficult or impossible to tell Calc key from Arrow key plus SHIFT in some cases.
447
448 Raw key events:
449 press release
450 ---------------- ----------------
451 Left: 0x79, 0x0D 0x79, 0x8D
452 Right: 0x79, 0x05 0x79, 0x85
453 Up: 0x79, 0x1B 0x79, 0x9B
454 Down: 0x79, 0x11 0x79, 0x91
455 Pad+: 0x71, 0x79, 0x0D 0xF1, 0x79, 0x8D
456 Pad*: 0x71, 0x79, 0x05 0xF1, 0x79, 0x85
457 Pad/: 0x71, 0x79, 0x1B 0xF1, 0x79, 0x9B
458 Pad=: 0x71, 0x79, 0x11 0xF1, 0x79, 0x91
459
460
461RAW CODE:
462 M0110A
463 ,---------------------------------------------------------. ,---------------.
464 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *|
465 |---------------------------------------------------------| |---------------|
466 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
467 |-----------------------------------------------------' | |---------------|
468 |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
469 |---------------------------------------------------------| |---------------|
470 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
471 |---------------------------------------------------------' |-----------|Ent|
472 |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| |
473 `---------------------------------------------------------' `---------------'
474 ,---------------------------------------------------------. ,---------------.
475 | 65| 25| 27| 29| 2B| 2F| 2D| 35| 39| 33| 3B| 37| 31| 67| |+0F|*11|*1B|*05|
476 |---------------------------------------------------------| |---------------|
477 | 61| 19| 1B| 1D| 1F| 23| 21| 41| 45| 3F| 47| 43| 3D| | |+33|+37|+39|+1D|
478 |-----------------------------------------------------' | |---------------|
479 | 73| 01| 03| 05| 07| 0B| 09| 4D| 51| 4B| 53| 4F| 49| |+2D|+2F|+31|*0D|
480 |---------------------------------------------------------| |---------------|
481 | 71| 0D| 0F| 11| 13| 17| 5B| 5D| 27| 5F| 59| 71|+1B| |+27|+29|+2B| |
482 |---------------------------------------------------------' |-----------|+19|
483 | 75| 6F| 63 | 55|+0D|+05|+11| | +25|+03| |
484 `---------------------------------------------------------' `---------------'
485 + 0x79, 0xDD / 0xF1, 0xUU
486 * 0x71, 0x79,DD / 0xF1, 0x79, 0xUU
487
488
489MODEL NUMBER:
490 M0110: 0x09 00001001 : model number 4 (100)
491 M0110A: 0x0B 00001011 : model number 5 (101)
492 M0110 & M0120: ???
493
494
495Scan Code
496---------
497 m0110_recv_key() function returns following scan codes instead of M0110 raw codes.
498 Scan codes are 1 byte size and MSB(bit7) is set when key is released.
499
500 scancode = ((raw&0x80) | ((raw&0x7F)>>1))
501
502 M0110 M0120
503 ,---------------------------------------------------------. ,---------------.
504 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| -|Lft|Rgt|
505 |---------------------------------------------------------| |---------------|
506 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9|Up |
507 |---------------------------------------------------------| |---------------|
508 |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6|Dn |
509 |---------------------------------------------------------| |---------------|
510 |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | 1| 2| 3| |
511 `---------------------------------------------------------' |-----------|Ent|
512 |Opt|Mac | Space |Enter|Opt| | 0| .| |
513 `------------------------------------------------' `---------------'
514 ,---------------------------------------------------------. ,---------------.
515 | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 4E| 46| 42|
516 |---------------------------------------------------------| |---------------|
517 | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | 59| 5B| 5C| 4D|
518 |---------------------------------------------------------| |---------------|
519 | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 48|
520 |---------------------------------------------------------| |---------------|
521 | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | 53| 54| 55| |
522 `---------------------------------------------------------' |-----------| 4C|
523 | 3A| 37| 31 | 34| 3A| | 52| 41| |
524 `------------------------------------------------' `---------------'
525
526 International keyboard(See page 22 of "Technical Info for 128K/512K")
527 ,---------------------------------------------------------.
528 | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33|
529 |---------------------------------------------------------|
530 | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A|
531 |------------------------------------------------------ |
532 | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| |
533 |---------------------------------------------------------|
534 | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 0A| 38|
535 `---------------------------------------------------------'
536 | 3A| 37| 34 | 31| 3A|
537 `------------------------------------------------'
538
539 M0110A
540 ,---------------------------------------------------------. ,---------------.
541 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *|
542 |---------------------------------------------------------| |---------------|
543 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
544 |-----------------------------------------------------' | |---------------|
545 |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
546 |---------------------------------------------------------| |---------------|
547 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
548 |---------------------------------------------------------' |-----------|Ent|
549 |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| |
550 `---------------------------------------------------------' `---------------'
551 ,---------------------------------------------------------. ,---------------.
552 | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62|
553 |---------------------------------------------------------| |---------------|
554 | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E|
555 |-----------------------------------------------------' | |---------------|
556 | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66|
557 |---------------------------------------------------------| |---------------|
558 | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| |
559 |---------------------------------------------------------' |-----------| 4C|
560 | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| |
561 `---------------------------------------------------------' `---------------'
562
563
564References
565----------
566Technical Info for 128K/512K and Plus
567 ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf
568 ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf
569Protocol:
570 Page 20 of Tech Info for 128K/512K
571 http://www.mac.linux-m68k.org/devel/plushw.php
572Connector:
573 Page 20 of Tech Info for 128K/512K
574 http://www.kbdbabel.org/conn/kbd_connector_macplus.png
575Signaling:
576 http://www.kbdbabel.org/signaling/kbd_signaling_mac.png
577 http://typematic.blog.shinobi.jp/Entry/14/
578M0110 raw scan codes:
579 Page 22 of Tech Info for 128K/512K
580 Page 07 of Tech Info for Plus
581 http://m0115.web.fc2.com/m0110.jpg
582 http://m0115.web.fc2.com/m0110a.jpg
583*/
diff --git a/tmk_core/protocol/m0110.h b/tmk_core/protocol/m0110.h
deleted file mode 100644
index 63ff3e90e..000000000
--- a/tmk_core/protocol/m0110.h
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2Copyright 2011,2012 Jun WAKO <wakojun@gmail.com>
3
4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free,
6GPL-compatible, and OK to use in both free and proprietary applications.
7Additions and corrections to this file are welcome.
8
9
10Redistribution and use in source and binary forms, with or without
11modification, 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
25THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35POSSIBILITY OF SUCH DAMAGE.
36*/
37
38#pragma once
39
40/* port settings for clock and data line */
41#if !(defined(M0110_CLOCK_PORT) && defined(M0110_CLOCK_PIN) && defined(M0110_CLOCK_DDR) && defined(M0110_CLOCK_BIT))
42# error "M0110 clock port setting is required in config.h"
43#endif
44
45#if !(defined(M0110_DATA_PORT) && defined(M0110_DATA_PIN) && defined(M0110_DATA_DDR) && defined(M0110_DATA_BIT))
46# error "M0110 data port setting is required in config.h"
47#endif
48
49/* Commands */
50#define M0110_INQUIRY 0x10
51#define M0110_INSTANT 0x14
52#define M0110_MODEL 0x16
53#define M0110_TEST 0x36
54
55/* Response(raw byte from M0110) */
56#define M0110_NULL 0x7B
57#define M0110_KEYPAD 0x79
58#define M0110_TEST_ACK 0x7D
59#define M0110_TEST_NAK 0x77
60#define M0110_SHIFT 0x71
61#define M0110_ARROW_UP 0x1B
62#define M0110_ARROW_DOWN 0x11
63#define M0110_ARROW_LEFT 0x0D
64#define M0110_ARROW_RIGHT 0x05
65
66/* This inidcates no response. */
67#define M0110_ERROR 0xFF
68
69/* scan code offset for keypad and arrow keys */
70#define M0110_KEYPAD_OFFSET 0x40
71#define M0110_CALC_OFFSET 0x60
72
73extern uint8_t m0110_error;
74
75/* host role */
76void m0110_init(void);
77uint8_t m0110_send(uint8_t data);
78uint8_t m0110_recv(void);
79uint8_t m0110_recv_key(void);
80uint8_t m0110_inquiry(void);
81uint8_t m0110_instant(void);
diff --git a/tmk_core/protocol/xt.h b/tmk_core/protocol/xt.h
deleted file mode 100644
index 538ff0e45..000000000
--- a/tmk_core/protocol/xt.h
+++ /dev/null
@@ -1,73 +0,0 @@
1/*
2Copyright 2018 Jun WAKO <wakojun@gmail.com>
3Copyright 2016 Ethan Apodaca <papodaca@gmail.com>
4
5This software is licensed with a Modified BSD License.
6All of this is supposed to be Free Software, Open Source, DFSG-free,
7GPL-compatible, and OK to use in both free and proprietary applications.
8Additions and corrections to this file are welcome.
9
10
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions are met:
13
14* Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16
17* Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in
19 the documentation and/or other materials provided with the
20 distribution.
21
22* Neither the name of the copyright holders nor the names of
23 contributors may be used to endorse or promote products derived
24 from this software without specific prior written permission.
25
26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36POSSIBILITY OF SUCH DAMAGE.
37*/
38
39#pragma once
40
41#include "quantum.h"
42
43#define XT_DATA_IN() \
44 do { \
45 setPinInput(XT_DATA_PIN); \
46 writePinHigh(XT_DATA_PIN); \
47 } while (0)
48
49#define XT_DATA_READ() readPin(XT_DATA_PIN)
50
51#define XT_DATA_LO() \
52 do { \
53 writePinLow(XT_DATA_PIN); \
54 setPinOutput(XT_DATA_PIN); \
55 } while (0)
56
57#define XT_CLOCK_IN() \
58 do { \
59 setPinInput(XT_CLOCK_PIN); \
60 writePinHigh(XT_CLOCK_PIN); \
61 } while (0)
62
63#define XT_CLOCK_READ() readPin(XT_CLOCK_PIN)
64
65#define XT_CLOCK_LO() \
66 do { \
67 writePinLow(XT_CLOCK_PIN); \
68 setPinOutput(XT_CLOCK_PIN); \
69 } while (0)
70
71void xt_host_init(void);
72
73uint8_t xt_host_recv(void);
diff --git a/tmk_core/protocol/xt_interrupt.c b/tmk_core/protocol/xt_interrupt.c
deleted file mode 100644
index ba9d71848..000000000
--- a/tmk_core/protocol/xt_interrupt.c
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2Copyright 2018 Jun WAKO <wakojun@gmail.com>
3Copyright 2016 Ethan Apodaca <papodaca@gmail.com>
4
5This software is licensed with a Modified BSD License.
6All of this is supposed to be Free Software, Open Source, DFSG-free,
7GPL-compatible, and OK to use in both free and proprietary applications.
8Additions and corrections to this file are welcome.
9
10
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions are met:
13
14* Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16
17* Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in
19 the documentation and/or other materials provided with the
20 distribution.
21
22* Neither the name of the copyright holders nor the names of
23 contributors may be used to endorse or promote products derived
24 from this software without specific prior written permission.
25
26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36POSSIBILITY OF SUCH DAMAGE.
37*/
38
39#include <stdbool.h>
40#include <avr/interrupt.h>
41#include "xt.h"
42#include "wait.h"
43#include "debug.h"
44
45static inline uint8_t pbuf_dequeue(void);
46static inline void pbuf_enqueue(uint8_t data);
47static inline bool pbuf_has_data(void);
48static inline void pbuf_clear(void);
49
50void xt_host_init(void) {
51 XT_INT_INIT();
52 XT_INT_OFF();
53
54 /* hard reset */
55#ifdef XT_RESET
56 XT_RESET();
57#endif
58
59 /* soft reset: pull clock line down for 20ms */
60 XT_DATA_LO();
61 XT_CLOCK_LO();
62 wait_ms(20);
63
64 /* input mode with pullup */
65 XT_CLOCK_IN();
66 XT_DATA_IN();
67
68 XT_INT_ON();
69}
70
71/* get data received by interrupt */
72uint8_t xt_host_recv(void) {
73 if (pbuf_has_data()) {
74 return pbuf_dequeue();
75 } else {
76 return 0;
77 }
78}
79
80ISR(XT_INT_VECT) {
81 /*
82 * XT signal format consits of 10 or 9 clocks and sends start bits and 8-bit data,
83 * which should be read on falling edge of clock.
84 *
85 * start(0), start(1), bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7
86 *
87 * Original IBM XT keyboard sends start(0) bit while some of clones don't.
88 * Start(0) bit is read as low on data line while start(1) as high.
89 *
90 * https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol
91 */
92 static enum { START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7 } state = START;
93 static uint8_t data = 0;
94
95 uint8_t dbit = XT_DATA_READ();
96
97 // This is needed if using PCINT which can be called on both falling and rising edge
98 // if (XT_CLOCK_READ()) return;
99
100 switch (state) {
101 case START:
102 // ignore start(0) bit
103 if (!dbit) return;
104 break;
105 case BIT0 ... BIT7:
106 data >>= 1;
107 if (dbit) data |= 0x80;
108 break;
109 }
110 if (state++ == BIT7) {
111 pbuf_enqueue(data);
112 state = START;
113 data = 0;
114 }
115 return;
116}
117
118/*--------------------------------------------------------------------
119 * Ring buffer to store scan codes from keyboard
120 *------------------------------------------------------------------*/
121#define PBUF_SIZE 32
122static uint8_t pbuf[PBUF_SIZE];
123static uint8_t pbuf_head = 0;
124static uint8_t pbuf_tail = 0;
125
126static inline void pbuf_enqueue(uint8_t data) {
127 uint8_t sreg = SREG;
128 cli();
129 uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
130 if (next != pbuf_tail) {
131 pbuf[pbuf_head] = data;
132 pbuf_head = next;
133 } else {
134 dprintf("pbuf: full\n");
135 }
136 SREG = sreg;
137}
138
139static inline uint8_t pbuf_dequeue(void) {
140 uint8_t val = 0;
141
142 uint8_t sreg = SREG;
143 cli();
144 if (pbuf_head != pbuf_tail) {
145 val = pbuf[pbuf_tail];
146 pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
147 }
148 SREG = sreg;
149
150 return val;
151}
152
153static inline bool pbuf_has_data(void) {
154 uint8_t sreg = SREG;
155 cli();
156 bool has_data = (pbuf_head != pbuf_tail);
157 SREG = sreg;
158 return has_data;
159}
160
161static inline void pbuf_clear(void) {
162 uint8_t sreg = SREG;
163 cli();
164 pbuf_head = pbuf_tail = 0;
165 SREG = sreg;
166}
diff --git a/tmk_core/readme.md b/tmk_core/readme.md
index a754cfee4..a47dc8818 100644
--- a/tmk_core/readme.md
+++ b/tmk_core/readme.md
@@ -25,7 +25,6 @@ These features can be used in your keyboard.
25* Media Control Key - Volume Down/Up, Mute, Next/Prev track, Play, Stop and etc 25* Media Control Key - Volume Down/Up, Mute, Next/Prev track, Play, Stop and etc
26* USB NKRO - 248 keys(+ 8 modifiers) simultaneously 26* USB NKRO - 248 keys(+ 8 modifiers) simultaneously
27* PS/2 mouse support - PS/2 mouse(TrackPoint) as composite device 27* PS/2 mouse support - PS/2 mouse(TrackPoint) as composite device
28* Keyboard protocols - PS/2, ADB, M0110, Sun and other old keyboard protocols
29* User Function - Customizable function of key with writing code 28* User Function - Customizable function of key with writing code
30* Macro - Very primitive at this time 29* Macro - Very primitive at this time
31* Keyboard Tricks - Oneshot modifier and modifier with tapping feature 30* Keyboard Tricks - Oneshot modifier and modifier with tapping feature
@@ -84,9 +83,9 @@ Architecture
84 / /| Keys/Mouse | Protocol |d| | Action | | | Protocol | 83 / /| Keys/Mouse | Protocol |d| | Action | | | Protocol |
85 /__________/ |<-----------| LUFA |r| | Layer, Tap | | | Matrix | 84 /__________/ |<-----------| LUFA |r| | Layer, Tap | | | Matrix |
86 |.--------.| | LED | V-USB |i| |-------------| | | PS/2,IBM | __________________ 85 |.--------.| | LED | V-USB |i| |-------------| | | PS/2,IBM | __________________
87 || || |----------->| UART |v| | Keymap | | | ADB,M0110| Keys / /_/_/_/_/_/_/_/ /| 86 || || |----------->| UART |v| | Keymap | | | | Keys / /_/_/_/_/_/_/_/ /|
88 || Host || | Console | |e| | Mousekey | | | SUN/NEWS |<----------/ /_/_/_/_/_/_/_/ / / 87 || Host || | Console | |e| | Mousekey | | | |<----------/ /_/_/_/_/_/_/_/ / /
89 ||________||/.<-----------| |r| | Report | | | X68K/PC98| Control / /_/_/_/_/_/_/_/ / / 88 ||________||/.<-----------| |r| | Report | | | | Control / /_/_/_/_/_/_/_/ / /
90 `_========_'/| |---------------------------------------------|-------->/___ /_______/ ___/ / 89 `_========_'/| |---------------------------------------------|-------->/___ /_______/ ___/ /
91 |_o______o_|/ | Sendchar, Print, Debug, Command, ... | |_________________|/ 90 |_o______o_|/ | Sendchar, Print, Debug, Command, ... | |_________________|/
92 +---------------------------------------------+ Keyboard 91 +---------------------------------------------+ Keyboard
@@ -134,10 +133,6 @@ Files and Directories
134* lufa/ - LUFA USB stack 133* lufa/ - LUFA USB stack
135* vusb/ - Objective Development V-USB 134* vusb/ - Objective Development V-USB
136* ps2.c - PS/2 protocol 135* ps2.c - PS/2 protocol
137* adb.c - Apple Desktop Bus protocol
138* m0110.c - Macintosh 128K/512K/Plus keyboard protocol
139* news.c - Sony NEWS keyboard protocol
140* x68k.c - Sharp X68000 keyboard protocol
141* serial_soft.c - Asynchronous Serial protocol implemented by software 136* serial_soft.c - Asynchronous Serial protocol implemented by software
142 137
143 138