]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Keyboard: Port of TMK XT USB Converter (#3619)
authormarkspanbroek <mark@spanbroek.net>
Mon, 22 Oct 2018 19:37:03 +0000 (21:37 +0200)
committerDrashna Jaelre <drashna@live.com>
Mon, 22 Oct 2018 19:37:03 +0000 (12:37 -0700)
* Converter: add XT USB converter from TMK

* Converter: port TMK code for USB converter to QMK

* Apply requested changes after code review by @drashna

- use "pragma once" instead of include guards
- use LAYOUT instead of KEYMAP
- allow customisation with matrix_init_user() and matrix_scan_user()
- set BOOTLOADER instead of BOOTLOADER_SIZE
- Add XT_ENABLE to OPT_DEFS

* Remove unnecessary lines

12 files changed:
keyboards/converter/xt_usb/README.md [new file with mode: 0644]
keyboards/converter/xt_usb/config.h [new file with mode: 0644]
keyboards/converter/xt_usb/keymaps/default/config.h [new file with mode: 0644]
keyboards/converter/xt_usb/keymaps/default/keymap.c [new file with mode: 0644]
keyboards/converter/xt_usb/led.c [new file with mode: 0644]
keyboards/converter/xt_usb/matrix.c [new file with mode: 0644]
keyboards/converter/xt_usb/rules.mk [new file with mode: 0644]
keyboards/converter/xt_usb/xt_usb.c [new file with mode: 0644]
keyboards/converter/xt_usb/xt_usb.h [new file with mode: 0644]
tmk_core/protocol.mk
tmk_core/protocol/xt.h [new file with mode: 0644]
tmk_core/protocol/xt_interrupt.c [new file with mode: 0644]

diff --git a/keyboards/converter/xt_usb/README.md b/keyboards/converter/xt_usb/README.md
new file mode 100644 (file)
index 0000000..40b265a
--- /dev/null
@@ -0,0 +1,17 @@
+XT to USB keyboard converter
+==============================
+This is a port of TMK's converter/xt_usb to QMK.
+
+This firmware converts XT keyboard protocol to USB.(It supports Scan Code Set 1.)
+
+
+Connect Wires
+-------------
+1. Connect **Vcc** and **GND**.
+2. Connect **Clock** and **Data** line. **Clock** is on `PD1`,  **Data** on `PD0` by default. And optionally you can use `PB7` for **Reset**.(Compatible to Soarer's converter) To change pin configuration edit `config.h`.
+3. You need pull-up resistor. **1K-10K Ohm** will be OK.
+
+
+XT keyboard protocol  resource
+------------------------------
+https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol
diff --git a/keyboards/converter/xt_usb/config.h b/keyboards/converter/xt_usb/config.h
new file mode 100644 (file)
index 0000000..963a3c6
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+Copyright 2012 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/>.
+*/
+
+#pragma once
+
+#define VENDOR_ID       0xFEED
+#define PRODUCT_ID      0x6512
+#define DEVICE_VER      0x0001
+#define MANUFACTURER    QMK
+#define PRODUCT         XT keyboard converter
+#define DESCRIPTION     convert XT keyboard to USB
+
+
+/* matrix size */
+#define MATRIX_ROWS 16  // keycode bit: 3-0
+#define MATRIX_COLS 8   // keycode bit: 6-4
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) || \
+    keyboard_report->mods == (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RSHIFT)) \
+)
+
+
+//#define NO_SUSPEND_POWER_DOWN
+
+/*
+ * XT Pin interrupt
+ */
+#define XT_CLOCK_PORT  PORTD
+#define XT_CLOCK_PIN   PIND
+#define XT_CLOCK_DDR   DDRD
+#define XT_CLOCK_BIT   1
+#define XT_DATA_PORT   PORTD
+#define XT_DATA_PIN    PIND
+#define XT_DATA_DDR    DDRD
+#define XT_DATA_BIT    0
+#define XT_RST_PORT    PORTB
+#define XT_RST_PIN     PINB
+#define XT_RST_DDR     DDRB
+#define XT_RST_BIT     7
+
+/* hard reset: low pulse for 500ms and after that HiZ for safety */
+#define XT_RESET() do { \
+    XT_RST_PORT &= ~(1<<XT_RST_BIT);  \
+    XT_RST_DDR  |=  (1<<XT_RST_BIT);  \
+    _delay_ms(500);                   \
+    XT_RST_DDR  &= ~(1<<XT_RST_BIT);  \
+} while (0)
+
+/* INT1 for falling edge of clock line */
+#define XT_INT_INIT()  do {    \
+    EICRA |= ((1<<ISC11) |      \
+              (0<<ISC10));      \
+} while (0)
+/* clears flag and enables interrupt */
+#define XT_INT_ON()  do {      \
+    EIFR  |= (1<<INTF1);        \
+    EIMSK |= (1<<INT1);         \
+} while (0)
+#define XT_INT_OFF() do {      \
+    EIMSK &= ~(1<<INT1);        \
+} while (0)
+#define XT_INT_VECT    INT1_vect
diff --git a/keyboards/converter/xt_usb/keymaps/default/config.h b/keyboards/converter/xt_usb/keymaps/default/config.h
new file mode 100644 (file)
index 0000000..6f70f09
--- /dev/null
@@ -0,0 +1 @@
+#pragma once
diff --git a/keyboards/converter/xt_usb/keymaps/default/keymap.c b/keyboards/converter/xt_usb/keymaps/default/keymap.c
new file mode 100644 (file)
index 0000000..3ef6060
--- /dev/null
@@ -0,0 +1,55 @@
+#include QMK_KEYBOARD_H
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+    /* IBM XT keyboard layout
+     * ,-------.  ,--------------------------------------------------------------------------.
+     * | F1| F2|  |Esc|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|  BS  |NumLck |ScrLck |
+     * |-------|  |--------------------------------------------------------------------------|
+     * | F3| F4|  | Tab |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ] |   |  7|  8|  9|  -|
+     * |-------|  |------------------------------------------------------|Ent|---------------|
+     * | F5| F6|  | Ctrl |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  `|   |  4|  5|  6|   |
+     * |-------|  |----------------------------------------------------------------------|   |
+     * | F7| F8|  |Shif|  \|  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /|Shift|PrS|  1|  2|  3|  +|
+     * |-------|  |----------------------------------------------------------------------|   |
+     * | F9|F10|  |  Alt  |               Space                  |CapsLck|   0   |   .   |   |
+     * `-------'  `--------------------------------------------------------------------------'
+     */
+    LAYOUT_xt( \
+    KC_F1,  KC_F2,    KC_ESC, 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_NLCK,      KC_SLCK,
+    KC_F3,  KC_F4,    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_P7,  KC_P8,  KC_P9,  KC_PMNS,
+    KC_F5,  KC_F6,    KC_LCTL,KC_A,   KC_S,   KC_D,   KC_F,   KC_G,   KC_H,   KC_J,   KC_K,   KC_L,   KC_SCLN,KC_QUOT,KC_GRV, KC_ENT, KC_P4,  KC_P5,  KC_P6,
+    KC_F7,  KC_F8,    KC_LSFT,KC_BSLS,KC_Z,   KC_X,   KC_C,   KC_V,   KC_B,   KC_N,   KC_M,   KC_COMM,KC_DOT, KC_SLSH,KC_RSFT,KC_PSCR,KC_P1,  KC_P2,  KC_P3,  KC_PPLS,
+    KC_F9,  KC_F10,   KC_LALT,                                    KC_SPC,                                       KC_CAPS,          KC_P0,          KC_PDOT
+    ),
+
+    /* Extended keyboard layout
+     *         ,-----------------------------------------------.
+     *         |F13|F14|F15|F16|F17|F18|F19|F20|F21|F22|F23|F24|
+     * ,---.   |-----------------------------------------------|     ,-----------.     ,-----------.
+     * |Esc|   |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|     |PrS|ScL|Pau|     |VDn|VUp|Mut|
+     * `---'   `-----------------------------------------------'     `-----------'     `-----------'
+     * ,-----------------------------------------------------------. ,-----------. ,---------------.
+     * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|JPY|Bsp| |Ins|Hom|PgU| |NmL|  /|  *|  -|
+     * |-----------------------------------------------------------| |-----------| |---------------|
+     * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \  | |Del|End|PgD| |  7|  8|  9|  +|
+     * |-----------------------------------------------------------| `-----------' |---------------|
+     * |CapsL |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  #|Entr|               |  4|  5|  6|KP,|
+     * |-----------------------------------------------------------|     ,---.     |---------------|
+     * |Shft|  <|  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /| RO|Shift |     |Up |     |  1|  2|  3|KP=|
+     * |-----------------------------------------------------------| ,-----------. |---------------|
+     * |Ctl|Gui|Alt|MHEN|     Space      |HENK|KANA|Alt|Gui|App|Ctl| |Lef|Dow|Rig| |      0|  .|Ent|
+     * `-----------------------------------------------------------' `-----------' `---------------'
+     */
+    /* Try this if your keyboad has exotic keys.
+    LAYOUT(
+                 KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, KC_F22, KC_F23, KC_F24,
+    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_VOLD,KC_VOLU,KC_MUTE,
+    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_JYEN,KC_BSPC,     KC_INS, KC_HOME,KC_PGUP,    KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS,
+    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_PPLS,
+    KC_CAPS,KC_A,   KC_S,   KC_D,   KC_F,   KC_G,   KC_H,   KC_J,   KC_K,   KC_L,   KC_SCLN,KC_QUOT,        KC_NUHS,KC_ENT,                                  KC_P4,  KC_P5,  KC_P6,  KC_PCMM,
+    KC_LSFT,KC_NUBS,KC_Z,   KC_X,   KC_C,   KC_V,   KC_B,   KC_N,   KC_M,   KC_COMM,KC_DOT, KC_SLSH,        KC_RO,  KC_RSFT,             KC_UP,              KC_P1,  KC_P2,  KC_P3,  KC_PENT,
+    KC_LCTL,KC_LGUI,KC_LALT,KC_MHEN,          KC_SPC,                       KC_HENK,KC_KANA,KC_RALT,KC_RGUI,KC_APP, KC_RCTL,     KC_LEFT,KC_DOWN,KC_RGHT,            KC_P0,  KC_PDOT,KC_PEQL
+    ),
+    */
+};
diff --git a/keyboards/converter/xt_usb/led.c b/keyboards/converter/xt_usb/led.c
new file mode 100644 (file)
index 0000000..6fa0770
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+Copyright 2016 Ethan Apodaca <papodaca@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 "led.h"
+
+void led_set(uint8_t usb_led) {
+  //XT Keyboards do not have LEDs, nothing to do.
+}
diff --git a/keyboards/converter/xt_usb/matrix.c b/keyboards/converter/xt_usb/matrix.c
new file mode 100644 (file)
index 0000000..e2d7117
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+Copyright 2016 Ethan Apodaca <papodaca@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 <stdbool.h>
+#include "action.h"
+#include "print.h"
+#include "util.h"
+#include "debug.h"
+#include "xt.h"
+#include "matrix.h"
+
+
+static void matrix_make(uint8_t code);
+static void matrix_break(uint8_t code);
+
+static uint8_t matrix[MATRIX_ROWS];
+#define ROW(code)      (code>>3)
+#define COL(code)      (code&0x07)
+
+__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)
+{
+    debug_enable = true;
+    xt_host_init();
+
+    // initialize matrix state: all keys off
+    for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
+
+    matrix_init_quantum();
+}
+
+// convert E0-escaped codes into unused area
+static uint8_t move_e0code(uint8_t code) {
+    switch(code) {
+        // Original IBM XT keyboard has these keys
+        case 0x37: return 0x54; // Print Screen
+        case 0x46: return 0x55; // Ctrl + Pause
+        case 0x1C: return 0x6F; // Keypad Enter
+        case 0x35: return 0x7F; // Keypad /
+
+        // Any XT keyobard with these keys?
+        // http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
+        // https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
+        case 0x5B: return 0x5A; // Left  GUI
+        case 0x5C: return 0x5B; // Right GUI
+        case 0x5D: return 0x5C; // Application
+        case 0x5E: return 0x5D; // Power(not used)
+        case 0x5F: return 0x5E; // Sleep(not used)
+        case 0x63: return 0x5F; // Wake (not used)
+        case 0x48: return 0x60; // Up
+        case 0x4B: return 0x61; // Left
+        case 0x50: return 0x62; // Down
+        case 0x4D: return 0x63; // Right
+        case 0x52: return 0x71; // Insert
+        case 0x53: return 0x72; // Delete
+        case 0x47: return 0x74; // Home
+        case 0x4F: return 0x75; // End
+        case 0x49: return 0x77; // Home
+        case 0x51: return 0x78; // End
+        case 0x1D: return 0x7A; // Right Ctrl
+        case 0x38: return 0x7C; // Right Alt
+    }
+    return 0x00;
+}
+
+uint8_t matrix_scan(void)
+{
+    static enum {
+        INIT,
+        E0,
+        // Pause: E1 1D 45, E1 9D C5
+        E1,
+        E1_1D,
+        E1_9D,
+    } state = INIT;
+
+    uint8_t code = xt_host_recv();
+    if (!code) return 0;
+    xprintf("%02X ", code);
+    switch (state) {
+        case INIT:
+            switch (code) {
+                case 0xE0:
+                    state = E0;
+                    break;
+                case 0xE1:
+                    state = E1;
+                    break;
+                default:
+                    if (code < 0x80)
+                        matrix_make(code);
+                    else
+                        matrix_break(code & 0x7F);
+                    break;
+            }
+            break;
+        case E0:
+            switch (code) {
+                case 0x2A:
+                case 0xAA:
+                case 0x36:
+                case 0xB6:
+                    //ignore fake shift
+                    state = INIT;
+                    break;
+                default:
+                    if (code < 0x80)
+                        matrix_make(move_e0code(code));
+                    else
+                        matrix_break(move_e0code(code & 0x7F));
+                    state = INIT;
+                    break;
+            }
+            break;
+        case E1:
+            switch (code) {
+                case 0x1D:
+                    state = E1_1D;
+                    break;
+                case 0x9D:
+                    state = E1_9D;
+                    break;
+                default:
+                    state = INIT;
+                    break;
+            }
+            break;
+        case E1_1D:
+            switch (code) {
+                case 0x45:
+                    matrix_make(0x55);
+                    break;
+                default:
+                    state = INIT;
+                    break;
+            }
+            break;
+        case E1_9D:
+            switch (code) {
+                case 0x45:
+                    matrix_break(0x55);
+                    break;
+                default:
+                    state = INIT;
+                    break;
+            }
+            break;
+        default:
+            state = INIT;
+    }
+    matrix_scan_quantum();
+    return 1;
+}
+
+inline
+uint8_t matrix_get_row(uint8_t row)
+{
+    return matrix[row];
+}
+
+inline
+static void matrix_make(uint8_t code)
+{
+    if (!matrix_is_on(ROW(code), COL(code))) {
+        matrix[ROW(code)] |= 1<<COL(code);
+    }
+}
+
+inline
+static void matrix_break(uint8_t code)
+{
+    if (matrix_is_on(ROW(code), COL(code))) {
+        matrix[ROW(code)] &= ~(1<<COL(code));
+    }
+}
+
+void matrix_clear(void)
+{
+    for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
+}
+
+bool matrix_is_on(uint8_t row, uint8_t col)
+{
+    return (matrix_get_row(row) & (1<<col));
+}
+
+#if (MATRIX_COLS <= 8)
+#    define print_matrix_header()  print("\nr/c 01234567\n")
+#    define print_matrix_row(row)  print_bin_reverse8(matrix_get_row(row))
+#elif (MATRIX_COLS <= 16)
+#    define print_matrix_header()  print("\nr/c 0123456789ABCDEF\n")
+#    define print_matrix_row(row)  print_bin_reverse16(matrix_get_row(row))
+#elif (MATRIX_COLS <= 32)
+#    define print_matrix_header()  print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
+#    define print_matrix_row(row)  print_bin_reverse32(matrix_get_row(row))
+#endif
+
+void matrix_print(void)
+{
+    print_matrix_header();
+
+    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+        phex(row); print(": ");
+        print_matrix_row(row);
+        print("\n");
+    }
+}
+
+/*
+XT Scancodes
+============
+- http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
+- https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
+
+01-53: Normal codes used in original XT keyboard
+54-7F: Not used in original XT keyboard
+
+       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    50  -   -   -   -   *   *   x   x   x   x   *   *   *   o   o   o
+    60  *   *   *   *   x   x   x   x   x   x   x   x   x   x   x   *
+    70  x   *   *   x   *   *   x   *   *   x   *   x   *   x   x   *
+
+-: codes existed in original XT keyboard
+*: E0-escaped codes converted into unused code area(internal use in TMK)
+x: Non-espcaped codes(not used in real keyboards probably, for CodeSet2-CodeSet1 translation purpose)
+o: reserved
+
+Usage in TMK:
+
+    00  (reserved) DO NOT USE
+    54  PrintScr*
+    55  Pause*
+    56  Euro2
+    57  F11
+    58  F12
+    59  Keypad =
+    5A  LGUI*
+    5B  RGUI*
+    5C  APP*
+    5D  (reserved)
+    5E  (reserved)
+    5F  (reserved)
+    60  cursor*
+    61  cursor*
+    62  cursor*
+    63  cursor*
+    64  F13
+    65  F14
+    66  F15
+    67  F16
+    68  F17
+    69  F18
+    6A  F19
+    6B  F20
+    6C  F21
+    6D  F22
+    6E  F23
+    6F  Keypad Enter*
+    70  KANA
+    71  nav*
+    72  nav*
+    73  RO
+    74  nav*
+    75  nav*
+    76  F24
+    77  nav*
+    78  nav*
+    79  HENKAN
+    7A  RCTL*
+    7B  MUHENKAN
+    7C  RALT*
+    7D  JPY
+    7E  Keypad ,
+    7F  Keypad / *
+
+*/
diff --git a/keyboards/converter/xt_usb/rules.mk b/keyboards/converter/xt_usb/rules.mk
new file mode 100644 (file)
index 0000000..0b8731f
--- /dev/null
@@ -0,0 +1,62 @@
+# MCU name
+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
+
+
+#
+# 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 indicates which bootloader is present on the board.
+# BOOTLOADER = caterina # Pro Micro
+BOOTLOADER = halfkay # Teensy
+
+
+# Build Options
+#   comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = no  # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = yes  # Mouse keys(+4700)
+EXTRAKEY_ENABLE = yes  # Audio control and System control(+450)
+CONSOLE_ENABLE = yes   # Console for debug(+400)
+COMMAND_ENABLE = yes   # Commands for debug and configuration
+NKRO_ENABLE = yes      # USB Nkey Rollover
+XT_ENABLE = yes
+CUSTOM_MATRIX = yes
+
+
+# Optimize size but this may cause error "relocation truncated to fit"
+#EXTRALDFLAGS = -Wl,--relax
+
+SRC = matrix.c led.c
diff --git a/keyboards/converter/xt_usb/xt_usb.c b/keyboards/converter/xt_usb/xt_usb.c
new file mode 100644 (file)
index 0000000..88acee0
--- /dev/null
@@ -0,0 +1 @@
+#include "xt_usb.h"
diff --git a/keyboards/converter/xt_usb/xt_usb.h b/keyboards/converter/xt_usb/xt_usb.h
new file mode 100644 (file)
index 0000000..9785158
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+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/>.
+*/
+#pragma once
+
+#include "quantum.h"
+
+/* IBM XT keyboard layout
+ * ,-------.  ,--------------------------------------------------------------------------.
+ * | F1| F2|  |Esc|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|  BS  |NumLck |ScrLck |
+ * |-------|  |--------------------------------------------------------------------------|
+ * | F3| F4|  | Tab |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ] |   |  7|  8|  9|  -|
+ * |-------|  |------------------------------------------------------|Ent|---------------|
+ * | F5| F6|  | Ctrl |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  `|   |  4|  5|  6|   |
+ * |-------|  |----------------------------------------------------------------------|   |
+ * | F7| F8|  |Shif|  \|  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /|Shift|PrS|  1|  2|  3|  +|
+ * |-------|  |----------------------------------------------------------------------|   |
+ * | F9|F10|  |  Alt  |               Space                  |CapsLck|   0   |   .   |   |
+ * `-------'  `--------------------------------------------------------------------------'
+ * Scan code set 1
+ * ,-------.  ,--------------------------------------------------------------------------.
+ * | 3B| 3C|  | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D|  0E  |  45   |  46   |
+ * |-------|  |--------------------------------------------------------------------------|
+ * | 3D| 3E|  | 0F  | 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B |   | 47| 48| 49| 4A|
+ * |-------|  |------------------------------------------------------| 1C|---------------|
+ * | 3F| 40|  | 1D   | 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29|   | 4B| 4C| 4D|   |
+ * |-------|  |----------------------------------------------------------------------|   |
+ * | 41| 42|  | 2A | 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35|  36 |*37| 4F| 50| 51| 4E|
+ * |-------|  |----------------------------------------------------------------------|   |
+ * | 43| 44|  |  38   |              39                      |  3A   |  52   |  53   |   |
+ * `-------'  `--------------------------------------------------------------------------'
+ */
+#define LAYOUT_xt( \
+    K3B,K3C,  K01,K02,K03,K04,K05,K06,K07,K08,K09,K0A,K0B,K0C,K0D,K0E,    K45,    K46, \
+    K3D,K3E,  K0F,K10,K11,K12,K13,K14,K15,K16,K17,K18,K19,K1A,K1B,    K47,K48,K49,K4A, \
+    K3F,K40,  K1D,K1E,K1F,K20,K21,K22,K23,K24,K25,K26,K27,K28,K29,K1C,K4B,K4C,K4D,     \
+    K41,K42,  K2A,K2B,K2C,K2D,K2E,K2F,K30,K31,K32,K33,K34,K35,K36,K54,K4F,K50,K51,K4E, \
+    K43,K44,  K38,                    K39,                    K3A,    K52,    K53      \
+) { \
+    { KC_NO, K01,   K02,   K03,   K04,   K05,   K06,   K07   }, \
+    { K08,   K09,   K0A,   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,   K34,   K35,   K36,   KC_NO }, \
+    { K38,   K39,   K3A,   K3B,   K3C,   K3D,   K3E,   K3F   }, \
+    { K40,   K41,   K42,   K43,   K44,   K45,   K46,   K47   }, \
+    { K48,   K49,   K4A,   K4B,   K4C,   K4D,   K4E,   K4F   }, \
+    { K50,   K51,   K52,   K53,   K54,   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, 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 }  \
+}
+
+/* Extended keyboard layout
+ *         ,-----------------------------------------------.
+ *         |F13|F14|F15|F16|F17|F18|F19|F20|F21|F22|F23|F24|
+ * ,---.   |-----------------------------------------------|     ,-----------.     ,-----------.
+ * |Esc|   |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|     |PrS|ScL|Pau|     |VDn|VUp|Mut|
+ * `---'   `-----------------------------------------------'     `-----------'     `-----------'
+ * ,-----------------------------------------------------------. ,-----------. ,---------------.
+ * |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|JPY|Bsp| |Ins|Hom|PgU| |NmL|  /|  *|  -|
+ * |-----------------------------------------------------------| |-----------| |---------------|
+ * |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \  | |Del|End|PgD| |  7|  8|  9|  +|
+ * |-----------------------------------------------------------| `-----------' |---------------|
+ * |CapsL |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|  #|Entr|               |  4|  5|  6|KP,|
+ * |-----------------------------------------------------------|     ,---.     |---------------|
+ * |Shft|  <|  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /| RO|Shift |     |Up |     |  1|  2|  3|Ent|
+ * |-----------------------------------------------------------| ,-----------. |---------------|
+ * |Ctl|Gui|Alt|MHEN|     Space      |HENK|KANA|Alt|Gui|App|Ctl| |Lef|Dow|Rig| |      0|  .|KP=|
+ * `-----------------------------------------------------------' `-----------' `---------------'
+ *         ,-----------------------------------------------.
+ *         | 64| 65| 66| 67| 68| 69| 6A| 6B| 6C| 6D| 6E| 76|
+ * ,---.   |-----------------------------------------------|     ,-----------.     ,-----------.
+ * | 01|   | 3B| 3C| 3D| 3E| 3F| 40| 41| 42| 43| 44| 57| 58|     |*37| 46|*45|     |e5E|e5F|e63|
+ * `---'   `-----------------------------------------------'     `-----------'     `-----------'
+ * ,-----------------------------------------------------------. ,-----------. ,---------------.
+ * | 29| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 7D| 0E| |e52|e47|e49| | 45|e35| 37| 4A|
+ * |-----------------------------------------------------------| |-----------| |---------------|
+ * | 0F  | 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B|  2B | |e53|e4F|e51| | 47| 48| 49| 4E|
+ * |-----------------------------------------------------------| `-----------' |---------------|
+ * |  3A  | 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| 00| 1C |               | 4B| 4C| 4D| 7E|
+ * |-----------------------------------------------------------|     ,---.     |---------------|
+ * | 2A | 56| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35| 73|  36  |     |e48|     | 4F| 50| 51|e1C|
+ * |-----------------------------------------------------------| ,-----------. |---------------|
+ * | 1D|e5B| 38| 7B |       39       | 79 | 70 |e38|e5C|e5D|e1D| |e4B|e50|e4D| |     52| 53| 59|
+ * `-----------------------------------------------------------' `-----------' `---------------'
+ * e: E0-escaped codes
+ * *: special handling codes
+ */
+#define LAYOUT( \
+            K64,K65,K66,K67,K68,K69,K6A,K6B,K6C,K6D,K6E,K76,                                     \
+    K01,    K3B,K3C,K3D,K3E,K3F,K40,K41,K42,K43,K44,K57,K58,      K54,K46,K55,      K5D,K5E,K5F, \
+    K29,K02,K03,K04,K05,K06,K07,K08,K09,K0A,K0B,K0C,K0D,K7D,K0E,  K71,K74,K77,  K45,K7F,K37,K4A, \
+    K0F,K10,K11,K12,K13,K14,K15,K16,K17,K18,K19,K1A,K1B,    K2B,  K72,K75,K78,  K47,K48,K49,K4E, \
+    K3A,K1E,K1F,K20,K21,K22,K23,K24,K25,K26,K27,K28,    K00,K1C,                K4B,K4C,K4D,K7E, \
+    K2A,K56,K2C,K2D,K2E,K2F,K30,K31,K32,K33,K34,K35,    K73,K36,      K60,      K4F,K50,K51,K6F, \
+    K1D,K5A,K38,K7B,        K39,        K79,K70,K7C,K5B,K5C,K7A,  K61,K62,K63,      K52,K53,K59  \
+) { \
+    { K00, K01, K02, K03, K04, K05, K06, K07 }, \
+    { K08, K09, K0A, 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, K34, K35, K36, K37 }, \
+    { K38, K39, K3A, K3B, K3C, K3D, K3E, K3F }, \
+    { K40, K41, K42, K43, K44, K45, K46, K47 }, \
+    { K48, K49, K4A, K4B, K4C, K4D, K4E, K4F }, \
+    { K50, K51, K52, K53, K54, K55, K56, K57 }, \
+    { K58, K59, K5A, K5B, K5C, K5D, K5E, K5F }, \
+    { K60, K61, K62, K63, K64, K65, K66, K67 }, \
+    { K68, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \
+    { K70, K71, K72, K73, K74, K75, K76, K77 }, \
+    { K78, K79, K7A, K7B, K7C, K7D, K7E, K7F }  \
+}
index 54913329e69ff0e9c9dcfde2445ad476d455b9c1..78b9deb2971d52f01e8426b76008b4cf548fc591 100644 (file)
@@ -50,5 +50,10 @@ ifdef ADB_MOUSE_ENABLE
         OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE
 endif
 
+ifdef XT_ENABLE
+  SRC += $(PROTOCOL_DIR)/xt_interrupt.c
+  OPT_DEFS += -DXT_ENABLE
+endif
+
 # Search Path
 VPATH += $(TMK_DIR)/protocol
diff --git a/tmk_core/protocol/xt.h b/tmk_core/protocol/xt.h
new file mode 100644 (file)
index 0000000..93bc5da
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+Copyright 2018 Jun WAKO <wakojun@gmail.com>
+Copyright 2016 Ethan Apodaca <papodaca@gmail.com>
+
+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.
+*/
+
+#ifndef XT_H
+#define XT_H
+
+#define XT_DATA_IN()        do { \
+    XT_DATA_DDR  &= ~(1<<XT_DATA_BIT); \
+    XT_DATA_PORT |=  (1<<XT_DATA_BIT); \
+} while (0)
+
+#define XT_DATA_READ()      (XT_DATA_PIN&(1<<XT_DATA_BIT))
+
+#define XT_DATA_LO()        do { \
+    XT_DATA_PORT &= ~(1<<XT_DATA_BIT); \
+    XT_DATA_DDR  |=  (1<<XT_DATA_BIT); \
+} while (0)
+
+
+#define XT_CLOCK_IN()       do { \
+    XT_CLOCK_DDR  &= ~(1<<XT_CLOCK_BIT); \
+    XT_CLOCK_PORT |=  (1<<XT_CLOCK_BIT); \
+} while (0)
+
+#define XT_CLOCK_READ()     (XT_CLOCK_PIN&(1<<XT_CLOCK_BIT))
+
+#define XT_CLOCK_LO()       do { \
+    XT_CLOCK_PORT &= ~(1<<XT_CLOCK_BIT); \
+    XT_CLOCK_DDR  |=  (1<<XT_CLOCK_BIT); \
+} while (0)
+
+
+void xt_host_init(void);
+uint8_t xt_host_recv(void);
+
+#endif
diff --git a/tmk_core/protocol/xt_interrupt.c b/tmk_core/protocol/xt_interrupt.c
new file mode 100644 (file)
index 0000000..3823bbd
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+Copyright 2018 Jun WAKO <wakojun@gmail.com>
+Copyright 2016 Ethan Apodaca <papodaca@gmail.com>
+
+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 <stdbool.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "xt.h"
+#include "wait.h"
+#include "print.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();
+    _delay_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 {
+        print("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;
+}