summaryrefslogtreecommitdiffstats
path: root/keyboards/converter
diff options
context:
space:
mode:
authorPeter Roe <pete@13bit.me>2018-10-23 20:52:57 +0200
committerDrashna Jaelre <drashna@live.com>2018-10-23 20:52:57 +0200
commit03d16db942fe0352cc3b3522a1c778b7e60a4b3a (patch)
treeab40e6c3849effc66a77f619c718efbe7704fd29 /keyboards/converter
parent572c316e7dfb0bcd495ce09e068078593fd4ec82 (diff)
downloadqmk_firmware-03d16db942fe0352cc3b3522a1c778b7e60a4b3a.tar.gz
qmk_firmware-03d16db942fe0352cc3b3522a1c778b7e60a4b3a.tar.xz
Keyboard: Ported ADB-to-USB converter from TMK to QMK (#3931)
* Ported ADB-to-USB converter from TMK to QMK * Updated pull request with reviewer suggestions. * Removed precompiled header file type (gch) from gitignore per reviewer request * Update keyboards/converter/adb_usb/matrix.c Changed instances of matrix_init_quantum to matrix_scan_quantum. * Update keyboards/converter/adb_usb/matrix.c Co-Authored-By: 13-bit <pete@13bit.me>
Diffstat (limited to 'keyboards/converter')
-rw-r--r--keyboards/converter/adb_usb/README.md83
-rw-r--r--keyboards/converter/adb_usb/adb_usb.c3
-rw-r--r--keyboards/converter/adb_usb/adb_usb.h109
-rw-r--r--keyboards/converter/adb_usb/config.h43
-rw-r--r--keyboards/converter/adb_usb/keymaps/13bit/keymap.c26
-rw-r--r--keyboards/converter/adb_usb/keymaps/default/keymap.c13
-rw-r--r--keyboards/converter/adb_usb/led.c27
-rw-r--r--keyboards/converter/adb_usb/led.h43
-rw-r--r--keyboards/converter/adb_usb/matrix.c267
-rw-r--r--keyboards/converter/adb_usb/rules.mk73
10 files changed, 687 insertions, 0 deletions
diff --git a/keyboards/converter/adb_usb/README.md b/keyboards/converter/adb_usb/README.md
new file mode 100644
index 000000000..ed7175008
--- /dev/null
+++ b/keyboards/converter/adb_usb/README.md
@@ -0,0 +1,83 @@
+ADB-to USB Keyboard Converter
+=============================
+This firmware converts Apple Desktop Bus (ADB) keyboard protocol to USB so that you can use an ADB keyboard on a modern computer. It works on the PJRC Teensy 2.0 and other USB AVR MCUs (ATMega32U4, AT90USB64/128, etc) and needs at least 10KB of flash memory.
+
+
+This is a port of the TMK ADB-to-USB converter to QMK. For information on QMK, please consult the following:
+https://github.com/qmk/qmk_firmware
+https://docs.qmk.fm
+
+
+Wiring
+------
+Connect the VCC, GND, and DATA lines of the ADB keyboard to the controller (Teensy 2.0 or similar). By default the DATA line uses port PD0. The Power SW line is unused by the converter.
+
+ADB female socket from the front:
+
+ ,--_--.
+ / o4 3o \ 1: DATA
+ | o2 1o | 2: Power SW
+ - === - 3: VCC
+ `-___-' 4: GND
+
+This converter uses AVR's internal pull-up, but it seems to be too weak, in particular when you want to use a long or coiled cable. Using an external pull-up resistor (1K-10K Ohm) between the DATA and VCC lines is strongly recommended.
+
+Pull-up resistor:
+
+ Keyboard Converter
+ ,------.
+ 5V------+------|VCC |
+ | | |
+ [R] | |
+ | | |
+ Signal--+------|PD0 |
+ | |
+ GND------------|GND |
+ `------'
+ R: 1K Ohm resistor
+
+
+Define following macros for ADB connection in config.h if you use other than port PD0.
+
+ ADB_PORT, ADB_PIN, ADB_DDR, ADB_DATA_BIT
+
+
+Building the Firmware
+------------------------------------------
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+
+Keymap
+------
+To build the default keymap run this command:
+
+ $ make converter/adb_usb:default
+
+You may add your own keymap to the converter/adb_usb/keymaps directory, as you would with any other QMK-powered keyboard.
+
+To build your custom keymap, change the build command to:
+
+ $ make converter/adb_usb:my_keymap
+
+Where 'my_keymap' is the name of your custom keymap directory.
+
+
+Locking Caps Lock
+----------------
+Many old ADB keyboards use a locking switch for the caps lock key. This converter supports the locking caps lock key by default.
+
+
+Notes
+-----
+Non-extended ADB keyboards make no distinction between the left and right modifiers,
+i.e. the keycode for the left modifier will be sent even if the right modifier
+
+The Apple Extended Keyboard and Apple Extended Keyboard II can differentiate between the left and right modifiers except for the GUI key (Windows/Command).
+
+Most ADB keyboards have no diodes in its matrix so they are not NKRO,
+though the ADB protocol itself supports it. See protocol/adb.c for more info.
+
+
+QMK Port Changelog
+---------
+- 2018/09/16 - Initial release.
diff --git a/keyboards/converter/adb_usb/adb_usb.c b/keyboards/converter/adb_usb/adb_usb.c
new file mode 100644
index 000000000..7026d6275
--- /dev/null
+++ b/keyboards/converter/adb_usb/adb_usb.c
@@ -0,0 +1,3 @@
+#include "adb_usb.h"
+#include <avr/io.h>
+#include "quantum.h"
diff --git a/keyboards/converter/adb_usb/adb_usb.h b/keyboards/converter/adb_usb/adb_usb.h
new file mode 100644
index 000000000..491db95f1
--- /dev/null
+++ b/keyboards/converter/adb_usb/adb_usb.h
@@ -0,0 +1,109 @@
+/*
+Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Ported to QMK by Peter Roe <pete@13bit.me>
+*/
+
+#ifndef KEYMAP_COMMON_H
+#define KEYMAP_COMMON_H
+
+#include "quantum.h"
+
+/* M0115/M3501 Apple Extended Keyboard ANSI
+ * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,---.
+ * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|
+ * `---' `---------------' `---------------' `---------------' `-----------' `---'
+ * ,-----------------------------------------------------------. ,-----------. ,---------------.
+ * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| =| /| *|
+ * |-----------------------------------------------------------| |-----------| |---------------|
+ * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 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| ,| ,| /|Shift | |Up | | 1| 2| 3| |
+ * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
+ * |Ctrl |Opt |Cmd | Space | |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| |
+ * `-----------------------------------------------------------' `-----------' `---------------'
+ */
+#define LAYOUT_ext_ansi( \
+ K35, K7A,K78,K63,K76,K60,K61,K62,K64,K65,K6D,K67,K6F, K69,K6B,K71, 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,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 \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07 }, \
+ { K08, K09, KC_NO, K0B, K0C, K0D, K0E, K0F }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17 }, \
+ { K18, K19, K1A, K1B, K1C, K1D, K1E, K1F }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27 }, \
+ { K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \
+ { K30, K31, K32, K33, KC_NO, K35, K36, K37 }, \
+ { K38, K39, K3A, K3B, K3C, K3D, K3E, KC_NO, }, \
+ { KC_NO, K41, KC_NO, K43, KC_NO, K45, KC_NO, K47 }, \
+ { KC_NO, KC_NO, KC_NO, K4B, K4C, KC_NO, K4E, KC_NO, }, \
+ { KC_NO, KC_NO, K52, K53, K54, K55, K56, K57 }, \
+ { K58, K59, KC_NO, K5B, K5C, KC_NO, KC_NO, KC_NO, }, \
+ { K60, K61, K62, K63, K64, K65, KC_NO, K67 }, \
+ { KC_NO, K69, KC_NO, K6B, KC_NO, K6D, KC_NO, K6F }, \
+ { KC_NO, K71, K72, K73, K74, K75, K76, K77 }, \
+ { K78, K79, K7A, K7B, K7C, K7D, KC_NO, K7F } \
+}
+
+/* M0116 Apple Standard Keyboard ANSI
+ * +-------+
+ * | power |
+ * +-------+
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+-----+ +---+---+---+---+
+ * |esc| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | bks | |clr| = | / | * |
+ * +---------------------------------------------------------+ +---+---+---+---+
+ * | tab | q | w | e | r | t | y | u | i | o | p | [ | ] | | | 7 | 8 | 9 | + |
+ * +-----------------------------------------------------+ | +---+---+---+---+
+ * | ctrl | a | s | d | f | g | h | j | k | l | ; | ' |return| | 4 | 5 | 6 | - |
+ * +---------------------------------------------------------+ +---+---+---+---+
+ * | shift | z | x | c | v | b | n | m | , | . | / | shift | | 1 | 2 | 3 | |
+ * +---------------------------------------------------------+ +-------+---|ent|
+ * |cap|opt|comnd| ` | | \ |lef|rig|dwn|up | | 0 | . | |
+ * +---------------------------------------------------------+ +-------+---+---+
+ */
+#define LAYOUT_m0116_ansi( \
+ K7F, \
+ K35,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K47,K51,K4B,K43, \
+ K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E, K59,K5B,K5C,K45, \
+ K36,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27, K24, K56,K57,K58,K4E, \
+ K38,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C, K7B, K53,K54,K55, \
+ K39,K3A,K37,K32, K31, K2A,K3B,K3C,K3D,K3E, K52, K41,K4C \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07 }, \
+ { K08, K09, KC_NO, K0B, K0C, K0D, K0E, K0F }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17 }, \
+ { K18, K19, K1A, K1B, K1C, K1D, K1E, K1F }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27 }, \
+ { K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \
+ { K30, K31, K32, K33, KC_NO, K35, K36, K37 }, \
+ { K38, K39, K3A, K3B, K3C, K3D, K3E, KC_NO }, \
+ { KC_NO, K41, KC_NO, K43, KC_NO, K45, KC_NO, K47 }, \
+ { KC_NO, KC_NO, KC_NO, K4B, K4C, KC_NO, K4E, KC_NO }, \
+ { KC_NO, K51, K52, K53, K54, K55, K56, K57 }, \
+ { K58, K59, KC_NO, K5B, K5C, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, K7B, KC_NO, KC_NO, KC_NO, K7F } \
+}
+
+#endif
diff --git a/keyboards/converter/adb_usb/config.h b/keyboards/converter/adb_usb/config.h
new file mode 100644
index 000000000..a5845a029
--- /dev/null
+++ b/keyboards/converter/adb_usb/config.h
@@ -0,0 +1,43 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Ported to QMK by Peter Roe <pete@13bit.me>
+*/
+
+#pragma once
+
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x0ADB
+#define DEVICE_VER 0x0101
+#define MANUFACTURER QMK
+#define PRODUCT ADB keyboard converter
+#define DESCRIPTION Convert ADB keyboard to USB
+
+/* matrix size */
+#define MATRIX_ROWS 16 // keycode bit: 3-0
+#define MATRIX_COLS 8 // keycode bit: 6-4
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+/* ADB port setting */
+#define ADB_PORT PORTD
+#define ADB_PIN PIND
+#define ADB_DDR DDRD
+#define ADB_DATA_BIT 0
+//#define ADB_PSW_BIT 1 // optional
diff --git a/keyboards/converter/adb_usb/keymaps/13bit/keymap.c b/keyboards/converter/adb_usb/keymaps/13bit/keymap.c
new file mode 100644
index 000000000..3b36a20c2
--- /dev/null
+++ b/keyboards/converter/adb_usb/keymaps/13bit/keymap.c
@@ -0,0 +1,26 @@
+#include QMK_KEYBOARD_H
+
+#define MCTL LCTL(KC_UP)
+#define SCST LSFT(LGUI(KC_4))
+#define SLP LALT(LGUI(KC_EJCT))
+
+#define APP1 LSFT(LALT(LCTL(LGUI(KC_1))))
+#define APP2 LSFT(LALT(LCTL(LGUI(KC_2))))
+#define APP3 LSFT(LALT(LCTL(LGUI(KC_3))))
+#define APP4 LSFT(LALT(LCTL(LGUI(KC_4))))
+#define APP5 LSFT(LALT(LCTL(LGUI(KC_5))))
+#define APP6 LSFT(LALT(LCTL(LGUI(KC_6))))
+#define APP7 LSFT(LALT(LCTL(LGUI(KC_7))))
+#define APP8 LSFT(LALT(LCTL(LGUI(KC_8))))
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ LAYOUT_ext_ansi(
+ KC_ESC, APP1, APP2, APP3, APP4, APP5, APP6, APP7, APP8, MCTL, KC_MUTE, KC_VOLD, KC_VOLU, SCST, KC_SLCK, KC_PAUS, SLP,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, KC_NLCK, KC_EQL, KC_PSLS, KC_PAST,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, KC_P7, KC_P8, KC_P9, KC_PMNS,
+ KC_LCAP, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3,
+ KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT, KC_PENT
+ ),
+};
diff --git a/keyboards/converter/adb_usb/keymaps/default/keymap.c b/keyboards/converter/adb_usb/keymaps/default/keymap.c
new file mode 100644
index 000000000..6b63c1a3c
--- /dev/null
+++ b/keyboards/converter/adb_usb/keymaps/default/keymap.c
@@ -0,0 +1,13 @@
+#include QMK_KEYBOARD_H
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ LAYOUT_ext_ansi(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR,KC_SLCK,KC_PAUS, KC_EJCT,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, KC_NLCK, KC_EQL, KC_PSLS, KC_PAST,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, KC_P7, KC_P8, KC_P9, KC_PMNS,
+ KC_LCAP, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3,
+ KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT, KC_PENT
+ ),
+};
diff --git a/keyboards/converter/adb_usb/led.c b/keyboards/converter/adb_usb/led.c
new file mode 100644
index 000000000..ea9bf77b5
--- /dev/null
+++ b/keyboards/converter/adb_usb/led.c
@@ -0,0 +1,27 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <util/delay.h>
+#include "adb.h"
+#include "led.h"
+
+
+void led_set(uint8_t usb_led)
+{
+ adb_host_kbd_led(ADB_ADDR_KEYBOARD, ~usb_led);
+}
diff --git a/keyboards/converter/adb_usb/led.h b/keyboards/converter/adb_usb/led.h
new file mode 100644
index 000000000..19952fae2
--- /dev/null
+++ b/keyboards/converter/adb_usb/led.h
@@ -0,0 +1,43 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Ported to QMK by Peter Roe <pete@13bit.me>
+*/
+
+#ifndef LED_H
+#define LED_H
+#include "stdint.h"
+
+
+/* keyboard LEDs */
+#define USB_LED_NUM_LOCK 0
+#define USB_LED_CAPS_LOCK 1
+#define USB_LED_SCROLL_LOCK 2
+#define USB_LED_COMPOSE 3
+#define USB_LED_KANA 4
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void led_set(uint8_t usb_led);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/keyboards/converter/adb_usb/matrix.c b/keyboards/converter/adb_usb/matrix.c
new file mode 100644
index 000000000..8ee48bf23
--- /dev/null
+++ b/keyboards/converter/adb_usb/matrix.c
@@ -0,0 +1,267 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Ported to QMK by Peter Roe <pete@13bit.me>
+*/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include "print.h"
+#include "util.h"
+#include "debug.h"
+#include "adb.h"
+#include "matrix.h"
+#include "report.h"
+#include "host.h"
+#include "led.h"
+#include "timer.h"
+
+static bool is_iso_layout = false;
+
+// matrix state buffer(1:on, 0:off)
+static matrix_row_t matrix[MATRIX_ROWS];
+
+static void register_key(uint8_t key);
+
+__attribute__ ((weak))
+void matrix_init_kb(void) {
+ matrix_init_user();
+}
+
+__attribute__ ((weak))
+void matrix_scan_kb(void) {
+ matrix_scan_user();
+}
+
+__attribute__ ((weak))
+void matrix_init_user(void) {
+}
+
+__attribute__ ((weak))
+void matrix_scan_user(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(2000);
+
+ // initialize matrix state: all keys off
+ for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
+
+ led_set(host_keyboard_leds());
+
+ // debug_enable = false;
+ // debug_matrix = true;
+ // debug_keyboard = true;
+ // debug_mouse = true;
+ // print("debug enabled.\n");
+
+ // LED off
+ DDRD |= (1<<6); PORTD &= ~(1<<6);
+ matrix_init_quantum();
+}
+
+#ifdef ADB_MOUSE_ENABLE
+
+#ifdef MAX
+#undef MAX
+#endif
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+
+static report_mouse_t mouse_report = {};
+
+void adb_mouse_task(void)
+{
+ uint16_t codes;
+ int16_t x, y;
+ static int8_t mouseacc;
+
+ /* tick of last polling */
+ static uint16_t tick_ms;
+
+ // polling with 12ms interval
+ if (timer_elapsed(tick_ms) < 12) return;
+ tick_ms = timer_read();
+
+ codes = adb_host_mouse_recv();
+ // If nothing received reset mouse acceleration, and quit.
+ if (!codes) {
+ mouseacc = 1;
+ return;
+ };
+ // Bit sixteen is button.
+ if (~codes & (1 << 15))
+ mouse_report.buttons |= MOUSE_BTN1;
+ if (codes & (1 << 15))
+ mouse_report.buttons &= ~MOUSE_BTN1;
+ // lower seven bits are movement, as signed int_7.
+ // low byte is X-axis, high byte is Y.
+ y = (codes>>8 & 0x3F);
+ x = (codes>>0 & 0x3F);
+ // bit seven and fifteen is negative
+ // usb does not use int_8, but int_7 (measuring distance) with sign-bit.
+ if (codes & (1 << 6))
+ x = (x-0x40);
+ if (codes & (1 << 14))
+ y = (y-0x40);
+ // Accelerate mouse. (They weren't meant to be used on screens larger than 320x200).
+ x *= mouseacc;
+ y *= mouseacc;
+ // Cap our two bytes per axis to one byte.
+ // Easier with a MIN-function, but since -MAX(-a,-b) = MIN(a,b)...
+ // I.E. MIN(MAX(x,-127),127) = -MAX(-MAX(x, -127), -127) = MIN(-MIN(-x,127),127)
+ mouse_report.x = -MAX(-MAX(x, -127), -127);
+ mouse_report.y = -MAX(-MAX(y, -127), -127);
+ if (debug_mouse) {
+ print("adb_host_mouse_recv: "); print_bin16(codes); print("\n");
+ print("adb_mouse raw: [");
+ phex(mouseacc); print(" ");
+ phex(mouse_report.buttons); print("|");
+ print_decs(mouse_report.x); print(" ");
+ print_decs(mouse_report.y); print("]\n");
+ }
+ // Send result by usb.
+ host_mouse_send(&mouse_report);
+ // increase acceleration of mouse
+ mouseacc += ( mouseacc < ADB_MOUSE_MAXACC ? 1 : 0 );
+ return;
+}
+#endif
+
+uint8_t matrix_scan(void)
+{
+ /* extra_key is volatile and more convoluted than necessary because gcc refused
+ to generate valid code otherwise. Making extra_key uint8_t and constructing codes
+ here via codes = extra_key<<8 | 0xFF; would consistently fail to even LOAD
+ extra_key from memory, and leave garbage in the high byte of codes. I tried
+ dozens of code variations and it kept generating broken assembly output. So
+ beware if attempting to make extra_key code more logical and efficient. */
+ static volatile uint16_t extra_key = 0xFFFF;
+ uint16_t codes;
+ uint8_t key0, key1;
+
+ /* tick of last polling */
+ static uint16_t tick_ms;
+
+ codes = extra_key;
+ extra_key = 0xFFFF;
+
+ if ( codes == 0xFFFF )
+ {
+ // polling with 12ms interval
+ if (timer_elapsed(tick_ms) < 12) return 0;
+ tick_ms = timer_read();
+
+ codes = adb_host_kbd_recv();
+ }
+
+ key0 = codes>>8;
+ key1 = codes&0xFF;
+
+ if (debug_matrix && codes) {
+ print("adb_host_kbd_recv: "); phex16(codes); print("\n");
+ }
+
+ if (codes == 0) { // no keys
+ return 0;
+ } else if (codes == 0x7F7F) { // power key press
+ register_key(0x7F);
+ } else if (codes == 0xFFFF) { // power key release
+ register_key(0xFF);
+ } else if (key0 == 0xFF) { // error
+ xprintf("adb_host_kbd_recv: ERROR(%d)\n", codes);
+ // something wrong or plug-in
+ matrix_init();
+ return key1;
+ } else {
+ /* Swap codes for ISO keyboard
+ * https://github.com/tmk/tmk_keyboard/issues/35
+ *
+ * ANSI
+ * ,----------- ----------.
+ * | *a| 1| 2 =|Backspa|
+ * |----------- ----------|
+ * |Tab | Q| | ]| *c|
+ * |----------- ----------|
+ * |CapsLo| A| '|Return |
+ * |----------- ----------|
+ * |Shift | Shift |
+ * `----------- ----------'
+ *
+ * ISO
+ * ,----------- ----------.
+ * | *a| 1| 2 =|Backspa|
+ * |----------- ----------|
+ * |Tab | Q| | ]|Retur|
+ * |----------- -----` |
+ * |CapsLo| A| '| *c| |
+ * |----------- ----------|
+ * |Shif| *b| Shift |
+ * `----------- ----------'
+ *
+ * ADB scan code USB usage
+ * ------------- ---------
+ * Key ANSI ISO ANSI ISO
+ * ---------------------------------------------
+ * *a 0x32 0x0A 0x35 0x35
+ * *b ---- 0x32 ---- 0x64
+ * *c 0x2A 0x2A 0x31 0x31(or 0x32)
+ */
+ if (is_iso_layout) {
+ if ((key0 & 0x7F) == 0x32) {
+ key0 = (key0 & 0x80) | 0x0A;
+ } else if ((key0 & 0x7F) == 0x0A) {
+ key0 = (key0 & 0x80) | 0x32;
+ }
+ }
+ register_key(key0);
+ if (key1 != 0xFF) // key1 is 0xFF when no second key.
+ extra_key = key1<<8 | 0xFF; // process in a separate call
+ }
+
+ matrix_scan_quantum();
+ return 1;
+}
+
+void matrix_print(void){
+
+}
+
+inline
+matrix_row_t matrix_get_row(uint8_t row)
+{
+ return matrix[row];
+}
+
+inline
+static void register_key(uint8_t key)
+{
+ uint8_t col, row;
+ col = key&0x07;
+ row = (key>>3)&0x0F;
+ if (key&0x80) {
+ matrix[row] &= ~(1<<col);
+ } else {
+ matrix[row] |= (1<<col);
+ }
+}
diff --git a/keyboards/converter/adb_usb/rules.mk b/keyboards/converter/adb_usb/rules.mk
new file mode 100644
index 000000000..3a9b6dedc
--- /dev/null
+++ b/keyboards/converter/adb_usb/rules.mk
@@ -0,0 +1,73 @@
+# MCU name
+# atmega32u4 Teensy2.0
+# atemga32u4 TMK Converter rev.1
+# atemga32u2 TMK Converter rev.2
+MCU = atmega32u4
+
+# Processor frequency.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+# automatically to create a 32-bit value in your source code.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
+#
+F_CPU = 16000000
+# F_CPU = 8000000
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+# Bootloader
+# This definition is optional, and if your keyboard supports multiple bootloaders of
+# different sizes, comment this out, and the correct address will be loaded
+# automatically (+60). See bootloader.mk for all options.
+BOOTLOADER = caterina
+
+# Boot Section Size in *bytes*
+# Teensy halfKay 512
+# Teensy++ halfKay 1024
+# Atmel DFU loader 4096 for TMK Converter rev.1/rev.2
+# LUFA bootloader 4096
+# USBaspLoader 2048
+
+# Build Options
+# comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = no # Mouse keys(+4700)
+CONSOLE_ENABLE = no # Console for debug(+400)
+COMMAND_ENABLE = no # Commands for debug and configuration
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+NKRO_ENABLE = no # USB Nkey Rollover - not yet supported in LUFA
+EXTRAKEY_ENABLE = yes
+USB_HID_ENABLE = yes
+BACKLIGHT_ENABLE = no
+#BLUETOOTH = AdafruitBLE # For Adafruit Feather 32U4 BLE support, uncomment this line
+
+CUSTOM_MATRIX = yes
+SRC = matrix.c \
+ adb.c