From 6d7745a110daad815fe5edbb35a2e33702f24aaa Mon Sep 17 00:00:00 2001 From: markspanbroek Date: Mon, 22 Oct 2018 21:37:03 +0200 Subject: Keyboard: Port of TMK XT USB Converter (#3619) * 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 --- keyboards/converter/xt_usb/matrix.c | 309 ++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 keyboards/converter/xt_usb/matrix.c (limited to 'keyboards/converter/xt_usb/matrix.c') diff --git a/keyboards/converter/xt_usb/matrix.c b/keyboards/converter/xt_usb/matrix.c new file mode 100644 index 0000000000..e2d7117b13 --- /dev/null +++ b/keyboards/converter/xt_usb/matrix.c @@ -0,0 +1,309 @@ +/* +Copyright 2011 Jun Wako +Copyright 2016 Ethan Apodaca + +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 . +*/ + +#include +#include +#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<