From e0d688d4c8040302fcacb735350c95fe6be4dbde Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 7 Oct 2021 23:14:26 +0100 Subject: Move converter specific tmk_core protocols (#14743) --- keyboards/converter/adb_usb/adb.c | 531 +++++++++++++++++++++++++++ keyboards/converter/adb_usb/adb.h | 106 ++++++ keyboards/converter/adb_usb/matrix.c | 8 + keyboards/converter/adb_usb/rules.mk | 3 + keyboards/converter/m0110_usb/m0110.c | 583 ++++++++++++++++++++++++++++++ keyboards/converter/m0110_usb/m0110.h | 81 +++++ keyboards/converter/xt_usb/rules.mk | 3 +- keyboards/converter/xt_usb/xt.h | 73 ++++ keyboards/converter/xt_usb/xt_interrupt.c | 166 +++++++++ quantum/keyboard.c | 10 - show_options.mk | 1 - tmk_core/protocol.mk | 9 - tmk_core/protocol/adb.c | 535 --------------------------- tmk_core/protocol/adb.h | 106 ------ tmk_core/protocol/m0110.c | 583 ------------------------------ tmk_core/protocol/m0110.h | 81 ----- tmk_core/protocol/xt.h | 73 ---- tmk_core/protocol/xt_interrupt.c | 166 --------- tmk_core/readme.md | 11 +- 19 files changed, 1555 insertions(+), 1574 deletions(-) create mode 100644 keyboards/converter/adb_usb/adb.c create mode 100644 keyboards/converter/adb_usb/adb.h create mode 100644 keyboards/converter/m0110_usb/m0110.c create mode 100644 keyboards/converter/m0110_usb/m0110.h create mode 100644 keyboards/converter/xt_usb/xt.h create mode 100644 keyboards/converter/xt_usb/xt_interrupt.c delete mode 100644 tmk_core/protocol/adb.c delete mode 100644 tmk_core/protocol/adb.h delete mode 100644 tmk_core/protocol/m0110.c delete mode 100644 tmk_core/protocol/m0110.h delete mode 100644 tmk_core/protocol/xt.h delete mode 100644 tmk_core/protocol/xt_interrupt.c diff --git a/keyboards/converter/adb_usb/adb.c b/keyboards/converter/adb_usb/adb.c new file mode 100644 index 000000000..28f14c9fe --- /dev/null +++ b/keyboards/converter/adb_usb/adb.c @@ -0,0 +1,531 @@ +/* +Copyright 2011-19 Jun WAKO +Copyright 2013 Shay Green + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include "adb.h" +#include "print.h" + +// GCC doesn't inline functions normally +#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) +#define data_hi() (ADB_DDR &= ~(1 << ADB_DATA_BIT)) +#define data_in() (ADB_PIN & (1 << ADB_DATA_BIT)) + +#ifdef ADB_PSW_BIT +static inline void psw_lo(void); +static inline void psw_hi(void); +static inline bool psw_in(void); +#endif + +static inline void attention(void); +static inline void place_bit0(void); +static inline void place_bit1(void); +static inline void send_byte(uint8_t data); +static inline uint16_t wait_data_lo(uint16_t us); +static inline uint16_t wait_data_hi(uint16_t us); + +void adb_host_init(void) { + ADB_PORT &= ~(1 << ADB_DATA_BIT); + data_hi(); +#ifdef ADB_PSW_BIT + psw_hi(); +#endif +} + +#ifdef ADB_PSW_BIT +bool adb_host_psw(void) { return psw_in(); } +#endif + +/* + * Don't call this in a row without the delay, otherwise it makes some of poor controllers + * overloaded and misses strokes. Recommended interval is 12ms. + * + * Thanks a lot, blargg! + * + * + */ +uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); } + +#ifdef ADB_MOUSE_ENABLE +uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); } +#endif + +// This sends Talk command to read data from register and returns length of the data. +uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { + for (int8_t i = 0; i < len; i++) buf[i] = 0; + + cli(); + attention(); + send_byte((addr << 4) | ADB_CMD_TALK | reg); + place_bit0(); // Stopbit(0) + // TODO: Service Request(Srq): + // Device holds low part of comannd stopbit for 140-260us + // + // Command: + // ......._ ______________________ ___ ............_ ------- + // | | | | | | | + // Command | | | | | Data bytes | | + // ........|___| | 140-260 |__| |_............|___| + // |stop0 | Tlt Stop-to-Start |start1| |stop0 | + // + // Command without data: + // ......._ __________________________ + // | | + // Command | | + // ........|___| | 140-260 | + // |stop0 | Tlt Stop-to-Start | + // + // Service Request: + // ......._ ______ ___ ............_ ------- + // | 140-260 | | | | | | + // Command | Service Request | | | | Data bytes | | + // ........|___________________| |__| |_............|___| + // |stop0 | |start1| |stop0 | + // ......._ __________ + // | 140-260 | + // Command | Service Request | + // ........|___________________| + // |stop0 | + // This can be happened? + // ......._ ______________________ ___ ............_ ----- + // | | | | | | 140-260 | + // Command | | | | | Data bytes | Service Request | + // ........|___| | 140-260 |__| |_............|_________________| + // |stop0 | Tlt Stop-to-Start |start1| |stop0 | + // + // "Service requests are issued by the devices during a very specific time at the + // end of the reception of the command packet. + // If a device in need of service issues a service request, it must do so within + // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs." + // + // "A device sends a Service Request signal by holding the bus low during the low + // portion of the stop bit of any command or data transaction. The device must lengthen + // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15." + // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf + if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored + xprintf("R"); + sei(); + return 0; + } + if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) + sei(); + return 0; // No data from device(not error); + } + + // start bit(1) + if (!wait_data_hi(40)) { + xprintf("S"); + sei(); + return 0; + } + if (!wait_data_lo(100)) { + xprintf("s"); + sei(); + return 0; + } + + uint8_t n = 0; // bit count + do { + // + // |<- bit_cell_max(130) ->| + // | |<- lo ->| + // | | |<-hi->| + // _______ + // | | | + // | 130-lo | lo-hi | + // |________| | + // + uint8_t lo = (uint8_t)wait_data_hi(130); + if (!lo) goto error; // no more bit or after stop bit + + uint8_t hi = (uint8_t)wait_data_lo(lo); + if (!hi) goto error; // stop bit extedned by Srq? + + if (n / 8 >= len) continue; // can't store in buf + + buf[n / 8] <<= 1; + if ((130 - lo) < (lo - hi)) { + buf[n / 8] |= 1; + } + } while (++n); + +error: + sei(); + return n / 8; +} + +uint16_t adb_host_talk(uint8_t addr, uint8_t reg) { + uint8_t len; + uint8_t buf[8]; + len = adb_host_talk_buf(addr, reg, buf, 8); + if (len != 2) return 0; + return (buf[0] << 8 | buf[1]); +} + +void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { + cli(); + attention(); + send_byte((addr << 4) | ADB_CMD_LISTEN | reg); + place_bit0(); // Stopbit(0) + // TODO: Service Request + _delay_us(200); // Tlt/Stop to Start + place_bit1(); // Startbit(1) + for (int8_t i = 0; i < len; i++) { + send_byte(buf[i]); + // xprintf("%02X ", buf[i]); + } + place_bit0(); // Stopbit(0); + sei(); +} + +void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) { + uint8_t buf[2] = {data_h, data_l}; + adb_host_listen_buf(addr, reg, buf, 2); +} + +void adb_host_flush(uint8_t addr) { + cli(); + attention(); + send_byte((addr << 4) | ADB_CMD_FLUSH); + place_bit0(); // Stopbit(0) + _delay_us(200); // Tlt/Stop to Start + sei(); +} + +// send state of LEDs +void adb_host_kbd_led(uint8_t led) { + // Listen Register2 + // upper byte: not used + // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock + adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07); +} + +#ifdef ADB_PSW_BIT +static inline void psw_lo() { + ADB_DDR |= (1 << ADB_PSW_BIT); + ADB_PORT &= ~(1 << ADB_PSW_BIT); +} +static inline void psw_hi() { + ADB_PORT |= (1 << ADB_PSW_BIT); + ADB_DDR &= ~(1 << ADB_PSW_BIT); +} +static inline bool psw_in() { + ADB_PORT |= (1 << ADB_PSW_BIT); + ADB_DDR &= ~(1 << ADB_PSW_BIT); + return ADB_PIN & (1 << ADB_PSW_BIT); +} +#endif + +static inline void attention(void) { + data_lo(); + _delay_us(800 - 35); // bit1 holds lo for 35 more + place_bit1(); +} + +static inline void place_bit0(void) { + data_lo(); + _delay_us(65); + data_hi(); + _delay_us(35); +} + +static inline void place_bit1(void) { + data_lo(); + _delay_us(35); + data_hi(); + _delay_us(65); +} + +static inline void send_byte(uint8_t data) { + for (int i = 0; i < 8; i++) { + if (data & (0x80 >> i)) + place_bit1(); + else + place_bit0(); + } +} + +// These are carefully coded to take 6 cycles of overhead. +// inline asm approach became too convoluted +static inline uint16_t wait_data_lo(uint16_t us) { + do { + if (!data_in()) break; + _delay_us(1 - (6 * 1000000.0 / F_CPU)); + } while (--us); + return us; +} + +static inline uint16_t wait_data_hi(uint16_t us) { + do { + if (data_in()) break; + _delay_us(1 - (6 * 1000000.0 / F_CPU)); + } while (--us); + return us; +} + +/* +ADB Protocol +============ + +Resources +--------- +ADB - The Untold Story: Space Aliens Ate My Mouse + http://developer.apple.com/legacy/mac/library/#technotes/hw/hw_01.html +ADB Manager + http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Devices/ADB_Manager.pdf + Service request(5-17) +Apple IIgs Hardware Reference Second Edition [Chapter6 p121] + ftp://ftp.apple.asimov.net/pub/apple_II/documentation/Apple%20IIgs%20Hardware%20Reference.pdf +ADB Keycode + http://72.0.193.250/Documentation/macppc/adbkeycodes/ + http://m0115.web.fc2.com/m0115.jpg + [Inside Macintosh volume V, pages 191-192] + http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-421.18.3/IOHIDFamily/Cosmo_USB2ADB.c +ADB Signaling + http://kbdbabel.sourceforge.net/doc/kbd_signaling_pcxt_ps2_adb.pdf +ADB Overview & History + http://en.wikipedia.org/wiki/Apple_Desktop_Bus +Microchip Application Note: ADB device(with code for PIC16C) + http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011062 +AVR ATtiny2131 ADB to PS/2 converter(Japanese) + http://hp.vector.co.jp/authors/VA000177/html/KeyBoardA5DEA5CBA5A2II.html + + +Pinouts +------- + ADB female socket from the front: + __________ + | | <--- top + | 4o o3 | + |2o o1| + | == | + |________| <--- bottom + | | <--- 4pins + + + ADB female socket from bottom: + + ========== <--- front + | | + | | + |2o o1| + |4o o3| + ---------- <--- back + + 1: Data + 2: Power SW(low when press Power key) + 3: Vcc(5V) + 4: GND + + +Commands +-------- + ADB command is 1byte and consists of 4bit-address, 2bit-command + type and 2bit-register. The commands are always sent by Host. + + Command format: + 7 6 5 4 3 2 1 0 + | | | |------------ address + | |-------- command type + | |---- register + + bits commands + ------------------------------------------------------ + - - - - 0 0 0 0 Send Reset(reset all devices) + A A A A 0 0 0 1 Flush(reset a device) + - - - - 0 0 1 0 Reserved + - - - - 0 0 1 1 Reserved + - - - - 0 1 - - Reserved + A A A A 1 0 R R Listen(write to a device) + A A A A 1 1 R R Talk(read from a device) + + The command to read keycodes from keyboard is 0x2C which + consist of keyboard address 2 and Talk against register 0. + + Address: + 2: keyboard + 3: mice + + Registers: + 0: application(keyboard uses this to store its data.) + 1: application + 2: application(keyboard uses this for LEDs and state of modifiers) + 3: status and command + + +Communication +------------- + This is a minimum information for keyboard communication. + See "Resources" for detail. + + Signaling: + + ~~~~____________~~||||||||||||__~~~~~_~~|||||||||||||||__~~~~ + + |800us | |7 Command 0| | | |15-64 Data 0|Stopbit(0) + +Attention | | | +Startbit(1) + +Startbit(1) | +Tlt(140-260us) + +stopbit(0) + + Bit cells: + + bit0: ______~~~ + 65 :35us + + bit1: ___~~~~~~ + 35 :65us + + bit0 low time: 60-70% of bit cell(42-91us) + bit1 low time: 30-40% of bit cell(21-52us) + bit cell time: 70-130us + [from Apple IIgs Hardware Reference Second Edition] + + Criterion for bit0/1: + After 55us if line is low/high then bit is 0/1. + + Attention & start bit: + Host asserts low in 560-1040us then places start bit(1). + + Tlt(Stop to Start): + Bus stays high in 140-260us then device places start bit(1). + + Global reset: + Host asserts low in 2.8-5.2ms. All devices are forced to reset. + + Service request from device(Srq): + Device can request to send at commad(Global only?) stop bit. + Requesting device keeps low for 140-260us at stop bit of command. + + +Keyboard Data(Register0) + This 16bit data can contains two keycodes and two released flags. + First keycode is palced in upper byte. When one keyocode is sent, + lower byte is 0xFF. + Release flag is 1 when key is released. + + 1514 . . . . . 8 7 6 . . . . . 0 + | | | | | | | | | +-+-+-+-+-+-+- Keycode2 + | | | | | | | | +--------------- Released2(1 when the key is released) + | +-+-+-+-+-+-+----------------- Keycode1 + +------------------------------- Released1(1 when the key is released) + + Keycodes: + Scancode consists of 7bit keycode and 1bit release flag. + Device can send two keycodes at once. If just one keycode is sent + keycode1 contains it and keyocode2 is 0xFF. + + Power switch: + You can read the state from PSW line(active low) however + the switch has a special scancode 0x7F7F, so you can + also read from Data line. It uses 0xFFFF for release scancode. + +Keyboard LEDs & state of keys(Register2) + This register hold current state of three LEDs and nine keys. + The state of LEDs can be changed by sending Listen command. + + 1514 . . . . . . 7 6 5 . 3 2 1 0 + | | | | | | | | | | | | | | | +- LED1(NumLock) + | | | | | | | | | | | | | | +--- LED2(CapsLock) + | | | | | | | | | | | | | +----- LED3(ScrollLock) + | | | | | | | | | | +-+-+------- Reserved + | | | | | | | | | +------------- ScrollLock + | | | | | | | | +--------------- NumLock + | | | | | | | +----------------- Apple/Command + | | | | | | +------------------- Option + | | | | | +--------------------- Shift + | | | | +----------------------- Control + | | | +------------------------- Reset/Power + | | +--------------------------- CapsLock + | +----------------------------- Delete + +------------------------------- Reserved + +Address, Handler ID and bits(Register3) + 1514131211 . . 8 7 . . . . . . 0 + | | | | | | | | | | | | | | | | + | | | | | | | | +-+-+-+-+-+-+-+- Handler ID + | | | | +-+-+-+----------------- Address + | | | +------------------------- 0 + | | +--------------------------- Service request enable(1 = enabled) + | +----------------------------- Exceptional event(alwyas 1 if not used) + +------------------------------- 0 + +ADB Bit Cells + bit cell time: 70-130us + low part of bit0: 60-70% of bit cell + low part of bit1: 30-40% of bit cell + + bit cell time 70us 130us + -------------------------------------------- + low part of bit0 42-49 78-91 + high part of bit0 21-28 39-52 + low part of bit1 21-28 39-52 + high part of bit1 42-49 78-91 + + + bit0: + 70us bit cell: + ____________~~~~~~ + 42-49 21-28 + + 130us bit cell: + ____________~~~~~~ + 78-91 39-52 + + bit1: + 70us bit cell: + ______~~~~~~~~~~~~ + 21-28 42-49 + + 130us bit cell: + ______~~~~~~~~~~~~ + 39-52 78-91 + + [from Apple IIgs Hardware Reference Second Edition] + +Keyboard Handle ID + Apple Standard Keyboard M0116: 0x01 + Apple Extended Keyboard M0115: 0x02 + Apple Extended Keyboard II M3501: 0x02 + Apple Adjustable Keybaord: 0x10 + + http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802 + +END_OF_ADB +*/ diff --git a/keyboards/converter/adb_usb/adb.h b/keyboards/converter/adb_usb/adb.h new file mode 100644 index 000000000..fe8becc2d --- /dev/null +++ b/keyboards/converter/adb_usb/adb.h @@ -0,0 +1,106 @@ +/* +Copyright 2011-19 Jun WAKO + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once + +#include +#include + +#if !(defined(ADB_PORT) && defined(ADB_PIN) && defined(ADB_DDR) && defined(ADB_DATA_BIT)) +# error "ADB port setting is required in config.h" +#endif + +#define ADB_POWER 0x7F +#define ADB_CAPS 0x39 + +/* ADB commands */ +// Default Address +#define ADB_ADDR_0 0 +#define ADB_ADDR_DONGLE 1 +#define ADB_ADDR_KEYBOARD 2 +#define ADB_ADDR_MOUSE 3 +#define ADB_ADDR_TABLET 4 +#define ADB_ADDR_APPLIANCE 7 +#define ADB_ADDR_8 8 +#define ADB_ADDR_9 9 +#define ADB_ADDR_10 10 +#define ADB_ADDR_11 11 +#define ADB_ADDR_12 12 +#define ADB_ADDR_13 13 +#define ADB_ADDR_14 14 +#define ADB_ADDR_15 15 +// for temporary purpose, do not use for polling +#define ADB_ADDR_TMP 15 +#define ADB_ADDR_MOUSE_POLL 10 +// Command Type +#define ADB_CMD_RESET 0 +#define ADB_CMD_FLUSH 1 +#define ADB_CMD_LISTEN 8 +#define ADB_CMD_TALK 12 +// Register +#define ADB_REG_0 0 +#define ADB_REG_1 1 +#define ADB_REG_2 2 +#define ADB_REG_3 3 + +/* ADB keyboard handler id */ +#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */ +#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */ +#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */ +#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */ +#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */ +#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */ +#define ADB_HANDLER_CLASSIC1_MOUSE 0x01 +#define ADB_HANDLER_CLASSIC2_MOUSE 0x02 +#define ADB_HANDLER_EXTENDED_MOUSE 0x04 +#define ADB_HANDLER_TURBO_MOUSE 0x32 + +// ADB host +void adb_host_init(void); +bool adb_host_psw(void); +uint16_t adb_host_talk(uint8_t addr, uint8_t reg); +uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); +void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l); +void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); +void adb_host_flush(uint8_t addr); +void adb_host_kbd_led(uint8_t led); +uint16_t adb_host_kbd_recv(void); +uint16_t adb_host_mouse_recv(void); + +// ADB Mouse +void adb_mouse_task(void); +void adb_mouse_init(void); diff --git a/keyboards/converter/adb_usb/matrix.c b/keyboards/converter/adb_usb/matrix.c index 9e5399de5..e6a492196 100644 --- a/keyboards/converter/adb_usb/matrix.c +++ b/keyboards/converter/adb_usb/matrix.c @@ -31,6 +31,10 @@ Ported to QMK by Peter Roe #include "led.h" #include "timer.h" +#ifndef ADB_MOUSE_MAXACC +# define ADB_MOUSE_MAXACC 8 +#endif + static bool is_iso_layout = false; // matrix state buffer(1:on, 0:off) @@ -84,6 +88,10 @@ void matrix_init(void) static report_mouse_t mouse_report = {}; +void housekeeping_task_kb(void) { + adb_mouse_task(); +} + void adb_mouse_task(void) { uint16_t codes; diff --git a/keyboards/converter/adb_usb/rules.mk b/keyboards/converter/adb_usb/rules.mk index 7c861e270..8f4649f55 100644 --- a/keyboards/converter/adb_usb/rules.mk +++ b/keyboards/converter/adb_usb/rules.mk @@ -19,3 +19,6 @@ BACKLIGHT_ENABLE = no CUSTOM_MATRIX = yes SRC = matrix.c adb.c led.c + +# ADB_MOUSE_ENABLE +# OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE diff --git a/keyboards/converter/m0110_usb/m0110.c b/keyboards/converter/m0110_usb/m0110.c new file mode 100644 index 000000000..64f2fa50a --- /dev/null +++ b/keyboards/converter/m0110_usb/m0110.c @@ -0,0 +1,583 @@ +/* +Copyright 2011,2012 Jun WAKO + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +/* M0110A Support was contributed by skagon@github */ + +#include +#include +#include +#include +#include "m0110.h" +#include "debug.h" + +static inline uint8_t raw2scan(uint8_t raw); +static inline uint8_t inquiry(void); +static inline uint8_t instant(void); +static inline void clock_lo(void); +static inline void clock_hi(void); +static inline bool clock_in(void); +static inline void data_lo(void); +static inline void data_hi(void); +static inline bool data_in(void); +static inline uint16_t wait_clock_lo(uint16_t us); +static inline uint16_t wait_clock_hi(uint16_t us); +static inline uint16_t wait_data_lo(uint16_t us); +static inline uint16_t wait_data_hi(uint16_t us); +static inline void idle(void); +static inline void request(void); + +#define WAIT_US(stat, us, err) \ + do { \ + if (!wait_##stat(us)) { \ + m0110_error = err; \ + goto ERROR; \ + } \ + } while (0) + +#define WAIT_MS(stat, ms, err) \ + do { \ + uint16_t _ms = ms; \ + while (_ms) { \ + if (wait_##stat(1000)) { \ + break; \ + } \ + _ms--; \ + } \ + if (_ms == 0) { \ + m0110_error = err; \ + goto ERROR; \ + } \ + } while (0) + +#define KEY(raw) ((raw)&0x7f) +#define IS_BREAK(raw) (((raw)&0x80) == 0x80) + +uint8_t m0110_error = 0; + +void m0110_init(void) { + idle(); + _delay_ms(1000); + + /* Not needed to initialize in fact. + uint8_t data; + m0110_send(M0110_MODEL); + data = m0110_recv(); + print("m0110_init model: "); print_hex8(data); print("\n"); + + m0110_send(M0110_TEST); + data = m0110_recv(); + print("m0110_init test: "); print_hex8(data); print("\n"); + */ +} + +uint8_t m0110_send(uint8_t data) { + m0110_error = 0; + + request(); + WAIT_MS(clock_lo, 250, 1); // keyboard may block long time + for (uint8_t bit = 0x80; bit; bit >>= 1) { + WAIT_US(clock_lo, 250, 3); + if (data & bit) { + data_hi(); + } else { + data_lo(); + } + WAIT_US(clock_hi, 200, 4); + } + _delay_us(100); // hold last bit for 80us + idle(); + return 1; +ERROR: + print("m0110_send err: "); + print_hex8(m0110_error); + print("\n"); + _delay_ms(500); + idle(); + return 0; +} + +uint8_t m0110_recv(void) { + uint8_t data = 0; + m0110_error = 0; + + WAIT_MS(clock_lo, 250, 1); // keyboard may block long time + for (uint8_t i = 0; i < 8; i++) { + data <<= 1; + WAIT_US(clock_lo, 200, 2); + WAIT_US(clock_hi, 200, 3); + if (data_in()) { + data |= 1; + } + } + idle(); + return data; +ERROR: + print("m0110_recv err: "); + print_hex8(m0110_error); + print("\n"); + _delay_ms(500); + idle(); + return 0xFF; +} + +/* +Handling for exceptional case of key combinations for M0110A + +Shift and Calc/Arrow key could be operated simultaneously: + + Case Shift Arrow Events Interpret + ------------------------------------------------------------------- + 1 Down Down 71, 79, DD Calc(d)*a *b + 2 Down Up 71, 79, UU Arrow&Calc(u)*a + 3 Up Down F1, 79, DD Shift(u) *c + 4 Up Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a + + Case Shift Calc Events Interpret + ------------------------------------------------------------------- + 5(1) Down Down 71, 71, 79, DD Shift(d) and Cacl(d) + 6(2) Down Up F1, 71, 79, UU Shift(u) and Arrow&Calc(u)*a + 7(1) Up Down F1, 71, 79, DD Shift(u) and Calc(d) + 8(4) Up Up F1, F1, 79, UU Shift(ux2) and Arrow&Calc(u)*a + +During Calc key is hold: + Case Shift Arrow Events Interpret + ------------------------------------------------------------------- + A(3) ---- Down F1, 79, DD Shift(u) *c + B ---- Up 79, UU Arrow&Calc(u)*a + C Down ---- F1, 71 Shift(u) and Shift(d) + D Up ---- F1 Shift(u) + E Hold Down 79, DD Normal + F Hold Up 79, UU Arrow&Calc(u)*a + G(1) Down Down F1, 71, 79, DD Shift(u)*b and Calc(d)*a + H(2) Down Up F1, 71, 79, UU Shift(u) and Arrow&Calc(u)*a + I(3) Up Down F1, F1, 79, DD Shift(ux2) *c + J(4) Up Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a + + Case Shift Calc Events Interpret + ------------------------------------------------------------------- + K(1) ---- Down 71, 79, DD Calc(d)*a + L(4) ---- Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a + M(1) Hold Down 71, 79, DD Calc(d)*a + N Hold Up 79, UU Arrow&Calc(u)*a + + Where DD/UU indicates part of Keypad Down/Up event. + *a: Impossible to distinguish btween Arrow and Calc event. + *b: Shift(d) event is ignored. + *c: Arrow/Calc(d) event is ignored. +*/ +uint8_t m0110_recv_key(void) { + static uint8_t keybuf = 0x00; + static uint8_t keybuf2 = 0x00; + static uint8_t rawbuf = 0x00; + uint8_t raw, raw2, raw3; + + if (keybuf) { + raw = keybuf; + keybuf = 0x00; + return raw; + } + if (keybuf2) { + raw = keybuf2; + keybuf2 = 0x00; + return raw; + } + + if (rawbuf) { + raw = rawbuf; + rawbuf = 0x00; + } else { + raw = instant(); // Use INSTANT for better response. Should be INQUIRY ? + } + switch (KEY(raw)) { + case M0110_KEYPAD: + raw2 = instant(); + switch (KEY(raw2)) { + case M0110_ARROW_UP: + case M0110_ARROW_DOWN: + case M0110_ARROW_LEFT: + case M0110_ARROW_RIGHT: + if (IS_BREAK(raw2)) { + // Case B,F,N: + keybuf = (raw2scan(raw2) | M0110_CALC_OFFSET); // Calc(u) + return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); // Arrow(u) + } + break; + } + // Keypad or Arrow + return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); + break; + case M0110_SHIFT: + raw2 = instant(); + switch (KEY(raw2)) { + case M0110_SHIFT: + // Case: 5-8,C,G,H + rawbuf = raw2; + return raw2scan(raw); // Shift(d/u) + break; + case M0110_KEYPAD: + // Shift + Arrow, Calc, or etc. + raw3 = instant(); + switch (KEY(raw3)) { + case M0110_ARROW_UP: + case M0110_ARROW_DOWN: + case M0110_ARROW_LEFT: + case M0110_ARROW_RIGHT: + if (IS_BREAK(raw)) { + if (IS_BREAK(raw3)) { + // Case 4: + print("(4)\n"); + keybuf2 = raw2scan(raw); // Shift(u) + keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u) + return (raw2scan(raw3) | M0110_KEYPAD_OFFSET); // Arrow(u) + } else { + // Case 3: + print("(3)\n"); + return (raw2scan(raw)); // Shift(u) + } + } else { + if (IS_BREAK(raw3)) { + // Case 2: + print("(2)\n"); + keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u) + return (raw2scan(raw3) | M0110_KEYPAD_OFFSET); // Arrow(u) + } else { + // Case 1: + print("(1)\n"); + return (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(d) + } + } + break; + default: + // Shift + Keypad + keybuf = (raw2scan(raw3) | M0110_KEYPAD_OFFSET); + return raw2scan(raw); // Shift(d/u) + break; + } + break; + default: + // Shift + Normal keys + keybuf = raw2scan(raw2); + return raw2scan(raw); // Shift(d/u) + break; + } + break; + default: + // Normal keys + return raw2scan(raw); + break; + } +} + +static inline uint8_t raw2scan(uint8_t raw) { return (raw == M0110_NULL) ? M0110_NULL : ((raw == M0110_ERROR) ? M0110_ERROR : (((raw & 0x80) | ((raw & 0x7F) >> 1)))); } + +static inline uint8_t inquiry(void) { + m0110_send(M0110_INQUIRY); + return m0110_recv(); +} + +static inline uint8_t instant(void) { + m0110_send(M0110_INSTANT); + uint8_t data = m0110_recv(); + if (data != M0110_NULL) { + debug_hex(data); + debug(" "); + } + return data; +} + +static inline void clock_lo() { + M0110_CLOCK_PORT &= ~(1 << M0110_CLOCK_BIT); + M0110_CLOCK_DDR |= (1 << M0110_CLOCK_BIT); +} +static inline void clock_hi() { + /* input with pull up */ + M0110_CLOCK_DDR &= ~(1 << M0110_CLOCK_BIT); + M0110_CLOCK_PORT |= (1 << M0110_CLOCK_BIT); +} +static inline bool clock_in() { + M0110_CLOCK_DDR &= ~(1 << M0110_CLOCK_BIT); + M0110_CLOCK_PORT |= (1 << M0110_CLOCK_BIT); + _delay_us(1); + return M0110_CLOCK_PIN & (1 << M0110_CLOCK_BIT); +} +static inline void data_lo() { + M0110_DATA_PORT &= ~(1 << M0110_DATA_BIT); + M0110_DATA_DDR |= (1 << M0110_DATA_BIT); +} +static inline void data_hi() { + /* input with pull up */ + M0110_DATA_DDR &= ~(1 << M0110_DATA_BIT); + M0110_DATA_PORT |= (1 << M0110_DATA_BIT); +} +static inline bool data_in() { + M0110_DATA_DDR &= ~(1 << M0110_DATA_BIT); + M0110_DATA_PORT |= (1 << M0110_DATA_BIT); + _delay_us(1); + return M0110_DATA_PIN & (1 << M0110_DATA_BIT); +} + +static inline uint16_t wait_clock_lo(uint16_t us) { + while (clock_in() && us) { + asm(""); + _delay_us(1); + us--; + } + return us; +} +static inline uint16_t wait_clock_hi(uint16_t us) { + while (!clock_in() && us) { + asm(""); + _delay_us(1); + us--; + } + return us; +} +static inline uint16_t wait_data_lo(uint16_t us) { + while (data_in() && us) { + asm(""); + _delay_us(1); + us--; + } + return us; +} +static inline uint16_t wait_data_hi(uint16_t us) { + while (!data_in() && us) { + asm(""); + _delay_us(1); + us--; + } + return us; +} + +static inline void idle(void) { + clock_hi(); + data_hi(); +} + +static inline void request(void) { + clock_hi(); + data_lo(); +} + +/* +Primitive M0110 Library for AVR +============================== + + +Signaling +--------- +CLOCK is always from KEYBOARD. DATA are sent with MSB first. + +1) IDLE: both lines are high. + CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +2) KEYBOARD->HOST: HOST reads bit on rising edge. + CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ + DATA ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ + <--> 160us(clock low) + <---> 180us(clock high) + +3) HOST->KEYBOARD: HOST asserts bit on falling edge. + CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ + DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ + <----> 840us(request to send by host) <---> 80us(hold DATA) + <--> 180us(clock low) + <---> 220us(clock high) + + +Protocol +-------- +COMMAND: + Inquiry 0x10 get key event with block + Instant 0x12 get key event + Model 0x14 get model number(M0110 responds with 0x09) + bit 7 1 if another device connected(used when keypad exists?) + bit4-6 next device model number + bit1-3 keyboard model number + bit 0 always 1 + Test 0x16 test(ACK:0x7D/NAK:0x77) + +KEY EVENT: + bit 7 key state(0:press 1:release) + bit 6-1 scan code(see below) + bit 0 always 1 + To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1). + + Note: On the M0110A, Keypad keys and Arrow keys are preceded by 0x79. + Moreover, some Keypad keys(=, /, * and +) are preceded by 0x71 on press and 0xF1 on release. + +ARROW KEYS: + Arrow keys and Calc keys(+,*,/,= on keypad) share same byte sequence and preceding byte of + Calc keys(0x71 and 0xF1) means press and release event of SHIFT. This causes a very confusing situation, + it is difficult or impossible to tell Calc key from Arrow key plus SHIFT in some cases. + + Raw key events: + press release + ---------------- ---------------- + Left: 0x79, 0x0D 0x79, 0x8D + Right: 0x79, 0x05 0x79, 0x85 + Up: 0x79, 0x1B 0x79, 0x9B + Down: 0x79, 0x11 0x79, 0x91 + Pad+: 0x71, 0x79, 0x0D 0xF1, 0x79, 0x8D + Pad*: 0x71, 0x79, 0x05 0xF1, 0x79, 0x85 + Pad/: 0x71, 0x79, 0x1B 0xF1, 0x79, 0x9B + Pad=: 0x71, 0x79, 0x11 0xF1, 0x79, 0x91 + + +RAW CODE: + M0110A + ,---------------------------------------------------------. ,---------------. + | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| + |---------------------------------------------------------| |---------------| + |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| + |-----------------------------------------------------' | |---------------| + |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| + |---------------------------------------------------------| |---------------| + |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | + |---------------------------------------------------------' |-----------|Ent| + |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | + `---------------------------------------------------------' `---------------' + ,---------------------------------------------------------. ,---------------. + | 65| 25| 27| 29| 2B| 2F| 2D| 35| 39| 33| 3B| 37| 31| 67| |+0F|*11|*1B|*05| + |---------------------------------------------------------| |---------------| + | 61| 19| 1B| 1D| 1F| 23| 21| 41| 45| 3F| 47| 43| 3D| | |+33|+37|+39|+1D| + |-----------------------------------------------------' | |---------------| + | 73| 01| 03| 05| 07| 0B| 09| 4D| 51| 4B| 53| 4F| 49| |+2D|+2F|+31|*0D| + |---------------------------------------------------------| |---------------| + | 71| 0D| 0F| 11| 13| 17| 5B| 5D| 27| 5F| 59| 71|+1B| |+27|+29|+2B| | + |---------------------------------------------------------' |-----------|+19| + | 75| 6F| 63 | 55|+0D|+05|+11| | +25|+03| | + `---------------------------------------------------------' `---------------' + + 0x79, 0xDD / 0xF1, 0xUU + * 0x71, 0x79,DD / 0xF1, 0x79, 0xUU + + +MODEL NUMBER: + M0110: 0x09 00001001 : model number 4 (100) + M0110A: 0x0B 00001011 : model number 5 (101) + M0110 & M0120: ??? + + +Scan Code +--------- + m0110_recv_key() function returns following scan codes instead of M0110 raw codes. + Scan codes are 1 byte size and MSB(bit7) is set when key is released. + + scancode = ((raw&0x80) | ((raw&0x7F)>>1)) + + M0110 M0120 + ,---------------------------------------------------------. ,---------------. + | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| -|Lft|Rgt| + |---------------------------------------------------------| |---------------| + |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9|Up | + |---------------------------------------------------------| |---------------| + |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6|Dn | + |---------------------------------------------------------| |---------------| + |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | 1| 2| 3| | + `---------------------------------------------------------' |-----------|Ent| + |Opt|Mac | Space |Enter|Opt| | 0| .| | + `------------------------------------------------' `---------------' + ,---------------------------------------------------------. ,---------------. + | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 4E| 46| 42| + |---------------------------------------------------------| |---------------| + | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | 59| 5B| 5C| 4D| + |---------------------------------------------------------| |---------------| + | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 48| + |---------------------------------------------------------| |---------------| + | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | 53| 54| 55| | + `---------------------------------------------------------' |-----------| 4C| + | 3A| 37| 31 | 34| 3A| | 52| 41| | + `------------------------------------------------' `---------------' + + International keyboard(See page 22 of "Technical Info for 128K/512K") + ,---------------------------------------------------------. + | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| + |---------------------------------------------------------| + | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| + |------------------------------------------------------ | + | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | + |---------------------------------------------------------| + | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 0A| 38| + `---------------------------------------------------------' + | 3A| 37| 34 | 31| 3A| + `------------------------------------------------' + + M0110A + ,---------------------------------------------------------. ,---------------. + | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| + |---------------------------------------------------------| |---------------| + |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| + |-----------------------------------------------------' | |---------------| + |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| + |---------------------------------------------------------| |---------------| + |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | + |---------------------------------------------------------' |-----------|Ent| + |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | + `---------------------------------------------------------' `---------------' + ,---------------------------------------------------------. ,---------------. + | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62| + |---------------------------------------------------------| |---------------| + | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E| + |-----------------------------------------------------' | |---------------| + | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66| + |---------------------------------------------------------| |---------------| + | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| | + |---------------------------------------------------------' |-----------| 4C| + | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| | + `---------------------------------------------------------' `---------------' + + +References +---------- +Technical Info for 128K/512K and Plus + ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf + ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf +Protocol: + Page 20 of Tech Info for 128K/512K + http://www.mac.linux-m68k.org/devel/plushw.php +Connector: + Page 20 of Tech Info for 128K/512K + http://www.kbdbabel.org/conn/kbd_connector_macplus.png +Signaling: + http://www.kbdbabel.org/signaling/kbd_signaling_mac.png + http://typematic.blog.shinobi.jp/Entry/14/ +M0110 raw scan codes: + Page 22 of Tech Info for 128K/512K + Page 07 of Tech Info for Plus + http://m0115.web.fc2.com/m0110.jpg + http://m0115.web.fc2.com/m0110a.jpg +*/ diff --git a/keyboards/converter/m0110_usb/m0110.h b/keyboards/converter/m0110_usb/m0110.h new file mode 100644 index 000000000..63ff3e90e --- /dev/null +++ b/keyboards/converter/m0110_usb/m0110.h @@ -0,0 +1,81 @@ +/* +Copyright 2011,2012 Jun WAKO + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once + +/* port settings for clock and data line */ +#if !(defined(M0110_CLOCK_PORT) && defined(M0110_CLOCK_PIN) && defined(M0110_CLOCK_DDR) && defined(M0110_CLOCK_BIT)) +# error "M0110 clock port setting is required in config.h" +#endif + +#if !(defined(M0110_DATA_PORT) && defined(M0110_DATA_PIN) && defined(M0110_DATA_DDR) && defined(M0110_DATA_BIT)) +# error "M0110 data port setting is required in config.h" +#endif + +/* Commands */ +#define M0110_INQUIRY 0x10 +#define M0110_INSTANT 0x14 +#define M0110_MODEL 0x16 +#define M0110_TEST 0x36 + +/* Response(raw byte from M0110) */ +#define M0110_NULL 0x7B +#define M0110_KEYPAD 0x79 +#define M0110_TEST_ACK 0x7D +#define M0110_TEST_NAK 0x77 +#define M0110_SHIFT 0x71 +#define M0110_ARROW_UP 0x1B +#define M0110_ARROW_DOWN 0x11 +#define M0110_ARROW_LEFT 0x0D +#define M0110_ARROW_RIGHT 0x05 + +/* This inidcates no response. */ +#define M0110_ERROR 0xFF + +/* scan code offset for keypad and arrow keys */ +#define M0110_KEYPAD_OFFSET 0x40 +#define M0110_CALC_OFFSET 0x60 + +extern uint8_t m0110_error; + +/* host role */ +void m0110_init(void); +uint8_t m0110_send(uint8_t data); +uint8_t m0110_recv(void); +uint8_t m0110_recv_key(void); +uint8_t m0110_inquiry(void); +uint8_t m0110_instant(void); diff --git a/keyboards/converter/xt_usb/rules.mk b/keyboards/converter/xt_usb/rules.mk index 519d76f4d..803361444 100644 --- a/keyboards/converter/xt_usb/rules.mk +++ b/keyboards/converter/xt_usb/rules.mk @@ -19,7 +19,6 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -XT_ENABLE = yes CUSTOM_MATRIX = yes -SRC += matrix.c +SRC += matrix.c xt_interrupt.c diff --git a/keyboards/converter/xt_usb/xt.h b/keyboards/converter/xt_usb/xt.h new file mode 100644 index 000000000..538ff0e45 --- /dev/null +++ b/keyboards/converter/xt_usb/xt.h @@ -0,0 +1,73 @@ +/* +Copyright 2018 Jun WAKO +Copyright 2016 Ethan Apodaca + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once + +#include "quantum.h" + +#define XT_DATA_IN() \ + do { \ + setPinInput(XT_DATA_PIN); \ + writePinHigh(XT_DATA_PIN); \ + } while (0) + +#define XT_DATA_READ() readPin(XT_DATA_PIN) + +#define XT_DATA_LO() \ + do { \ + writePinLow(XT_DATA_PIN); \ + setPinOutput(XT_DATA_PIN); \ + } while (0) + +#define XT_CLOCK_IN() \ + do { \ + setPinInput(XT_CLOCK_PIN); \ + writePinHigh(XT_CLOCK_PIN); \ + } while (0) + +#define XT_CLOCK_READ() readPin(XT_CLOCK_PIN) + +#define XT_CLOCK_LO() \ + do { \ + writePinLow(XT_CLOCK_PIN); \ + setPinOutput(XT_CLOCK_PIN); \ + } while (0) + +void xt_host_init(void); + +uint8_t xt_host_recv(void); diff --git a/keyboards/converter/xt_usb/xt_interrupt.c b/keyboards/converter/xt_usb/xt_interrupt.c new file mode 100644 index 000000000..ba9d71848 --- /dev/null +++ b/keyboards/converter/xt_usb/xt_interrupt.c @@ -0,0 +1,166 @@ +/* +Copyright 2018 Jun WAKO +Copyright 2016 Ethan Apodaca + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include "xt.h" +#include "wait.h" +#include "debug.h" + +static inline uint8_t pbuf_dequeue(void); +static inline void pbuf_enqueue(uint8_t data); +static inline bool pbuf_has_data(void); +static inline void pbuf_clear(void); + +void xt_host_init(void) { + XT_INT_INIT(); + XT_INT_OFF(); + + /* hard reset */ +#ifdef XT_RESET + XT_RESET(); +#endif + + /* soft reset: pull clock line down for 20ms */ + XT_DATA_LO(); + XT_CLOCK_LO(); + wait_ms(20); + + /* input mode with pullup */ + XT_CLOCK_IN(); + XT_DATA_IN(); + + XT_INT_ON(); +} + +/* get data received by interrupt */ +uint8_t xt_host_recv(void) { + if (pbuf_has_data()) { + return pbuf_dequeue(); + } else { + return 0; + } +} + +ISR(XT_INT_VECT) { + /* + * XT signal format consits of 10 or 9 clocks and sends start bits and 8-bit data, + * which should be read on falling edge of clock. + * + * start(0), start(1), bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7 + * + * Original IBM XT keyboard sends start(0) bit while some of clones don't. + * Start(0) bit is read as low on data line while start(1) as high. + * + * https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol + */ + static enum { START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7 } state = START; + static uint8_t data = 0; + + uint8_t dbit = XT_DATA_READ(); + + // This is needed if using PCINT which can be called on both falling and rising edge + // if (XT_CLOCK_READ()) return; + + switch (state) { + case START: + // ignore start(0) bit + if (!dbit) return; + break; + case BIT0 ... BIT7: + data >>= 1; + if (dbit) data |= 0x80; + break; + } + if (state++ == BIT7) { + pbuf_enqueue(data); + state = START; + data = 0; + } + return; +} + +/*-------------------------------------------------------------------- + * Ring buffer to store scan codes from keyboard + *------------------------------------------------------------------*/ +#define PBUF_SIZE 32 +static uint8_t pbuf[PBUF_SIZE]; +static uint8_t pbuf_head = 0; +static uint8_t pbuf_tail = 0; + +static inline void pbuf_enqueue(uint8_t data) { + uint8_t sreg = SREG; + cli(); + uint8_t next = (pbuf_head + 1) % PBUF_SIZE; + if (next != pbuf_tail) { + pbuf[pbuf_head] = data; + pbuf_head = next; + } else { + dprintf("pbuf: full\n"); + } + SREG = sreg; +} + +static inline uint8_t pbuf_dequeue(void) { + uint8_t val = 0; + + uint8_t sreg = SREG; + cli(); + if (pbuf_head != pbuf_tail) { + val = pbuf[pbuf_tail]; + pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; + } + SREG = sreg; + + return val; +} + +static inline bool pbuf_has_data(void) { + uint8_t sreg = SREG; + cli(); + bool has_data = (pbuf_head != pbuf_tail); + SREG = sreg; + return has_data; +} + +static inline void pbuf_clear(void) { + uint8_t sreg = SREG; + cli(); + pbuf_head = pbuf_tail = 0; + SREG = sreg; +} diff --git a/quantum/keyboard.c b/quantum/keyboard.c index ee7fa2bd4..401abdd8f 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -43,9 +43,6 @@ along with this program. If not, see . #ifdef SERIAL_MOUSE_ENABLE # include "serial_mouse.h" #endif -#ifdef ADB_MOUSE_ENABLE -# include "adb.h" -#endif #ifdef RGBLIGHT_ENABLE # include "rgblight.h" #endif @@ -322,9 +319,6 @@ void keyboard_init(void) { #ifdef SERIAL_MOUSE_ENABLE serial_mouse_init(); #endif -#ifdef ADB_MOUSE_ENABLE - adb_mouse_init(); -#endif #ifdef BACKLIGHT_ENABLE backlight_init(); #endif @@ -504,10 +498,6 @@ MATRIX_LOOP_END: serial_mouse_task(); #endif -#ifdef ADB_MOUSE_ENABLE - adb_mouse_task(); -#endif - #ifdef POINTING_DEVICE_ENABLE pointing_device_task(); #endif diff --git a/show_options.mk b/show_options.mk index 083106963..e0d7c9b07 100644 --- a/show_options.mk +++ b/show_options.mk @@ -71,7 +71,6 @@ OTHER_OPTION_NAMES = \ SWAP_HANDS_ENABLE \ RING_BUFFERED_6KRO_REPORT_ENABLE \ WATCHDOG_ENABLE \ - XT_ENABLE \ ERGOINU \ NO_USB_STARTUP_CHECK \ DISABLE_PROMICRO_LEDs \ 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) SRC += $(PROTOCOL_DIR)/serial_uart.c endif -ifeq ($(strip $(ADB_MOUSE_ENABLE)), yes) - OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE -endif - -ifeq ($(strip $(XT_ENABLE)), yes) - SRC += $(PROTOCOL_DIR)/xt_interrupt.c - OPT_DEFS += -DXT_ENABLE -endif - ifeq ($(strip $(USB_HID_ENABLE)), yes) include $(TMK_DIR)/protocol/usb_hid.mk endif 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 @@ -/* -Copyright 2011-19 Jun WAKO -Copyright 2013 Shay Green - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -* Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include -#include "adb.h" -#include "print.h" - -// GCC doesn't inline functions normally -#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) -#define data_hi() (ADB_DDR &= ~(1 << ADB_DATA_BIT)) -#define data_in() (ADB_PIN & (1 << ADB_DATA_BIT)) - -#ifdef ADB_PSW_BIT -static inline void psw_lo(void); -static inline void psw_hi(void); -static inline bool psw_in(void); -#endif - -static inline void attention(void); -static inline void place_bit0(void); -static inline void place_bit1(void); -static inline void send_byte(uint8_t data); -static inline uint16_t wait_data_lo(uint16_t us); -static inline uint16_t wait_data_hi(uint16_t us); - -void adb_host_init(void) { - ADB_PORT &= ~(1 << ADB_DATA_BIT); - data_hi(); -#ifdef ADB_PSW_BIT - psw_hi(); -#endif -} - -#ifdef ADB_PSW_BIT -bool adb_host_psw(void) { return psw_in(); } -#endif - -/* - * Don't call this in a row without the delay, otherwise it makes some of poor controllers - * overloaded and misses strokes. Recommended interval is 12ms. - * - * Thanks a lot, blargg! - * - * - */ -uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); } - -#ifdef ADB_MOUSE_ENABLE -__attribute__((weak)) void adb_mouse_init(void) { return; } - -__attribute__((weak)) void adb_mouse_task(void) { return; } - -uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); } -#endif - -// This sends Talk command to read data from register and returns length of the data. -uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { - for (int8_t i = 0; i < len; i++) buf[i] = 0; - - cli(); - attention(); - send_byte((addr << 4) | ADB_CMD_TALK | reg); - place_bit0(); // Stopbit(0) - // TODO: Service Request(Srq): - // Device holds low part of comannd stopbit for 140-260us - // - // Command: - // ......._ ______________________ ___ ............_ ------- - // | | | | | | | - // Command | | | | | Data bytes | | - // ........|___| | 140-260 |__| |_............|___| - // |stop0 | Tlt Stop-to-Start |start1| |stop0 | - // - // Command without data: - // ......._ __________________________ - // | | - // Command | | - // ........|___| | 140-260 | - // |stop0 | Tlt Stop-to-Start | - // - // Service Request: - // ......._ ______ ___ ............_ ------- - // | 140-260 | | | | | | - // Command | Service Request | | | | Data bytes | | - // ........|___________________| |__| |_............|___| - // |stop0 | |start1| |stop0 | - // ......._ __________ - // | 140-260 | - // Command | Service Request | - // ........|___________________| - // |stop0 | - // This can be happened? - // ......._ ______________________ ___ ............_ ----- - // | | | | | | 140-260 | - // Command | | | | | Data bytes | Service Request | - // ........|___| | 140-260 |__| |_............|_________________| - // |stop0 | Tlt Stop-to-Start |start1| |stop0 | - // - // "Service requests are issued by the devices during a very specific time at the - // end of the reception of the command packet. - // If a device in need of service issues a service request, it must do so within - // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs." - // - // "A device sends a Service Request signal by holding the bus low during the low - // portion of the stop bit of any command or data transaction. The device must lengthen - // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15." - // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf - if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored - xprintf("R"); - sei(); - return 0; - } - if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) - sei(); - return 0; // No data from device(not error); - } - - // start bit(1) - if (!wait_data_hi(40)) { - xprintf("S"); - sei(); - return 0; - } - if (!wait_data_lo(100)) { - xprintf("s"); - sei(); - return 0; - } - - uint8_t n = 0; // bit count - do { - // - // |<- bit_cell_max(130) ->| - // | |<- lo ->| - // | | |<-hi->| - // _______ - // | | | - // | 130-lo | lo-hi | - // |________| | - // - uint8_t lo = (uint8_t)wait_data_hi(130); - if (!lo) goto error; // no more bit or after stop bit - - uint8_t hi = (uint8_t)wait_data_lo(lo); - if (!hi) goto error; // stop bit extedned by Srq? - - if (n / 8 >= len) continue; // can't store in buf - - buf[n / 8] <<= 1; - if ((130 - lo) < (lo - hi)) { - buf[n / 8] |= 1; - } - } while (++n); - -error: - sei(); - return n / 8; -} - -uint16_t adb_host_talk(uint8_t addr, uint8_t reg) { - uint8_t len; - uint8_t buf[8]; - len = adb_host_talk_buf(addr, reg, buf, 8); - if (len != 2) return 0; - return (buf[0] << 8 | buf[1]); -} - -void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { - cli(); - attention(); - send_byte((addr << 4) | ADB_CMD_LISTEN | reg); - place_bit0(); // Stopbit(0) - // TODO: Service Request - _delay_us(200); // Tlt/Stop to Start - place_bit1(); // Startbit(1) - for (int8_t i = 0; i < len; i++) { - send_byte(buf[i]); - // xprintf("%02X ", buf[i]); - } - place_bit0(); // Stopbit(0); - sei(); -} - -void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) { - uint8_t buf[2] = {data_h, data_l}; - adb_host_listen_buf(addr, reg, buf, 2); -} - -void adb_host_flush(uint8_t addr) { - cli(); - attention(); - send_byte((addr << 4) | ADB_CMD_FLUSH); - place_bit0(); // Stopbit(0) - _delay_us(200); // Tlt/Stop to Start - sei(); -} - -// send state of LEDs -void adb_host_kbd_led(uint8_t led) { - // Listen Register2 - // upper byte: not used - // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock - adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07); -} - -#ifdef ADB_PSW_BIT -static inline void psw_lo() { - ADB_DDR |= (1 << ADB_PSW_BIT); - ADB_PORT &= ~(1 << ADB_PSW_BIT); -} -static inline void psw_hi() { - ADB_PORT |= (1 << ADB_PSW_BIT); - ADB_DDR &= ~(1 << ADB_PSW_BIT); -} -static inline bool psw_in() { - ADB_PORT |= (1 << ADB_PSW_BIT); - ADB_DDR &= ~(1 << ADB_PSW_BIT); - return ADB_PIN & (1 << ADB_PSW_BIT); -} -#endif - -static inline void attention(void) { - data_lo(); - _delay_us(800 - 35); // bit1 holds lo for 35 more - place_bit1(); -} - -static inline void place_bit0(void) { - data_lo(); - _delay_us(65); - data_hi(); - _delay_us(35); -} - -static inline void place_bit1(void) { - data_lo(); - _delay_us(35); - data_hi(); - _delay_us(65); -} - -static inline void send_byte(uint8_t data) { - for (int i = 0; i < 8; i++) { - if (data & (0x80 >> i)) - place_bit1(); - else - place_bit0(); - } -} - -// These are carefully coded to take 6 cycles of overhead. -// inline asm approach became too convoluted -static inline uint16_t wait_data_lo(uint16_t us) { - do { - if (!data_in()) break; - _delay_us(1 - (6 * 1000000.0 / F_CPU)); - } while (--us); - return us; -} - -static inline uint16_t wait_data_hi(uint16_t us) { - do { - if (data_in()) break; - _delay_us(1 - (6 * 1000000.0 / F_CPU)); - } while (--us); - return us; -} - -/* -ADB Protocol -============ - -Resources ---------- -ADB - The Untold Story: Space Aliens Ate My Mouse - http://developer.apple.com/legacy/mac/library/#technotes/hw/hw_01.html -ADB Manager - http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Devices/ADB_Manager.pdf - Service request(5-17) -Apple IIgs Hardware Reference Second Edition [Chapter6 p121] - ftp://ftp.apple.asimov.net/pub/apple_II/documentation/Apple%20IIgs%20Hardware%20Reference.pdf -ADB Keycode - http://72.0.193.250/Documentation/macppc/adbkeycodes/ - http://m0115.web.fc2.com/m0115.jpg - [Inside Macintosh volume V, pages 191-192] - http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-421.18.3/IOHIDFamily/Cosmo_USB2ADB.c -ADB Signaling - http://kbdbabel.sourceforge.net/doc/kbd_signaling_pcxt_ps2_adb.pdf -ADB Overview & History - http://en.wikipedia.org/wiki/Apple_Desktop_Bus -Microchip Application Note: ADB device(with code for PIC16C) - http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011062 -AVR ATtiny2131 ADB to PS/2 converter(Japanese) - http://hp.vector.co.jp/authors/VA000177/html/KeyBoardA5DEA5CBA5A2II.html - - -Pinouts -------- - ADB female socket from the front: - __________ - | | <--- top - | 4o o3 | - |2o o1| - | == | - |________| <--- bottom - | | <--- 4pins - - - ADB female socket from bottom: - - ========== <--- front - | | - | | - |2o o1| - |4o o3| - ---------- <--- back - - 1: Data - 2: Power SW(low when press Power key) - 3: Vcc(5V) - 4: GND - - -Commands --------- - ADB command is 1byte and consists of 4bit-address, 2bit-command - type and 2bit-register. The commands are always sent by Host. - - Command format: - 7 6 5 4 3 2 1 0 - | | | |------------ address - | |-------- command type - | |---- register - - bits commands - ------------------------------------------------------ - - - - - 0 0 0 0 Send Reset(reset all devices) - A A A A 0 0 0 1 Flush(reset a device) - - - - - 0 0 1 0 Reserved - - - - - 0 0 1 1 Reserved - - - - - 0 1 - - Reserved - A A A A 1 0 R R Listen(write to a device) - A A A A 1 1 R R Talk(read from a device) - - The command to read keycodes from keyboard is 0x2C which - consist of keyboard address 2 and Talk against register 0. - - Address: - 2: keyboard - 3: mice - - Registers: - 0: application(keyboard uses this to store its data.) - 1: application - 2: application(keyboard uses this for LEDs and state of modifiers) - 3: status and command - - -Communication -------------- - This is a minimum information for keyboard communication. - See "Resources" for detail. - - Signaling: - - ~~~~____________~~||||||||||||__~~~~~_~~|||||||||||||||__~~~~ - - |800us | |7 Command 0| | | |15-64 Data 0|Stopbit(0) - +Attention | | | +Startbit(1) - +Startbit(1) | +Tlt(140-260us) - +stopbit(0) - - Bit cells: - - bit0: ______~~~ - 65 :35us - - bit1: ___~~~~~~ - 35 :65us - - bit0 low time: 60-70% of bit cell(42-91us) - bit1 low time: 30-40% of bit cell(21-52us) - bit cell time: 70-130us - [from Apple IIgs Hardware Reference Second Edition] - - Criterion for bit0/1: - After 55us if line is low/high then bit is 0/1. - - Attention & start bit: - Host asserts low in 560-1040us then places start bit(1). - - Tlt(Stop to Start): - Bus stays high in 140-260us then device places start bit(1). - - Global reset: - Host asserts low in 2.8-5.2ms. All devices are forced to reset. - - Service request from device(Srq): - Device can request to send at commad(Global only?) stop bit. - Requesting device keeps low for 140-260us at stop bit of command. - - -Keyboard Data(Register0) - This 16bit data can contains two keycodes and two released flags. - First keycode is palced in upper byte. When one keyocode is sent, - lower byte is 0xFF. - Release flag is 1 when key is released. - - 1514 . . . . . 8 7 6 . . . . . 0 - | | | | | | | | | +-+-+-+-+-+-+- Keycode2 - | | | | | | | | +--------------- Released2(1 when the key is released) - | +-+-+-+-+-+-+----------------- Keycode1 - +------------------------------- Released1(1 when the key is released) - - Keycodes: - Scancode consists of 7bit keycode and 1bit release flag. - Device can send two keycodes at once. If just one keycode is sent - keycode1 contains it and keyocode2 is 0xFF. - - Power switch: - You can read the state from PSW line(active low) however - the switch has a special scancode 0x7F7F, so you can - also read from Data line. It uses 0xFFFF for release scancode. - -Keyboard LEDs & state of keys(Register2) - This register hold current state of three LEDs and nine keys. - The state of LEDs can be changed by sending Listen command. - - 1514 . . . . . . 7 6 5 . 3 2 1 0 - | | | | | | | | | | | | | | | +- LED1(NumLock) - | | | | | | | | | | | | | | +--- LED2(CapsLock) - | | | | | | | | | | | | | +----- LED3(ScrollLock) - | | | | | | | | | | +-+-+------- Reserved - | | | | | | | | | +------------- ScrollLock - | | | | | | | | +--------------- NumLock - | | | | | | | +----------------- Apple/Command - | | | | | | +------------------- Option - | | | | | +--------------------- Shift - | | | | +----------------------- Control - | | | +------------------------- Reset/Power - | | +--------------------------- CapsLock - | +----------------------------- Delete - +------------------------------- Reserved - -Address, Handler ID and bits(Register3) - 1514131211 . . 8 7 . . . . . . 0 - | | | | | | | | | | | | | | | | - | | | | | | | | +-+-+-+-+-+-+-+- Handler ID - | | | | +-+-+-+----------------- Address - | | | +------------------------- 0 - | | +--------------------------- Service request enable(1 = enabled) - | +----------------------------- Exceptional event(alwyas 1 if not used) - +------------------------------- 0 - -ADB Bit Cells - bit cell time: 70-130us - low part of bit0: 60-70% of bit cell - low part of bit1: 30-40% of bit cell - - bit cell time 70us 130us - -------------------------------------------- - low part of bit0 42-49 78-91 - high part of bit0 21-28 39-52 - low part of bit1 21-28 39-52 - high part of bit1 42-49 78-91 - - - bit0: - 70us bit cell: - ____________~~~~~~ - 42-49 21-28 - - 130us bit cell: - ____________~~~~~~ - 78-91 39-52 - - bit1: - 70us bit cell: - ______~~~~~~~~~~~~ - 21-28 42-49 - - 130us bit cell: - ______~~~~~~~~~~~~ - 39-52 78-91 - - [from Apple IIgs Hardware Reference Second Edition] - -Keyboard Handle ID - Apple Standard Keyboard M0116: 0x01 - Apple Extended Keyboard M0115: 0x02 - Apple Extended Keyboard II M3501: 0x02 - Apple Adjustable Keybaord: 0x10 - - http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802 - -END_OF_ADB -*/ 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 @@ -/* -Copyright 2011-19 Jun WAKO - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -* Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#pragma once - -#include -#include - -#if !(defined(ADB_PORT) && defined(ADB_PIN) && defined(ADB_DDR) && defined(ADB_DATA_BIT)) -# error "ADB port setting is required in config.h" -#endif - -#define ADB_POWER 0x7F -#define ADB_CAPS 0x39 - -/* ADB commands */ -// Default Address -#define ADB_ADDR_0 0 -#define ADB_ADDR_DONGLE 1 -#define ADB_ADDR_KEYBOARD 2 -#define ADB_ADDR_MOUSE 3 -#define ADB_ADDR_TABLET 4 -#define ADB_ADDR_APPLIANCE 7 -#define ADB_ADDR_8 8 -#define ADB_ADDR_9 9 -#define ADB_ADDR_10 10 -#define ADB_ADDR_11 11 -#define ADB_ADDR_12 12 -#define ADB_ADDR_13 13 -#define ADB_ADDR_14 14 -#define ADB_ADDR_15 15 -// for temporary purpose, do not use for polling -#define ADB_ADDR_TMP 15 -#define ADB_ADDR_MOUSE_POLL 10 -// Command Type -#define ADB_CMD_RESET 0 -#define ADB_CMD_FLUSH 1 -#define ADB_CMD_LISTEN 8 -#define ADB_CMD_TALK 12 -// Register -#define ADB_REG_0 0 -#define ADB_REG_1 1 -#define ADB_REG_2 2 -#define ADB_REG_3 3 - -/* ADB keyboard handler id */ -#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */ -#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */ -#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */ -#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */ -#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */ -#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */ -#define ADB_HANDLER_CLASSIC1_MOUSE 0x01 -#define ADB_HANDLER_CLASSIC2_MOUSE 0x02 -#define ADB_HANDLER_EXTENDED_MOUSE 0x04 -#define ADB_HANDLER_TURBO_MOUSE 0x32 - -// ADB host -void adb_host_init(void); -bool adb_host_psw(void); -uint16_t adb_host_talk(uint8_t addr, uint8_t reg); -uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); -void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l); -void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); -void adb_host_flush(uint8_t addr); -void adb_host_kbd_led(uint8_t led); -uint16_t adb_host_kbd_recv(void); -uint16_t adb_host_mouse_recv(void); - -// ADB Mouse -void adb_mouse_task(void); -void 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 @@ -/* -Copyright 2011,2012 Jun WAKO - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -* Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ -/* M0110A Support was contributed by skagon@github */ - -#include -#include -#include -#include -#include "m0110.h" -#include "debug.h" - -static inline uint8_t raw2scan(uint8_t raw); -static inline uint8_t inquiry(void); -static inline uint8_t instant(void); -static inline void clock_lo(void); -static inline void clock_hi(void); -static inline bool clock_in(void); -static inline void data_lo(void); -static inline void data_hi(void); -static inline bool data_in(void); -static inline uint16_t wait_clock_lo(uint16_t us); -static inline uint16_t wait_clock_hi(uint16_t us); -static inline uint16_t wait_data_lo(uint16_t us); -static inline uint16_t wait_data_hi(uint16_t us); -static inline void idle(void); -static inline void request(void); - -#define WAIT_US(stat, us, err) \ - do { \ - if (!wait_##stat(us)) { \ - m0110_error = err; \ - goto ERROR; \ - } \ - } while (0) - -#define WAIT_MS(stat, ms, err) \ - do { \ - uint16_t _ms = ms; \ - while (_ms) { \ - if (wait_##stat(1000)) { \ - break; \ - } \ - _ms--; \ - } \ - if (_ms == 0) { \ - m0110_error = err; \ - goto ERROR; \ - } \ - } while (0) - -#define KEY(raw) ((raw)&0x7f) -#define IS_BREAK(raw) (((raw)&0x80) == 0x80) - -uint8_t m0110_error = 0; - -void m0110_init(void) { - idle(); - _delay_ms(1000); - - /* Not needed to initialize in fact. - uint8_t data; - m0110_send(M0110_MODEL); - data = m0110_recv(); - print("m0110_init model: "); print_hex8(data); print("\n"); - - m0110_send(M0110_TEST); - data = m0110_recv(); - print("m0110_init test: "); print_hex8(data); print("\n"); - */ -} - -uint8_t m0110_send(uint8_t data) { - m0110_error = 0; - - request(); - WAIT_MS(clock_lo, 250, 1); // keyboard may block long time - for (uint8_t bit = 0x80; bit; bit >>= 1) { - WAIT_US(clock_lo, 250, 3); - if (data & bit) { - data_hi(); - } else { - data_lo(); - } - WAIT_US(clock_hi, 200, 4); - } - _delay_us(100); // hold last bit for 80us - idle(); - return 1; -ERROR: - print("m0110_send err: "); - print_hex8(m0110_error); - print("\n"); - _delay_ms(500); - idle(); - return 0; -} - -uint8_t m0110_recv(void) { - uint8_t data = 0; - m0110_error = 0; - - WAIT_MS(clock_lo, 250, 1); // keyboard may block long time - for (uint8_t i = 0; i < 8; i++) { - data <<= 1; - WAIT_US(clock_lo, 200, 2); - WAIT_US(clock_hi, 200, 3); - if (data_in()) { - data |= 1; - } - } - idle(); - return data; -ERROR: - print("m0110_recv err: "); - print_hex8(m0110_error); - print("\n"); - _delay_ms(500); - idle(); - return 0xFF; -} - -/* -Handling for exceptional case of key combinations for M0110A - -Shift and Calc/Arrow key could be operated simultaneously: - - Case Shift Arrow Events Interpret - ------------------------------------------------------------------- - 1 Down Down 71, 79, DD Calc(d)*a *b - 2 Down Up 71, 79, UU Arrow&Calc(u)*a - 3 Up Down F1, 79, DD Shift(u) *c - 4 Up Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a - - Case Shift Calc Events Interpret - ------------------------------------------------------------------- - 5(1) Down Down 71, 71, 79, DD Shift(d) and Cacl(d) - 6(2) Down Up F1, 71, 79, UU Shift(u) and Arrow&Calc(u)*a - 7(1) Up Down F1, 71, 79, DD Shift(u) and Calc(d) - 8(4) Up Up F1, F1, 79, UU Shift(ux2) and Arrow&Calc(u)*a - -During Calc key is hold: - Case Shift Arrow Events Interpret - ------------------------------------------------------------------- - A(3) ---- Down F1, 79, DD Shift(u) *c - B ---- Up 79, UU Arrow&Calc(u)*a - C Down ---- F1, 71 Shift(u) and Shift(d) - D Up ---- F1 Shift(u) - E Hold Down 79, DD Normal - F Hold Up 79, UU Arrow&Calc(u)*a - G(1) Down Down F1, 71, 79, DD Shift(u)*b and Calc(d)*a - H(2) Down Up F1, 71, 79, UU Shift(u) and Arrow&Calc(u)*a - I(3) Up Down F1, F1, 79, DD Shift(ux2) *c - J(4) Up Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a - - Case Shift Calc Events Interpret - ------------------------------------------------------------------- - K(1) ---- Down 71, 79, DD Calc(d)*a - L(4) ---- Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a - M(1) Hold Down 71, 79, DD Calc(d)*a - N Hold Up 79, UU Arrow&Calc(u)*a - - Where DD/UU indicates part of Keypad Down/Up event. - *a: Impossible to distinguish btween Arrow and Calc event. - *b: Shift(d) event is ignored. - *c: Arrow/Calc(d) event is ignored. -*/ -uint8_t m0110_recv_key(void) { - static uint8_t keybuf = 0x00; - static uint8_t keybuf2 = 0x00; - static uint8_t rawbuf = 0x00; - uint8_t raw, raw2, raw3; - - if (keybuf) { - raw = keybuf; - keybuf = 0x00; - return raw; - } - if (keybuf2) { - raw = keybuf2; - keybuf2 = 0x00; - return raw; - } - - if (rawbuf) { - raw = rawbuf; - rawbuf = 0x00; - } else { - raw = instant(); // Use INSTANT for better response. Should be INQUIRY ? - } - switch (KEY(raw)) { - case M0110_KEYPAD: - raw2 = instant(); - switch (KEY(raw2)) { - case M0110_ARROW_UP: - case M0110_ARROW_DOWN: - case M0110_ARROW_LEFT: - case M0110_ARROW_RIGHT: - if (IS_BREAK(raw2)) { - // Case B,F,N: - keybuf = (raw2scan(raw2) | M0110_CALC_OFFSET); // Calc(u) - return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); // Arrow(u) - } - break; - } - // Keypad or Arrow - return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); - break; - case M0110_SHIFT: - raw2 = instant(); - switch (KEY(raw2)) { - case M0110_SHIFT: - // Case: 5-8,C,G,H - rawbuf = raw2; - return raw2scan(raw); // Shift(d/u) - break; - case M0110_KEYPAD: - // Shift + Arrow, Calc, or etc. - raw3 = instant(); - switch (KEY(raw3)) { - case M0110_ARROW_UP: - case M0110_ARROW_DOWN: - case M0110_ARROW_LEFT: - case M0110_ARROW_RIGHT: - if (IS_BREAK(raw)) { - if (IS_BREAK(raw3)) { - // Case 4: - print("(4)\n"); - keybuf2 = raw2scan(raw); // Shift(u) - keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u) - return (raw2scan(raw3) | M0110_KEYPAD_OFFSET); // Arrow(u) - } else { - // Case 3: - print("(3)\n"); - return (raw2scan(raw)); // Shift(u) - } - } else { - if (IS_BREAK(raw3)) { - // Case 2: - print("(2)\n"); - keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u) - return (raw2scan(raw3) | M0110_KEYPAD_OFFSET); // Arrow(u) - } else { - // Case 1: - print("(1)\n"); - return (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(d) - } - } - break; - default: - // Shift + Keypad - keybuf = (raw2scan(raw3) | M0110_KEYPAD_OFFSET); - return raw2scan(raw); // Shift(d/u) - break; - } - break; - default: - // Shift + Normal keys - keybuf = raw2scan(raw2); - return raw2scan(raw); // Shift(d/u) - break; - } - break; - default: - // Normal keys - return raw2scan(raw); - break; - } -} - -static inline uint8_t raw2scan(uint8_t raw) { return (raw == M0110_NULL) ? M0110_NULL : ((raw == M0110_ERROR) ? M0110_ERROR : (((raw & 0x80) | ((raw & 0x7F) >> 1)))); } - -static inline uint8_t inquiry(void) { - m0110_send(M0110_INQUIRY); - return m0110_recv(); -} - -static inline uint8_t instant(void) { - m0110_send(M0110_INSTANT); - uint8_t data = m0110_recv(); - if (data != M0110_NULL) { - debug_hex(data); - debug(" "); - } - return data; -} - -static inline void clock_lo() { - M0110_CLOCK_PORT &= ~(1 << M0110_CLOCK_BIT); - M0110_CLOCK_DDR |= (1 << M0110_CLOCK_BIT); -} -static inline void clock_hi() { - /* input with pull up */ - M0110_CLOCK_DDR &= ~(1 << M0110_CLOCK_BIT); - M0110_CLOCK_PORT |= (1 << M0110_CLOCK_BIT); -} -static inline bool clock_in() { - M0110_CLOCK_DDR &= ~(1 << M0110_CLOCK_BIT); - M0110_CLOCK_PORT |= (1 << M0110_CLOCK_BIT); - _delay_us(1); - return M0110_CLOCK_PIN & (1 << M0110_CLOCK_BIT); -} -static inline void data_lo() { - M0110_DATA_PORT &= ~(1 << M0110_DATA_BIT); - M0110_DATA_DDR |= (1 << M0110_DATA_BIT); -} -static inline void data_hi() { - /* input with pull up */ - M0110_DATA_DDR &= ~(1 << M0110_DATA_BIT); - M0110_DATA_PORT |= (1 << M0110_DATA_BIT); -} -static inline bool data_in() { - M0110_DATA_DDR &= ~(1 << M0110_DATA_BIT); - M0110_DATA_PORT |= (1 << M0110_DATA_BIT); - _delay_us(1); - return M0110_DATA_PIN & (1 << M0110_DATA_BIT); -} - -static inline uint16_t wait_clock_lo(uint16_t us) { - while (clock_in() && us) { - asm(""); - _delay_us(1); - us--; - } - return us; -} -static inline uint16_t wait_clock_hi(uint16_t us) { - while (!clock_in() && us) { - asm(""); - _delay_us(1); - us--; - } - return us; -} -static inline uint16_t wait_data_lo(uint16_t us) { - while (data_in() && us) { - asm(""); - _delay_us(1); - us--; - } - return us; -} -static inline uint16_t wait_data_hi(uint16_t us) { - while (!data_in() && us) { - asm(""); - _delay_us(1); - us--; - } - return us; -} - -static inline void idle(void) { - clock_hi(); - data_hi(); -} - -static inline void request(void) { - clock_hi(); - data_lo(); -} - -/* -Primitive M0110 Library for AVR -============================== - - -Signaling ---------- -CLOCK is always from KEYBOARD. DATA are sent with MSB first. - -1) IDLE: both lines are high. - CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -2) KEYBOARD->HOST: HOST reads bit on rising edge. - CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ - DATA ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ - <--> 160us(clock low) - <---> 180us(clock high) - -3) HOST->KEYBOARD: HOST asserts bit on falling edge. - CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ - DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ - <----> 840us(request to send by host) <---> 80us(hold DATA) - <--> 180us(clock low) - <---> 220us(clock high) - - -Protocol --------- -COMMAND: - Inquiry 0x10 get key event with block - Instant 0x12 get key event - Model 0x14 get model number(M0110 responds with 0x09) - bit 7 1 if another device connected(used when keypad exists?) - bit4-6 next device model number - bit1-3 keyboard model number - bit 0 always 1 - Test 0x16 test(ACK:0x7D/NAK:0x77) - -KEY EVENT: - bit 7 key state(0:press 1:release) - bit 6-1 scan code(see below) - bit 0 always 1 - To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1). - - Note: On the M0110A, Keypad keys and Arrow keys are preceded by 0x79. - Moreover, some Keypad keys(=, /, * and +) are preceded by 0x71 on press and 0xF1 on release. - -ARROW KEYS: - Arrow keys and Calc keys(+,*,/,= on keypad) share same byte sequence and preceding byte of - Calc keys(0x71 and 0xF1) means press and release event of SHIFT. This causes a very confusing situation, - it is difficult or impossible to tell Calc key from Arrow key plus SHIFT in some cases. - - Raw key events: - press release - ---------------- ---------------- - Left: 0x79, 0x0D 0x79, 0x8D - Right: 0x79, 0x05 0x79, 0x85 - Up: 0x79, 0x1B 0x79, 0x9B - Down: 0x79, 0x11 0x79, 0x91 - Pad+: 0x71, 0x79, 0x0D 0xF1, 0x79, 0x8D - Pad*: 0x71, 0x79, 0x05 0xF1, 0x79, 0x85 - Pad/: 0x71, 0x79, 0x1B 0xF1, 0x79, 0x9B - Pad=: 0x71, 0x79, 0x11 0xF1, 0x79, 0x91 - - -RAW CODE: - M0110A - ,---------------------------------------------------------. ,---------------. - | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| - |---------------------------------------------------------| |---------------| - |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| - |-----------------------------------------------------' | |---------------| - |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| - |---------------------------------------------------------| |---------------| - |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | - |---------------------------------------------------------' |-----------|Ent| - |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | - `---------------------------------------------------------' `---------------' - ,---------------------------------------------------------. ,---------------. - | 65| 25| 27| 29| 2B| 2F| 2D| 35| 39| 33| 3B| 37| 31| 67| |+0F|*11|*1B|*05| - |---------------------------------------------------------| |---------------| - | 61| 19| 1B| 1D| 1F| 23| 21| 41| 45| 3F| 47| 43| 3D| | |+33|+37|+39|+1D| - |-----------------------------------------------------' | |---------------| - | 73| 01| 03| 05| 07| 0B| 09| 4D| 51| 4B| 53| 4F| 49| |+2D|+2F|+31|*0D| - |---------------------------------------------------------| |---------------| - | 71| 0D| 0F| 11| 13| 17| 5B| 5D| 27| 5F| 59| 71|+1B| |+27|+29|+2B| | - |---------------------------------------------------------' |-----------|+19| - | 75| 6F| 63 | 55|+0D|+05|+11| | +25|+03| | - `---------------------------------------------------------' `---------------' - + 0x79, 0xDD / 0xF1, 0xUU - * 0x71, 0x79,DD / 0xF1, 0x79, 0xUU - - -MODEL NUMBER: - M0110: 0x09 00001001 : model number 4 (100) - M0110A: 0x0B 00001011 : model number 5 (101) - M0110 & M0120: ??? - - -Scan Code ---------- - m0110_recv_key() function returns following scan codes instead of M0110 raw codes. - Scan codes are 1 byte size and MSB(bit7) is set when key is released. - - scancode = ((raw&0x80) | ((raw&0x7F)>>1)) - - M0110 M0120 - ,---------------------------------------------------------. ,---------------. - | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| -|Lft|Rgt| - |---------------------------------------------------------| |---------------| - |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9|Up | - |---------------------------------------------------------| |---------------| - |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6|Dn | - |---------------------------------------------------------| |---------------| - |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | 1| 2| 3| | - `---------------------------------------------------------' |-----------|Ent| - |Opt|Mac | Space |Enter|Opt| | 0| .| | - `------------------------------------------------' `---------------' - ,---------------------------------------------------------. ,---------------. - | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 4E| 46| 42| - |---------------------------------------------------------| |---------------| - | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | 59| 5B| 5C| 4D| - |---------------------------------------------------------| |---------------| - | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 48| - |---------------------------------------------------------| |---------------| - | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | 53| 54| 55| | - `---------------------------------------------------------' |-----------| 4C| - | 3A| 37| 31 | 34| 3A| | 52| 41| | - `------------------------------------------------' `---------------' - - International keyboard(See page 22 of "Technical Info for 128K/512K") - ,---------------------------------------------------------. - | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| - |---------------------------------------------------------| - | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| - |------------------------------------------------------ | - | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | - |---------------------------------------------------------| - | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 0A| 38| - `---------------------------------------------------------' - | 3A| 37| 34 | 31| 3A| - `------------------------------------------------' - - M0110A - ,---------------------------------------------------------. ,---------------. - | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| - |---------------------------------------------------------| |---------------| - |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| - |-----------------------------------------------------' | |---------------| - |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| - |---------------------------------------------------------| |---------------| - |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | - |---------------------------------------------------------' |-----------|Ent| - |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | - `---------------------------------------------------------' `---------------' - ,---------------------------------------------------------. ,---------------. - | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62| - |---------------------------------------------------------| |---------------| - | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E| - |-----------------------------------------------------' | |---------------| - | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66| - |---------------------------------------------------------| |---------------| - | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| | - |---------------------------------------------------------' |-----------| 4C| - | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| | - `---------------------------------------------------------' `---------------' - - -References ----------- -Technical Info for 128K/512K and Plus - ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf - ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf -Protocol: - Page 20 of Tech Info for 128K/512K - http://www.mac.linux-m68k.org/devel/plushw.php -Connector: - Page 20 of Tech Info for 128K/512K - http://www.kbdbabel.org/conn/kbd_connector_macplus.png -Signaling: - http://www.kbdbabel.org/signaling/kbd_signaling_mac.png - http://typematic.blog.shinobi.jp/Entry/14/ -M0110 raw scan codes: - Page 22 of Tech Info for 128K/512K - Page 07 of Tech Info for Plus - http://m0115.web.fc2.com/m0110.jpg - http://m0115.web.fc2.com/m0110a.jpg -*/ 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 @@ -/* -Copyright 2011,2012 Jun WAKO - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -* Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#pragma once - -/* port settings for clock and data line */ -#if !(defined(M0110_CLOCK_PORT) && defined(M0110_CLOCK_PIN) && defined(M0110_CLOCK_DDR) && defined(M0110_CLOCK_BIT)) -# error "M0110 clock port setting is required in config.h" -#endif - -#if !(defined(M0110_DATA_PORT) && defined(M0110_DATA_PIN) && defined(M0110_DATA_DDR) && defined(M0110_DATA_BIT)) -# error "M0110 data port setting is required in config.h" -#endif - -/* Commands */ -#define M0110_INQUIRY 0x10 -#define M0110_INSTANT 0x14 -#define M0110_MODEL 0x16 -#define M0110_TEST 0x36 - -/* Response(raw byte from M0110) */ -#define M0110_NULL 0x7B -#define M0110_KEYPAD 0x79 -#define M0110_TEST_ACK 0x7D -#define M0110_TEST_NAK 0x77 -#define M0110_SHIFT 0x71 -#define M0110_ARROW_UP 0x1B -#define M0110_ARROW_DOWN 0x11 -#define M0110_ARROW_LEFT 0x0D -#define M0110_ARROW_RIGHT 0x05 - -/* This inidcates no response. */ -#define M0110_ERROR 0xFF - -/* scan code offset for keypad and arrow keys */ -#define M0110_KEYPAD_OFFSET 0x40 -#define M0110_CALC_OFFSET 0x60 - -extern uint8_t m0110_error; - -/* host role */ -void m0110_init(void); -uint8_t m0110_send(uint8_t data); -uint8_t m0110_recv(void); -uint8_t m0110_recv_key(void); -uint8_t m0110_inquiry(void); -uint8_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 @@ -/* -Copyright 2018 Jun WAKO -Copyright 2016 Ethan Apodaca - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -* Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#pragma once - -#include "quantum.h" - -#define XT_DATA_IN() \ - do { \ - setPinInput(XT_DATA_PIN); \ - writePinHigh(XT_DATA_PIN); \ - } while (0) - -#define XT_DATA_READ() readPin(XT_DATA_PIN) - -#define XT_DATA_LO() \ - do { \ - writePinLow(XT_DATA_PIN); \ - setPinOutput(XT_DATA_PIN); \ - } while (0) - -#define XT_CLOCK_IN() \ - do { \ - setPinInput(XT_CLOCK_PIN); \ - writePinHigh(XT_CLOCK_PIN); \ - } while (0) - -#define XT_CLOCK_READ() readPin(XT_CLOCK_PIN) - -#define XT_CLOCK_LO() \ - do { \ - writePinLow(XT_CLOCK_PIN); \ - setPinOutput(XT_CLOCK_PIN); \ - } while (0) - -void xt_host_init(void); - -uint8_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 @@ -/* -Copyright 2018 Jun WAKO -Copyright 2016 Ethan Apodaca - -This software is licensed with a Modified BSD License. -All of this is supposed to be Free Software, Open Source, DFSG-free, -GPL-compatible, and OK to use in both free and proprietary applications. -Additions and corrections to this file are welcome. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -* Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include "xt.h" -#include "wait.h" -#include "debug.h" - -static inline uint8_t pbuf_dequeue(void); -static inline void pbuf_enqueue(uint8_t data); -static inline bool pbuf_has_data(void); -static inline void pbuf_clear(void); - -void xt_host_init(void) { - XT_INT_INIT(); - XT_INT_OFF(); - - /* hard reset */ -#ifdef XT_RESET - XT_RESET(); -#endif - - /* soft reset: pull clock line down for 20ms */ - XT_DATA_LO(); - XT_CLOCK_LO(); - wait_ms(20); - - /* input mode with pullup */ - XT_CLOCK_IN(); - XT_DATA_IN(); - - XT_INT_ON(); -} - -/* get data received by interrupt */ -uint8_t xt_host_recv(void) { - if (pbuf_has_data()) { - return pbuf_dequeue(); - } else { - return 0; - } -} - -ISR(XT_INT_VECT) { - /* - * XT signal format consits of 10 or 9 clocks and sends start bits and 8-bit data, - * which should be read on falling edge of clock. - * - * start(0), start(1), bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7 - * - * Original IBM XT keyboard sends start(0) bit while some of clones don't. - * Start(0) bit is read as low on data line while start(1) as high. - * - * https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol - */ - static enum { START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7 } state = START; - static uint8_t data = 0; - - uint8_t dbit = XT_DATA_READ(); - - // This is needed if using PCINT which can be called on both falling and rising edge - // if (XT_CLOCK_READ()) return; - - switch (state) { - case START: - // ignore start(0) bit - if (!dbit) return; - break; - case BIT0 ... BIT7: - data >>= 1; - if (dbit) data |= 0x80; - break; - } - if (state++ == BIT7) { - pbuf_enqueue(data); - state = START; - data = 0; - } - return; -} - -/*-------------------------------------------------------------------- - * Ring buffer to store scan codes from keyboard - *------------------------------------------------------------------*/ -#define PBUF_SIZE 32 -static uint8_t pbuf[PBUF_SIZE]; -static uint8_t pbuf_head = 0; -static uint8_t pbuf_tail = 0; - -static inline void pbuf_enqueue(uint8_t data) { - uint8_t sreg = SREG; - cli(); - uint8_t next = (pbuf_head + 1) % PBUF_SIZE; - if (next != pbuf_tail) { - pbuf[pbuf_head] = data; - pbuf_head = next; - } else { - dprintf("pbuf: full\n"); - } - SREG = sreg; -} - -static inline uint8_t pbuf_dequeue(void) { - uint8_t val = 0; - - uint8_t sreg = SREG; - cli(); - if (pbuf_head != pbuf_tail) { - val = pbuf[pbuf_tail]; - pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; - } - SREG = sreg; - - return val; -} - -static inline bool pbuf_has_data(void) { - uint8_t sreg = SREG; - cli(); - bool has_data = (pbuf_head != pbuf_tail); - SREG = sreg; - return has_data; -} - -static inline void pbuf_clear(void) { - uint8_t sreg = SREG; - cli(); - pbuf_head = pbuf_tail = 0; - SREG = sreg; -} 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. * Media Control Key - Volume Down/Up, Mute, Next/Prev track, Play, Stop and etc * USB NKRO - 248 keys(+ 8 modifiers) simultaneously * PS/2 mouse support - PS/2 mouse(TrackPoint) as composite device -* Keyboard protocols - PS/2, ADB, M0110, Sun and other old keyboard protocols * User Function - Customizable function of key with writing code * Macro - Very primitive at this time * Keyboard Tricks - Oneshot modifier and modifier with tapping feature @@ -84,9 +83,9 @@ Architecture / /| Keys/Mouse | Protocol |d| | Action | | | Protocol | /__________/ |<-----------| LUFA |r| | Layer, Tap | | | Matrix | |.--------.| | LED | V-USB |i| |-------------| | | PS/2,IBM | __________________ - || || |----------->| UART |v| | Keymap | | | ADB,M0110| Keys / /_/_/_/_/_/_/_/ /| - || Host || | Console | |e| | Mousekey | | | SUN/NEWS |<----------/ /_/_/_/_/_/_/_/ / / - ||________||/.<-----------| |r| | Report | | | X68K/PC98| Control / /_/_/_/_/_/_/_/ / / + || || |----------->| UART |v| | Keymap | | | | Keys / /_/_/_/_/_/_/_/ /| + || Host || | Console | |e| | Mousekey | | | |<----------/ /_/_/_/_/_/_/_/ / / + ||________||/.<-----------| |r| | Report | | | | Control / /_/_/_/_/_/_/_/ / / `_========_'/| |---------------------------------------------|-------->/___ /_______/ ___/ / |_o______o_|/ | Sendchar, Print, Debug, Command, ... | |_________________|/ +---------------------------------------------+ Keyboard @@ -134,10 +133,6 @@ Files and Directories * lufa/ - LUFA USB stack * vusb/ - Objective Development V-USB * ps2.c - PS/2 protocol -* adb.c - Apple Desktop Bus protocol -* m0110.c - Macintosh 128K/512K/Plus keyboard protocol -* news.c - Sony NEWS keyboard protocol -* x68k.c - Sharp X68000 keyboard protocol * serial_soft.c - Asynchronous Serial protocol implemented by software -- cgit v1.2.3