From 230ed4bdef855202a4c340fe645f05e2ca124521 Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 4 Jun 2016 19:02:41 +0900 Subject: [PATCH 1/2] core: change API of adb.c to accept device address --- tmk_core/protocol/adb.c | 22 +++++++++++----------- tmk_core/protocol/adb.h | 26 ++++++++++++++++++-------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c index b9b0be98..164255ef 100644 --- a/tmk_core/protocol/adb.c +++ b/tmk_core/protocol/adb.c @@ -86,9 +86,9 @@ bool adb_host_psw(void) * * */ -uint16_t adb_host_kbd_recv(void) +uint16_t adb_host_kbd_recv(uint8_t addr) { - return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); + return adb_host_talk(addr, ADB_REG_0); } #ifdef ADB_MOUSE_ENABLE @@ -156,11 +156,11 @@ error: return -n; } -void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) +void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) { cli(); attention(); - send_byte(cmd); + send_byte((addr<<4) | (ADB_CMD_LISTEN<<2) | reg); place_bit0(); // Stopbit(0) _delay_us(200); // Tlt/Stop to Start place_bit1(); // Startbit(1) @@ -171,12 +171,12 @@ void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) } // send state of LEDs -void adb_host_kbd_led(uint8_t led) +void adb_host_kbd_led(uint8_t addr, uint8_t led) { - // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) - // send upper byte (not used) - // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: - adb_host_listen(0x2A,0,led&0x07); + // Listen Register2 + // upper byte: not used + // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock + adb_host_listen(addr, 2, 0, led & 0x07); } @@ -325,7 +325,7 @@ Commands bits commands ------------------------------------------------------ - - - - - 0 0 0 0 Send Request(reset all devices) + - - - - 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 @@ -440,7 +440,7 @@ Address, Handler ID and bits(Register3) | | | | +-+-+-+----------------- Address | | | +------------------------- 0 | | +--------------------------- Service request enable(1 = enabled) - | +----------------------------- Exeptional event(alwyas 1 if not used) + | +----------------------------- Exceptional event(alwyas 1 if not used) +------------------------------- 0 ADB Bit Cells diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h index d81c4a77..a8b97ea5 100644 --- a/tmk_core/protocol/adb.h +++ b/tmk_core/protocol/adb.h @@ -53,30 +53,40 @@ POSSIBILITY OF SUCH DAMAGE. /* ADB commands */ +// Default Address +#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 +// Command Type +#define ADB_CMD_RESET 0 +#define ADB_CMD_FLUSH 1 #define ADB_CMD_LISTEN 2 #define ADB_CMD_TALK 3 +// Register #define ADB_REG_0 0 #define ADB_REG_1 1 #define ADB_REG_2 2 #define ADB_REG_3 3 -/* ADB keyboard handle id */ -#define ADB_HANDLE_M0116 0x01 -#define ADB_HANDLE_M0115 0x02 -#define ADB_HANDLE_M3501 0x02 -#define ADB_HANDLE_M1242 0x10 +/* ADB keyboard handler id */ +#define ADB_HANDLER_M0116 0x01 +#define ADB_HANDLER_IIGS 0x01 +#define ADB_HANDLER_M0115 0x02 +#define ADB_HANDLER_M3501 0x02 +#define ADB_HANDLER_M1242_ANSI 0x10 +#define ADB_HANDLER_EXTENDED_PROTOCOL 0x03 // ADB host void adb_host_init(void); bool adb_host_psw(void); -uint16_t adb_host_kbd_recv(void); +uint16_t adb_host_kbd_recv(uint8_t addr); uint16_t adb_host_mouse_recv(void); uint16_t adb_host_talk(uint8_t addr, uint8_t reg); -void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); -void adb_host_kbd_led(uint8_t led); +void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l); +void adb_host_kbd_led(uint8_t addr, uint8_t led); void adb_mouse_task(void); void adb_mouse_init(void); From b653b622a623f0e8e2c03af8254e6ac3d29b71c7 Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 4 Jun 2016 19:29:02 +0900 Subject: [PATCH 2/2] adb_usb: Add support for Apple Adjustable keybaord media keys --- converter/adb_usb/MEMO.txt | 27 +++++++++ converter/adb_usb/keymap_common.h | 22 +++---- converter/adb_usb/keymap_plain.c | 8 +-- converter/adb_usb/led.c | 2 +- converter/adb_usb/matrix.c | 95 ++++++++++++++++++++++++++----- 5 files changed, 124 insertions(+), 30 deletions(-) create mode 100644 converter/adb_usb/MEMO.txt diff --git a/converter/adb_usb/MEMO.txt b/converter/adb_usb/MEMO.txt new file mode 100644 index 00000000..f079442c --- /dev/null +++ b/converter/adb_usb/MEMO.txt @@ -0,0 +1,27 @@ +ADB keyboard handle id +====================== +0x01 Apple Standard keyboard M0116 ANSI +0x01 Apple Desktop Bus keyboard 658-4081 ANSI +0x02 Apple Extended Keyboard M0115 ANSI +0x02 Apple Extended Keyboard II M3501 ANSI +0x03 Logical id for Extended Protocol +0x10 Apple Adjustable keyboard M1242 ANSI + + +Adjustable Keyboard media key +============================= +Media key part has different address than the main keyboard(0x02). + +Device Address: 0x07(Appliances/Misc devices) +Handler ID: 0x02 + +Scan Codes +---------- +Media key ADB Code Code in Matix +----------------------------------------- +Volume Up: 0x03 0x48 +Volume Down: 0x02 0x49 +Mute: 0x01 0x4a +Mic: 0x00 0x42 + +As for these keys raw ADB codes are translate into logical codes in matrix. diff --git a/converter/adb_usb/keymap_common.h b/converter/adb_usb/keymap_common.h index 0a917cbc..cb643c8f 100644 --- a/converter/adb_usb/keymap_common.h +++ b/converter/adb_usb/keymap_common.h @@ -34,9 +34,9 @@ extern const uint16_t fn_actions[]; /* Common layout: ANSI+ISO - * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,---. - * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr| - * `---' `---------------' `---------------' `---------------' `-----------' `---' + * ,---. .---------------. ,---------------. ,---------------. ,-----------. ,---------------. + * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |VDn|VUp|Mut|Pwr| + * `---' `---------------' `---------------' `---------------' `-----------' `---------------' * ,-----------------------------------------------------------. ,-----------. ,---------------. * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| =| /| *| * |-----------------------------------------------------------| |-----------| |---------------| @@ -46,16 +46,16 @@ extern const uint16_t fn_actions[]; * |-----------------------------------------------------------| ,---. |---------------| * |Shif|\ | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| | * |-----------------------------------------------------------| ,-----------. |-----------|Ent| - * |Ctrl |Opt |Cmd | Space | |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| | + * |Ctrl |Opt |Cmd | Space |App |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| | * `-----------------------------------------------------------' `-----------' `---------------' */ #define KEYMAP( \ - K35, K7A,K78,K63,K76, K60,K61,K62,K64, K65,K6D,K67,K6F, K69,K6B,K71, K7F, \ + K35, K7A,K78,K63,K76, K60,K61,K62,K64, K65,K6D,K67,K6F, K69,K6B,K71, K49,K48,K4A,K7F, \ K32,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K72,K73,K74, K47,K51,K4B,K43, \ K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E,K2A, K75,K77,K79, K59,K5B,K5C,K4E, \ K39,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27, K24, K56,K57,K58,K45, \ K38,K0A,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C, K7B, K3E, K53,K54,K55, \ - K36,K3A,K37, K31, K7C,K7D, K3B,K3D,K3C, K52, K41,K4C \ + K36,K3A,K37, K31, K42,K7C,K7D, K3B,K3D,K3C, K52, K41,K4C \ ) { \ { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \ { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \ @@ -65,12 +65,12 @@ extern const uint16_t fn_actions[]; { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \ { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_PENT, KC_##K35, KC_##K36, KC_##K37 }, \ { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO }, \ - { KC_F17, KC_##K41, KC_NO, KC_##K43, KC_F18, KC_##K45, KC_NO, KC_##K47 }, \ - { KC_NO, KC_NO, KC_NO, KC_##K4B, KC_##K4C, KC_NO, KC_##K4E, KC_F18 }, \ + { KC_F17, KC_##K41, KC_##K42, KC_##K43, KC_F18, KC_##K45, KC_NO, KC_##K47 }, \ + { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_NO, KC_##K4E, KC_F18 }, \ { KC_F19, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \ - { KC_##K58, KC_##K59, KC_F20, KC_##K5B, KC_##K5C, KC_INT3, KC_INT1, KC_PCMM }, \ - { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_LANG2, KC_##K67 }, \ - { KC_LANG1, KC_##K69, KC_F16, KC_##K6B, KC_NO, KC_##K6D, KC_APP, KC_##K6F }, \ + { KC_##K58, KC_##K59, KC_F20, KC_##K5B, KC_##K5C, KC_JYEN, KC_RO, KC_PCMM }, \ + { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_HANJ, KC_##K67 }, \ + { KC_HAEN, KC_##K69, KC_F16, KC_##K6B, KC_NO, KC_##K6D, KC_APP, KC_##K6F }, \ { KC_NO, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \ { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_NO, KC_##K7F } \ } diff --git a/converter/adb_usb/keymap_plain.c b/converter/adb_usb/keymap_plain.c index 433a5cb3..2f11f86a 100644 --- a/converter/adb_usb/keymap_plain.c +++ b/converter/adb_usb/keymap_plain.c @@ -19,20 +19,20 @@ */ const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = KEYMAP( - ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, NO, + ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, VOLD,VOLU,MUTE,NO, FN0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,EQL, PSLS,PAST, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,FN1, DEL, END, PGDN, P7, P8, P9, PMNS, LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, - LCTL,LALT,LGUI, SPC, RALT,RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT + LCTL,LALT,LGUI, SPC, APP, RALT,RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT ), [1] = KEYMAP( - GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, NO, + GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, VOLD,VOLU,MUTE,NO, FN0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, INS, HOME,PGUP, NLCK,BTN1,BTN2,BTN3, TAB, Q, W, E, R, T, Y, U, PSCR,SLCK,PAUS,UP, INS, FN1, DEL, END, PGDN, WH_D,MS_U,WH_U,WH_D, LCAP,VOLD,VOLU,MUTE,F, G, H, J, HOME,PGUP,LEFT,RGHT, ENT, MS_L,MS_D,MS_R,WH_U, LSFT,NUBS,Z, X, C, V, B, N, M, END, PGDN,DOWN, RSFT, PGUP, WH_L,MS_D,WH_R, - LCTL,LGUI,LALT, SPC, RGUI,RCTL, HOME,PGDN,END, BTN1, BTN2,BTN3 + LCTL,LALT,LGUI, SPC, APP, RALT,RCTL, HOME,PGDN,END, BTN1, BTN2,BTN3 ), }; diff --git a/converter/adb_usb/led.c b/converter/adb_usb/led.c index 3ee64a8e..ea9bf77b 100644 --- a/converter/adb_usb/led.c +++ b/converter/adb_usb/led.c @@ -23,5 +23,5 @@ along with this program. If not, see . void led_set(uint8_t usb_led) { - adb_host_kbd_led(~usb_led); + adb_host_kbd_led(ADB_ADDR_KEYBOARD, ~usb_led); } diff --git a/converter/adb_usb/matrix.c b/converter/adb_usb/matrix.c index 12c3ada7..6190c71a 100644 --- a/converter/adb_usb/matrix.c +++ b/converter/adb_usb/matrix.c @@ -39,6 +39,7 @@ along with this program. If not, see . #endif +static bool has_media_keys = false; static bool is_iso_layout = false; static bool is_modified = false; static report_mouse_t mouse_report = {}; @@ -70,13 +71,26 @@ uint8_t matrix_cols(void) void matrix_init(void) { + // LED on + DDRD |= (1<<6); PORTD |= (1<<6); + adb_host_init(); // wait for keyboard to boot up and receive command - _delay_ms(1000); + _delay_ms(2000); + + // device scan + xprintf("Before init:\n"); + for (uint8_t addr = 1; addr < 16; addr++) { + uint16_t reg3 = adb_host_talk(addr, ADB_REG_3); + if (reg3) { + xprintf("Scan: addr:%d, reg3:%04X\n", addr, reg3); + } + _delay_ms(20); + } // Determine ISO keyboard by handler id // http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L815 - uint16_t handler_id = adb_host_talk(ADB_ADDR_KEYBOARD, 3); + uint16_t handler_id = adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_3); switch (handler_id) { case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D: case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1: @@ -88,11 +102,27 @@ void matrix_init(void) break; } + // Adjustable keyboard media keys: address=0x07 and handlerID=0x02 + has_media_keys = (0x02 == (adb_host_talk(ADB_ADDR_APPLIANCE, ADB_REG_3) & 0xff)); + if (has_media_keys) { + xprintf("Found: media keys\n"); + } + // Enable keyboard left/right modifier distinction - // Addr:Keyboard(0010), Cmd:Listen(10), Register3(11) - // upper byte: reserved bits 0000, device address 0010 - // lower byte: device handler 00000011 - adb_host_listen(0x2B,0x02,0x03); + // Listen Register3 + // upper byte: reserved bits 0000, keyboard address 0010 + // lower byte: device handler 00000011 + adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_3, ADB_ADDR_KEYBOARD, ADB_HANDLER_EXTENDED_PROTOCOL); + + // device scan + xprintf("After init:\n"); + for (uint8_t addr = 1; addr < 16; addr++) { + uint16_t reg3 = adb_host_talk(addr, ADB_REG_3); + if (reg3) { + xprintf("Scan: addr:%d, reg3:%04X\n", addr, reg3); + } + _delay_ms(20); + } // initialize matrix state: all keys off for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; @@ -103,14 +133,8 @@ void matrix_init(void) //debug_mouse = true; print("debug enabled.\n"); - // LED flash - DDRD |= (1<<6); PORTD |= (1<<6); - _delay_ms(500); + // LED off DDRD |= (1<<6); PORTD &= ~(1<<6); - - uint16_t handler_id2 = adb_host_talk(ADB_ADDR_KEYBOARD, 3); - xprintf("handler_id: %02X -> %02X\n", (handler_id & 0xff), (handler_id2 & 0xff)); - return; } @@ -192,7 +216,50 @@ uint8_t matrix_scan(void) if ( codes == 0xFFFF ) { _delay_ms(12); // delay for preventing overload of poor ADB keyboard controller - codes = adb_host_kbd_recv(); + codes = adb_host_kbd_recv(ADB_ADDR_KEYBOARD); + + // Adjustable keybaord media keys + if (codes == 0 && has_media_keys && + (codes = adb_host_kbd_recv(ADB_ADDR_APPLIANCE))) { + // key1 + switch (codes & 0x7f ) { + case 0x00: // Mic + codes = (codes & ~0x007f) | 0x42; + break; + case 0x01: // Mute + codes = (codes & ~0x007f) | 0x4a; + break; + case 0x02: // Volume down + codes = (codes & ~0x007f) | 0x49; + break; + case 0x03: // Volume Up + codes = (codes & ~0x007f) | 0x48; + break; + case 0x7F: // no code + break; + default: + xprintf("ERROR: media key1\n"); + return 0x11; + } + // key0 + switch ((codes >> 8) & 0x7f ) { + case 0x00: // Mic + codes = (codes & ~0x7f00) | (0x42 << 8); + break; + case 0x01: // Mute + codes = (codes & ~0x7f00) | (0x4a << 8); + break; + case 0x02: // Volume down + codes = (codes & ~0x7f00) | (0x49 << 8); + break; + case 0x03: // Volume Up + codes = (codes & ~0x7f00) | (0x48 << 8); + break; + default: + xprintf("ERROR: media key0\n"); + return 0x10; + } + } } key0 = codes>>8; key1 = codes&0xFF;