diff options
| author | tmk <nobody@nowhere> | 2012-06-11 10:53:02 +0900 |
|---|---|---|
| committer | tmk <nobody@nowhere> | 2012-06-11 10:53:02 +0900 |
| commit | 62d1ebb91c7b381ce3d88aad9ee0b03bea9fce26 (patch) | |
| tree | 6b10864a310f611187e1b61102da7da1db1d2e29 /converter | |
| parent | 225de7a847a511d004bf909b1334e19497cf2f9d (diff) | |
| parent | 81706d1130fdc3c0d6d110f4d8665c47ffd7fb59 (diff) | |
| download | qmk_firmware-62d1ebb91c7b381ce3d88aad9ee0b03bea9fce26.tar.gz qmk_firmware-62d1ebb91c7b381ce3d88aad9ee0b03bea9fce26.zip | |
Merge branch 'newdir'
Diffstat (limited to 'converter')
46 files changed, 5042 insertions, 0 deletions
diff --git a/converter/adb_usb/Makefile b/converter/adb_usb/Makefile new file mode 100644 index 000000000..64a23d09d --- /dev/null +++ b/converter/adb_usb/Makefile | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | # Target file name (without extension). | ||
| 2 | TARGET = adb_usb | ||
| 3 | |||
| 4 | # Directory common source filess exist | ||
| 5 | TOP_DIR = ../.. | ||
| 6 | |||
| 7 | # Directory keyboard dependent files exist | ||
| 8 | TARGET_DIR = . | ||
| 9 | |||
| 10 | # keyboard dependent files | ||
| 11 | SRC = main.c \ | ||
| 12 | keymap.c \ | ||
| 13 | matrix.c \ | ||
| 14 | led.c \ | ||
| 15 | adb.c | ||
| 16 | |||
| 17 | CONFIG_H = config.h | ||
| 18 | |||
| 19 | |||
| 20 | # MCU name, you MUST set this to match the board you are using | ||
| 21 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 22 | #MCU = at90usb162 # Teensy 1.0 | ||
| 23 | MCU = atmega32u4 # Teensy 2.0 | ||
| 24 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 25 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 26 | |||
| 27 | |||
| 28 | # Processor frequency. | ||
| 29 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 30 | # so your program will run at the correct speed. You should also set this | ||
| 31 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 32 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 33 | F_CPU = 16000000 | ||
| 34 | |||
| 35 | |||
| 36 | # Build Options | ||
| 37 | # comment out to disable the options. | ||
| 38 | # | ||
| 39 | #MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 40 | #PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support | ||
| 41 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 42 | #NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 43 | |||
| 44 | |||
| 45 | |||
| 46 | #---------------- Programming Options -------------------------- | ||
| 47 | PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | ||
| 48 | |||
| 49 | |||
| 50 | |||
| 51 | include $(TOP_DIR)/protocol/pjrc.mk | ||
| 52 | include $(TOP_DIR)/protocol.mk | ||
| 53 | include $(TOP_DIR)/common.mk | ||
| 54 | include $(TOP_DIR)/rules.mk | ||
diff --git a/converter/adb_usb/README b/converter/adb_usb/README new file mode 100644 index 000000000..5d0e1bc86 --- /dev/null +++ b/converter/adb_usb/README | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | ADB to USB keyboard converter | ||
| 2 | ============================= | ||
| 3 | http://geekhack.org/showwiki.php?title=Island:14290 | ||
| 4 | |||
| 5 | This firmware converts ADB keyboard protocol to USB. | ||
| 6 | |||
| 7 | |||
| 8 | Build | ||
| 9 | ----- | ||
| 10 | 0. Connect ADB keyboard to Teensy by 3 lines(Vcc, GND, Data). | ||
| 11 | You need a external pull-up resistor on DATA line in most case, | ||
| 12 | in particular when you want to use a long or coiled cable. | ||
| 13 | This converter uses AVR's internal pull-up, but it seems to be too weak. | ||
| 14 | The external pull-up resistor is strongly recommended. | ||
| 15 | PSW line is optional. See ADB.txt for details. | ||
| 16 | 1. Define following macros for ADB connection in config.h: | ||
| 17 | ADB_PORT | ||
| 18 | ADB_PIN | ||
| 19 | ADB_DDR | ||
| 20 | ADB_DATA_BIT | ||
| 21 | ADB_PSW_BIT | ||
| 22 | 2. make | ||
| 23 | 3. program Teensy. | ||
| 24 | |||
| 25 | |||
| 26 | Keymap | ||
| 27 | ------ | ||
| 28 | You can change a keymap by editing code of keymap.c like following. | ||
| 29 | This is a keymap for AEK, however, also used for other keyboards. | ||
| 30 | How to define the keymap is probably obvious. You can find key | ||
| 31 | symbols in usb_keycodes.h. | ||
| 32 | If you want to define some keymaps than just one, see hhkb/keymap.c and | ||
| 33 | macway/keymap.c as examples. Keymap(layer) switching may needs a bit of | ||
| 34 | effort at this time. | ||
| 35 | |||
| 36 | /* Default Layer: plain keymap | ||
| 37 | * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,---. | ||
| 38 | * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr| | ||
| 39 | * `---' `---------------' `---------------' `---------------' `-----------' `---' | ||
| 40 | * ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 41 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| =| /| *| | ||
| 42 | * |-----------------------------------------------------------| |-----------| |---------------| | ||
| 43 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| -| | ||
| 44 | * |-----------------------------------------------------------| `-----------' |---------------| | ||
| 45 | * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| +| | ||
| 46 | * |-----------------------------------------------------------| ,---. |---------------| | ||
| 47 | * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| | | ||
| 48 | * |-----------------------------------------------------------| ,-----------. |-----------|Ent| | ||
| 49 | * |Ctrl |Gui |Alt | Space | | | | |Lef|Dow|Rig| | 0| .| | | ||
| 50 | * `-----------------------------------------------------------' `-----------' `---------------' | ||
| 51 | */ | ||
| 52 | KEYMAP( | ||
| 53 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, | ||
| 54 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,EQL, PSLS,PAST, | ||
| 55 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9, PMNS, | ||
| 56 | CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, | ||
| 57 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, | ||
| 58 | LCTL,LGUI,LALT, SPC, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 59 | ), | ||
| 60 | |||
| 61 | |||
| 62 | Notes | ||
| 63 | ----- | ||
| 64 | Many ADB keyboards has no discrimination between right modifier and left one, | ||
| 65 | you will always see left control even if you press right control key. | ||
| 66 | Apple Extended Keyboard and Apple Extended Keyboard II are the examples. | ||
| 67 | Though ADB protocol itsef has the ability of distinction between right and left. | ||
| 68 | And most ADB keyboard has no NKRO functionality, though ADB protocol itsef has that. | ||
| 69 | |||
| 70 | EOF | ||
diff --git a/converter/adb_usb/config.h b/converter/adb_usb/config.h new file mode 100644 index 000000000..52d5925a5 --- /dev/null +++ b/converter/adb_usb/config.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | /* controller configuration */ | ||
| 22 | #include "controller_teensy.h" | ||
| 23 | |||
| 24 | #define VENDOR_ID 0xFEED | ||
| 25 | #define PRODUCT_ID 0x0ADB | ||
| 26 | #define DEVICE_VER 0x0101 | ||
| 27 | #define MANUFACTURER t.m.k. | ||
| 28 | #define PRODUCT ADB keyboard converter | ||
| 29 | #define DESCRIPTION convert ADB keyboard to USB | ||
| 30 | |||
| 31 | /* matrix size */ | ||
| 32 | #define MATRIX_ROWS 16 // keycode bit: 3-0 | ||
| 33 | #define MATRIX_COLS 8 // keycode bit: 6-4 | ||
| 34 | |||
| 35 | /* Locking Caps Lock support */ | ||
| 36 | #define MATRIX_HAS_LOCKING_CAPS | ||
| 37 | |||
| 38 | |||
| 39 | /* key combination for command */ | ||
| 40 | #define IS_COMMAND() ( \ | ||
| 41 | keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_LCTRL) | MOD_BIT(KB_LALT) | MOD_BIT(KB_LGUI)) || \ | ||
| 42 | keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) \ | ||
| 43 | ) | ||
| 44 | |||
| 45 | |||
| 46 | /* mouse keys */ | ||
| 47 | #ifdef MOUSEKEY_ENABLE | ||
| 48 | # define MOUSEKEY_DELAY_TIME 192 | ||
| 49 | #endif | ||
| 50 | |||
| 51 | |||
| 52 | /* PS/2 mouse */ | ||
| 53 | #ifdef PS2_MOUSE_ENABLE | ||
| 54 | # define PS2_CLOCK_PORT PORTF | ||
| 55 | # define PS2_CLOCK_PIN PINF | ||
| 56 | # define PS2_CLOCK_DDR DDRF | ||
| 57 | # define PS2_CLOCK_BIT 0 | ||
| 58 | # define PS2_DATA_PORT PORTF | ||
| 59 | # define PS2_DATA_PIN PINF | ||
| 60 | # define PS2_DATA_DDR DDRF | ||
| 61 | # define PS2_DATA_BIT 1 | ||
| 62 | #endif | ||
| 63 | |||
| 64 | |||
| 65 | /* ADB port setting */ | ||
| 66 | #define ADB_PORT PORTF | ||
| 67 | #define ADB_PIN PINF | ||
| 68 | #define ADB_DDR DDRF | ||
| 69 | #define ADB_DATA_BIT 0 | ||
| 70 | //#define ADB_PSW_BIT 1 // optional | ||
| 71 | |||
| 72 | #endif | ||
diff --git a/converter/adb_usb/keymap.c b/converter/adb_usb/keymap.c new file mode 100644 index 000000000..cdaa935d3 --- /dev/null +++ b/converter/adb_usb/keymap.c | |||
| @@ -0,0 +1,150 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Keymap for ADB keyboard | ||
| 20 | */ | ||
| 21 | #include <stdint.h> | ||
| 22 | #include <stdbool.h> | ||
| 23 | #include <avr/pgmspace.h> | ||
| 24 | #include "usb_keyboard.h" | ||
| 25 | #include "usb_keycodes.h" | ||
| 26 | #include "print.h" | ||
| 27 | #include "debug.h" | ||
| 28 | #include "util.h" | ||
| 29 | #include "keymap.h" | ||
| 30 | |||
| 31 | |||
| 32 | #define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) | ||
| 33 | |||
| 34 | // Convert physical keyboard layout to matrix array. | ||
| 35 | // This is a macro to define keymap easily in keyboard layout form. | ||
| 36 | /* Apple Extended Keyboard */ | ||
| 37 | #define KEYMAP( \ | ||
| 38 | K35, K7A,K78,K63,K76, K60,K61,K62,K64, K65,K6D,K67,K6F, K69,K6B,K71, K7F, \ | ||
| 39 | K32,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K72,K73,K74, K47,K51,K4B,K43, \ | ||
| 40 | K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E,K2A, K75,K77,K79, K59,K5B,K5C,K4E, \ | ||
| 41 | K39,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27, K24, K56,K57,K58,K45, \ | ||
| 42 | K38,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C, K7B, K3E, K53,K54,K55, \ | ||
| 43 | K36,K3A,K37, K31, K3B,K3D,K3C, K52, K41,K4C \ | ||
| 44 | ) { \ | ||
| 45 | { KB_##K00, KB_##K01, KB_##K02, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \ | ||
| 46 | { KB_##K08, KB_##K09, KB_NO, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_##K0F }, \ | ||
| 47 | { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_##K17 }, \ | ||
| 48 | { KB_##K18, KB_##K19, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_##K1F }, \ | ||
| 49 | { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, \ | ||
| 50 | { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, \ | ||
| 51 | { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_NO, KB_##K35, KB_##K36, KB_##K37 }, \ | ||
| 52 | { KB_##K38, KB_##K39, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_NO }, \ | ||
| 53 | { KB_NO, KB_##K41, KB_NO, KB_##K43, KB_NO, KB_##K45, KB_NO, KB_##K47 }, \ | ||
| 54 | { KB_NO, KB_NO, KB_NO, KB_##K4B, KB_##K4C, KB_NO, KB_##K4E, KB_NO }, \ | ||
| 55 | { KB_NO, KB_##K51, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, \ | ||
| 56 | { KB_##K58, KB_##K59, KB_NO, KB_##K5B, KB_##K5C, KB_NO, KB_NO, KB_NO }, \ | ||
| 57 | { KB_##K60, KB_##K61, KB_##K62, KB_##K63, KB_##K64, KB_##K65, KB_NO, KB_##K67 }, \ | ||
| 58 | { KB_NO, KB_##K69, KB_NO, KB_##K6B, KB_NO, KB_##K6D, KB_NO, KB_##K6F }, \ | ||
| 59 | { KB_NO, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_##K77 }, \ | ||
| 60 | { KB_##K78, KB_##K79, KB_##K7A, KB_##K7B, KB_NO, KB_NO, KB_NO, KB_##K7F } \ | ||
| 61 | } | ||
| 62 | /* plain keymap | ||
| 63 | { | ||
| 64 | { KB_A, KB_S, KB_D, KB_F, KB_H, KB_G, KB_Z, KB_X }, // 00-07 | ||
| 65 | { KB_C, KB_V, KB_NO, KB_B, KB_Q, KB_W, KB_E, KB_R }, // 08-0F | ||
| 66 | { KB_Y, KB_T, KB_1, KB_2, KB_3, KB_4, KB_6, KB_5 }, // 10-17 | ||
| 67 | { KB_EQL, KB_9, KB_7, KB_MINS,KB_8, KB_0, KB_RBRC,KB_O }, // 18-1F | ||
| 68 | { KB_U, KB_LBRC,KB_I, KB_P, KB_ENT, KB_L, KB_J, KB_QUOT}, // 20-27 | ||
| 69 | { KB_K, KB_SCLN,KB_BSLS,KB_COMM,KB_SLSH,KB_N, KB_M, KB_DOT }, // 28-2F | ||
| 70 | { KB_TAB, KB_SPC, KB_GRV, KB_BSPC,KB_NO, KB_ESC, KB_LCTL,KB_LGUI}, // 30-37 | ||
| 71 | { KB_LSFT,KB_CAPS,KB_LALT,KB_LEFT,KB_RGHT,KB_DOWN,KB_UP, KB_NO }, // 38-3F | ||
| 72 | { KB_NO, KB_PDOT,KB_NO, KB_PAST,KB_NO, KB_PPLS,KB_NO, KB_NLCK}, // 40-47 | ||
| 73 | { KB_NO, KB_NO, KB_NO, KB_PSLS,KB_PENT,KB_NO, KB_PMNS,KB_NO }, // 48-4F | ||
| 74 | { KB_NO, KB_PEQL,KB_P0, KB_P1, KB_P2, KB_P3, KB_P4, KB_P5 }, // 50-57 | ||
| 75 | { KB_P6, KB_P7, KB_NO, KB_P8, KB_P9, KB_NO, KB_NO, KB_NO }, // 58-5F | ||
| 76 | { KB_F5, KB_F6, KB_F7, KB_F3, KB_F8, KB_F9, KB_NO, KB_F11 }, // 60-67 | ||
| 77 | { KB_NO, KB_PSCR,KB_NO, KB_SLCK,KB_NO, KB_F10, KB_NO, KB_F12 }, // 68-6F | ||
| 78 | { KB_NO, KB_BRK, KB_INS, KB_HOME,KB_PGUP,KB_DEL, KB_F4, KB_END }, // 70-77 | ||
| 79 | { KB_F2, KB_PGDN,KB_F1, KB_RSFT,KB_NO, KB_NO, KB_NO, KB_PWR }, // 78-7F | ||
| 80 | }, | ||
| 81 | */ | ||
| 82 | |||
| 83 | |||
| 84 | // Assign Fn key(0-7) to a layer to which switch with the Fn key pressed. | ||
| 85 | static const uint8_t PROGMEM fn_layer[] = { | ||
| 86 | 0, // Fn0 | ||
| 87 | 0, // Fn1 | ||
| 88 | 0, // Fn2 | ||
| 89 | 0, // Fn3 | ||
| 90 | 0, // Fn4 | ||
| 91 | 0, // Fn5 | ||
| 92 | 0, // Fn6 | ||
| 93 | 0 // Fn7 | ||
| 94 | }; | ||
| 95 | |||
| 96 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. | ||
| 97 | // See layer.c for details. | ||
| 98 | static const uint8_t PROGMEM fn_keycode[] = { | ||
| 99 | KB_NO, // Fn0 | ||
| 100 | KB_NO, // Fn1 | ||
| 101 | KB_NO, // Fn2 | ||
| 102 | KB_NO, // Fn3 | ||
| 103 | KB_NO, // Fn4 | ||
| 104 | KB_NO, // Fn5 | ||
| 105 | KB_NO, // Fn6 | ||
| 106 | KB_NO // Fn7 | ||
| 107 | }; | ||
| 108 | |||
| 109 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 110 | /* Default Layer: plain keymap | ||
| 111 | * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,---. | ||
| 112 | * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr| | ||
| 113 | * `---' `---------------' `---------------' `---------------' `-----------' `---' | ||
| 114 | * ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 115 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| =| /| *| | ||
| 116 | * |-----------------------------------------------------------| |-----------| |---------------| | ||
| 117 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| -| | ||
| 118 | * |-----------------------------------------------------------| `-----------' |---------------| | ||
| 119 | * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| +| | ||
| 120 | * |-----------------------------------------------------------| ,---. |---------------| | ||
| 121 | * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| | | ||
| 122 | * |-----------------------------------------------------------| ,-----------. |-----------|Ent| | ||
| 123 | * |Ctrl |Gui |Alt | Space | | | | |Lef|Dow|Rig| | 0| .| | | ||
| 124 | * `-----------------------------------------------------------' `-----------' `---------------' | ||
| 125 | */ | ||
| 126 | KEYMAP( | ||
| 127 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, | ||
| 128 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,EQL, PSLS,PAST, | ||
| 129 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9, PMNS, | ||
| 130 | CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, | ||
| 131 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, | ||
| 132 | LCTL,LGUI,LALT, SPC, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 133 | ), | ||
| 134 | }; | ||
| 135 | |||
| 136 | |||
| 137 | uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | ||
| 138 | { | ||
| 139 | return KEYCODE(layer, row, col); | ||
| 140 | } | ||
| 141 | |||
| 142 | uint8_t keymap_fn_layer(uint8_t fn_bits) | ||
| 143 | { | ||
| 144 | return pgm_read_byte(&fn_layer[biton(fn_bits)]); | ||
| 145 | } | ||
| 146 | |||
| 147 | uint8_t keymap_fn_keycode(uint8_t fn_bits) | ||
| 148 | { | ||
| 149 | return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | ||
| 150 | } | ||
diff --git a/converter/adb_usb/led.c b/converter/adb_usb/led.c new file mode 100644 index 000000000..0e162f379 --- /dev/null +++ b/converter/adb_usb/led.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "stdint.h" | ||
| 19 | #include "adb.h" | ||
| 20 | #include "led.h" | ||
| 21 | |||
| 22 | |||
| 23 | void led_set(uint8_t usb_led) | ||
| 24 | { | ||
| 25 | adb_host_kbd_led(~usb_led); | ||
| 26 | } | ||
diff --git a/converter/adb_usb/matrix.c b/converter/adb_usb/matrix.c new file mode 100644 index 000000000..a2367af56 --- /dev/null +++ b/converter/adb_usb/matrix.c | |||
| @@ -0,0 +1,241 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * scan matrix | ||
| 20 | */ | ||
| 21 | #include <stdint.h> | ||
| 22 | #include <stdbool.h> | ||
| 23 | #include <avr/io.h> | ||
| 24 | #include <util/delay.h> | ||
| 25 | #include "print.h" | ||
| 26 | #include "util.h" | ||
| 27 | #include "debug.h" | ||
| 28 | #include "host.h" | ||
| 29 | #include "led.h" | ||
| 30 | #include "adb.h" | ||
| 31 | #include "matrix.h" | ||
| 32 | |||
| 33 | |||
| 34 | #if (MATRIX_COLS > 16) | ||
| 35 | # error "MATRIX_COLS must not exceed 16" | ||
| 36 | #endif | ||
| 37 | #if (MATRIX_ROWS > 255) | ||
| 38 | # error "MATRIX_ROWS must not exceed 255" | ||
| 39 | #endif | ||
| 40 | |||
| 41 | #define CAPS 0x39 | ||
| 42 | #define CAPS_UP (CAPS | 0x80) | ||
| 43 | #define ROW(key) ((key)>>3&0x0F) | ||
| 44 | #define COL(key) ((key)&0x07) | ||
| 45 | |||
| 46 | |||
| 47 | static bool _matrix_is_modified = false; | ||
| 48 | |||
| 49 | // matrix state buffer(1:on, 0:off) | ||
| 50 | #if (MATRIX_COLS <= 8) | ||
| 51 | static uint8_t *matrix; | ||
| 52 | static uint8_t _matrix0[MATRIX_ROWS]; | ||
| 53 | #else | ||
| 54 | static uint16_t *matrix; | ||
| 55 | static uint16_t _matrix0[MATRIX_ROWS]; | ||
| 56 | #endif | ||
| 57 | |||
| 58 | #ifdef MATRIX_HAS_GHOST | ||
| 59 | static bool matrix_has_ghost_in_row(uint8_t row); | ||
| 60 | #endif | ||
| 61 | static void _register_key(uint8_t key); | ||
| 62 | |||
| 63 | |||
| 64 | inline | ||
| 65 | uint8_t matrix_rows(void) | ||
| 66 | { | ||
| 67 | return MATRIX_ROWS; | ||
| 68 | } | ||
| 69 | |||
| 70 | inline | ||
| 71 | uint8_t matrix_cols(void) | ||
| 72 | { | ||
| 73 | return MATRIX_COLS; | ||
| 74 | } | ||
| 75 | |||
| 76 | void matrix_init(void) | ||
| 77 | { | ||
| 78 | adb_host_init(); | ||
| 79 | |||
| 80 | // initialize matrix state: all keys off | ||
| 81 | for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00; | ||
| 82 | matrix = _matrix0; | ||
| 83 | |||
| 84 | print_enable = true; | ||
| 85 | debug_enable = true; | ||
| 86 | debug_matrix = true; | ||
| 87 | debug_keyboard = true; | ||
| 88 | debug_mouse = true; | ||
| 89 | print("debug enabled.\n"); | ||
| 90 | return; | ||
| 91 | } | ||
| 92 | |||
| 93 | uint8_t matrix_scan(void) | ||
| 94 | { | ||
| 95 | uint16_t codes; | ||
| 96 | uint8_t key0, key1; | ||
| 97 | |||
| 98 | _matrix_is_modified = false; | ||
| 99 | codes = adb_host_kbd_recv(); | ||
| 100 | key0 = codes>>8; | ||
| 101 | key1 = codes&0xFF; | ||
| 102 | |||
| 103 | #ifdef MATRIX_HAS_LOCKING_CAPS | ||
| 104 | // Send Caps key up event | ||
| 105 | if (matrix_is_on(ROW(CAPS), COL(CAPS))) { | ||
| 106 | _matrix_is_modified = true; | ||
| 107 | _register_key(CAPS_UP); | ||
| 108 | } | ||
| 109 | #endif | ||
| 110 | if (codes == 0) { // no keys | ||
| 111 | return 0; | ||
| 112 | } else if (key0 == 0xFF && key1 != 0xFF) { // error | ||
| 113 | return codes&0xFF; | ||
| 114 | } else { | ||
| 115 | #ifdef MATRIX_HAS_LOCKING_CAPS | ||
| 116 | if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { | ||
| 117 | // Ignore LockingCaps key down event when CAPS LOCK is on | ||
| 118 | if (key0 == CAPS && (key1 == CAPS || key1 == 0xFF)) return 0; | ||
| 119 | if (key0 == CAPS) key0 = key1; | ||
| 120 | if (key1 == CAPS) key1 = 0xFF; | ||
| 121 | // Convert LockingCaps key up event into down event | ||
| 122 | if (key0 == CAPS_UP) key0 = CAPS; | ||
| 123 | if (key1 == CAPS_UP) key1 = CAPS; | ||
| 124 | } else { | ||
| 125 | // CAPS LOCK off: | ||
| 126 | // Ignore LockingCaps key up event when CAPS LOCK is off | ||
| 127 | if (key0 == CAPS_UP && (key1 == CAPS_UP || key1 == 0xFF)) return 0; | ||
| 128 | if (key0 == CAPS_UP) key0 = key1; | ||
| 129 | if (key1 == CAPS_UP) key1 = 0xFF; | ||
| 130 | } | ||
| 131 | #endif | ||
| 132 | _matrix_is_modified = true; | ||
| 133 | _register_key(key0); | ||
| 134 | if (key1 != 0xFF) // key1 is 0xFF when no second key. | ||
| 135 | _register_key(key1); | ||
| 136 | } | ||
| 137 | |||
| 138 | if (debug_enable) { | ||
| 139 | print("adb_host_kbd_recv: "); phex16(codes); print("\n"); | ||
| 140 | } | ||
| 141 | return 1; | ||
| 142 | } | ||
| 143 | |||
| 144 | bool matrix_is_modified(void) | ||
| 145 | { | ||
| 146 | return _matrix_is_modified; | ||
| 147 | } | ||
| 148 | |||
| 149 | inline | ||
| 150 | bool matrix_has_ghost(void) | ||
| 151 | { | ||
| 152 | #ifdef MATRIX_HAS_GHOST | ||
| 153 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 154 | if (matrix_has_ghost_in_row(i)) | ||
| 155 | return true; | ||
| 156 | } | ||
| 157 | #endif | ||
| 158 | return false; | ||
| 159 | } | ||
| 160 | |||
| 161 | inline | ||
| 162 | bool matrix_is_on(uint8_t row, uint8_t col) | ||
| 163 | { | ||
| 164 | return (matrix[row] & (1<<col)); | ||
| 165 | } | ||
| 166 | |||
| 167 | inline | ||
| 168 | #if (MATRIX_COLS <= 8) | ||
| 169 | uint8_t matrix_get_row(uint8_t row) | ||
| 170 | #else | ||
| 171 | uint16_t matrix_get_row(uint8_t row) | ||
| 172 | #endif | ||
| 173 | { | ||
| 174 | return matrix[row]; | ||
| 175 | } | ||
| 176 | |||
| 177 | void matrix_print(void) | ||
| 178 | { | ||
| 179 | #if (MATRIX_COLS <= 8) | ||
| 180 | print("\nr/c 01234567\n"); | ||
| 181 | #else | ||
| 182 | print("\nr/c 0123456789ABCDEF\n"); | ||
| 183 | #endif | ||
| 184 | for (uint8_t row = 0; row < matrix_rows(); row++) { | ||
| 185 | phex(row); print(": "); | ||
| 186 | #if (MATRIX_COLS <= 8) | ||
| 187 | pbin_reverse(matrix_get_row(row)); | ||
| 188 | #else | ||
| 189 | pbin_reverse16(matrix_get_row(row)); | ||
| 190 | #endif | ||
| 191 | #ifdef MATRIX_HAS_GHOST | ||
| 192 | if (matrix_has_ghost_in_row(row)) { | ||
| 193 | print(" <ghost"); | ||
| 194 | } | ||
| 195 | #endif | ||
| 196 | print("\n"); | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | uint8_t matrix_key_count(void) | ||
| 201 | { | ||
| 202 | uint8_t count = 0; | ||
| 203 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 204 | #if (MATRIX_COLS <= 8) | ||
| 205 | count += bitpop(matrix[i]); | ||
| 206 | #else | ||
| 207 | count += bitpop16(matrix[i]); | ||
| 208 | #endif | ||
| 209 | } | ||
| 210 | return count; | ||
| 211 | } | ||
| 212 | |||
| 213 | #ifdef MATRIX_HAS_GHOST | ||
| 214 | inline | ||
| 215 | static bool matrix_has_ghost_in_row(uint8_t row) | ||
| 216 | { | ||
| 217 | // no ghost exists in case less than 2 keys on | ||
| 218 | if (((matrix[row] - 1) & matrix[row]) == 0) | ||
| 219 | return false; | ||
| 220 | |||
| 221 | // ghost exists in case same state as other row | ||
| 222 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | ||
| 223 | if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | ||
| 224 | return true; | ||
| 225 | } | ||
| 226 | return false; | ||
| 227 | } | ||
| 228 | #endif | ||
| 229 | |||
| 230 | inline | ||
| 231 | static void _register_key(uint8_t key) | ||
| 232 | { | ||
| 233 | uint8_t col, row; | ||
| 234 | col = key&0x07; | ||
| 235 | row = (key>>3)&0x0F; | ||
| 236 | if (key&0x80) { | ||
| 237 | matrix[row] &= ~(1<<col); | ||
| 238 | } else { | ||
| 239 | matrix[row] |= (1<<col); | ||
| 240 | } | ||
| 241 | } | ||
diff --git a/converter/m0110_usb/Makefile b/converter/m0110_usb/Makefile new file mode 100644 index 000000000..4a687b933 --- /dev/null +++ b/converter/m0110_usb/Makefile | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | # Target file name (without extension). | ||
| 2 | TARGET = m0110 | ||
| 3 | |||
| 4 | # Directory common source filess exist | ||
| 5 | TOP_DIR = ../.. | ||
| 6 | |||
| 7 | # Directory keyboard dependent files exist | ||
| 8 | TARGET_DIR = . | ||
| 9 | |||
| 10 | # keyboard dependent files | ||
| 11 | SRC = main.c \ | ||
| 12 | keymap.c \ | ||
| 13 | matrix.c \ | ||
| 14 | led.c \ | ||
| 15 | m0110.c | ||
| 16 | |||
| 17 | CONFIG_H = config.h | ||
| 18 | |||
| 19 | |||
| 20 | # MCU name, you MUST set this to match the board you are using | ||
| 21 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 22 | #MCU = at90usb162 # Teensy 1.0 | ||
| 23 | MCU = atmega32u4 # Teensy 2.0 | ||
| 24 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 25 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 26 | |||
| 27 | |||
| 28 | # Processor frequency. | ||
| 29 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 30 | # so your program will run at the correct speed. You should also set this | ||
| 31 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 32 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 33 | F_CPU = 16000000 | ||
| 34 | |||
| 35 | |||
| 36 | # Build Options | ||
| 37 | # *Comment out* to disable the options. | ||
| 38 | # | ||
| 39 | MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 40 | #PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support | ||
| 41 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 42 | #NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 43 | |||
| 44 | |||
| 45 | |||
| 46 | #---------------- Programming Options -------------------------- | ||
| 47 | PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | ||
| 48 | |||
| 49 | |||
| 50 | |||
| 51 | include $(TOP_DIR)/protocol/pjrc.mk | ||
| 52 | include $(TOP_DIR)/protocol.mk | ||
| 53 | include $(TOP_DIR)/common.mk | ||
| 54 | include $(TOP_DIR)/rules.mk | ||
| 55 | |||
| 56 | hasu: EXTRAFLAGS += -DHASU | ||
| 57 | hasu: all | ||
diff --git a/converter/m0110_usb/README.md b/converter/m0110_usb/README.md new file mode 100644 index 000000000..0ad3631f7 --- /dev/null +++ b/converter/m0110_usb/README.md | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | M0110/M0110A to USB keyboard converter | ||
| 2 | ====================================== | ||
| 3 | This firmware converts the protocol of Apple Macintosh keyboard M0110/M0110A into USB. | ||
| 4 | Target board of this project is [PJRC Teensy](http://www.pjrc.com/teensy/), though, | ||
| 5 | you can use other board with USB AVR like `ATmega32U4` and `AT90USB`. | ||
| 6 | |||
| 7 |  | ||
| 8 | |||
| 9 | M0110A support was contributed by [skagon@github](https://github.com/skagon). | ||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | Connection | ||
| 14 | ---------- | ||
| 15 | You need 4P4C plug and cable to connect Teensy or other AVR dev board into the keyboard. | ||
| 16 | Teensy port `PF0` is assigned for `CLOCK` line and `PF1` for `DATA` by default, | ||
| 17 | you can change pin configuration with editing *config.h*. | ||
| 18 | |||
| 19 | You can find 4P4C plugs on telephone handset cable. Note that it is *crossover* connection | ||
| 20 | while Macintosh keyboard cable is *straight*. | ||
| 21 | |||
| 22 | [](http://i.imgur.com/vJoVO.jpg) | ||
| 23 | |||
| 24 | In this pic: | ||
| 25 | |||
| 26 | 1. `GND`(Black) | ||
| 27 | 2. `CLOCK`(Red) | ||
| 28 | 3. `DATA`(Green) | ||
| 29 | 4. `+5V`(Yellow) | ||
| 30 | |||
| 31 | Not that wire colors may vary in your cable. | ||
| 32 | |||
| 33 | |||
| 34 | ### Pinout | ||
| 35 | - <http://pinouts.ru/Inputs/MacKeyboard_pinout.shtml> | ||
| 36 | - <http://en.wikipedia.org/wiki/Modular_connector#4P4C> | ||
| 37 | |||
| 38 |  | ||
| 39 | |||
| 40 | |||
| 41 | ### Pull-up Registor | ||
| 42 | You may need pull-up registors on signal lines(`CLOCK`, `DATA`) in particular | ||
| 43 | when you have long or coiled cable. 1k-10k Ohm will be OK for this purpose. | ||
| 44 | In some cases MCU can't read signal from keyboard correctly without pull-up resistors. | ||
| 45 | |||
| 46 | |||
| 47 | |||
| 48 | Building Frimware | ||
| 49 | ----------------- | ||
| 50 | To compile firmware you need AVR GCC. You can use [WinAVR](http://winavr.sourceforge.net/) on Windows. | ||
| 51 | You can edit *Makefile* and *config.h* to change compile options and pin configuration. | ||
| 52 | |||
| 53 | $ git clone git://github.com/tmk/tmk_keyboard.git (or download source) | ||
| 54 | $ cd m0110_usb | ||
| 55 | $ make | ||
| 56 | |||
| 57 | and program your Teensy with [PJRC Teensy loader](http://www.pjrc.com/teensy/loader.html). | ||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | Keymap | ||
| 62 | ------ | ||
| 63 | You can change keymaps by editing *keymap.c*. | ||
| 64 | |||
| 65 | ### M0110 | ||
| 66 | #### *Default* | ||
| 67 | ,---------------------------------------------------------. | ||
| 68 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| | ||
| 69 | |---------------------------------------------------------| | ||
| 70 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | ||
| 71 | |---------------------------------------------------------| | ||
| 72 | |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | ||
| 73 | |---------------------------------------------------------| | ||
| 74 | |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | ||
| 75 | `---------------------------------------------------------' | ||
| 76 | |Ctr|Alt | Space |Gui |Ctr| | ||
| 77 | `-----------------------------------------------' | ||
| 78 | #### *HHKB/WASD Layer* | ||
| 79 | ,---------------------------------------------------------. | ||
| 80 | |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| | ||
| 81 | |---------------------------------------------------------| | ||
| 82 | |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up | |Ins| | ||
| 83 | |---------------------------------------------------------| | ||
| 84 | |Fn0 |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Return| | ||
| 85 | |---------------------------------------------------------| | ||
| 86 | |Shift |End| |PgD| |VoD|VoU|Mut|End|PgD|Dow|Shift | | ||
| 87 | `---------------------------------------------------------' | ||
| 88 | |Ctr|Alt | Space |Gui |Ctr| | ||
| 89 | `-----------------------------------------------' | ||
| 90 | |||
| 91 | ### M0110A | ||
| 92 | #### *Default* | ||
| 93 | ,---------------------------------------------------------. ,---------------. | ||
| 94 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Gui| =| /| *| | ||
| 95 | |---------------------------------------------------------| |---------------| | ||
| 96 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 97 | |-----------------------------------------------------' | |---------------| | ||
| 98 | |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 99 | |---------------------------------------------------------| |---------------| | ||
| 100 | |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 101 | |---------------------------------------------------------| |-----------|Ent| | ||
| 102 | |Ctrl |Alt | Space | \|Lft|Rgt|Dn | | 0| .| | | ||
| 103 | `---------------------------------------------------------' `---------------' | ||
| 104 | #### *HHKB/WASD/mousekey Layer* | ||
| 105 | ,---------------------------------------------------------. ,---------------. | ||
| 106 | |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk|Mb1|Mb3|Mb2| | ||
| 107 | |---------------------------------------------------------| |---------------| | ||
| 108 | |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up | | | |MwD|McU|MwU|MwU| | ||
| 109 | |-----------------------------------------------------' | |---------------| | ||
| 110 | |Fn0 |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Return| |McL|McD|McR|MwD| | ||
| 111 | |---------------------------------------------------------| |---------------| | ||
| 112 | |Shift |End| |PgD| |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | |MwL|McD|MwR| | | ||
| 113 | |---------------------------------------------------------| |-----------|Mb2| | ||
| 114 | |Ctrl |Alt | Space |Ins|Lft|Rgt|Dn | | Mb1|Mb3| | | ||
| 115 | `---------------------------------------------------------' `---------------' | ||
| 116 | |||
| 117 | |||
| 118 | |||
| 119 | Debug | ||
| 120 | ----- | ||
| 121 | You can use [PJRC HID listen](http://www.pjrc.com/teensy/hid_listen.html) to see debug output. | ||
| 122 | |||
| 123 | The converter has some functions for debug, press `Alt+Gui+H` simultaneously to get help. | ||
| 124 | These function is totally undocumented, tentative, inconsistent and buggy. | ||
diff --git a/converter/m0110_usb/config.h b/converter/m0110_usb/config.h new file mode 100644 index 000000000..4563d6da5 --- /dev/null +++ b/converter/m0110_usb/config.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011,2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | /* controller configuration */ | ||
| 22 | #include "controller_teensy.h" | ||
| 23 | |||
| 24 | |||
| 25 | #define VENDOR_ID 0xFEED | ||
| 26 | #define PRODUCT_ID 0x0110 | ||
| 27 | #define MANUFACTURER t.m.k. | ||
| 28 | #define PRODUCT M0110 keyboard converter | ||
| 29 | #define DESCRIPTION convert M0110 keyboard to USB | ||
| 30 | |||
| 31 | |||
| 32 | /* matrix size */ | ||
| 33 | #define MATRIX_ROWS 14 | ||
| 34 | #define MATRIX_COLS 8 | ||
| 35 | |||
| 36 | /* Locking Caps Lock support */ | ||
| 37 | //#define MATRIX_HAS_LOCKING_CAPS | ||
| 38 | |||
| 39 | /* key combination for command */ | ||
| 40 | #define IS_COMMAND() ( \ | ||
| 41 | keyboard_report->mods == (MOD_BIT(KB_LALT) | MOD_BIT(KB_LGUI)) \ | ||
| 42 | ) | ||
| 43 | |||
| 44 | |||
| 45 | /* mouse keys */ | ||
| 46 | #ifdef MOUSEKEY_ENABLE | ||
| 47 | # define MOUSEKEY_DELAY_TIME 192 | ||
| 48 | #endif | ||
| 49 | |||
| 50 | |||
| 51 | /* ports */ | ||
| 52 | #define M0110_CLOCK_PORT PORTF | ||
| 53 | #define M0110_CLOCK_PIN PINF | ||
| 54 | #define M0110_CLOCK_DDR DDRF | ||
| 55 | #define M0110_CLOCK_BIT 0 | ||
| 56 | #define M0110_DATA_PORT PORTF | ||
| 57 | #define M0110_DATA_PIN PINF | ||
| 58 | #define M0110_DATA_DDR DDRF | ||
| 59 | #define M0110_DATA_BIT 1 | ||
| 60 | |||
| 61 | #endif | ||
diff --git a/converter/m0110_usb/doc/m0110.jpg b/converter/m0110_usb/doc/m0110.jpg new file mode 100644 index 000000000..ef9a123ab --- /dev/null +++ b/converter/m0110_usb/doc/m0110.jpg | |||
| Binary files differ | |||
diff --git a/converter/m0110_usb/doc/teensy.jpg b/converter/m0110_usb/doc/teensy.jpg new file mode 100644 index 000000000..96e93e7e2 --- /dev/null +++ b/converter/m0110_usb/doc/teensy.jpg | |||
| Binary files differ | |||
diff --git a/converter/m0110_usb/keymap.c b/converter/m0110_usb/keymap.c new file mode 100644 index 000000000..b5cdd300b --- /dev/null +++ b/converter/m0110_usb/keymap.c | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011,2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | /* M0110A Support was contributed by skagon@github */ | ||
| 18 | |||
| 19 | #include <stdint.h> | ||
| 20 | #include <stdbool.h> | ||
| 21 | #include <avr/pgmspace.h> | ||
| 22 | #include "usb_keyboard.h" | ||
| 23 | #include "usb_keycodes.h" | ||
| 24 | #include "print.h" | ||
| 25 | #include "debug.h" | ||
| 26 | #include "util.h" | ||
| 27 | #include "keymap.h" | ||
| 28 | |||
| 29 | |||
| 30 | #define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) | ||
| 31 | |||
| 32 | #define KEYMAP( \ | ||
| 33 | K32,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K47,K68,K6D,K62, \ | ||
| 34 | K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E, K59,K5B,K5C,K4E, \ | ||
| 35 | K39,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27, K24, K56,K57,K58,K66, \ | ||
| 36 | K38,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C, K4D, K53,K54,K55,K4C, \ | ||
| 37 | K3A,K37, K31, K34,K2A,K46,K42,K48, K52, K41 \ | ||
| 38 | ) { \ | ||
| 39 | { KB_##K00, KB_##K01, KB_##K02, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \ | ||
| 40 | { KB_##K08, KB_##K09, KB_NO, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_##K0F }, \ | ||
| 41 | { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_##K17 }, \ | ||
| 42 | { KB_##K18, KB_##K19, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_##K1F }, \ | ||
| 43 | { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, \ | ||
| 44 | { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, \ | ||
| 45 | { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_NO, KB_NO, KB_##K37 }, \ | ||
| 46 | { KB_##K38, KB_##K39, KB_##K3A, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \ | ||
| 47 | { KB_NO, KB_##K41, KB_##K42, KB_NO, KB_NO, KB_NO, KB_##K46, KB_##K47 }, \ | ||
| 48 | { KB_##K48, KB_NO, KB_NO, KB_NO, KB_##K4C, KB_##K4D, KB_##K4E, KB_NO }, \ | ||
| 49 | { KB_NO, KB_NO, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, \ | ||
| 50 | { KB_##K58, KB_##K59, KB_NO, KB_##K5B, KB_##K5C, KB_NO, KB_NO, KB_NO }, \ | ||
| 51 | { KB_NO, KB_NO, KB_##K62, KB_NO, KB_NO, KB_NO, KB_##K66, KB_NO }, \ | ||
| 52 | { KB_##K68, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K6D, KB_NO, KB_NO }, \ | ||
| 53 | } | ||
| 54 | |||
| 55 | |||
| 56 | // Assign Fn key(0-7) to a layer to which switch with the Fn key pressed. | ||
| 57 | static const uint8_t PROGMEM fn_layer[] = { | ||
| 58 | #ifndef HASU | ||
| 59 | 1, // Fn0 | ||
| 60 | 0, // Fn1 | ||
| 61 | 0, // Fn2 | ||
| 62 | 0, // Fn3 | ||
| 63 | 0, // Fn4 | ||
| 64 | 0, // Fn5 | ||
| 65 | 0, // Fn6 | ||
| 66 | 0 // Fn7 | ||
| 67 | #else | ||
| 68 | 1, // Fn0 | ||
| 69 | 2, // Fn1 | ||
| 70 | 3, // Fn2 | ||
| 71 | 1, // Fn3 | ||
| 72 | 2, // Fn4 | ||
| 73 | 0, // Fn5 | ||
| 74 | 0, // Fn6 | ||
| 75 | 0 // Fn7 | ||
| 76 | #endif | ||
| 77 | }; | ||
| 78 | |||
| 79 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. | ||
| 80 | // See layer.c for details. | ||
| 81 | static const uint8_t PROGMEM fn_keycode[] = { | ||
| 82 | #ifndef HASU | ||
| 83 | KB_NO, // Fn0 | ||
| 84 | KB_NO, // Fn1 | ||
| 85 | KB_NO, // Fn2 | ||
| 86 | KB_NO, // Fn3 | ||
| 87 | KB_NO, // Fn4 | ||
| 88 | KB_NO, // Fn5 | ||
| 89 | KB_NO, // Fn6 | ||
| 90 | KB_NO // Fn7 | ||
| 91 | #else | ||
| 92 | KB_ENTER, // Fn0 | ||
| 93 | KB_SCOLON, // Fn1 | ||
| 94 | KB_SLASH, // Fn2 | ||
| 95 | KB_UP, // Fn3 | ||
| 96 | KB_NO, // Fn4 | ||
| 97 | KB_NO, // Fn5 | ||
| 98 | KB_NO, // Fn6 | ||
| 99 | KB_NO // Fn7 | ||
| 100 | #endif | ||
| 101 | }; | ||
| 102 | |||
| 103 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 104 | /* | ||
| 105 | * The keymap works with both M0110 and M0110A keyboards. As you can see, the M0110A is a superset | ||
| 106 | * of the M0110 keyboard, with only one exception: 'Enter' in M0110 does not exist | ||
| 107 | * on the M0110A, but since it generates a unique scan code which is not used for some other key in | ||
| 108 | * the M0110A, they are totally interchangeable. In fact, the M0110A is functionally (almost) | ||
| 109 | * identical to the combination of the M0110 along with the M0120 keypad. The only difference | ||
| 110 | * (which is causing some problems as you will read below) is that the M0110+M0120 don't have | ||
| 111 | * dedicated arrow keys, while the M0110A does. However, the M0120 did have arrow keys, which | ||
| 112 | * doubled as the [comma], [/], [*] and [+] keys, when used with the [Shift] key. The M0110A has | ||
| 113 | * substituted the [comma] key with the [=] key, however its scancode is the same. | ||
| 114 | * | ||
| 115 | * Default: | ||
| 116 | * ,---------------------------------------------------------. ,---------------. | ||
| 117 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Gui| =| /| *| | ||
| 118 | * |---------------------------------------------------------| |---------------| | ||
| 119 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 120 | * |-----------------------------------------------------' | |---------------| | ||
| 121 | * |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 122 | * |---------------------------------------------------------| |---------------| | ||
| 123 | * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 124 | * |---------------------------------------------------------| |-----------|Ent| | ||
| 125 | * |Ctrl |Alt | Space |Gui| \|Lft|Rgt|Dn | | 0| .| | | ||
| 126 | * `---------------------------------------------------------' `---------------' | ||
| 127 | * | ||
| 128 | * HHKB/WASD/Mouse Layer(Fn0): | ||
| 129 | * ,---------------------------------------------------------. ,---------------. | ||
| 130 | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk|Mb1|Mb3|Mb2| | ||
| 131 | * |---------------------------------------------------------| |---------------| | ||
| 132 | * |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | |MwD|McU|MwU|MwU| | ||
| 133 | * |-----------------------------------------------------' | |---------------| | ||
| 134 | * |Fn0 |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Return| |McL|McD|McR|MwD| | ||
| 135 | * |---------------------------------------------------------| |---------------| | ||
| 136 | * |Shift |End| |PgD| |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | |MwL|McD|MwR| | | ||
| 137 | * |---------------------------------------------------------| |-----------|Mb2| | ||
| 138 | * |Ctrl |Alt | Space |Gui | \|Lft|Rgt|Dn | | Mb1|Mb3| | | ||
| 139 | * `---------------------------------------------------------' `---------------' | ||
| 140 | * Mb: Mouse Button / Mc: Mouse Cursor / Mw: Mouse Wheel | ||
| 141 | * | ||
| 142 | * NOTE: M0110 has no arrow and keypad keys. | ||
| 143 | * NOTE: \ is located next to ] on M0110. | ||
| 144 | * NOTE: Gui between Space and \ is Enter on M0110 not exists on M0110A. | ||
| 145 | * NOTE: LShift and RShift are logically same key. (M0110, M0110A) | ||
| 146 | * NOTE: LOption and ROption are logically same key. (M0110) | ||
| 147 | */ | ||
| 148 | #ifndef HASU | ||
| 149 | KEYMAP( | ||
| 150 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LGUI,EQL, PSLS,PAST, | ||
| 151 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS, | ||
| 152 | FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, | ||
| 153 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT, | ||
| 154 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT | ||
| 155 | ), | ||
| 156 | // HHKB & WASD | ||
| 157 | KEYMAP( | ||
| 158 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,BTN1,BTN3,BTN2, | ||
| 159 | CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, NO, WH_D,MS_U,WH_U,WH_U, | ||
| 160 | FN0, LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, MS_L,MS_D,MS_R,WH_D, | ||
| 161 | LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, UP, WH_L,MS_D,WH_R,BTN2, | ||
| 162 | LCTL,LALT, SPC, LGUI,INS, LEFT,RGHT,DOWN, BTN1, BTN3 | ||
| 163 | ), | ||
| 164 | #else | ||
| 165 | // hasu's keymap(To enable this use 'make hasu' to add option flag: EXTRAFLAGS=-DHASU) | ||
| 166 | KEYMAP( | ||
| 167 | ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LGUI,EQL, PSLS,PAST, | ||
| 168 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS, | ||
| 169 | LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT, FN0, P4, P5, P6, PPLS, | ||
| 170 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN2, FN3, P1, P2, P3, PENT, | ||
| 171 | FN4, LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, LGUI, PDOT | ||
| 172 | ), | ||
| 173 | // HHKB & WASD | ||
| 174 | KEYMAP( | ||
| 175 | GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST, | ||
| 176 | CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, NO, P7, P8, P9, PMNS, | ||
| 177 | LCTL,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, FN0, P4, P5, P6, PPLS, | ||
| 178 | LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, FN3, P1, P2, P3, PENT, | ||
| 179 | LCTL,LALT, SPC, LGUI,INS, LEFT,RGHT,DOWN, P0, PDOT | ||
| 180 | ), | ||
| 181 | // vi mousekeys | ||
| 182 | KEYMAP( | ||
| 183 | GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST, | ||
| 184 | CAPS,NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, P7, P8, P9, PMNS, | ||
| 185 | NO, VOLD,VOLU,MUTE,NO, NO, MS_L,MS_D,MS_U,MS_R,FN1, NO, ENT, P4, P5, P6, PPLS, | ||
| 186 | LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,NO, NO, NO, UP, P1, P2, P3, PENT, | ||
| 187 | FN4, LALT, BTN1, LGUI,NO, LEFT,RGHT,DOWN, P0, PDOT | ||
| 188 | ), | ||
| 189 | // vi cusorkeys | ||
| 190 | KEYMAP( | ||
| 191 | GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST, | ||
| 192 | CAPS,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, PSCR,SLCK,PAUS, P7, P8, P9, PMNS, | ||
| 193 | NO, NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS, | ||
| 194 | LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN2, UP, P1, P2, P3, PENT, | ||
| 195 | LCTL,LALT, SPC, LGUI,INS, LEFT,RGHT,DOWN, P0, PDOT | ||
| 196 | ), | ||
| 197 | #endif | ||
| 198 | }; | ||
| 199 | |||
| 200 | |||
| 201 | uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | ||
| 202 | { | ||
| 203 | return KEYCODE(layer, row, col); | ||
| 204 | } | ||
| 205 | |||
| 206 | uint8_t keymap_fn_layer(uint8_t fn_bits) | ||
| 207 | { | ||
| 208 | return pgm_read_byte(&fn_layer[biton(fn_bits)]); | ||
| 209 | } | ||
| 210 | |||
| 211 | uint8_t keymap_fn_keycode(uint8_t fn_bits) | ||
| 212 | { | ||
| 213 | return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | ||
| 214 | } | ||
diff --git a/converter/m0110_usb/led.c b/converter/m0110_usb/led.c new file mode 100644 index 000000000..f76545f0b --- /dev/null +++ b/converter/m0110_usb/led.c | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "stdint.h" | ||
| 19 | #include "led.h" | ||
| 20 | |||
| 21 | |||
| 22 | void led_set(uint8_t usb_led) | ||
| 23 | { | ||
| 24 | } | ||
diff --git a/converter/m0110_usb/matrix.c b/converter/m0110_usb/matrix.c new file mode 100644 index 000000000..1ca6894c4 --- /dev/null +++ b/converter/m0110_usb/matrix.c | |||
| @@ -0,0 +1,169 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011,2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * scan matrix | ||
| 20 | */ | ||
| 21 | #include <stdint.h> | ||
| 22 | #include <stdbool.h> | ||
| 23 | #include <avr/io.h> | ||
| 24 | #include <util/delay.h> | ||
| 25 | #include "print.h" | ||
| 26 | #include "util.h" | ||
| 27 | #include "debug.h" | ||
| 28 | #include "host.h" | ||
| 29 | #include "led.h" | ||
| 30 | #include "m0110.h" | ||
| 31 | #include "matrix.h" | ||
| 32 | |||
| 33 | |||
| 34 | #define CAPS 0x39 | ||
| 35 | #define CAPS_BREAK (CAPS | 0x80) | ||
| 36 | #define ROW(key) ((key)>>3&0x0F) | ||
| 37 | #define COL(key) ((key)&0x07) | ||
| 38 | |||
| 39 | |||
| 40 | static bool is_modified = false; | ||
| 41 | |||
| 42 | // matrix state buffer(1:on, 0:off) | ||
| 43 | static uint8_t *matrix; | ||
| 44 | static uint8_t _matrix0[MATRIX_ROWS]; | ||
| 45 | |||
| 46 | static void register_key(uint8_t key); | ||
| 47 | |||
| 48 | |||
| 49 | inline | ||
| 50 | uint8_t matrix_rows(void) | ||
| 51 | { | ||
| 52 | return MATRIX_ROWS; | ||
| 53 | } | ||
| 54 | |||
| 55 | inline | ||
| 56 | uint8_t matrix_cols(void) | ||
| 57 | { | ||
| 58 | return MATRIX_COLS; | ||
| 59 | } | ||
| 60 | |||
| 61 | void matrix_init(void) | ||
| 62 | { | ||
| 63 | print_enable = true; | ||
| 64 | debug_enable = true; | ||
| 65 | debug_matrix = false; | ||
| 66 | debug_keyboard = false; | ||
| 67 | debug_mouse = false; | ||
| 68 | print("debug enabled.\n"); | ||
| 69 | |||
| 70 | m0110_init(); | ||
| 71 | // initialize matrix state: all keys off | ||
| 72 | for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00; | ||
| 73 | matrix = _matrix0; | ||
| 74 | return; | ||
| 75 | } | ||
| 76 | |||
| 77 | uint8_t matrix_scan(void) | ||
| 78 | { | ||
| 79 | uint8_t key; | ||
| 80 | |||
| 81 | is_modified = false; | ||
| 82 | key = m0110_recv_key(); | ||
| 83 | |||
| 84 | #ifdef MATRIX_HAS_LOCKING_CAPS | ||
| 85 | // Send Caps key up event | ||
| 86 | if (matrix_is_on(ROW(CAPS), COL(CAPS))) { | ||
| 87 | is_modified = true; | ||
| 88 | register_key(CAPS_BREAK); | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | if (key == M0110_NULL) { | ||
| 92 | return 0; | ||
| 93 | } else if (key == M0110_ERROR) { | ||
| 94 | return 0; | ||
| 95 | } else { | ||
| 96 | #ifdef MATRIX_HAS_LOCKING_CAPS | ||
| 97 | if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { | ||
| 98 | // CAPS LOCK on: | ||
| 99 | // Ignore LockingCaps key down event | ||
| 100 | if (key == CAPS) return 0; | ||
| 101 | // Convert LockingCaps key up event into down event | ||
| 102 | if (key == CAPS_BREAK) key = CAPS; | ||
| 103 | } else { | ||
| 104 | // CAPS LOCK off: | ||
| 105 | // Ignore LockingCaps key up event | ||
| 106 | if (key == CAPS_BREAK) return 0; | ||
| 107 | } | ||
| 108 | #endif | ||
| 109 | is_modified = true; | ||
| 110 | register_key(key); | ||
| 111 | } | ||
| 112 | |||
| 113 | if (debug_enable) { | ||
| 114 | print("["); phex(key); print("]\n"); | ||
| 115 | } | ||
| 116 | return 1; | ||
| 117 | } | ||
| 118 | |||
| 119 | bool matrix_is_modified(void) | ||
| 120 | { | ||
| 121 | return is_modified; | ||
| 122 | } | ||
| 123 | |||
| 124 | inline | ||
| 125 | bool matrix_has_ghost(void) | ||
| 126 | { | ||
| 127 | return false; | ||
| 128 | } | ||
| 129 | |||
| 130 | inline | ||
| 131 | bool matrix_is_on(uint8_t row, uint8_t col) | ||
| 132 | { | ||
| 133 | return (matrix[row] & (1<<col)); | ||
| 134 | } | ||
| 135 | |||
| 136 | inline | ||
| 137 | uint8_t matrix_get_row(uint8_t row) | ||
| 138 | { | ||
| 139 | return matrix[row]; | ||
| 140 | } | ||
| 141 | |||
| 142 | void matrix_print(void) | ||
| 143 | { | ||
| 144 | print("\nr/c 01234567\n"); | ||
| 145 | for (uint8_t row = 0; row < matrix_rows(); row++) { | ||
| 146 | phex(row); print(": "); | ||
| 147 | pbin_reverse(matrix_get_row(row)); | ||
| 148 | print("\n"); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | uint8_t matrix_key_count(void) | ||
| 153 | { | ||
| 154 | uint8_t count = 0; | ||
| 155 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 156 | count += bitpop(matrix[i]); | ||
| 157 | } | ||
| 158 | return count; | ||
| 159 | } | ||
| 160 | |||
| 161 | inline | ||
| 162 | static void register_key(uint8_t key) | ||
| 163 | { | ||
| 164 | if (key&0x80) { | ||
| 165 | matrix[ROW(key)] &= ~(1<<COL(key)); | ||
| 166 | } else { | ||
| 167 | matrix[ROW(key)] |= (1<<COL(key)); | ||
| 168 | } | ||
| 169 | } | ||
diff --git a/converter/news_usb/Makefile.pjrc b/converter/news_usb/Makefile.pjrc new file mode 100644 index 000000000..376133ad5 --- /dev/null +++ b/converter/news_usb/Makefile.pjrc | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | # | ||
| 2 | # Makefile for PJRC Teensy | ||
| 3 | # | ||
| 4 | |||
| 5 | |||
| 6 | # Target file name (without extension). | ||
| 7 | TARGET = news_usb_pjrc | ||
| 8 | |||
| 9 | # Directory common source filess exist | ||
| 10 | TOP_DIR = ../.. | ||
| 11 | |||
| 12 | # Directory keyboard dependent files exist | ||
| 13 | TARGET_DIR = . | ||
| 14 | |||
| 15 | # keyboard dependent files | ||
| 16 | SRC = main.c \ | ||
| 17 | keymap.c \ | ||
| 18 | matrix.c \ | ||
| 19 | led.c \ | ||
| 20 | news.c | ||
| 21 | |||
| 22 | CONFIG_H = config_pjrc.h | ||
| 23 | |||
| 24 | |||
| 25 | # MCU name, you MUST set this to match the board you are using | ||
| 26 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 27 | #MCU = at90usb162 # Teensy 1.0 | ||
| 28 | MCU = atmega32u4 # Teensy 2.0 | ||
| 29 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 30 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 31 | |||
| 32 | |||
| 33 | # Processor frequency. | ||
| 34 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 35 | # so your program will run at the correct speed. You should also set this | ||
| 36 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 37 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 38 | F_CPU = 16000000 | ||
| 39 | |||
| 40 | |||
| 41 | # Build Options | ||
| 42 | # *Comment out* to disable the options. | ||
| 43 | # | ||
| 44 | MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 45 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 46 | NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | #---------------- Programming Options -------------------------- | ||
| 51 | PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | ||
| 52 | |||
| 53 | |||
| 54 | |||
| 55 | include $(TOP_DIR)/protocol/pjrc.mk | ||
| 56 | include $(TOP_DIR)/protocol.mk | ||
| 57 | include $(TOP_DIR)/common.mk | ||
| 58 | include $(TOP_DIR)/rules.mk | ||
diff --git a/converter/news_usb/config_pjrc.h b/converter/news_usb/config_pjrc.h new file mode 100644 index 000000000..e9cf7dedb --- /dev/null +++ b/converter/news_usb/config_pjrc.h | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | /* controller configuration */ | ||
| 22 | #include "controller_teensy.h" | ||
| 23 | |||
| 24 | #define VENDOR_ID 0xFEED | ||
| 25 | #define PRODUCT_ID 0x5021 | ||
| 26 | #define MANUFACTURER t.m.k. | ||
| 27 | #define PRODUCT SONY NEWS keyboard converter | ||
| 28 | #define DESCRIPTION converts SONY NEWS protocol into USB | ||
| 29 | |||
| 30 | |||
| 31 | /* matrix size */ | ||
| 32 | #define MATRIX_ROWS 16 // keycode bit: 3-0 | ||
| 33 | #define MATRIX_COLS 8 // keycode bit: 6-4 | ||
| 34 | |||
| 35 | |||
| 36 | /* key combination for command */ | ||
| 37 | #define IS_COMMAND() ( \ | ||
| 38 | keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \ | ||
| 39 | keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \ | ||
| 40 | ) | ||
| 41 | |||
| 42 | |||
| 43 | /* mouse keys */ | ||
| 44 | #ifdef MOUSEKEY_ENABLE | ||
| 45 | # define MOUSEKEY_DELAY_TIME 255 | ||
| 46 | #endif | ||
| 47 | |||
| 48 | |||
| 49 | /* Asynchronous USART | ||
| 50 | * 8-data bit, non parity, 1-stop bit, no flow control | ||
| 51 | */ | ||
| 52 | #ifdef __AVR_ATmega32U4__ | ||
| 53 | # define NEWS_KBD_RX_VECT USART1_RX_vect | ||
| 54 | # define NEWS_KBD_RX_DATA UDR1 | ||
| 55 | # define NEWS_KBD_RX_BAUD 9600 | ||
| 56 | # define NEWS_KBD_RX_UBBR ((F_CPU/(16UL*NEWS_KBD_RX_BAUD))-1) | ||
| 57 | # define NEWS_KBD_RX_INIT() do { \ | ||
| 58 | UBRR1L = (uint8_t) NEWS_KBD_RX_UBBR; \ | ||
| 59 | UBRR1H = (uint8_t) (NEWS_KBD_RX_UBBR>>8); \ | ||
| 60 | UCSR1B |= (1<<RXCIE1) | (1<<RXEN1); \ | ||
| 61 | } while(0) | ||
| 62 | #else | ||
| 63 | # error "USART configuration is needed." | ||
| 64 | #endif | ||
| 65 | |||
| 66 | #endif | ||
diff --git a/converter/news_usb/keymap.c b/converter/news_usb/keymap.c new file mode 100644 index 000000000..4bd556ba0 --- /dev/null +++ b/converter/news_usb/keymap.c | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdbool.h> | ||
| 20 | #include <avr/pgmspace.h> | ||
| 21 | #include "usb_keycodes.h" | ||
| 22 | #include "util.h" | ||
| 23 | #include "keymap.h" | ||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | // Following macros help you to define a keymap with the form of actual keyboard layout. | ||
| 29 | |||
| 30 | /* SONY NEWS NWP-5461 */ | ||
| 31 | #define KEYMAP( \ | ||
| 32 | K7A, K01,K02,K03,K04,K05, K06,K07,K08,K09,K0A, K68,K69, K64,K65,K52, \ | ||
| 33 | K0B,K0C,K0D,K0E,K0F,K10,K11,K12,K13,K14,K15,K16,K17,K18,K19, K6A, K4B,K4C,K4D,K4E, \ | ||
| 34 | K1A,K1B,K1C,K1D,K1E,K1F,K20,K21,K22,K23,K24,K25,K26,K27, K6B, K4F,K50,K51,K56, \ | ||
| 35 | K28,K29,K2A,K2B,K2C,K2D,K2E,K2F,K30,K31,K32,K33,K34, K35, K6C, K53,K54,K55,K5A, \ | ||
| 36 | K36,K37,K38,K39,K3A,K3B,K3C,K3D,K3E,K3F,K40,K41, K42, K6D, K57,K59,K58, \ | ||
| 37 | K43,K44,K45, K46, K47, K48,K49,K4A, K6E, K66,K5B,K5C,K5D \ | ||
| 38 | ) { \ | ||
| 39 | { KB_NO, KB_##K01, KB_##K02, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \ | ||
| 40 | { KB_##K08, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_##K0F }, \ | ||
| 41 | { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_##K17 }, \ | ||
| 42 | { KB_##K18, KB_##K19, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_##K1F }, \ | ||
| 43 | { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, \ | ||
| 44 | { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, \ | ||
| 45 | { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_##K37 }, \ | ||
| 46 | { KB_##K38, KB_##K39, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_##K3F }, \ | ||
| 47 | { KB_##K40, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_##K47 }, \ | ||
| 48 | { KB_##K48, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_##K4F }, \ | ||
| 49 | { KB_##K50, KB_##K51, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, \ | ||
| 50 | { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_##K5C, KB_##K5D, KB_NO, KB_NO }, \ | ||
| 51 | { KB_NO, KB_NO, KB_NO, KB_NO, KB_##K64, KB_##K65, KB_##K66, KB_NO }, \ | ||
| 52 | { KB_##K68, KB_##K69, KB_##K6A, KB_##K6B, KB_##K6C, KB_##K6D, KB_##K6E, KB_NO }, \ | ||
| 53 | { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, }, \ | ||
| 54 | { KB_NO, KB_NO, KB_##K7A, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO } \ | ||
| 55 | } | ||
| 56 | |||
| 57 | |||
| 58 | // Assign Fn key(0-7) to a layer to which switch with the Fn key pressed. | ||
| 59 | static const uint8_t PROGMEM fn_layer[] = { | ||
| 60 | 0, // Fn0 | ||
| 61 | 0, // Fn1 | ||
| 62 | 0, // Fn2 | ||
| 63 | 0, // Fn3 | ||
| 64 | 0, // Fn4 | ||
| 65 | 0, // Fn5 | ||
| 66 | 0, // Fn6 | ||
| 67 | 0 // Fn7 | ||
| 68 | }; | ||
| 69 | |||
| 70 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. | ||
| 71 | // See layer.c for details. | ||
| 72 | static const uint8_t PROGMEM fn_keycode[] = { | ||
| 73 | KB_NO, // Fn0 | ||
| 74 | KB_NO, // Fn1 | ||
| 75 | KB_NO, // Fn2 | ||
| 76 | KB_NO, // Fn3 | ||
| 77 | KB_NO, // Fn4 | ||
| 78 | KB_NO, // Fn5 | ||
| 79 | KB_NO, // Fn6 | ||
| 80 | KB_NO // Fn7 | ||
| 81 | }; | ||
| 82 | |||
| 83 | |||
| 84 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 85 | /* 0: default | ||
| 86 | * ,---. ,------------------------, ,------------------------. ,---------. | ||
| 87 | * |Pow| | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10| | F11| F12| ,-----------. | ||
| 88 | * `---' `------------------------' `------------------------' `---------' | *| /| +| | ||
| 89 | * ,-------------------------------------------------------------. ,---. ,---------------| | ||
| 90 | * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| BS | |Hlp| | 7| 8| 9| -| | ||
| 91 | * |-------------------------------------------------------------| |---| |---------------| | ||
| 92 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Del| | |Ins| | 4| 5| 6| ,| | ||
| 93 | * |---------------------------------------------------------' | |---| |---------------| | ||
| 94 | * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '| `|Return| |Clr| | 1| 2| 3| | | ||
| 95 | * |-------------------------------------------------------------| |---| |-----------|Ent| | ||
| 96 | * |Shift | Z| X| C| V| B| N| M| ,| ,| /| |Shift | |PgU| | 0| .| Up| | | ||
| 97 | * |-------------------------------------------------------------| |---| |---------------| | ||
| 98 | * |Alt |Gui |Alt | Space | |Gui|App|Ctrl | |PgD| |Tab|Lef|Dow|Rig| | ||
| 99 | * `-------------------------------------------------------------' `---' `---------------' | ||
| 100 | */ | ||
| 101 | KEYMAP( | ||
| 102 | PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PAST,PSLS,PPLS, | ||
| 103 | ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,BSPC, HELP, P7, P8, P9, PMNS, | ||
| 104 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,DEL, INS, P4, P5, P6, PCMM, | ||
| 105 | CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT,GRV, ENT, CLR, P1, P2, P3, PENT, | ||
| 106 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,RO, RSFT, PGUP, P0, PDOT,UP, | ||
| 107 | LCTL,LGUI,LALT, SPC, ERAS, RALT,RGUI,RCTL, PGDN, TAB, LEFT,DOWN,RGHT | ||
| 108 | ), | ||
| 109 | }; | ||
| 110 | |||
| 111 | |||
| 112 | uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | ||
| 113 | { | ||
| 114 | return pgm_read_byte(&keymaps[(layer)][(row)][(col)]); | ||
| 115 | } | ||
| 116 | |||
| 117 | uint8_t keymap_fn_layer(uint8_t fn_bits) | ||
| 118 | { | ||
| 119 | return pgm_read_byte(&fn_layer[biton(fn_bits)]); | ||
| 120 | } | ||
| 121 | |||
| 122 | uint8_t keymap_fn_keycode(uint8_t fn_bits) | ||
| 123 | { | ||
| 124 | return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | ||
| 125 | } | ||
diff --git a/converter/news_usb/led.c b/converter/news_usb/led.c new file mode 100644 index 000000000..51e601318 --- /dev/null +++ b/converter/news_usb/led.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "stdint.h" | ||
| 19 | #include "news.h" | ||
| 20 | #include "led.h" | ||
| 21 | |||
| 22 | |||
| 23 | void led_set(uint8_t usb_led) | ||
| 24 | { | ||
| 25 | // not supported now | ||
| 26 | } | ||
diff --git a/converter/news_usb/matrix.c b/converter/news_usb/matrix.c new file mode 100644 index 000000000..bf363e7d9 --- /dev/null +++ b/converter/news_usb/matrix.c | |||
| @@ -0,0 +1,141 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdbool.h> | ||
| 20 | #include <avr/io.h> | ||
| 21 | #include <util/delay.h> | ||
| 22 | #include "print.h" | ||
| 23 | #include "util.h" | ||
| 24 | #include "news.h" | ||
| 25 | #include "matrix.h" | ||
| 26 | |||
| 27 | |||
| 28 | /* | ||
| 29 | * Matrix Array usage: | ||
| 30 | * | ||
| 31 | * ROW: 16 | ||
| 32 | * COL:8 | ||
| 33 | * | ||
| 34 | * 8bit wide | ||
| 35 | * +---------+ | ||
| 36 | * 0|00 ... 07| | ||
| 37 | * 1|08 ... 0F| | ||
| 38 | * :| ... | | ||
| 39 | * :| ... | | ||
| 40 | * E|70 ... 77| | ||
| 41 | * F|78 ... 7F| | ||
| 42 | * +---------+ | ||
| 43 | * | ||
| 44 | */ | ||
| 45 | static uint8_t matrix[MATRIX_ROWS]; | ||
| 46 | #define ROW(code) ((code>>3)&0xF) | ||
| 47 | #define COL(code) (code&0x07) | ||
| 48 | |||
| 49 | static bool is_modified = false; | ||
| 50 | |||
| 51 | |||
| 52 | inline | ||
| 53 | uint8_t matrix_rows(void) | ||
| 54 | { | ||
| 55 | return MATRIX_ROWS; | ||
| 56 | } | ||
| 57 | |||
| 58 | inline | ||
| 59 | uint8_t matrix_cols(void) | ||
| 60 | { | ||
| 61 | return MATRIX_COLS; | ||
| 62 | } | ||
| 63 | |||
| 64 | void matrix_init(void) | ||
| 65 | { | ||
| 66 | news_init(); | ||
| 67 | |||
| 68 | // initialize matrix state: all keys off | ||
| 69 | for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; | ||
| 70 | |||
| 71 | return; | ||
| 72 | } | ||
| 73 | |||
| 74 | uint8_t matrix_scan(void) | ||
| 75 | { | ||
| 76 | is_modified = false; | ||
| 77 | |||
| 78 | uint8_t code; | ||
| 79 | code = news_recv(); | ||
| 80 | if (code == 0) { | ||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | phex(code); print(" "); | ||
| 85 | if (code&0x80) { | ||
| 86 | // break code | ||
| 87 | if (matrix_is_on(ROW(code), COL(code))) { | ||
| 88 | matrix[ROW(code)] &= ~(1<<COL(code)); | ||
| 89 | is_modified = true; | ||
| 90 | } | ||
| 91 | } else { | ||
| 92 | // make code | ||
| 93 | if (!matrix_is_on(ROW(code), COL(code))) { | ||
| 94 | matrix[ROW(code)] |= (1<<COL(code)); | ||
| 95 | is_modified = true; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | return code; | ||
| 99 | } | ||
| 100 | |||
| 101 | bool matrix_is_modified(void) | ||
| 102 | { | ||
| 103 | return is_modified; | ||
| 104 | } | ||
| 105 | |||
| 106 | inline | ||
| 107 | bool matrix_has_ghost(void) | ||
| 108 | { | ||
| 109 | return false; | ||
| 110 | } | ||
| 111 | |||
| 112 | inline | ||
| 113 | bool matrix_is_on(uint8_t row, uint8_t col) | ||
| 114 | { | ||
| 115 | return (matrix[row] & (1<<col)); | ||
| 116 | } | ||
| 117 | |||
| 118 | inline | ||
| 119 | uint8_t matrix_get_row(uint8_t row) | ||
| 120 | { | ||
| 121 | return matrix[row]; | ||
| 122 | } | ||
| 123 | |||
| 124 | void matrix_print(void) | ||
| 125 | { | ||
| 126 | print("\nr/c 01234567\n"); | ||
| 127 | for (uint8_t row = 0; row < matrix_rows(); row++) { | ||
| 128 | phex(row); print(": "); | ||
| 129 | pbin_reverse(matrix_get_row(row)); | ||
| 130 | print("\n"); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | uint8_t matrix_key_count(void) | ||
| 135 | { | ||
| 136 | uint8_t count = 0; | ||
| 137 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 138 | count += bitpop(matrix[i]); | ||
| 139 | } | ||
| 140 | return count; | ||
| 141 | } | ||
diff --git a/converter/ps2_usb/Makefile b/converter/ps2_usb/Makefile new file mode 100644 index 000000000..0bba191a3 --- /dev/null +++ b/converter/ps2_usb/Makefile | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | # | ||
| 2 | # Makefile for PJRC Teensy | ||
| 3 | # | ||
| 4 | |||
| 5 | |||
| 6 | # Target file name (without extension). | ||
| 7 | TARGET = ps2_usb_pjrc | ||
| 8 | |||
| 9 | # Directory common source filess exist | ||
| 10 | TOP_DIR = ../.. | ||
| 11 | |||
| 12 | # Directory keyboard dependent files exist | ||
| 13 | TARGET_DIR = . | ||
| 14 | |||
| 15 | # keyboard dependent files | ||
| 16 | SRC = main.c \ | ||
| 17 | keymap.c \ | ||
| 18 | matrix.c \ | ||
| 19 | led.c \ | ||
| 20 | ps2.c | ||
| 21 | |||
| 22 | CONFIG_H = config_pjrc.h | ||
| 23 | |||
| 24 | |||
| 25 | # MCU name, you MUST set this to match the board you are using | ||
| 26 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 27 | #MCU = at90usb162 # Teensy 1.0 | ||
| 28 | MCU = atmega32u4 # Teensy 2.0 | ||
| 29 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 30 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 31 | |||
| 32 | |||
| 33 | # Processor frequency. | ||
| 34 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 35 | # so your program will run at the correct speed. You should also set this | ||
| 36 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 37 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 38 | F_CPU = 16000000 | ||
| 39 | |||
| 40 | |||
| 41 | # Build Options | ||
| 42 | # *Comment out* to disable the options. | ||
| 43 | # | ||
| 44 | MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 45 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 46 | NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | #---------------- Programming Options -------------------------- | ||
| 51 | PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | ||
| 52 | |||
| 53 | |||
| 54 | |||
| 55 | include $(TOP_DIR)/protocol/pjrc.mk | ||
| 56 | include $(TOP_DIR)/protocol.mk | ||
| 57 | include $(TOP_DIR)/common.mk | ||
| 58 | include $(TOP_DIR)/rules.mk | ||
diff --git a/converter/ps2_usb/Makefile.pjrc_usart b/converter/ps2_usb/Makefile.pjrc_usart new file mode 100644 index 000000000..3dad7e2f8 --- /dev/null +++ b/converter/ps2_usb/Makefile.pjrc_usart | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | # | ||
| 2 | # Makefile for PJRC Teensy | ||
| 3 | # | ||
| 4 | |||
| 5 | |||
| 6 | # Target file name (without extension). | ||
| 7 | TARGET = ps2_usb_pjrc_usart | ||
| 8 | |||
| 9 | # Directory common source filess exist | ||
| 10 | TOP_DIR = ../.. | ||
| 11 | |||
| 12 | # Directory keyboard dependent files exist | ||
| 13 | TARGET_DIR = . | ||
| 14 | |||
| 15 | # keyboard dependent files | ||
| 16 | SRC = main.c \ | ||
| 17 | keymap.c \ | ||
| 18 | matrix.c \ | ||
| 19 | led.c \ | ||
| 20 | ps2_usart.c | ||
| 21 | |||
| 22 | CONFIG_H = config_pjrc_usart.h | ||
| 23 | |||
| 24 | |||
| 25 | # MCU name, you MUST set this to match the board you are using | ||
| 26 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 27 | #MCU = at90usb162 # Teensy 1.0 | ||
| 28 | MCU = atmega32u4 # Teensy 2.0 | ||
| 29 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 30 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 31 | |||
| 32 | |||
| 33 | # Processor frequency. | ||
| 34 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 35 | # so your program will run at the correct speed. You should also set this | ||
| 36 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 37 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 38 | F_CPU = 16000000 | ||
| 39 | |||
| 40 | |||
| 41 | # Build Options | ||
| 42 | # *Comment out* to disable the options. | ||
| 43 | # | ||
| 44 | MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 45 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 46 | NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | #---------------- Programming Options -------------------------- | ||
| 51 | PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | ||
| 52 | |||
| 53 | |||
| 54 | |||
| 55 | include $(TOP_DIR)/protocol/pjrc.mk | ||
| 56 | include $(TOP_DIR)/protocol.mk | ||
| 57 | include $(TOP_DIR)/common.mk | ||
| 58 | include $(TOP_DIR)/rules.mk | ||
diff --git a/converter/ps2_usb/Makefile.vusb b/converter/ps2_usb/Makefile.vusb new file mode 100644 index 000000000..4d5240c30 --- /dev/null +++ b/converter/ps2_usb/Makefile.vusb | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | # | ||
| 2 | # Makefile for V-USB | ||
| 3 | # | ||
| 4 | |||
| 5 | |||
| 6 | # Target file name (without extension). | ||
| 7 | TARGET = ps2_usb_vusb | ||
| 8 | |||
| 9 | # Directory common source filess exist | ||
| 10 | TOP_DIR = ../.. | ||
| 11 | |||
| 12 | # Directory keyboard dependent files exist | ||
| 13 | TARGET_DIR = . | ||
| 14 | |||
| 15 | # keyboard dependent files | ||
| 16 | SRC = main.c \ | ||
| 17 | keymap.c \ | ||
| 18 | matrix.c \ | ||
| 19 | led.c \ | ||
| 20 | ps2_usart.c | ||
| 21 | |||
| 22 | CONFIG_H = config_vusb.h | ||
| 23 | |||
| 24 | |||
| 25 | # V-USB debug level: To use ps2_usart.c level must be 0 | ||
| 26 | # ps2_usart.c requires USART to receive PS/2 signal. | ||
| 27 | OPT_DEFS = -DDEBUG_LEVEL=0 | ||
| 28 | |||
| 29 | |||
| 30 | # MCU name, you MUST set this to match the board you are using | ||
| 31 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 32 | #MCU = at90usb162 # Teensy 1.0 | ||
| 33 | #MCU = atmega32u4 # Teensy 2.0 | ||
| 34 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 35 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 36 | MCU = atmega168 | ||
| 37 | |||
| 38 | |||
| 39 | # Processor frequency. | ||
| 40 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 41 | # so your program will run at the correct speed. You should also set this | ||
| 42 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 43 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 44 | F_CPU = 20000000 | ||
| 45 | |||
| 46 | |||
| 47 | # Build Options | ||
| 48 | # comment out to disable the options. | ||
| 49 | # | ||
| 50 | MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 51 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 52 | #NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 53 | NO_UART = yes # UART is unavailable | ||
| 54 | |||
| 55 | |||
| 56 | |||
| 57 | #---------------- Programming Options -------------------------- | ||
| 58 | AVRDUDE = avrdude | ||
| 59 | # Type: avrdude -c ? to get a full listing. | ||
| 60 | AVRDUDE_PROGRAMMER = usbasp | ||
| 61 | AVRDUDE_PORT = | ||
| 62 | AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex | ||
| 63 | #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep | ||
| 64 | |||
| 65 | # Uncomment the following if you want avrdude's erase cycle counter. | ||
| 66 | # Note that this counter needs to be initialized first using -Yn, | ||
| 67 | # see avrdude manual. | ||
| 68 | #AVRDUDE_ERASE_COUNTER = -y | ||
| 69 | |||
| 70 | # Uncomment the following if you do /not/ wish a verification to be | ||
| 71 | # performed after programming the device. | ||
| 72 | #AVRDUDE_NO_VERIFY = -V | ||
| 73 | |||
| 74 | # Increase verbosity level. Please use this when submitting bug | ||
| 75 | # reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> | ||
| 76 | # to submit bug reports. | ||
| 77 | #AVRDUDE_VERBOSE = -v -v | ||
| 78 | |||
| 79 | #AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) | ||
| 80 | AVRDUDE_FLAGS = -p $(MCU) -c $(AVRDUDE_PROGRAMMER) | ||
| 81 | AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) | ||
| 82 | AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) | ||
| 83 | AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) | ||
| 84 | |||
| 85 | PROGRAM_CMD = $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) | ||
| 86 | |||
| 87 | |||
| 88 | |||
| 89 | include $(TOP_DIR)/protocol/vusb.mk | ||
| 90 | include $(TOP_DIR)/protocol.mk | ||
| 91 | include $(TOP_DIR)/common.mk | ||
| 92 | include $(TOP_DIR)/rules.mk | ||
diff --git a/converter/ps2_usb/README b/converter/ps2_usb/README new file mode 100644 index 000000000..c10393e5e --- /dev/null +++ b/converter/ps2_usb/README | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | PS/2 to USB keyboard converter | ||
| 2 | ============================== | ||
| 3 | This firmware converts PS/2 keyboard protocol to USB and for now supports only Scan Code Set 2. | ||
| 4 | This will works on USB AVR(ATMega32U4, AT90USB) or V-USB. | ||
| 5 | |||
| 6 | |||
| 7 | Features | ||
| 8 | -------- | ||
| 9 | Mouse keys | ||
| 10 | You can emulates mouse move and button click using keyboard. | ||
| 11 | System/Media control | ||
| 12 | You can sends Power event, Volume down/up and Mute. | ||
| 13 | USB NKRO(actually 120KRO+8Modifiers) | ||
| 14 | You can tolggles NKRO feature. | ||
| 15 | Keymap customization | ||
| 16 | You can customize keymaps easily by editing source code. See keymap.c. | ||
| 17 | |||
| 18 | |||
| 19 | PS/2 signal handling implementations | ||
| 20 | ------------------------------------ | ||
| 21 | Following three methods are used to implement PS/2 signal handling. | ||
| 22 | a. Simple and stupid wait & read loop(intensive use of cycles) | ||
| 23 | This is implemented with (expected) portable C code for reference. See ps2.c. | ||
| 24 | b. Interrupt driven | ||
| 25 | See ps2_intr.c | ||
| 26 | c. Using USART hardware module(no cycle needed) | ||
| 27 | This uses AVR USART function to recevie PS/2 signal and be used in V-USB converter. | ||
| 28 | See ps2_usart.c. | ||
| 29 | |||
| 30 | |||
| 31 | Build Converter | ||
| 32 | --------------- | ||
| 33 | Connect PS/2 keyboard into Teensy with 4 lines(Vcc, GND, Data, Clock). | ||
| 34 | For a. Simple and stupid and b. Interrupt implementaion: | ||
| 35 | By default Clock is on PF0 and Data on PF1. | ||
| 36 | You can change this pin configuration by editing config_pjrc.h. | ||
| 37 | In this photo Vcc is yellow, GND is green, Data is red and Clock is black. | ||
| 38 | http://img17.imageshack.us/img17/7243/201101181933.jpg | ||
| 39 | For c. USART implementation: | ||
| 40 | In case of Teensny(ATMega32u4) CLock is on PD5 and Data on PD2. | ||
| 41 | |||
| 42 | |||
| 43 | Build Frimware | ||
| 44 | -------------- | ||
| 45 | 1. Edit Makefile for build options and MCU setting. | ||
| 46 | Use 'atmega32u4' for Teensy 2.0 or 'at90usb1286' for Teensy++ 2.0. | ||
| 47 | 2. make | ||
| 48 | Just type 'make' in a terminal. | ||
| 49 | Use '-f Makefile.pjrc_intr' option to use b. Interrupt. | ||
| 50 | Use '-f Makefile.pjrc_usart' option to use c. USART. | ||
| 51 | Use '-f Makefile.vusb' option to build V-USB converter. | ||
| 52 | 3. program with Teensy Loader. | ||
| 53 | http://www.pjrc.com/teensy/loader.html | ||
| 54 | |||
| 55 | |||
| 56 | Demonstration of Features | ||
| 57 | ------------------------- | ||
| 58 | In default configuration, you can try several keymaps, mousekeys and USB NKRO. | ||
| 59 | Use following magic key combinations to enable some features. | ||
| 60 | |||
| 61 | keymaps and NKRO: | ||
| 62 | Magic+0: Qwerty with mousekeys(default) | ||
| 63 | Magic+1: Qwerty without mousekeys | ||
| 64 | Magic+2: Colemak | ||
| 65 | Magic+3: Dvorak | ||
| 66 | Magic+4: Workman | ||
| 67 | Magic+N: toggles NKRO/6KRO(6KRO by default) | ||
| 68 | Magic+Esc: sends Power Event(Power button) | ||
| 69 | |||
| 70 | where Magic=(LShift+RShift) or (LControl+RShift) | ||
| 71 | |||
| 72 | Fn layer function: | ||
| 73 | Fn0+(hjkl): Mousekey move(vi cursor like) | ||
| 74 | Fn0+(yuio): Mouse wheel(left,down,up,right) | ||
| 75 | Fn0+space: Mouse left button | ||
| 76 | Fn0+(mnb): Mouse buttons(m=left, n=right, b=middle) | ||
| 77 | Fn0+(zxc): Media control(Volup, Voldown, Mute) | ||
| 78 | Fn1+(hjkl): Cursor move(vi cursor like) | ||
| 79 | Fn1+(nm,.): Cursor move(Home,PageDown,PageUp,End) | ||
| 80 | |||
| 81 | where Fn0=;, Fn1=/ | ||
| 82 | |||
| 83 | |||
| 84 | Keymap | ||
| 85 | ------ | ||
| 86 | You can change a keymap by editing code of keymap.c like following. | ||
| 87 | How to define the keymap is probably obvious. You can find key symbols in usb_keycodes.h. | ||
| 88 | To define keymap layer switching may needs a bit of your effort at this time. | ||
| 89 | |||
| 90 | /* Default Layer: plain keymap | ||
| 91 | * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------. | ||
| 92 | * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|Slp|Wak| | ||
| 93 | * `---' `---------------' `---------------' `---------------' `-----------' `-----------' | ||
| 94 | * ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 95 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| /| *| -| | ||
| 96 | * |-----------------------------------------------------------| |-----------| |---------------| | ||
| 97 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| | | ||
| 98 | * |-----------------------------------------------------------| `-----------' |-----------| +| | ||
| 99 | * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| | | ||
| 100 | * |-----------------------------------------------------------| ,---. |---------------| | ||
| 101 | * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| | | ||
| 102 | * |-----------------------------------------------------------| ,-----------. |-----------|Ent| | ||
| 103 | * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| |Lef|Dow|Rig| | 0| .| | | ||
| 104 | * `-----------------------------------------------------------' `-----------' `---------------' | ||
| 105 | */ | ||
| 106 | KEYMAP( | ||
| 107 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14, | ||
| 108 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 109 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9, | ||
| 110 | CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, | ||
| 111 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, | ||
| 112 | LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 113 | ), | ||
| 114 | |||
| 115 | |||
| 116 | EOF | ||
diff --git a/converter/ps2_usb/README.vusb b/converter/ps2_usb/README.vusb new file mode 100644 index 000000000..c92871bcd --- /dev/null +++ b/converter/ps2_usb/README.vusb | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | V-USB Support | ||
| 2 | ============= | ||
| 3 | You can also use this converter on ATmega(168/328) with V-USB instead of Teensy. | ||
| 4 | The converter on V-USB lacks some features for now: USB NKRO and System/Media control. | ||
| 5 | |||
| 6 | To build a firmware use Makefile.vusb instead of Makefile. | ||
| 7 | |||
| 8 | |||
| 9 | Circuit | ||
| 10 | ------- | ||
| 11 | +---+ +---------------+ | ||
| 12 | USB GND | | ATmega168 | | ||
| 13 | === C3 | | | ||
| 14 | 5V <-------+--------+---|Vcc,AVCC | PS/2 | ||
| 15 | R1 | | ==== | ||
| 16 | D- <----+--+-----R2-----|INT1 RXD|------->DATA | ||
| 17 | D+ <----|---+----R3-----|INT0 XCK|------->CLOCK | ||
| 18 | Z1 Z2 | | ->5V | ||
| 19 | GND<----+---+--+--+-----|GND | ->GND | ||
| 20 | | | | | | ||
| 21 | | C2-+--|XTAL1 | | ||
| 22 | | X1 | | | ||
| 23 | +--C3-+--|XTAL2 | | ||
| 24 | +---------------+ | ||
| 25 | R1: 1.5K Ohm | ||
| 26 | R2,R3: 68 Ohm | ||
| 27 | Z1,Z2: Zenner 3.6V | ||
| 28 | C1,C2: 22pF | ||
| 29 | C3: 0.1uF | ||
| 30 | X1: Crystal 20MHz(16MHz/12MHz) | ||
| 31 | |||
| 32 | |||
| 33 | This is my V-USB converter on breadboard. | ||
| 34 | [IMG]http://i.imgur.com/8jJCZl.jpg[/IMG] | ||
| 35 | |||
| 36 | |||
| 37 | EOF | ||
diff --git a/converter/ps2_usb/config_pjrc.h b/converter/ps2_usb/config_pjrc.h new file mode 100644 index 000000000..883ffab27 --- /dev/null +++ b/converter/ps2_usb/config_pjrc.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | /* controller configuration */ | ||
| 22 | #include "controller_teensy.h" | ||
| 23 | |||
| 24 | #define VENDOR_ID 0xFEED | ||
| 25 | #define PRODUCT_ID 0x6512 | ||
| 26 | #define MANUFACTURER t.m.k. | ||
| 27 | #define PRODUCT PS/2 keyboard converter | ||
| 28 | #define DESCRIPTION convert PS/2 keyboard to USB | ||
| 29 | |||
| 30 | |||
| 31 | /* matrix size */ | ||
| 32 | #define MATRIX_ROWS 32 // keycode bit: 3-0 | ||
| 33 | #define MATRIX_COLS 8 // keycode bit: 6-4 | ||
| 34 | |||
| 35 | |||
| 36 | /* key combination for command */ | ||
| 37 | #define IS_COMMAND() ( \ | ||
| 38 | keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \ | ||
| 39 | keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \ | ||
| 40 | ) | ||
| 41 | |||
| 42 | |||
| 43 | /* mouse keys */ | ||
| 44 | #ifdef MOUSEKEY_ENABLE | ||
| 45 | # define MOUSEKEY_DELAY_TIME 255 | ||
| 46 | #endif | ||
| 47 | |||
| 48 | |||
| 49 | /* PS/2 lines */ | ||
| 50 | #define PS2_CLOCK_PORT PORTF | ||
| 51 | #define PS2_CLOCK_PIN PINF | ||
| 52 | #define PS2_CLOCK_DDR DDRF | ||
| 53 | #define PS2_CLOCK_BIT 0 | ||
| 54 | #define PS2_DATA_PORT PORTF | ||
| 55 | #define PS2_DATA_PIN PINF | ||
| 56 | #define PS2_DATA_DDR DDRF | ||
| 57 | #define PS2_DATA_BIT 1 | ||
| 58 | |||
| 59 | #endif | ||
diff --git a/converter/ps2_usb/config_pjrc_usart.h b/converter/ps2_usb/config_pjrc_usart.h new file mode 100644 index 000000000..83ddbf770 --- /dev/null +++ b/converter/ps2_usb/config_pjrc_usart.h | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | /* controller configuration */ | ||
| 22 | #include "controller_teensy.h" | ||
| 23 | |||
| 24 | #define VENDOR_ID 0xFEED | ||
| 25 | #define PRODUCT_ID 0x6513 | ||
| 26 | #define MANUFACTURER t.m.k. | ||
| 27 | #define PRODUCT PS/2 keyboard converter(USART) | ||
| 28 | #define DESCRIPTION convert PS/2 keyboard to USB | ||
| 29 | |||
| 30 | |||
| 31 | /* matrix size */ | ||
| 32 | #define MATRIX_ROWS 32 // keycode bit: 3-0 | ||
| 33 | #define MATRIX_COLS 8 // keycode bit: 6-4 | ||
| 34 | |||
| 35 | |||
| 36 | /* key combination for command */ | ||
| 37 | #define IS_COMMAND() ( \ | ||
| 38 | keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \ | ||
| 39 | keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \ | ||
| 40 | ) | ||
| 41 | |||
| 42 | |||
| 43 | /* mouse keys */ | ||
| 44 | #ifdef MOUSEKEY_ENABLE | ||
| 45 | # define MOUSEKEY_DELAY_TIME 255 | ||
| 46 | #endif | ||
| 47 | |||
| 48 | |||
| 49 | /* PS/2 lines */ | ||
| 50 | #define PS2_CLOCK_PORT PORTD | ||
| 51 | #define PS2_CLOCK_PIN PIND | ||
| 52 | #define PS2_CLOCK_DDR DDRD | ||
| 53 | #define PS2_CLOCK_BIT 5 | ||
| 54 | #define PS2_DATA_PORT PORTD | ||
| 55 | #define PS2_DATA_PIN PIND | ||
| 56 | #define PS2_DATA_DDR DDRD | ||
| 57 | #define PS2_DATA_BIT 2 | ||
| 58 | |||
| 59 | |||
| 60 | // synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge | ||
| 61 | // set DDR of CLOCK as input to be slave | ||
| 62 | #define PS2_USART_INIT() do { \ | ||
| 63 | PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \ | ||
| 64 | PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \ | ||
| 65 | UCSR1C = ((1 << UMSEL10) | \ | ||
| 66 | (3 << UPM10) | \ | ||
| 67 | (0 << USBS1) | \ | ||
| 68 | (3 << UCSZ10) | \ | ||
| 69 | (0 << UCPOL1)); \ | ||
| 70 | UCSR1A = 0; \ | ||
| 71 | UBRR1H = 0; \ | ||
| 72 | UBRR1L = 0; \ | ||
| 73 | } while (0) | ||
| 74 | #define PS2_USART_RX_INT_ON() do { \ | ||
| 75 | UCSR1B = ((1 << RXCIE1) | \ | ||
| 76 | (1 << RXEN1)); \ | ||
| 77 | } while (0) | ||
| 78 | #define PS2_USART_RX_POLL_ON() do { \ | ||
| 79 | UCSR1B = (1 << RXEN1); \ | ||
| 80 | } while (0) | ||
| 81 | #define PS2_USART_OFF() do { \ | ||
| 82 | UCSR1C = 0; \ | ||
| 83 | UCSR1B &= ~((1 << RXEN1) | \ | ||
| 84 | (1 << TXEN1)); \ | ||
| 85 | } while (0) | ||
| 86 | #define PS2_USART_RX_READY (UCSR1A & (1<<RXC1)) | ||
| 87 | #define PS2_USART_RX_DATA UDR1 | ||
| 88 | #define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1))) | ||
| 89 | #define PS2_USART_RX_VECT USART1_RX_vect | ||
| 90 | |||
| 91 | #endif | ||
diff --git a/converter/ps2_usb/config_vusb.h b/converter/ps2_usb/config_vusb.h new file mode 100644 index 000000000..afd2f7911 --- /dev/null +++ b/converter/ps2_usb/config_vusb.h | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | |||
| 22 | #define VENDOR_ID 0xFEED | ||
| 23 | #define PRODUCT_ID 0x2233 | ||
| 24 | // TODO: share these strings with usbconfig.h | ||
| 25 | // Edit usbconfig.h to change these. | ||
| 26 | #define MANUFACTURER t.m.k. | ||
| 27 | #define PRODUCT PS/2 keyboard converter | ||
| 28 | #define DESCRIPTION convert PS/2 keyboard to USB | ||
| 29 | |||
| 30 | |||
| 31 | /* matrix size */ | ||
| 32 | #define MATRIX_ROWS 32 // keycode bit: 3-0 | ||
| 33 | #define MATRIX_COLS 8 // keycode bit: 6-4 | ||
| 34 | |||
| 35 | |||
| 36 | /* key combination for command */ | ||
| 37 | #define IS_COMMAND() ( \ | ||
| 38 | keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \ | ||
| 39 | keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \ | ||
| 40 | ) | ||
| 41 | |||
| 42 | |||
| 43 | /* mouse keys */ | ||
| 44 | #ifdef MOUSEKEY_ENABLE | ||
| 45 | # define MOUSEKEY_DELAY_TIME 255 | ||
| 46 | #endif | ||
| 47 | |||
| 48 | |||
| 49 | /* PS/2 lines */ | ||
| 50 | #define PS2_CLOCK_PORT PORTD | ||
| 51 | #define PS2_CLOCK_PIN PIND | ||
| 52 | #define PS2_CLOCK_DDR DDRD | ||
| 53 | #define PS2_CLOCK_BIT 4 | ||
| 54 | #define PS2_DATA_PORT PORTD | ||
| 55 | #define PS2_DATA_PIN PIND | ||
| 56 | #define PS2_DATA_DDR DDRD | ||
| 57 | #define PS2_DATA_BIT 0 | ||
| 58 | |||
| 59 | |||
| 60 | // Synchronous USART is used to receive data from keyboard. | ||
| 61 | // Use RXD pin for PS/2 DATA line and XCK for PS/2 CLOCK. | ||
| 62 | // NOTE: This is recomended strongly if you use V-USB library. | ||
| 63 | #define PS2_USE_USART | ||
| 64 | |||
| 65 | // External or Pin Change Interrupt is used to receive data from keyboard. | ||
| 66 | // Use INT1 or PCINTxx for PS/2 CLOCK line. see below. | ||
| 67 | //#define PS2_USE_INT | ||
| 68 | |||
| 69 | |||
| 70 | #ifdef PS2_USE_USART | ||
| 71 | // synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge | ||
| 72 | // set DDR of CLOCK as input to be slave | ||
| 73 | #define PS2_USART_INIT() do { \ | ||
| 74 | PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \ | ||
| 75 | PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \ | ||
| 76 | UCSR0C = ((1 << UMSEL00) | \ | ||
| 77 | (3 << UPM00) | \ | ||
| 78 | (0 << USBS0) | \ | ||
| 79 | (3 << UCSZ00) | \ | ||
| 80 | (0 << UCPOL0)); \ | ||
| 81 | UCSR0A = 0; \ | ||
| 82 | UBRR0H = 0; \ | ||
| 83 | UBRR0L = 0; \ | ||
| 84 | } while (0) | ||
| 85 | #define PS2_USART_RX_INT_ON() do { \ | ||
| 86 | UCSR0B = ((1 << RXCIE0) | \ | ||
| 87 | (1 << RXEN0)); \ | ||
| 88 | } while (0) | ||
| 89 | #define PS2_USART_RX_POLL_ON() do { \ | ||
| 90 | UCSR0B = (1 << RXEN0); \ | ||
| 91 | } while (0) | ||
| 92 | #define PS2_USART_OFF() do { \ | ||
| 93 | UCSR0C = 0; \ | ||
| 94 | UCSR0B &= ~((1 << RXEN0) | \ | ||
| 95 | (1 << TXEN0)); \ | ||
| 96 | } while (0) | ||
| 97 | #define PS2_USART_RX_READY (UCSR0A & (1<<RXC0)) | ||
| 98 | #define PS2_USART_RX_DATA UDR0 | ||
| 99 | #define PS2_USART_ERROR (UCSR0A & ((1<<FE0) | (1<<DOR0) | (1<<UPE0))) | ||
| 100 | #define PS2_USART_RX_VECT USART_RX_vect | ||
| 101 | #endif | ||
| 102 | |||
| 103 | |||
| 104 | #ifdef PS2_USE_INT | ||
| 105 | /* INT1 | ||
| 106 | #define PS2_INT_INIT() do { \ | ||
| 107 | EICRA |= ((1<<ISC11) | \ | ||
| 108 | (0<<ISC10)); \ | ||
| 109 | } while (0) | ||
| 110 | #define PS2_INT_ON() do { \ | ||
| 111 | EIMSK |= (1<<INT1); \ | ||
| 112 | } while (0) | ||
| 113 | #define PS2_INT_OFF() do { \ | ||
| 114 | EIMSK &= ~(1<<INT1); \ | ||
| 115 | } while (0) | ||
| 116 | #define PS2_INT_VECT INT1_vect | ||
| 117 | */ | ||
| 118 | |||
| 119 | /* PCINT20 */ | ||
| 120 | #define PS2_INT_INIT() do { \ | ||
| 121 | PCICR |= (1<<PCIE2); \ | ||
| 122 | } while (0) | ||
| 123 | #define PS2_INT_ON() do { \ | ||
| 124 | PCMSK2 |= (1<<PCINT20); \ | ||
| 125 | } while (0) | ||
| 126 | #define PS2_INT_OFF() do { \ | ||
| 127 | PCMSK2 &= ~(1<<PCINT20); \ | ||
| 128 | PCICR &= ~(1<<PCIE2); \ | ||
| 129 | } while (0) | ||
| 130 | #define PS2_INT_VECT PCINT2_vect | ||
| 131 | #endif | ||
| 132 | |||
| 133 | #endif | ||
diff --git a/converter/ps2_usb/keymap.c b/converter/ps2_usb/keymap.c new file mode 100644 index 000000000..f1e34a929 --- /dev/null +++ b/converter/ps2_usb/keymap.c | |||
| @@ -0,0 +1,379 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Keymap for PS/2 keyboard | ||
| 20 | */ | ||
| 21 | #include <stdint.h> | ||
| 22 | #include <stdbool.h> | ||
| 23 | #include <avr/pgmspace.h> | ||
| 24 | #include "usb_keycodes.h" | ||
| 25 | #include "print.h" | ||
| 26 | #include "debug.h" | ||
| 27 | #include "util.h" | ||
| 28 | #include "keymap.h" | ||
| 29 | |||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | // Following macros help you to define a keymap with the form of actual keyboard layout. | ||
| 34 | |||
| 35 | /* US layout plus all other various keys */ | ||
| 36 | #define KEYMAP_ALL( \ | ||
| 37 | K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ | ||
| 38 | K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ | ||
| 39 | K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \ | ||
| 40 | K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \ | ||
| 41 | K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \ | ||
| 42 | K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \ | ||
| 43 | \ | ||
| 44 | K61, /* for European ISO */ \ | ||
| 45 | K51, K13, K6A, K64, K67, /* for Japanese JIS */ \ | ||
| 46 | K08, K10, K18, K20, K28, K30, K38, K40, K48, K50, K57, K5F, /* F13-24 */ \ | ||
| 47 | KB7, KBF, KDE, /* System Power, Sleep, Wake */ \ | ||
| 48 | KA3, KB2, KA1, /* Mute, Volume Up, Volume Down */ \ | ||
| 49 | KCD, K95, KBB, KB4, KD0, /* Next, Previous, Stop, Pause, Media Select */ \ | ||
| 50 | KC8, KAB, KC0, /* Mail, Calculator, My Computer */ \ | ||
| 51 | K90, KBA, KB8, KB0, /* WWW Search, Home, Back, Forward */ \ | ||
| 52 | KA8, KA0, K98 /* WWW Stop, Refresh, Favorites */ \ | ||
| 53 | ) { \ | ||
| 54 | { KB_NO, KB_##K01, KB_NO, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \ | ||
| 55 | { KB_##K08, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_NO }, \ | ||
| 56 | { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_NO }, \ | ||
| 57 | { KB_##K18, KB_NO, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_NO }, \ | ||
| 58 | { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_NO }, \ | ||
| 59 | { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_NO }, \ | ||
| 60 | { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_NO }, \ | ||
| 61 | { KB_##K38, KB_NO, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_NO }, \ | ||
| 62 | { KB_##K40, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_NO }, \ | ||
| 63 | { KB_##K48, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_NO }, \ | ||
| 64 | { KB_##K50, KB_##K51, KB_##K52, KB_NO, KB_##K54, KB_##K55, KB_NO, KB_##K57 }, \ | ||
| 65 | { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_NO, KB_##K5D, KB_NO, KB_##K5F }, \ | ||
| 66 | { KB_NO, KB_##K61, KB_NO, KB_NO, KB_##K64, KB_NO, KB_##K66, KB_##K67 }, \ | ||
| 67 | { KB_NO, KB_##K69, KB_##K6A, KB_##K6B, KB_##K6C, KB_NO, KB_NO, KB_NO }, \ | ||
| 68 | { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_##K77 }, \ | ||
| 69 | { KB_##K78, KB_##K79, KB_##K7A, KB_##K7B, KB_##K7C, KB_##K7D, KB_##K7E, KB_NO }, \ | ||
| 70 | { KB_NO, KB_NO, KB_NO, KB_##K83, KB_NO, KB_NO, KB_NO, KB_NO }, \ | ||
| 71 | { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \ | ||
| 72 | { KB_##K90, KB_##K91, KB_NO, KB_NO, KB_##K94, KB_##K95, KB_NO, KB_NO }, \ | ||
| 73 | { KB_##K98, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K9F }, \ | ||
| 74 | { KB_##KA0, KB_##KA1, KB_NO, KB_##KA3, KB_NO, KB_NO, KB_NO, KB_##KA7 }, \ | ||
| 75 | { KB_##KA8, KB_NO, KB_NO, KB_##KAB, KB_NO, KB_NO, KB_NO, KB_##KAF }, \ | ||
| 76 | { KB_##KB0, KB_NO, KB_##KB2, KB_NO, KB_##KB4, KB_NO, KB_NO, KB_##KB7 }, \ | ||
| 77 | { KB_##KB8, KB_NO, KB_##KBA, KB_##KBB, KB_NO, KB_NO, KB_NO, KB_##KBF }, \ | ||
| 78 | { KB_##KC0, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \ | ||
| 79 | { KB_##KC8, KB_NO, KB_##KCA, KB_NO, KB_NO, KB_##KCD, KB_NO, KB_NO }, \ | ||
| 80 | { KB_##KD0, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \ | ||
| 81 | { KB_NO, KB_NO, KB_##KDA, KB_NO, KB_NO, KB_NO, KB_##KDE, KB_NO }, \ | ||
| 82 | { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \ | ||
| 83 | { KB_NO, KB_##KE9, KB_NO, KB_##KEB, KB_##KEC, KB_NO, KB_NO, KB_NO }, \ | ||
| 84 | { KB_##KF0, KB_##KF1, KB_##KF2, KB_NO, KB_##KF4, KB_##KF5, KB_NO, KB_NO }, \ | ||
| 85 | { KB_NO, KB_NO, KB_##KFA, KB_NO, KB_##KFC, KB_##KFD, KB_##KFE, KB_NO }, \ | ||
| 86 | } | ||
| 87 | |||
| 88 | /* US layout */ | ||
| 89 | #define KEYMAP( \ | ||
| 90 | K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ | ||
| 91 | K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ | ||
| 92 | K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \ | ||
| 93 | K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \ | ||
| 94 | K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \ | ||
| 95 | K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \ | ||
| 96 | ) \ | ||
| 97 | KEYMAP_ALL( \ | ||
| 98 | K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ | ||
| 99 | K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ | ||
| 100 | K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \ | ||
| 101 | K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \ | ||
| 102 | K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \ | ||
| 103 | K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \ | ||
| 104 | \ | ||
| 105 | NUBS, \ | ||
| 106 | RO, KANA, JYEN, HENK, MHEN, \ | ||
| 107 | F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \ | ||
| 108 | SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \ | ||
| 109 | AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \ | ||
| 110 | MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \ | ||
| 111 | MAIL, CALCULATOR, MY_COMPUTER, \ | ||
| 112 | WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \ | ||
| 113 | WWW_STOP, WWW_REFRESH, WWW_FAVORITES \ | ||
| 114 | ) | ||
| 115 | |||
| 116 | /* ISO layout */ | ||
| 117 | #define KEYMAP_ISO( \ | ||
| 118 | K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ | ||
| 119 | K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ | ||
| 120 | K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, KF1,KE9,KFA, K6C,K75,K7D, \ | ||
| 121 | K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D,K5A, K6B,K73,K74,K79, \ | ||
| 122 | K12,K61,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \ | ||
| 123 | K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \ | ||
| 124 | ) \ | ||
| 125 | KEYMAP_ALL( \ | ||
| 126 | K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ | ||
| 127 | K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ | ||
| 128 | K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \ | ||
| 129 | K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \ | ||
| 130 | K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \ | ||
| 131 | K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \ | ||
| 132 | \ | ||
| 133 | K61, \ | ||
| 134 | RO, KANA, JYEN, HENK, MHEN, \ | ||
| 135 | F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \ | ||
| 136 | SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \ | ||
| 137 | AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \ | ||
| 138 | MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \ | ||
| 139 | MAIL, CALCULATOR, MY_COMPUTER, \ | ||
| 140 | WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \ | ||
| 141 | WWW_STOP, WWW_REFRESH, WWW_FAVORITES \ | ||
| 142 | ) | ||
| 143 | |||
| 144 | /* JIS layout */ | ||
| 145 | #define KEYMAP_JIS( \ | ||
| 146 | K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ | ||
| 147 | K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K6A,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ | ||
| 148 | K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, KF1,KE9,KFA, K6C,K75,K7D, \ | ||
| 149 | K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D, K5A, K6B,K73,K74,K79, \ | ||
| 150 | K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,K51, K59, KF5, K69,K72,K7A, \ | ||
| 151 | K14,K9F,K11, K67,K29,K64,K13, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \ | ||
| 152 | ) \ | ||
| 153 | KEYMAP_ALL( \ | ||
| 154 | K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ | ||
| 155 | K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ | ||
| 156 | K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \ | ||
| 157 | K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \ | ||
| 158 | K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \ | ||
| 159 | K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \ | ||
| 160 | \ | ||
| 161 | NUBS, \ | ||
| 162 | K51, K13, K6A, K64, K67, \ | ||
| 163 | F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \ | ||
| 164 | SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \ | ||
| 165 | AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \ | ||
| 166 | MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \ | ||
| 167 | MAIL, CALCULATOR, MY_COMPUTER, \ | ||
| 168 | WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \ | ||
| 169 | WWW_STOP, WWW_REFRESH, WWW_FAVORITES \ | ||
| 170 | ) | ||
| 171 | |||
| 172 | |||
| 173 | // Assign Fn key(0-7) to a layer to which switch with the Fn key pressed. | ||
| 174 | static const uint8_t PROGMEM fn_layer[] = { | ||
| 175 | 5, // Fn0 | ||
| 176 | 6, // Fn1 | ||
| 177 | 0, // Fn2 | ||
| 178 | 0, // Fn3 | ||
| 179 | 0, // Fn4 | ||
| 180 | 0, // Fn5 | ||
| 181 | 0, // Fn6 | ||
| 182 | 0 // Fn7 | ||
| 183 | }; | ||
| 184 | |||
| 185 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. | ||
| 186 | // See layer.c for details. | ||
| 187 | static const uint8_t PROGMEM fn_keycode[] = { | ||
| 188 | KB_SCLN, // Fn0 | ||
| 189 | KB_SLSH, // Fn1 | ||
| 190 | KB_NO, // Fn2 | ||
| 191 | KB_NO, // Fn3 | ||
| 192 | KB_NO, // Fn4 | ||
| 193 | KB_NO, // Fn5 | ||
| 194 | KB_NO, // Fn6 | ||
| 195 | KB_NO // Fn7 | ||
| 196 | }; | ||
| 197 | |||
| 198 | |||
| 199 | // The keymap is a 32*8 byte array which convert a PS/2 scan code into a USB keycode. | ||
| 200 | // See usb_keycodes.h for USB keycodes. You should omit a 'KB_' prefix of USB keycodes in keymap macro. | ||
| 201 | // Use KEYMAP_ISO() or KEYMAP_JIS() instead of KEYMAP() if your keyboard is ISO or JIS. | ||
| 202 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 203 | /* 0: default | ||
| 204 | * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------. | ||
| 205 | * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|Slp|Wak| | ||
| 206 | * `---' `---------------' `---------------' `---------------' `-----------' `-----------' | ||
| 207 | * ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 208 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| /| *| -| | ||
| 209 | * |-----------------------------------------------------------| |-----------| |---------------| | ||
| 210 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| | | ||
| 211 | * |-----------------------------------------------------------| `-----------' |-----------| +| | ||
| 212 | * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| | | ||
| 213 | * |-----------------------------------------------------------| ,---. |---------------| | ||
| 214 | * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| | | ||
| 215 | * |-----------------------------------------------------------| ,-----------. |-----------|Ent| | ||
| 216 | * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| |Lef|Dow|Rig| | 0| .| | | ||
| 217 | * `-----------------------------------------------------------' `-----------' `---------------' | ||
| 218 | * ; = Fn0(to Layer 5) | ||
| 219 | * / = Fn1(to Layer 6) | ||
| 220 | */ | ||
| 221 | KEYMAP( | ||
| 222 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 223 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 224 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9, | ||
| 225 | CAPS,A, S, D, F, G, H, J, K, L, FN0, QUOT, ENT, P4, P5, P6, PPLS, | ||
| 226 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN1, RSFT, UP, P1, P2, P3, | ||
| 227 | LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 228 | ), | ||
| 229 | |||
| 230 | /* 1: plain Qwerty without layer switching | ||
| 231 | * ,-----------------------------------------------------------. | ||
| 232 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| | ||
| 233 | * |-----------------------------------------------------------| | ||
| 234 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | ||
| 235 | * |-----------------------------------------------------------| | ||
| 236 | * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | ||
| 237 | * |-----------------------------------------------------------| | ||
| 238 | * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | ||
| 239 | * |-----------------------------------------------------------| | ||
| 240 | * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| | ||
| 241 | * `-----------------------------------------------------------' | ||
| 242 | */ | ||
| 243 | KEYMAP( | ||
| 244 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 245 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 246 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9, | ||
| 247 | CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, | ||
| 248 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, | ||
| 249 | LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 250 | ), | ||
| 251 | |||
| 252 | /* 2: Colemak http://colemak.com | ||
| 253 | * ,-----------------------------------------------------------. | ||
| 254 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| | ||
| 255 | * |-----------------------------------------------------------| | ||
| 256 | * |Tab | Q| W| F| P| G| J| L| U| Y| ;| [| ]| \| | ||
| 257 | * |-----------------------------------------------------------| | ||
| 258 | * |BackSp| A| R| S| T| D| H| N| E| I| O| '|Return | | ||
| 259 | * |-----------------------------------------------------------| | ||
| 260 | * |Shift | Z| X| C| V| B| K| M| ,| ,| /|Shift | | ||
| 261 | * |-----------------------------------------------------------| | ||
| 262 | * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| | ||
| 263 | * `----------------------------------------------------------' | ||
| 264 | */ | ||
| 265 | KEYMAP( | ||
| 266 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 267 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 268 | TAB, Q, W, F, P, G, J, L, U, Y, SCLN,LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9, | ||
| 269 | BSPC,A, R, S, T, D, H, N, E, I, O, QUOT, ENT, P4, P5, P6, PPLS, | ||
| 270 | LSFT,Z, X, C, V, B, K, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, | ||
| 271 | LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 272 | ), | ||
| 273 | |||
| 274 | /* 3: Dvorak http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard | ||
| 275 | * ,-----------------------------------------------------------. | ||
| 276 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| [| ]|Backspa| | ||
| 277 | * |-----------------------------------------------------------| | ||
| 278 | * |Tab | '| ,| .| P| Y| F| G| C| R| L| /| =| \| | ||
| 279 | * |-----------------------------------------------------------| | ||
| 280 | * |BackSp| A| O| E| U| I| D| H| T| N| S| -|Return | | ||
| 281 | * |-----------------------------------------------------------| | ||
| 282 | * |Shift | ;| Q| J| K| X| B| M| Wl V| Z|Shift | | ||
| 283 | * |-----------------------------------------------------------| | ||
| 284 | * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| | ||
| 285 | * `-----------------------------------------------------------' | ||
| 286 | */ | ||
| 287 | KEYMAP( | ||
| 288 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 289 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, LBRC,RBRC,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 290 | TAB, QUOT,COMM,DOT, P, Y, F, G, C, R, L, SLSH,EQL, BSLS, DEL, END, PGDN, P7, P8, P9, | ||
| 291 | CAPS,A, O, E, U, I, D, H, T, N, S, MINS, ENT, P4, P5, P6, PPLS, | ||
| 292 | LSFT,SCLN,Q, J, K, X, B, M, W, V, Z, RSFT, UP, P1, P2, P3, | ||
| 293 | LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 294 | ), | ||
| 295 | |||
| 296 | /* 4: Workman http://viralintrospection.wordpress.com/2010/09/06/a-different-philosophy-in-designing-keyboard-layouts/ | ||
| 297 | * ,-----------------------------------------------------------. | ||
| 298 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| | ||
| 299 | * |-----------------------------------------------------------| | ||
| 300 | * |Tab | Q| D| R| W| B| J| F| U| P| ;| [| ]| \| | ||
| 301 | * |-----------------------------------------------------------| | ||
| 302 | * |CapsLo| A| S| H| T| G| Y| N| E| O| I| '|Return | | ||
| 303 | * |-----------------------------------------------------------| | ||
| 304 | * |Shift | Z| X| M| C| V| K| L| ,| ,| /|Shift | | ||
| 305 | * |-----------------------------------------------------------| | ||
| 306 | * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| | ||
| 307 | * `-----------------------------------------------------------' | ||
| 308 | */ | ||
| 309 | KEYMAP( | ||
| 310 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 311 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 312 | TAB, Q, D, R, W, B, J, F, U, P, SCLN,LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9, | ||
| 313 | BSPC,A, S, H, T, G, Y, N, E, O, I, QUOT, ENT, P4, P5, P6, PPLS, | ||
| 314 | LSFT,Z, X, M, C, V, K, L, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, | ||
| 315 | LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 316 | ), | ||
| 317 | |||
| 318 | /* 5: Mouse keys | ||
| 319 | * ,-----------------------------------------------------------. | ||
| 320 | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa| | ||
| 321 | * |-----------------------------------------------------------| | ||
| 322 | * |Tab |MwL|MwU|McU|WwU|WwR|MwL|MwD|MwU|MwR| | | | \| | ||
| 323 | * |-----------------------------------------------------------| | ||
| 324 | * |CapsLo| |McL|McD|McR| |McL|McD|McU|McR|Fn0| |Return | | ||
| 325 | * |-----------------------------------------------------------| | ||
| 326 | * |Shift |VoD|VoU|Mut|Mb2|Mb3|Mb2|Mb1|VoD|VoU|Mut|Shift | | ||
| 327 | * |-----------------------------------------------------------| | ||
| 328 | * |Ctrl |Gui |Alt | Mb1 |Alt |Gui |Menu|Ctrl| | ||
| 329 | * `-----------------------------------------------------------' | ||
| 330 | * Mc = mouse cursor, Mw = mouse wheel, Mb = mouse button | ||
| 331 | * Vo = Volume, Mut = Mute | ||
| 332 | */ | ||
| 333 | KEYMAP( | ||
| 334 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 335 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 336 | TAB, WH_L,WH_D,MS_U,WH_U,WH_R,WH_L,WH_D,WH_U,WH_R,NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9, | ||
| 337 | CAPS,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN0, NO, ENT, P4, P5, P6, PPLS, | ||
| 338 | LSFT,VOLD,VOLU,MUTE,BTN2,BTN3,BTN2,BTN1,VOLD,VOLU,MUTE, RSFT, UP, P1, P2, P3, | ||
| 339 | LCTL,LGUI,LALT, BTN1, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 340 | ), | ||
| 341 | |||
| 342 | /* 6: Cursor keys | ||
| 343 | * ,-----------------------------------------------------------. | ||
| 344 | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa| | ||
| 345 | * |-----------------------------------------------------------| | ||
| 346 | * |Tab |Hom|PgU| Up|PgU|End|Hom|PgD|PgU|End| | | | \| | ||
| 347 | * |-----------------------------------------------------------| | ||
| 348 | * |CapsLo| |Lef|Dow|Rig| |Lef|Dow| Up|Rig| | |Return | | ||
| 349 | * |-----------------------------------------------------------| | ||
| 350 | * |Shift | | | | | |Hom|PgD|PgU|End|Fn1|Shift | | ||
| 351 | * |-----------------------------------------------------------| | ||
| 352 | * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| | ||
| 353 | * `-----------------------------------------------------------' | ||
| 354 | */ | ||
| 355 | KEYMAP( | ||
| 356 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 357 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 358 | TAB, NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9, | ||
| 359 | CAPS,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS, | ||
| 360 | LSFT,VOLD,VOLU,MUTE,NO, NO, HOME,PGDN,PGUP,END, FN1, RSFT, UP, P1, P2, P3, | ||
| 361 | LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT | ||
| 362 | ), | ||
| 363 | }; | ||
| 364 | |||
| 365 | |||
| 366 | uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | ||
| 367 | { | ||
| 368 | return pgm_read_byte(&keymaps[(layer)][(row)][(col)]); | ||
| 369 | } | ||
| 370 | |||
| 371 | uint8_t keymap_fn_layer(uint8_t fn_bits) | ||
| 372 | { | ||
| 373 | return pgm_read_byte(&fn_layer[biton(fn_bits)]); | ||
| 374 | } | ||
| 375 | |||
| 376 | uint8_t keymap_fn_keycode(uint8_t fn_bits) | ||
| 377 | { | ||
| 378 | return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | ||
| 379 | } | ||
diff --git a/converter/ps2_usb/led.c b/converter/ps2_usb/led.c new file mode 100644 index 000000000..e448e84ec --- /dev/null +++ b/converter/ps2_usb/led.c | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "stdint.h" | ||
| 19 | #include "ps2.h" | ||
| 20 | #include "led.h" | ||
| 21 | |||
| 22 | |||
| 23 | void led_set(uint8_t usb_led) | ||
| 24 | { | ||
| 25 | uint8_t ps2_led = 0; | ||
| 26 | if (usb_led & (1<<USB_LED_SCROLL_LOCK)) | ||
| 27 | ps2_led |= (1<<PS2_LED_SCROLL_LOCK); | ||
| 28 | if (usb_led & (1<<USB_LED_NUM_LOCK)) | ||
| 29 | ps2_led |= (1<<PS2_LED_NUM_LOCK); | ||
| 30 | if (usb_led & (1<<USB_LED_CAPS_LOCK)) | ||
| 31 | ps2_led |= (1<<PS2_LED_CAPS_LOCK); | ||
| 32 | ps2_host_set_led(ps2_led); | ||
| 33 | } | ||
diff --git a/converter/ps2_usb/matrix.c b/converter/ps2_usb/matrix.c new file mode 100644 index 000000000..4187ea060 --- /dev/null +++ b/converter/ps2_usb/matrix.c | |||
| @@ -0,0 +1,452 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdbool.h> | ||
| 20 | #include <avr/io.h> | ||
| 21 | #include <util/delay.h> | ||
| 22 | #include "print.h" | ||
| 23 | #include "util.h" | ||
| 24 | #include "debug.h" | ||
| 25 | #include "ps2.h" | ||
| 26 | #include "matrix.h" | ||
| 27 | |||
| 28 | |||
| 29 | static void matrix_make(uint8_t code); | ||
| 30 | static void matrix_break(uint8_t code); | ||
| 31 | #ifdef MATRIX_HAS_GHOST | ||
| 32 | static bool matrix_has_ghost_in_row(uint8_t row); | ||
| 33 | #endif | ||
| 34 | |||
| 35 | |||
| 36 | /* | ||
| 37 | * Matrix Array usage: | ||
| 38 | * 'Scan Code Set 2' is assigned into 256(32x8)cell matrix. | ||
| 39 | * Hmm, it is very sparse and not efficient :( | ||
| 40 | * | ||
| 41 | * Notes: | ||
| 42 | * Both 'Hanguel/English'(F1) and 'Hanja'(F2) collide with 'Delete'(E0 71) and 'Down'(E0 72). | ||
| 43 | * These two Korean keys need exceptional handling and are not supported for now. Sorry. | ||
| 44 | * | ||
| 45 | * 8bit wide | ||
| 46 | * +---------+ | ||
| 47 | * 0| | | ||
| 48 | * :| XX | 00-7F for normal codes(without E0-prefix) | ||
| 49 | * f|_________| | ||
| 50 | * 10| | | ||
| 51 | * :| E0 YY | 80-FF for E0-prefixed codes | ||
| 52 | * 1f| | (<YY>|0x80) is used as matrix position. | ||
| 53 | * +---------+ | ||
| 54 | * | ||
| 55 | * Exceptions: | ||
| 56 | * 0x83: F7(0x83) This is a normal code but beyond 0x7F. | ||
| 57 | * 0xFC: PrintScreen | ||
| 58 | * 0xFE: Pause | ||
| 59 | */ | ||
| 60 | static uint8_t matrix[MATRIX_ROWS]; | ||
| 61 | #define ROW(code) (code>>3) | ||
| 62 | #define COL(code) (code&0x07) | ||
| 63 | |||
| 64 | // matrix positions for exceptional keys | ||
| 65 | #define F7 (0x83) | ||
| 66 | #define PRINT_SCREEN (0xFC) | ||
| 67 | #define PAUSE (0xFE) | ||
| 68 | |||
| 69 | static bool is_modified = false; | ||
| 70 | |||
| 71 | |||
| 72 | inline | ||
| 73 | uint8_t matrix_rows(void) | ||
| 74 | { | ||
| 75 | return MATRIX_ROWS; | ||
| 76 | } | ||
| 77 | |||
| 78 | inline | ||
| 79 | uint8_t matrix_cols(void) | ||
| 80 | { | ||
| 81 | return MATRIX_COLS; | ||
| 82 | } | ||
| 83 | |||
| 84 | void matrix_init(void) | ||
| 85 | { | ||
| 86 | ps2_host_init(); | ||
| 87 | |||
| 88 | // initialize matrix state: all keys off | ||
| 89 | for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; | ||
| 90 | |||
| 91 | return; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* | ||
| 95 | * PS/2 Scan Code Set 2: Exceptional Handling | ||
| 96 | * | ||
| 97 | * There are several keys to be handled exceptionally. | ||
| 98 | * The scan code for these keys are varied or prefix/postfix'd | ||
| 99 | * depending on modifier key state. | ||
| 100 | * | ||
| 101 | * Keyboard Scan Code Specification: | ||
| 102 | * http://www.microsoft.com/whdc/archive/scancode.mspx | ||
| 103 | * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc | ||
| 104 | * | ||
| 105 | * | ||
| 106 | * 1) Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left | ||
| 107 | * a) when Num Lock is off | ||
| 108 | * modifiers | make | break | ||
| 109 | * ----------+---------------------------+---------------------- | ||
| 110 | * Ohter | <make> | <break> | ||
| 111 | * LShift | E0 F0 12 <make> | <break> E0 12 | ||
| 112 | * RShift | E0 F0 59 <make> | <break> E0 59 | ||
| 113 | * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 | ||
| 114 | * | ||
| 115 | * b) when Num Lock is on | ||
| 116 | * modifiers | make | break | ||
| 117 | * ----------+---------------------------+---------------------- | ||
| 118 | * Other | E0 12 <make> | <break> E0 F0 12 | ||
| 119 | * Shift'd | <make> | <break> | ||
| 120 | * | ||
| 121 | * Handling: These prefix/postfix codes are ignored. | ||
| 122 | * | ||
| 123 | * | ||
| 124 | * 2) Keypad / | ||
| 125 | * modifiers | make | break | ||
| 126 | * ----------+---------------------------+---------------------- | ||
| 127 | * Ohter | <make> | <break> | ||
| 128 | * LShift | E0 F0 12 <make> | <break> E0 12 | ||
| 129 | * RShift | E0 F0 59 <make> | <break> E0 59 | ||
| 130 | * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 | ||
| 131 | * | ||
| 132 | * Handling: These prefix/postfix codes are ignored. | ||
| 133 | * | ||
| 134 | * | ||
| 135 | * 3) PrintScreen | ||
| 136 | * modifiers | make | break | ||
| 137 | * ----------+--------------+----------------------------------- | ||
| 138 | * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12 | ||
| 139 | * Shift'd | E0 7C | E0 F0 7C | ||
| 140 | * Control'd | E0 7C | E0 F0 7C | ||
| 141 | * Alt'd | 84 | F0 84 | ||
| 142 | * | ||
| 143 | * Handling: These prefix/postfix codes are ignored, and both scan codes | ||
| 144 | * 'E0 7C' and 84 are seen as PrintScreen. | ||
| 145 | * | ||
| 146 | * 4) Pause | ||
| 147 | * modifiers | make(no break code) | ||
| 148 | * ----------+-------------------------------------------------- | ||
| 149 | * Other | E1 14 77 E1 F0 14 F0 77 | ||
| 150 | * Control'd | E0 7E E0 F0 7E | ||
| 151 | * | ||
| 152 | * Handling: Both code sequences are treated as a whole. | ||
| 153 | * And we need a ad hoc 'pseudo break code' hack to get the key off | ||
| 154 | * because it has no break code. | ||
| 155 | * | ||
| 156 | */ | ||
| 157 | uint8_t matrix_scan(void) | ||
| 158 | { | ||
| 159 | |||
| 160 | // scan code reading states | ||
| 161 | static enum { | ||
| 162 | INIT, | ||
| 163 | F0, | ||
| 164 | E0, | ||
| 165 | E0_F0, | ||
| 166 | // Pause | ||
| 167 | E1, | ||
| 168 | E1_14, | ||
| 169 | E1_14_77, | ||
| 170 | E1_14_77_E1, | ||
| 171 | E1_14_77_E1_F0, | ||
| 172 | E1_14_77_E1_F0_14, | ||
| 173 | E1_14_77_E1_F0_14_F0, | ||
| 174 | // Control'd Pause | ||
| 175 | E0_7E, | ||
| 176 | E0_7E_E0, | ||
| 177 | E0_7E_E0_F0, | ||
| 178 | } state = INIT; | ||
| 179 | |||
| 180 | |||
| 181 | is_modified = false; | ||
| 182 | |||
| 183 | // 'pseudo break code' hack | ||
| 184 | if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { | ||
| 185 | matrix_break(PAUSE); | ||
| 186 | } | ||
| 187 | |||
| 188 | uint8_t code; | ||
| 189 | while ((code = ps2_host_recv())) { | ||
| 190 | switch (state) { | ||
| 191 | case INIT: | ||
| 192 | switch (code) { | ||
| 193 | case 0xE0: | ||
| 194 | state = E0; | ||
| 195 | break; | ||
| 196 | case 0xF0: | ||
| 197 | state = F0; | ||
| 198 | break; | ||
| 199 | case 0xE1: | ||
| 200 | state = E1; | ||
| 201 | break; | ||
| 202 | case 0x83: // F7 | ||
| 203 | matrix_make(F7); | ||
| 204 | state = INIT; | ||
| 205 | break; | ||
| 206 | case 0x84: // Alt'd PrintScreen | ||
| 207 | matrix_make(PRINT_SCREEN); | ||
| 208 | state = INIT; | ||
| 209 | break; | ||
| 210 | default: // normal key make | ||
| 211 | if (code < 0x80) { | ||
| 212 | matrix_make(code); | ||
| 213 | } else { | ||
| 214 | debug("unexpected scan code at INIT: "); debug_hex(code); debug("\n"); | ||
| 215 | } | ||
| 216 | state = INIT; | ||
| 217 | } | ||
| 218 | break; | ||
| 219 | case E0: // E0-Prefixed | ||
| 220 | switch (code) { | ||
| 221 | case 0x12: // to be ignored | ||
| 222 | case 0x59: // to be ignored | ||
| 223 | state = INIT; | ||
| 224 | break; | ||
| 225 | case 0x7E: // Control'd Pause | ||
| 226 | state = E0_7E; | ||
| 227 | break; | ||
| 228 | case 0xF0: | ||
| 229 | state = E0_F0; | ||
| 230 | break; | ||
| 231 | default: | ||
| 232 | if (code < 0x80) { | ||
| 233 | matrix_make(code|0x80); | ||
| 234 | } else { | ||
| 235 | debug("unexpected scan code at E0: "); debug_hex(code); debug("\n"); | ||
| 236 | } | ||
| 237 | state = INIT; | ||
| 238 | } | ||
| 239 | break; | ||
| 240 | case F0: // Break code | ||
| 241 | switch (code) { | ||
| 242 | case 0x83: // F7 | ||
| 243 | matrix_break(F7); | ||
| 244 | state = INIT; | ||
| 245 | break; | ||
| 246 | case 0x84: // Alt'd PrintScreen | ||
| 247 | matrix_break(PRINT_SCREEN); | ||
| 248 | state = INIT; | ||
| 249 | break; | ||
| 250 | default: | ||
| 251 | if (code < 0x80) { | ||
| 252 | matrix_break(code); | ||
| 253 | } else { | ||
| 254 | debug("unexpected scan code at F0: "); debug_hex(code); debug("\n"); | ||
| 255 | } | ||
| 256 | state = INIT; | ||
| 257 | } | ||
| 258 | break; | ||
| 259 | case E0_F0: // Break code of E0-prefixed | ||
| 260 | switch (code) { | ||
| 261 | case 0x12: // to be ignored | ||
| 262 | case 0x59: // to be ignored | ||
| 263 | state = INIT; | ||
| 264 | break; | ||
| 265 | default: | ||
| 266 | if (code < 0x80) { | ||
| 267 | matrix_break(code|0x80); | ||
| 268 | } else { | ||
| 269 | debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n"); | ||
| 270 | } | ||
| 271 | state = INIT; | ||
| 272 | } | ||
| 273 | break; | ||
| 274 | // following are states of Pause | ||
| 275 | case E1: | ||
| 276 | switch (code) { | ||
| 277 | case 0x14: | ||
| 278 | state = E1_14; | ||
| 279 | break; | ||
| 280 | default: | ||
| 281 | state = INIT; | ||
| 282 | } | ||
| 283 | break; | ||
| 284 | case E1_14: | ||
| 285 | switch (code) { | ||
| 286 | case 0x77: | ||
| 287 | state = E1_14_77; | ||
| 288 | break; | ||
| 289 | default: | ||
| 290 | state = INIT; | ||
| 291 | } | ||
| 292 | break; | ||
| 293 | case E1_14_77: | ||
| 294 | switch (code) { | ||
| 295 | case 0xE1: | ||
| 296 | state = E1_14_77_E1; | ||
| 297 | break; | ||
| 298 | default: | ||
| 299 | state = INIT; | ||
| 300 | } | ||
| 301 | break; | ||
| 302 | case E1_14_77_E1: | ||
| 303 | switch (code) { | ||
| 304 | case 0xF0: | ||
| 305 | state = E1_14_77_E1_F0; | ||
| 306 | break; | ||
| 307 | default: | ||
| 308 | state = INIT; | ||
| 309 | } | ||
| 310 | break; | ||
| 311 | case E1_14_77_E1_F0: | ||
| 312 | switch (code) { | ||
| 313 | case 0x14: | ||
| 314 | state = E1_14_77_E1_F0_14; | ||
| 315 | break; | ||
| 316 | default: | ||
| 317 | state = INIT; | ||
| 318 | } | ||
| 319 | break; | ||
| 320 | case E1_14_77_E1_F0_14: | ||
| 321 | switch (code) { | ||
| 322 | case 0xF0: | ||
| 323 | state = E1_14_77_E1_F0_14_F0; | ||
| 324 | break; | ||
| 325 | default: | ||
| 326 | state = INIT; | ||
| 327 | } | ||
| 328 | break; | ||
| 329 | case E1_14_77_E1_F0_14_F0: | ||
| 330 | switch (code) { | ||
| 331 | case 0x77: | ||
| 332 | matrix_make(PAUSE); | ||
| 333 | state = INIT; | ||
| 334 | break; | ||
| 335 | default: | ||
| 336 | state = INIT; | ||
| 337 | } | ||
| 338 | break; | ||
| 339 | // Following are states of Control'd Pause | ||
| 340 | case E0_7E: | ||
| 341 | if (code == 0xE0) | ||
| 342 | state = E0_7E_E0; | ||
| 343 | else | ||
| 344 | state = INIT; | ||
| 345 | break; | ||
| 346 | case E0_7E_E0: | ||
| 347 | if (code == 0xF0) | ||
| 348 | state = E0_7E_E0_F0; | ||
| 349 | else | ||
| 350 | state = INIT; | ||
| 351 | break; | ||
| 352 | case E0_7E_E0_F0: | ||
| 353 | if (code == 0x7E) | ||
| 354 | matrix_make(PAUSE); | ||
| 355 | state = INIT; | ||
| 356 | break; | ||
| 357 | default: | ||
| 358 | state = INIT; | ||
| 359 | } | ||
| 360 | phex(code); | ||
| 361 | } | ||
| 362 | return 1; | ||
| 363 | } | ||
| 364 | |||
| 365 | bool matrix_is_modified(void) | ||
| 366 | { | ||
| 367 | return is_modified; | ||
| 368 | } | ||
| 369 | |||
| 370 | inline | ||
| 371 | bool matrix_has_ghost(void) | ||
| 372 | { | ||
| 373 | #ifdef MATRIX_HAS_GHOST | ||
| 374 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 375 | if (matrix_has_ghost_in_row(i)) | ||
| 376 | return true; | ||
| 377 | } | ||
| 378 | #endif | ||
| 379 | return false; | ||
| 380 | } | ||
| 381 | |||
| 382 | inline | ||
| 383 | bool matrix_is_on(uint8_t row, uint8_t col) | ||
| 384 | { | ||
| 385 | return (matrix[row] & (1<<col)); | ||
| 386 | } | ||
| 387 | |||
| 388 | inline | ||
| 389 | uint8_t matrix_get_row(uint8_t row) | ||
| 390 | { | ||
| 391 | return matrix[row]; | ||
| 392 | } | ||
| 393 | |||
| 394 | void matrix_print(void) | ||
| 395 | { | ||
| 396 | print("\nr/c 01234567\n"); | ||
| 397 | for (uint8_t row = 0; row < matrix_rows(); row++) { | ||
| 398 | phex(row); print(": "); | ||
| 399 | pbin_reverse(matrix_get_row(row)); | ||
| 400 | #ifdef MATRIX_HAS_GHOST | ||
| 401 | if (matrix_has_ghost_in_row(row)) { | ||
| 402 | print(" <ghost"); | ||
| 403 | } | ||
| 404 | #endif | ||
| 405 | print("\n"); | ||
| 406 | } | ||
| 407 | } | ||
| 408 | |||
| 409 | uint8_t matrix_key_count(void) | ||
| 410 | { | ||
| 411 | uint8_t count = 0; | ||
| 412 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 413 | count += bitpop(matrix[i]); | ||
| 414 | } | ||
| 415 | return count; | ||
| 416 | } | ||
| 417 | |||
| 418 | #ifdef MATRIX_HAS_GHOST | ||
| 419 | inline | ||
| 420 | static bool matrix_has_ghost_in_row(uint8_t row) | ||
| 421 | { | ||
| 422 | // no ghost exists in case less than 2 keys on | ||
| 423 | if (((matrix[row] - 1) & matrix[row]) == 0) | ||
| 424 | return false; | ||
| 425 | |||
| 426 | // ghost exists in case same state as other row | ||
| 427 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | ||
| 428 | if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | ||
| 429 | return true; | ||
| 430 | } | ||
| 431 | return false; | ||
| 432 | } | ||
| 433 | #endif | ||
| 434 | |||
| 435 | |||
| 436 | inline | ||
| 437 | static void matrix_make(uint8_t code) | ||
| 438 | { | ||
| 439 | if (!matrix_is_on(ROW(code), COL(code))) { | ||
| 440 | matrix[ROW(code)] |= 1<<COL(code); | ||
| 441 | is_modified = true; | ||
| 442 | } | ||
| 443 | } | ||
| 444 | |||
| 445 | inline | ||
| 446 | static void matrix_break(uint8_t code) | ||
| 447 | { | ||
| 448 | if (matrix_is_on(ROW(code), COL(code))) { | ||
| 449 | matrix[ROW(code)] &= ~(1<<COL(code)); | ||
| 450 | is_modified = true; | ||
| 451 | } | ||
| 452 | } | ||
diff --git a/converter/ps2_usb/usbconfig.h b/converter/ps2_usb/usbconfig.h new file mode 100644 index 000000000..9038f1eb8 --- /dev/null +++ b/converter/ps2_usb/usbconfig.h | |||
| @@ -0,0 +1,378 @@ | |||
| 1 | /* Name: usbconfig.h | ||
| 2 | * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers | ||
| 3 | * Author: Christian Starkjohann | ||
| 4 | * Creation Date: 2005-04-01 | ||
| 5 | * Tabsize: 4 | ||
| 6 | * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH | ||
| 7 | * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) | ||
| 8 | * This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $ | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __usbconfig_h_included__ | ||
| 12 | #define __usbconfig_h_included__ | ||
| 13 | |||
| 14 | #include "config_vusb.h" | ||
| 15 | |||
| 16 | /* | ||
| 17 | General Description: | ||
| 18 | This file is an example configuration (with inline documentation) for the USB | ||
| 19 | driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is | ||
| 20 | also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may | ||
| 21 | wire the lines to any other port, as long as D+ is also wired to INT0 (or any | ||
| 22 | other hardware interrupt, as long as it is the highest level interrupt, see | ||
| 23 | section at the end of this file). | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* ---------------------------- Hardware Config ---------------------------- */ | ||
| 27 | |||
| 28 | #define USB_CFG_IOPORTNAME D | ||
| 29 | /* This is the port where the USB bus is connected. When you configure it to | ||
| 30 | * "B", the registers PORTB, PINB and DDRB will be used. | ||
| 31 | */ | ||
| 32 | #define USB_CFG_DMINUS_BIT 3 | ||
| 33 | /* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. | ||
| 34 | * This may be any bit in the port. | ||
| 35 | */ | ||
| 36 | #define USB_CFG_DPLUS_BIT 2 | ||
| 37 | /* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. | ||
| 38 | * This may be any bit in the port. Please note that D+ must also be connected | ||
| 39 | * to interrupt pin INT0! [You can also use other interrupts, see section | ||
| 40 | * "Optional MCU Description" below, or you can connect D- to the interrupt, as | ||
| 41 | * it is required if you use the USB_COUNT_SOF feature. If you use D- for the | ||
| 42 | * interrupt, the USB interrupt will also be triggered at Start-Of-Frame | ||
| 43 | * markers every millisecond.] | ||
| 44 | */ | ||
| 45 | #define USB_CFG_CLOCK_KHZ (F_CPU/1000) | ||
| 46 | /* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000, | ||
| 47 | * 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code | ||
| 48 | * require no crystal, they tolerate +/- 1% deviation from the nominal | ||
| 49 | * frequency. All other rates require a precision of 2000 ppm and thus a | ||
| 50 | * crystal! | ||
| 51 | * Since F_CPU should be defined to your actual clock rate anyway, you should | ||
| 52 | * not need to modify this setting. | ||
| 53 | */ | ||
| 54 | #define USB_CFG_CHECK_CRC 0 | ||
| 55 | /* Define this to 1 if you want that the driver checks integrity of incoming | ||
| 56 | * data packets (CRC checks). CRC checks cost quite a bit of code size and are | ||
| 57 | * currently only available for 18 MHz crystal clock. You must choose | ||
| 58 | * USB_CFG_CLOCK_KHZ = 18000 if you enable this option. | ||
| 59 | */ | ||
| 60 | |||
| 61 | /* ----------------------- Optional Hardware Config ------------------------ */ | ||
| 62 | |||
| 63 | /* #define USB_CFG_PULLUP_IOPORTNAME D */ | ||
| 64 | /* If you connect the 1.5k pullup resistor from D- to a port pin instead of | ||
| 65 | * V+, you can connect and disconnect the device from firmware by calling | ||
| 66 | * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). | ||
| 67 | * This constant defines the port on which the pullup resistor is connected. | ||
| 68 | */ | ||
| 69 | /* #define USB_CFG_PULLUP_BIT 4 */ | ||
| 70 | /* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined | ||
| 71 | * above) where the 1.5k pullup resistor is connected. See description | ||
| 72 | * above for details. | ||
| 73 | */ | ||
| 74 | |||
| 75 | /* --------------------------- Functional Range ---------------------------- */ | ||
| 76 | |||
| 77 | #define USB_CFG_HAVE_INTRIN_ENDPOINT 1 | ||
| 78 | /* Define this to 1 if you want to compile a version with two endpoints: The | ||
| 79 | * default control endpoint 0 and an interrupt-in endpoint (any other endpoint | ||
| 80 | * number). | ||
| 81 | */ | ||
| 82 | #define USB_CFG_HAVE_INTRIN_ENDPOINT3 1 | ||
| 83 | /* Define this to 1 if you want to compile a version with three endpoints: The | ||
| 84 | * default control endpoint 0, an interrupt-in endpoint 3 (or the number | ||
| 85 | * configured below) and a catch-all default interrupt-in endpoint as above. | ||
| 86 | * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. | ||
| 87 | */ | ||
| 88 | #define USB_CFG_EP3_NUMBER 3 | ||
| 89 | /* If the so-called endpoint 3 is used, it can now be configured to any other | ||
| 90 | * endpoint number (except 0) with this macro. Default if undefined is 3. | ||
| 91 | */ | ||
| 92 | /* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ | ||
| 93 | /* The above macro defines the startup condition for data toggling on the | ||
| 94 | * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. | ||
| 95 | * Since the token is toggled BEFORE sending any data, the first packet is | ||
| 96 | * sent with the oposite value of this configuration! | ||
| 97 | */ | ||
| 98 | #define USB_CFG_IMPLEMENT_HALT 0 | ||
| 99 | /* Define this to 1 if you also want to implement the ENDPOINT_HALT feature | ||
| 100 | * for endpoint 1 (interrupt endpoint). Although you may not need this feature, | ||
| 101 | * it is required by the standard. We have made it a config option because it | ||
| 102 | * bloats the code considerably. | ||
| 103 | */ | ||
| 104 | #define USB_CFG_SUPPRESS_INTR_CODE 0 | ||
| 105 | /* Define this to 1 if you want to declare interrupt-in endpoints, but don't | ||
| 106 | * want to send any data over them. If this macro is defined to 1, functions | ||
| 107 | * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if | ||
| 108 | * you need the interrupt-in endpoints in order to comply to an interface | ||
| 109 | * (e.g. HID), but never want to send any data. This option saves a couple | ||
| 110 | * of bytes in flash memory and the transmit buffers in RAM. | ||
| 111 | */ | ||
| 112 | #define USB_CFG_INTR_POLL_INTERVAL 10 | ||
| 113 | /* If you compile a version with endpoint 1 (interrupt-in), this is the poll | ||
| 114 | * interval. The value is in milliseconds and must not be less than 10 ms for | ||
| 115 | * low speed devices. | ||
| 116 | */ | ||
| 117 | #define USB_CFG_IS_SELF_POWERED 0 | ||
| 118 | /* Define this to 1 if the device has its own power supply. Set it to 0 if the | ||
| 119 | * device is powered from the USB bus. | ||
| 120 | */ | ||
| 121 | #define USB_CFG_MAX_BUS_POWER 100 | ||
| 122 | /* Set this variable to the maximum USB bus power consumption of your device. | ||
| 123 | * The value is in milliamperes. [It will be divided by two since USB | ||
| 124 | * communicates power requirements in units of 2 mA.] | ||
| 125 | */ | ||
| 126 | #define USB_CFG_IMPLEMENT_FN_WRITE 1 | ||
| 127 | /* Set this to 1 if you want usbFunctionWrite() to be called for control-out | ||
| 128 | * transfers. Set it to 0 if you don't need it and want to save a couple of | ||
| 129 | * bytes. | ||
| 130 | */ | ||
| 131 | #define USB_CFG_IMPLEMENT_FN_READ 0 | ||
| 132 | /* Set this to 1 if you need to send control replies which are generated | ||
| 133 | * "on the fly" when usbFunctionRead() is called. If you only want to send | ||
| 134 | * data from a static buffer, set it to 0 and return the data from | ||
| 135 | * usbFunctionSetup(). This saves a couple of bytes. | ||
| 136 | */ | ||
| 137 | #define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 | ||
| 138 | /* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. | ||
| 139 | * You must implement the function usbFunctionWriteOut() which receives all | ||
| 140 | * interrupt/bulk data sent to any endpoint other than 0. The endpoint number | ||
| 141 | * can be found in 'usbRxToken'. | ||
| 142 | */ | ||
| 143 | #define USB_CFG_HAVE_FLOWCONTROL 0 | ||
| 144 | /* Define this to 1 if you want flowcontrol over USB data. See the definition | ||
| 145 | * of the macros usbDisableAllRequests() and usbEnableAllRequests() in | ||
| 146 | * usbdrv.h. | ||
| 147 | */ | ||
| 148 | #define USB_CFG_DRIVER_FLASH_PAGE 0 | ||
| 149 | /* If the device has more than 64 kBytes of flash, define this to the 64 k page | ||
| 150 | * where the driver's constants (descriptors) are located. Or in other words: | ||
| 151 | * Define this to 1 for boot loaders on the ATMega128. | ||
| 152 | */ | ||
| 153 | #define USB_CFG_LONG_TRANSFERS 0 | ||
| 154 | /* Define this to 1 if you want to send/receive blocks of more than 254 bytes | ||
| 155 | * in a single control-in or control-out transfer. Note that the capability | ||
| 156 | * for long transfers increases the driver size. | ||
| 157 | */ | ||
| 158 | /* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */ | ||
| 159 | /* This macro is a hook if you want to do unconventional things. If it is | ||
| 160 | * defined, it's inserted at the beginning of received message processing. | ||
| 161 | * If you eat the received message and don't want default processing to | ||
| 162 | * proceed, do a return after doing your things. One possible application | ||
| 163 | * (besides debugging) is to flash a status LED on each packet. | ||
| 164 | */ | ||
| 165 | /* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ | ||
| 166 | /* This macro is a hook if you need to know when an USB RESET occurs. It has | ||
| 167 | * one parameter which distinguishes between the start of RESET state and its | ||
| 168 | * end. | ||
| 169 | */ | ||
| 170 | /* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ | ||
| 171 | /* This macro (if defined) is executed when a USB SET_ADDRESS request was | ||
| 172 | * received. | ||
| 173 | */ | ||
| 174 | #define USB_COUNT_SOF 0 | ||
| 175 | /* define this macro to 1 if you need the global variable "usbSofCount" which | ||
| 176 | * counts SOF packets. This feature requires that the hardware interrupt is | ||
| 177 | * connected to D- instead of D+. | ||
| 178 | */ | ||
| 179 | /* #ifdef __ASSEMBLER__ | ||
| 180 | * macro myAssemblerMacro | ||
| 181 | * in YL, TCNT0 | ||
| 182 | * sts timer0Snapshot, YL | ||
| 183 | * endm | ||
| 184 | * #endif | ||
| 185 | * #define USB_SOF_HOOK myAssemblerMacro | ||
| 186 | * This macro (if defined) is executed in the assembler module when a | ||
| 187 | * Start Of Frame condition is detected. It is recommended to define it to | ||
| 188 | * the name of an assembler macro which is defined here as well so that more | ||
| 189 | * than one assembler instruction can be used. The macro may use the register | ||
| 190 | * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages | ||
| 191 | * immediately after an SOF pulse may be lost and must be retried by the host. | ||
| 192 | * What can you do with this hook? Since the SOF signal occurs exactly every | ||
| 193 | * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in | ||
| 194 | * designs running on the internal RC oscillator. | ||
| 195 | * Please note that Start Of Frame detection works only if D- is wired to the | ||
| 196 | * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! | ||
| 197 | */ | ||
| 198 | #define USB_CFG_CHECK_DATA_TOGGLING 0 | ||
| 199 | /* define this macro to 1 if you want to filter out duplicate data packets | ||
| 200 | * sent by the host. Duplicates occur only as a consequence of communication | ||
| 201 | * errors, when the host does not receive an ACK. Please note that you need to | ||
| 202 | * implement the filtering yourself in usbFunctionWriteOut() and | ||
| 203 | * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable | ||
| 204 | * for each control- and out-endpoint to check for duplicate packets. | ||
| 205 | */ | ||
| 206 | #define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 | ||
| 207 | /* define this macro to 1 if you want the function usbMeasureFrameLength() | ||
| 208 | * compiled in. This function can be used to calibrate the AVR's RC oscillator. | ||
| 209 | */ | ||
| 210 | #define USB_USE_FAST_CRC 0 | ||
| 211 | /* The assembler module has two implementations for the CRC algorithm. One is | ||
| 212 | * faster, the other is smaller. This CRC routine is only used for transmitted | ||
| 213 | * messages where timing is not critical. The faster routine needs 31 cycles | ||
| 214 | * per byte while the smaller one needs 61 to 69 cycles. The faster routine | ||
| 215 | * may be worth the 32 bytes bigger code size if you transmit lots of data and | ||
| 216 | * run the AVR close to its limit. | ||
| 217 | */ | ||
| 218 | |||
| 219 | /* -------------------------- Device Description --------------------------- */ | ||
| 220 | |||
| 221 | #define USB_CFG_VENDOR_ID (VENDOR_ID & 0xFF), ((VENDOR_ID >> 8) & 0xFF) | ||
| 222 | /* USB vendor ID for the device, low byte first. If you have registered your | ||
| 223 | * own Vendor ID, define it here. Otherwise you may use one of obdev's free | ||
| 224 | * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules! | ||
| 225 | * *** IMPORTANT NOTE *** | ||
| 226 | * This template uses obdev's shared VID/PID pair for Vendor Class devices | ||
| 227 | * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand | ||
| 228 | * the implications! | ||
| 229 | */ | ||
| 230 | #define USB_CFG_DEVICE_ID (PRODUCT_ID & 0xFF), ((PRODUCT_ID >> 8) & 0xFF) | ||
| 231 | /* This is the ID of the product, low byte first. It is interpreted in the | ||
| 232 | * scope of the vendor ID. If you have registered your own VID with usb.org | ||
| 233 | * or if you have licensed a PID from somebody else, define it here. Otherwise | ||
| 234 | * you may use one of obdev's free shared VID/PID pairs. See the file | ||
| 235 | * USB-IDs-for-free.txt for details! | ||
| 236 | * *** IMPORTANT NOTE *** | ||
| 237 | * This template uses obdev's shared VID/PID pair for Vendor Class devices | ||
| 238 | * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand | ||
| 239 | * the implications! | ||
| 240 | */ | ||
| 241 | #define USB_CFG_DEVICE_VERSION 0x00, 0x01 | ||
| 242 | /* Version number of the device: Minor number first, then major number. | ||
| 243 | */ | ||
| 244 | #define USB_CFG_VENDOR_NAME 't', '.', 'm', '.', 'k', '.' | ||
| 245 | #define USB_CFG_VENDOR_NAME_LEN 6 | ||
| 246 | /* These two values define the vendor name returned by the USB device. The name | ||
| 247 | * must be given as a list of characters under single quotes. The characters | ||
| 248 | * are interpreted as Unicode (UTF-16) entities. | ||
| 249 | * If you don't want a vendor name string, undefine these macros. | ||
| 250 | * ALWAYS define a vendor name containing your Internet domain name if you use | ||
| 251 | * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for | ||
| 252 | * details. | ||
| 253 | */ | ||
| 254 | #define USB_CFG_DEVICE_NAME 'P', 'S', '/', '2', ' ', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', ' ', 'c', 'o', 'n', 'v', 'e', 'r', 't', 'e', 'r' | ||
| 255 | #define USB_CFG_DEVICE_NAME_LEN 23 | ||
| 256 | /* Same as above for the device name. If you don't want a device name, undefine | ||
| 257 | * the macros. See the file USB-IDs-for-free.txt before you assign a name if | ||
| 258 | * you use a shared VID/PID. | ||
| 259 | */ | ||
| 260 | /*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ | ||
| 261 | /*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ | ||
| 262 | /* Same as above for the serial number. If you don't want a serial number, | ||
| 263 | * undefine the macros. | ||
| 264 | * It may be useful to provide the serial number through other means than at | ||
| 265 | * compile time. See the section about descriptor properties below for how | ||
| 266 | * to fine tune control over USB descriptors such as the string descriptor | ||
| 267 | * for the serial number. | ||
| 268 | */ | ||
| 269 | #define USB_CFG_DEVICE_CLASS 0 | ||
| 270 | #define USB_CFG_DEVICE_SUBCLASS 0 | ||
| 271 | /* See USB specification if you want to conform to an existing device class. | ||
| 272 | * Class 0xff is "vendor specific". | ||
| 273 | */ | ||
| 274 | #define USB_CFG_INTERFACE_CLASS 3 /* HID */ | ||
| 275 | #define USB_CFG_INTERFACE_SUBCLASS 1 /* Boot */ | ||
| 276 | #define USB_CFG_INTERFACE_PROTOCOL 1 /* Keyboard */ | ||
| 277 | /* See USB specification if you want to conform to an existing device class or | ||
| 278 | * protocol. The following classes must be set at interface level: | ||
| 279 | * HID class is 3, no subclass and protocol required (but may be useful!) | ||
| 280 | * CDC class is 2, use subclass 2 and protocol 1 for ACM | ||
| 281 | */ | ||
| 282 | #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0 | ||
| 283 | /* Define this to the length of the HID report descriptor, if you implement | ||
| 284 | * an HID device. Otherwise don't define it or define it to 0. | ||
| 285 | * If you use this define, you must add a PROGMEM character array named | ||
| 286 | * "usbHidReportDescriptor" to your code which contains the report descriptor. | ||
| 287 | * Don't forget to keep the array and this define in sync! | ||
| 288 | */ | ||
| 289 | |||
| 290 | /* #define USB_PUBLIC static */ | ||
| 291 | /* Use the define above if you #include usbdrv.c instead of linking against it. | ||
| 292 | * This technique saves a couple of bytes in flash memory. | ||
| 293 | */ | ||
| 294 | |||
| 295 | /* ------------------- Fine Control over USB Descriptors ------------------- */ | ||
| 296 | /* If you don't want to use the driver's default USB descriptors, you can | ||
| 297 | * provide our own. These can be provided as (1) fixed length static data in | ||
| 298 | * flash memory, (2) fixed length static data in RAM or (3) dynamically at | ||
| 299 | * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more | ||
| 300 | * information about this function. | ||
| 301 | * Descriptor handling is configured through the descriptor's properties. If | ||
| 302 | * no properties are defined or if they are 0, the default descriptor is used. | ||
| 303 | * Possible properties are: | ||
| 304 | * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched | ||
| 305 | * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is | ||
| 306 | * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if | ||
| 307 | * you want RAM pointers. | ||
| 308 | * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found | ||
| 309 | * in static memory is in RAM, not in flash memory. | ||
| 310 | * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), | ||
| 311 | * the driver must know the descriptor's length. The descriptor itself is | ||
| 312 | * found at the address of a well known identifier (see below). | ||
| 313 | * List of static descriptor names (must be declared PROGMEM if in flash): | ||
| 314 | * char usbDescriptorDevice[]; | ||
| 315 | * char usbDescriptorConfiguration[]; | ||
| 316 | * char usbDescriptorHidReport[]; | ||
| 317 | * char usbDescriptorString0[]; | ||
| 318 | * int usbDescriptorStringVendor[]; | ||
| 319 | * int usbDescriptorStringDevice[]; | ||
| 320 | * int usbDescriptorStringSerialNumber[]; | ||
| 321 | * Other descriptors can't be provided statically, they must be provided | ||
| 322 | * dynamically at runtime. | ||
| 323 | * | ||
| 324 | * Descriptor properties are or-ed or added together, e.g.: | ||
| 325 | * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) | ||
| 326 | * | ||
| 327 | * The following descriptors are defined: | ||
| 328 | * USB_CFG_DESCR_PROPS_DEVICE | ||
| 329 | * USB_CFG_DESCR_PROPS_CONFIGURATION | ||
| 330 | * USB_CFG_DESCR_PROPS_STRINGS | ||
| 331 | * USB_CFG_DESCR_PROPS_STRING_0 | ||
| 332 | * USB_CFG_DESCR_PROPS_STRING_VENDOR | ||
| 333 | * USB_CFG_DESCR_PROPS_STRING_PRODUCT | ||
| 334 | * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER | ||
| 335 | * USB_CFG_DESCR_PROPS_HID | ||
| 336 | * USB_CFG_DESCR_PROPS_HID_REPORT | ||
| 337 | * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) | ||
| 338 | * | ||
| 339 | * Note about string descriptors: String descriptors are not just strings, they | ||
| 340 | * are Unicode strings prefixed with a 2 byte header. Example: | ||
| 341 | * int serialNumberDescriptor[] = { | ||
| 342 | * USB_STRING_DESCRIPTOR_HEADER(6), | ||
| 343 | * 'S', 'e', 'r', 'i', 'a', 'l' | ||
| 344 | * }; | ||
| 345 | */ | ||
| 346 | |||
| 347 | #define USB_CFG_DESCR_PROPS_DEVICE 0 | ||
| 348 | #define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC | ||
| 349 | //#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 | ||
| 350 | #define USB_CFG_DESCR_PROPS_STRINGS 0 | ||
| 351 | #define USB_CFG_DESCR_PROPS_STRING_0 0 | ||
| 352 | #define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 | ||
| 353 | #define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 | ||
| 354 | #define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 | ||
| 355 | //#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC | ||
| 356 | #define USB_CFG_DESCR_PROPS_HID 0 | ||
| 357 | #define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC | ||
| 358 | //#define USB_CFG_DESCR_PROPS_HID_REPORT 0 | ||
| 359 | #define USB_CFG_DESCR_PROPS_UNKNOWN 0 | ||
| 360 | |||
| 361 | /* ----------------------- Optional MCU Description ------------------------ */ | ||
| 362 | |||
| 363 | /* The following configurations have working defaults in usbdrv.h. You | ||
| 364 | * usually don't need to set them explicitly. Only if you want to run | ||
| 365 | * the driver on a device which is not yet supported or with a compiler | ||
| 366 | * which is not fully supported (such as IAR C) or if you use a differnt | ||
| 367 | * interrupt than INT0, you may have to define some of these. | ||
| 368 | */ | ||
| 369 | /* #define USB_INTR_CFG MCUCR */ | ||
| 370 | /* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ | ||
| 371 | /* #define USB_INTR_CFG_CLR 0 */ | ||
| 372 | /* #define USB_INTR_ENABLE GIMSK */ | ||
| 373 | /* #define USB_INTR_ENABLE_BIT INT0 */ | ||
| 374 | /* #define USB_INTR_PENDING GIFR */ | ||
| 375 | /* #define USB_INTR_PENDING_BIT INTF0 */ | ||
| 376 | /* #define USB_INTR_VECTOR INT0_vect */ | ||
| 377 | |||
| 378 | #endif /* __usbconfig_h_included__ */ | ||
diff --git a/converter/terminal_usb/Makefile.102_pjrc b/converter/terminal_usb/Makefile.102_pjrc new file mode 100644 index 000000000..e9d14e7a0 --- /dev/null +++ b/converter/terminal_usb/Makefile.102_pjrc | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | # | ||
| 2 | # Makefile for PJRC Teensy | ||
| 3 | # | ||
| 4 | |||
| 5 | |||
| 6 | # Target file name (without extension). | ||
| 7 | TARGET = terminal_usb_102_pjrc | ||
| 8 | |||
| 9 | # Directory common source filess exist | ||
| 10 | TOP_DIR = ../.. | ||
| 11 | |||
| 12 | # Directory keyboard dependent files exist | ||
| 13 | TARGET_DIR = . | ||
| 14 | |||
| 15 | # keyboard dependent files | ||
| 16 | SRC = main.c \ | ||
| 17 | keymap_102.c \ | ||
| 18 | matrix.c \ | ||
| 19 | led.c \ | ||
| 20 | ps2.c | ||
| 21 | |||
| 22 | CONFIG_H = config_102_pjrc.h | ||
| 23 | |||
| 24 | |||
| 25 | # MCU name, you MUST set this to match the board you are using | ||
| 26 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 27 | #MCU = at90usb162 # Teensy 1.0 | ||
| 28 | MCU = atmega32u4 # Teensy 2.0 | ||
| 29 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 30 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 31 | |||
| 32 | |||
| 33 | # Processor frequency. | ||
| 34 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 35 | # so your program will run at the correct speed. You should also set this | ||
| 36 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 37 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 38 | F_CPU = 16000000 | ||
| 39 | |||
| 40 | |||
| 41 | # Build Options | ||
| 42 | # *Comment out* to disable the options. | ||
| 43 | # | ||
| 44 | MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 45 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 46 | NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | #---------------- Programming Options -------------------------- | ||
| 51 | PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | ||
| 52 | |||
| 53 | |||
| 54 | |||
| 55 | include $(TOP_DIR)/protocol/pjrc.mk | ||
| 56 | include $(TOP_DIR)/protocol.mk | ||
| 57 | include $(TOP_DIR)/common.mk | ||
| 58 | include $(TOP_DIR)/rules.mk | ||
diff --git a/converter/terminal_usb/Makefile.122_pjrc b/converter/terminal_usb/Makefile.122_pjrc new file mode 100644 index 000000000..bec00510e --- /dev/null +++ b/converter/terminal_usb/Makefile.122_pjrc | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | # | ||
| 2 | # Makefile for PJRC Teensy | ||
| 3 | # | ||
| 4 | |||
| 5 | |||
| 6 | # Target file name (without extension). | ||
| 7 | TARGET = terminal_usb_122_pjrc | ||
| 8 | |||
| 9 | # Directory common source filess exist | ||
| 10 | TOP_DIR = ../.. | ||
| 11 | |||
| 12 | # Directory keyboard dependent files exist | ||
| 13 | TARGET_DIR = . | ||
| 14 | |||
| 15 | # keyboard dependent files | ||
| 16 | SRC = main.c \ | ||
| 17 | keymap_122.c \ | ||
| 18 | matrix.c \ | ||
| 19 | led.c \ | ||
| 20 | ps2.c | ||
| 21 | |||
| 22 | CONFIG_H = config_122_pjrc.h | ||
| 23 | |||
| 24 | |||
| 25 | # MCU name, you MUST set this to match the board you are using | ||
| 26 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 27 | #MCU = at90usb162 # Teensy 1.0 | ||
| 28 | MCU = atmega32u4 # Teensy 2.0 | ||
| 29 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 30 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 31 | |||
| 32 | |||
| 33 | # Processor frequency. | ||
| 34 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 35 | # so your program will run at the correct speed. You should also set this | ||
| 36 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 37 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 38 | F_CPU = 16000000 | ||
| 39 | |||
| 40 | |||
| 41 | # Build Options | ||
| 42 | # *Comment out* to disable the options. | ||
| 43 | # | ||
| 44 | #MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 45 | #EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 46 | #NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | #---------------- Programming Options -------------------------- | ||
| 51 | PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | ||
| 52 | |||
| 53 | |||
| 54 | |||
| 55 | include $(TOP_DIR)/protocol/pjrc.mk | ||
| 56 | include $(TOP_DIR)/protocol.mk | ||
| 57 | include $(TOP_DIR)/common.mk | ||
| 58 | include $(TOP_DIR)/rules.mk | ||
diff --git a/converter/terminal_usb/README b/converter/terminal_usb/README new file mode 100644 index 000000000..1ce49f33d --- /dev/null +++ b/converter/terminal_usb/README | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | PS/2 to USB keyboard converter for IBM terminal keyboard | ||
| 2 | ========================================================= | ||
| 3 | It supports PS/2 Scan Code Set 3 and runs on Teensy, Teensy++ and boards withATMega32u4/AT90USB. | ||
| 4 | I tested the converter only on Teensy with 1392595(102keys terminal keyboard), | ||
| 5 | though, I think it will also work with 122keys boards. | ||
| 6 | |||
| 7 | http://geekhack.org/showwiki.php?title=Island:27272 | ||
| 8 | |||
| 9 | |||
| 10 | CONNECTION | ||
| 11 | ---------- | ||
| 12 | Data: PD0 | ||
| 13 | Clock: PD1 | ||
| 14 | VCC and GND, of course. | ||
| 15 | |||
| 16 | It is the same as Soarer's converter pin configuration. | ||
| 17 | See RESOURCE for keyboard connector pin assign. | ||
| 18 | |||
| 19 | |||
| 20 | |||
| 21 | BUILD | ||
| 22 | ----- | ||
| 23 | Get source: | ||
| 24 | $ git clone https://github.com/tmk/tmk_keyboard.git | ||
| 25 | $ cd terminal_usb | ||
| 26 | |||
| 27 | For 102keys: | ||
| 28 | $ make -f Makefile.102_pjrc | ||
| 29 | |||
| 30 | For 122keys(not tested): | ||
| 31 | $ make -f Makefile.122_pjrc | ||
| 32 | |||
| 33 | I used WinAVR 20100110 to develop and build. | ||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | RESOURCE | ||
| 38 | -------- | ||
| 39 | Soarer's Converter: http://geekhack.org/showwiki.php?title=Island:17458 | ||
| 40 | 102keys(1392595): http://geekhack.org/showthread.php?10737-What-Can-I-Do-With-a-Terminal-Model-M | ||
| 41 | 122keys(1390876): http://www.seasip.info/VintagePC/ibm_1390876.html | ||
| 42 | KbdBabel: http://www.kbdbabel.org/ | ||
| 43 | RJ45 Connector: http://www.kbdbabel.org/conn/kbd_connector_ibmterm.png | ||
| 44 | DIN Connector: http://www.kbdbabel.org/conn/kbd_connector_ibm3179_318x_319x.png | ||
| 45 | WinAVR: http://winavr.sourceforge.net/ | ||
| 46 | |||
| 47 | EOF | ||
diff --git a/converter/terminal_usb/config_102_pjrc.h b/converter/terminal_usb/config_102_pjrc.h new file mode 100644 index 000000000..2dce04af7 --- /dev/null +++ b/converter/terminal_usb/config_102_pjrc.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | /* controller configuration */ | ||
| 22 | #include "controller_teensy.h" | ||
| 23 | |||
| 24 | #define VENDOR_ID 0xFEED | ||
| 25 | #define PRODUCT_ID 0x6531 | ||
| 26 | #define MANUFACTURER t.m.k. | ||
| 27 | #define PRODUCT PS/2(Set3)-USB Keyboard converter(IBM 102keys) | ||
| 28 | #define DESCRIPTION USB converter for IBM Terminal Keyboard 102keys | ||
| 29 | |||
| 30 | |||
| 31 | /* matrix size */ | ||
| 32 | #define MATRIX_ROWS 17 // keycode bit: 3-0 | ||
| 33 | #define MATRIX_COLS 8 // keycode bit: 6-4 | ||
| 34 | |||
| 35 | |||
| 36 | /* key combination for command */ | ||
| 37 | #define IS_COMMAND() ( \ | ||
| 38 | keyboard_report->mods == (MOD_BIT(KB_RALT) | MOD_BIT(KB_RCTL)) \ | ||
| 39 | ) | ||
| 40 | |||
| 41 | |||
| 42 | /* mouse keys */ | ||
| 43 | #ifdef MOUSEKEY_ENABLE | ||
| 44 | # define MOUSEKEY_DELAY_TIME 255 | ||
| 45 | #endif | ||
| 46 | |||
| 47 | |||
| 48 | /* PS/2 lines */ | ||
| 49 | #define PS2_CLOCK_PORT PORTD | ||
| 50 | #define PS2_CLOCK_PIN PIND | ||
| 51 | #define PS2_CLOCK_DDR DDRD | ||
| 52 | #define PS2_CLOCK_BIT 1 | ||
| 53 | #define PS2_DATA_PORT PORTD | ||
| 54 | #define PS2_DATA_PIN PIND | ||
| 55 | #define PS2_DATA_DDR DDRD | ||
| 56 | #define PS2_DATA_BIT 0 | ||
| 57 | |||
| 58 | #endif | ||
diff --git a/converter/terminal_usb/config_122_pjrc.h b/converter/terminal_usb/config_122_pjrc.h new file mode 100644 index 000000000..43691bd71 --- /dev/null +++ b/converter/terminal_usb/config_122_pjrc.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | /* controller configuration */ | ||
| 22 | #include "controller_teensy.h" | ||
| 23 | |||
| 24 | #define VENDOR_ID 0xFEED | ||
| 25 | #define PRODUCT_ID 0x6532 | ||
| 26 | #define MANUFACTURER t.m.k. | ||
| 27 | #define PRODUCT PS/2(Set3)-USB Keyboard converter(IBM 122keys) | ||
| 28 | #define DESCRIPTION USB converter for IBM Terminal Keyboard 122keys | ||
| 29 | |||
| 30 | |||
| 31 | /* matrix size */ | ||
| 32 | #define MATRIX_ROWS 17 // keycode bit: 3-0 | ||
| 33 | #define MATRIX_COLS 8 // keycode bit: 6-4 | ||
| 34 | |||
| 35 | |||
| 36 | /* key combination for command */ | ||
| 37 | #define IS_COMMAND() ( \ | ||
| 38 | keyboard_report->mods == (MOD_BIT(KB_RALT) | MOD_BIT(KB_RCTL)) \ | ||
| 39 | ) | ||
| 40 | |||
| 41 | |||
| 42 | /* mouse keys */ | ||
| 43 | #ifdef MOUSEKEY_ENABLE | ||
| 44 | # define MOUSEKEY_DELAY_TIME 255 | ||
| 45 | #endif | ||
| 46 | |||
| 47 | |||
| 48 | /* PS/2 lines */ | ||
| 49 | #define PS2_CLOCK_PORT PORTD | ||
| 50 | #define PS2_CLOCK_PIN PIND | ||
| 51 | #define PS2_CLOCK_DDR DDRD | ||
| 52 | #define PS2_CLOCK_BIT 1 | ||
| 53 | #define PS2_DATA_PORT PORTD | ||
| 54 | #define PS2_DATA_PIN PIND | ||
| 55 | #define PS2_DATA_DDR DDRD | ||
| 56 | #define PS2_DATA_BIT 0 | ||
| 57 | |||
| 58 | #endif | ||
diff --git a/converter/terminal_usb/keymap_102.c b/converter/terminal_usb/keymap_102.c new file mode 100644 index 000000000..430570c47 --- /dev/null +++ b/converter/terminal_usb/keymap_102.c | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdbool.h> | ||
| 20 | #include <avr/pgmspace.h> | ||
| 21 | #include "usb_keycodes.h" | ||
| 22 | #include "print.h" | ||
| 23 | #include "debug.h" | ||
| 24 | #include "util.h" | ||
| 25 | #include "keymap.h" | ||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | |||
| 30 | /* | ||
| 31 | * IBM Terminal keyboard 1392595(102keys) | ||
| 32 | * http://geekhack.org/showthread.php?10737-What-Can-I-Do-With-a-Terminal-Model-M | ||
| 33 | * http://www.seasip.info/VintagePC/ibm_1391406.html | ||
| 34 | * | ||
| 35 | * Keymap array: | ||
| 36 | * 8 bytes | ||
| 37 | * +---------+ | ||
| 38 | * 0| | | ||
| 39 | * :| | 0x00-0x87 | ||
| 40 | * ;| | | ||
| 41 | * 17| | | ||
| 42 | * +---------+ | ||
| 43 | */ | ||
| 44 | #define KEYMAP( \ | ||
| 45 | K08, K07,K0F,K17,K1F,K27,K2F,K37,K3F,K47,K4F,K56,K5E, K57,K5F,K62, \ | ||
| 46 | \ | ||
| 47 | K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K5D,K66, K67,K6E,K6F, K76,K77,K7E,K84, \ | ||
| 48 | K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, K5C, K64,K65,K6D, K6C,K75,K7D,K7C, \ | ||
| 49 | K14,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K53,K5A, K6B,K73,K74,K7B, \ | ||
| 50 | K12,K13,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K51,K59, K63, K69,K72,K7A,K79, \ | ||
| 51 | K11, K19, K29, K39, K58, K61,K60,K6A, K68,K70,K71,K78 \ | ||
| 52 | ) { \ | ||
| 53 | { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K07 }, \ | ||
| 54 | { KB_##K08, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K0D, KB_##K0E, KB_##K0F }, \ | ||
| 55 | { KB_NO, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_##K17 }, \ | ||
| 56 | { KB_NO, KB_##K19, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_##K1F }, \ | ||
| 57 | { KB_NO, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, \ | ||
| 58 | { KB_NO, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, \ | ||
| 59 | { KB_NO, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_##K37 }, \ | ||
| 60 | { KB_NO, KB_##K39, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_##K3F }, \ | ||
| 61 | { KB_NO, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_##K47 }, \ | ||
| 62 | { KB_NO, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_##K4F }, \ | ||
| 63 | { KB_NO, KB_##K51, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, \ | ||
| 64 | { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_##K5C, KB_##K5D, KB_##K5E, KB_##K5F }, \ | ||
| 65 | { KB_##K60, KB_##K61, KB_##K62, KB_##K63, KB_##K64, KB_##K65, KB_##K66, KB_##K67 }, \ | ||
| 66 | { KB_##K68, KB_##K69, KB_##K6A, KB_##K6B, KB_##K6C, KB_##K6D, KB_##K6E, KB_##K6F }, \ | ||
| 67 | { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_##K77 }, \ | ||
| 68 | { KB_##K78, KB_##K79, KB_##K7A, KB_##K7B, KB_##K7C, KB_##K7D, KB_##K7E, KB_NO }, \ | ||
| 69 | { KB_NO, KB_NO, KB_NO, KB_NO, KB_##K84, KB_NO, KB_NO, KB_NO, }, \ | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | // Assign Fn key(0-7) to a layer to which switch with the Fn key pressed. | ||
| 74 | static const uint8_t PROGMEM fn_layer[] = { | ||
| 75 | 1, // Fn0 | ||
| 76 | 2, // Fn1 | ||
| 77 | 3, // Fn2 | ||
| 78 | 0, // Fn3 | ||
| 79 | 0, // Fn4 | ||
| 80 | 0, // Fn5 | ||
| 81 | 0, // Fn6 | ||
| 82 | 0 // Fn7 | ||
| 83 | }; | ||
| 84 | |||
| 85 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. | ||
| 86 | // See layer.c for details. | ||
| 87 | static const uint8_t PROGMEM fn_keycode[] = { | ||
| 88 | KB_SCLN, // Fn0 | ||
| 89 | KB_SLSH, // Fn1 | ||
| 90 | KB_ESC, // Fn2 | ||
| 91 | KB_NO, // Fn3 | ||
| 92 | KB_NO, // Fn4 | ||
| 93 | KB_NO, // Fn5 | ||
| 94 | KB_NO, // Fn6 | ||
| 95 | KB_NO // Fn7 | ||
| 96 | }; | ||
| 97 | |||
| 98 | |||
| 99 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 100 | /* 0: default | ||
| 101 | * ,---. ,---------------. ,---------------. ,---------------. ,-----------. | ||
| 102 | * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| | ||
| 103 | * `---' `---------------' `---------------' `---------------' `-----------' | ||
| 104 | * ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 105 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \|BS | |Ins|Hom|PgU| |NmL| /| *| -| | ||
| 106 | * |-----------------------------------------------------------| |-----------| |---------------| | ||
| 107 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| | | ||
| 108 | * |-----------------------------------------------------------| `-----------' |-----------| +| | ||
| 109 | * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '| #|Retu| | 4| 5| 6| | | ||
| 110 | * |-----------------------------------------------------------| ,---. |---------------| | ||
| 111 | * |Shif| \| Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| | | ||
| 112 | * |-----------------------------------------------------------| ,-----------. |-----------|Ent| | ||
| 113 | * |Ctrl| |Alt | Space |Alt | |Ctrl| |Lef|Dow|Rig| | 0| .| | | ||
| 114 | * `----' `---------------------------------------' `----' `-----------' `---------------' | ||
| 115 | */ | ||
| 116 | KEYMAP( | ||
| 117 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 118 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 119 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS, | ||
| 120 | LCTL,A, S, D, F, G, H, J, K, L, FN0, QUOT, NUHS,ENT, P4, P5, P6, PCMM, | ||
| 121 | LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, FN1, RO, FN2, UP, P1, P2, P3, PENT, | ||
| 122 | LGUI, LALT, SPC, RALT, RCTL, LEFT,DOWN,RGHT, NO, P0, PDOT,NO | ||
| 123 | ), | ||
| 124 | |||
| 125 | /* 1: Mouse keys | ||
| 126 | * ,-----------------------------------------------------------. | ||
| 127 | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa| | ||
| 128 | * |-----------------------------------------------------------| | ||
| 129 | * |Tab |MwL|MwU|McU|WwU|WwR|MwL|MwD|MwU|MwR| | | | \| | ||
| 130 | * |-----------------------------------------------------------| | ||
| 131 | * |CapsLo| |McL|McD|McR| |McL|McD|McU|McR|Fn0| |Return | | ||
| 132 | * |-----------------------------------------------------------| | ||
| 133 | * |Shift |VoD|VoU|Mut|Mb2|Mb3|Mb2|Mb1|VoD|VoU|Mut|Shift | | ||
| 134 | * |-----------------------------------------------------------| | ||
| 135 | * |Ctrl | |Alt | Mb1 |Alt | |Ctrl| | ||
| 136 | * `-----' `--------------------------------------' `----' | ||
| 137 | * Mc = mouse cursor, Mw = mouse wheel, Mb = mouse button | ||
| 138 | * Vo = Volume, Mut = Mute | ||
| 139 | */ | ||
| 140 | KEYMAP( | ||
| 141 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 142 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, NO, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 143 | TAB, WH_L,WH_D,MS_U,WH_U,WH_R,WH_L,WH_D,WH_U,WH_R,NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS, | ||
| 144 | LCTL,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN0, NO, NO, ENT, P4, P5, P6, PCMM, | ||
| 145 | LSFT,NO, VOLD,VOLU,MUTE,BTN2,BTN3,BTN2,BTN1,VOLD,VOLU,MUTE, NO, RSFT, UP, P1, P2, P3, PENT, | ||
| 146 | LGUI, LALT, BTN1, RALT, RCTL, LEFT,DOWN,RGHT, NO, P0, PDOT,NO | ||
| 147 | ), | ||
| 148 | |||
| 149 | /* 2: Cursor keys | ||
| 150 | * ,-----------------------------------------------------------. | ||
| 151 | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa| | ||
| 152 | * |-----------------------------------------------------------| | ||
| 153 | * |Tab |Hom|PgU| Up|PgU|End|Hom|PgD|PgU|End| | | | \| | ||
| 154 | * |-----------------------------------------------------------| | ||
| 155 | * |CapsLo| |Lef|Dow|Rig| |Lef|Dow| Up|Rig| | |Return | | ||
| 156 | * |-----------------------------------------------------------| | ||
| 157 | * |Shift | | | | | |Hom|PgD|PgU|End|Fn1|Shift | | ||
| 158 | * |-----------------------------------------------------------| | ||
| 159 | * |Ctrl | |Alt | Space |Alt | |Ctrl| | ||
| 160 | * `-----' `--------------------------------------' `----' | ||
| 161 | */ | ||
| 162 | KEYMAP( | ||
| 163 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 164 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, NO, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 165 | TAB, NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9, PMNS, | ||
| 166 | LCTL,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, NO, ENT, P4, P5, P6, PCMM, | ||
| 167 | LSFT,NO, VOLD,VOLU,MUTE,NO, NO, HOME,PGDN,PGUP,END, FN1, NO, RSFT, UP, P1, P2, P3, PENT, | ||
| 168 | LGUI, LALT, SPC, RALT, RCTL, LEFT,DOWN,RGHT, NO, P0, PDOT,NO | ||
| 169 | ), | ||
| 170 | |||
| 171 | /* 3: HHKB | ||
| 172 | * ,-----------------------------------------------------------. | ||
| 173 | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| | ||
| 174 | * |-----------------------------------------------------------| | ||
| 175 | * |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| | ||
| 176 | * |-----------------------------------------------------------| | ||
| 177 | * |Contro|VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | | ||
| 178 | * |-----------------------------------------------------------| | ||
| 179 | * |Shift | | | | | | +| -|End|PgD|Dow|Fn2 | | ||
| 180 | * |-----------------------------------------------------------| | ||
| 181 | * |Ctrl | |Alt | Space |Alt | |Ctrl| | ||
| 182 | * `-----' `--------------------------------------' `----' | ||
| 183 | */ | ||
| 184 | KEYMAP( | ||
| 185 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, | ||
| 186 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, NO, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 187 | CAPS,NO, NO, NO, NO, NO, NO, NO, PSCR,SLCK,BRK, UP, NO, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS, | ||
| 188 | LCTL,VOLD,VOLU,MUTE,NO, NO, PAST,PSLS,HOME,PGUP,LEFT,RGHT, NO, ENT, P4, P5, P6, PCMM, | ||
| 189 | LSFT,NO, NO, NO, NO, NO, NO, PPLS,PMNS,END, PGDN,DOWN, NO, FN2, UP, P1, P2, P3, PENT, | ||
| 190 | LGUI, LALT, SPC, RALT, RCTL, LEFT,DOWN,RGHT, NO, P0, PDOT,NO | ||
| 191 | ), | ||
| 192 | }; | ||
| 193 | |||
| 194 | |||
| 195 | uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | ||
| 196 | { | ||
| 197 | return pgm_read_byte(&keymaps[(layer)][(row)][(col)]); | ||
| 198 | } | ||
| 199 | |||
| 200 | uint8_t keymap_fn_layer(uint8_t fn_bits) | ||
| 201 | { | ||
| 202 | return pgm_read_byte(&fn_layer[biton(fn_bits)]); | ||
| 203 | } | ||
| 204 | |||
| 205 | uint8_t keymap_fn_keycode(uint8_t fn_bits) | ||
| 206 | { | ||
| 207 | return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | ||
| 208 | } | ||
diff --git a/converter/terminal_usb/keymap_122.c b/converter/terminal_usb/keymap_122.c new file mode 100644 index 000000000..7a2168122 --- /dev/null +++ b/converter/terminal_usb/keymap_122.c | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdbool.h> | ||
| 20 | #include <avr/pgmspace.h> | ||
| 21 | #include "usb_keycodes.h" | ||
| 22 | #include "print.h" | ||
| 23 | #include "debug.h" | ||
| 24 | #include "util.h" | ||
| 25 | #include "keymap.h" | ||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | |||
| 30 | /* | ||
| 31 | * IBM Terminal keyboard 1392595(102keys) | ||
| 32 | * http://geekhack.org/showthread.php?10737-What-Can-I-Do-With-a-Terminal-Model-M | ||
| 33 | * http://www.seasip.info/VintagePC/ibm_1391406.html | ||
| 34 | * | ||
| 35 | * Keymap array: | ||
| 36 | * 8 bytes | ||
| 37 | * +---------+ | ||
| 38 | * 0| | | ||
| 39 | * :| | 0x00-0x87 | ||
| 40 | * ;| | | ||
| 41 | * 17| | | ||
| 42 | * +---------+ | ||
| 43 | */ | ||
| 44 | #define KEYMAP( \ | ||
| 45 | K08,K10,K18,K20,K28,K30,K38,K40,K48,K50,K57,K5F, \ | ||
| 46 | K07,K0F,K17,K1F,K27,K2F,K37,K3F,K47,K4F,K56,K5E, \ | ||
| 47 | \ | ||
| 48 | K05,K06, K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K5D,K66, K67,K6E,K6F, K76,K77,K7E,K84, \ | ||
| 49 | K04,K0C, K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, K5C, K64,K65,K6D, K6C,K75,K7D,K7C, \ | ||
| 50 | K03,K0B, K14,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K53,K5A, K63, K6B,K73,K74,K7B, \ | ||
| 51 | K83,K0A, K12,K13,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K51,K59, K61,K62,K6A, K69,K72,K7A,K79, \ | ||
| 52 | K01,K09, K11, K19, K29, K39, K58, K60, K68,K70,K71,K78 \ | ||
| 53 | ) { \ | ||
| 54 | { KB_NO, KB_##K01, KB_NO, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \ | ||
| 55 | { KB_##K08, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_##K0F }, \ | ||
| 56 | { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_##K17 }, \ | ||
| 57 | { KB_##K18, KB_##K19, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_##K1F }, \ | ||
| 58 | { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, \ | ||
| 59 | { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, \ | ||
| 60 | { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_##K37 }, \ | ||
| 61 | { KB_##K38, KB_##K39, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_##K3F }, \ | ||
| 62 | { KB_##K40, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_##K47 }, \ | ||
| 63 | { KB_##K48, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_##K4F }, \ | ||
| 64 | { KB_##K50, KB_##K51, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, \ | ||
| 65 | { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_##K5C, KB_##K5D, KB_##K5E, KB_##K5F }, \ | ||
| 66 | { KB_##K60, KB_##K61, KB_##K62, KB_##K63, KB_##K64, KB_##K65, KB_##K66, KB_##K67 }, \ | ||
| 67 | { KB_##K68, KB_##K69, KB_##K6A, KB_##K6B, KB_##K6C, KB_##K6D, KB_##K6E, KB_##K6F }, \ | ||
| 68 | { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_##K77 }, \ | ||
| 69 | { KB_##K78, KB_##K79, KB_##K7A, KB_##K7B, KB_##K7C, KB_##K7D, KB_##K7E, KB_NO }, \ | ||
| 70 | { KB_NO, KB_NO, KB_NO, KB_##K83, KB_##K84, KB_NO, KB_NO, KB_NO, }, \ | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | // Assign Fn key(0-7) to a layer to which switch with the Fn key pressed. | ||
| 75 | static const uint8_t PROGMEM fn_layer[] = { | ||
| 76 | 0, // Fn0 | ||
| 77 | 0, // Fn1 | ||
| 78 | 0, // Fn2 | ||
| 79 | 0, // Fn3 | ||
| 80 | 0, // Fn4 | ||
| 81 | 0, // Fn5 | ||
| 82 | 0, // Fn6 | ||
| 83 | 0 // Fn7 | ||
| 84 | }; | ||
| 85 | |||
| 86 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. | ||
| 87 | // See layer.c for details. | ||
| 88 | static const uint8_t PROGMEM fn_keycode[] = { | ||
| 89 | KB_NO, // Fn0 | ||
| 90 | KB_NO, // Fn1 | ||
| 91 | KB_NO, // Fn2 | ||
| 92 | KB_NO, // Fn3 | ||
| 93 | KB_NO, // Fn4 | ||
| 94 | KB_NO, // Fn5 | ||
| 95 | KB_NO, // Fn6 | ||
| 96 | KB_NO // Fn7 | ||
| 97 | }; | ||
| 98 | |||
| 99 | |||
| 100 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 101 | /* 0: default | ||
| 102 | * ,---. ,---------------. ,---------------. ,---------------. ,-----------. | ||
| 103 | * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| | ||
| 104 | * `---' `---------------' `---------------' `---------------' `-----------' | ||
| 105 | * ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 106 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \|BS | |Ins|Hom|PgU| |NmL| /| *| -| | ||
| 107 | * |-----------------------------------------------------------| |-----------| |---------------| | ||
| 108 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| | | ||
| 109 | * |-----------------------------------------------------------| `-----------' |-----------| +| | ||
| 110 | * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '| #|Retu| | 4| 5| 6| | | ||
| 111 | * |-----------------------------------------------------------| ,---. |---------------| | ||
| 112 | * |Shif| \| Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| | | ||
| 113 | * |-----------------------------------------------------------| ,-----------. |-----------|Ent| | ||
| 114 | * |Ctrl| |Alt | Space |Alt | |Ctrl| |Lef|Dow|Rig| | 0| .| | | ||
| 115 | * `----' `---------------------------------------' `----' `-----------' `---------------' | ||
| 116 | */ | ||
| 117 | KEYMAP( | ||
| 118 | F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, | ||
| 119 | F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, | ||
| 120 | |||
| 121 | PSCR,ESC, GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 122 | SLCK,INT4, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS, | ||
| 123 | PAUS,INT5, CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, UP, P4, P5, P6, PCMM, | ||
| 124 | APP, INT6, LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RO, RSFT, LEFT,INT2,RGHT, P1, P2, P3, PENT, | ||
| 125 | RGUI,LGUI, LCTL, LALT, SPC, RALT, RCTL, DOWN, NO, P0, PDOT,NO | ||
| 126 | ), | ||
| 127 | }; | ||
| 128 | |||
| 129 | |||
| 130 | uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | ||
| 131 | { | ||
| 132 | return pgm_read_byte(&keymaps[(layer)][(row)][(col)]); | ||
| 133 | } | ||
| 134 | |||
| 135 | uint8_t keymap_fn_layer(uint8_t fn_bits) | ||
| 136 | { | ||
| 137 | return pgm_read_byte(&fn_layer[biton(fn_bits)]); | ||
| 138 | } | ||
| 139 | |||
| 140 | uint8_t keymap_fn_keycode(uint8_t fn_bits) | ||
| 141 | { | ||
| 142 | return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | ||
| 143 | } | ||
diff --git a/converter/terminal_usb/led.c b/converter/terminal_usb/led.c new file mode 100644 index 000000000..e448e84ec --- /dev/null +++ b/converter/terminal_usb/led.c | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "stdint.h" | ||
| 19 | #include "ps2.h" | ||
| 20 | #include "led.h" | ||
| 21 | |||
| 22 | |||
| 23 | void led_set(uint8_t usb_led) | ||
| 24 | { | ||
| 25 | uint8_t ps2_led = 0; | ||
| 26 | if (usb_led & (1<<USB_LED_SCROLL_LOCK)) | ||
| 27 | ps2_led |= (1<<PS2_LED_SCROLL_LOCK); | ||
| 28 | if (usb_led & (1<<USB_LED_NUM_LOCK)) | ||
| 29 | ps2_led |= (1<<PS2_LED_NUM_LOCK); | ||
| 30 | if (usb_led & (1<<USB_LED_CAPS_LOCK)) | ||
| 31 | ps2_led |= (1<<PS2_LED_CAPS_LOCK); | ||
| 32 | ps2_host_set_led(ps2_led); | ||
| 33 | } | ||
diff --git a/converter/terminal_usb/matrix.c b/converter/terminal_usb/matrix.c new file mode 100644 index 000000000..a6eff8c1e --- /dev/null +++ b/converter/terminal_usb/matrix.c | |||
| @@ -0,0 +1,226 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdbool.h> | ||
| 20 | #include <avr/io.h> | ||
| 21 | #include <util/delay.h> | ||
| 22 | #include "print.h" | ||
| 23 | #include "util.h" | ||
| 24 | #include "debug.h" | ||
| 25 | #include "ps2.h" | ||
| 26 | #include "matrix.h" | ||
| 27 | |||
| 28 | |||
| 29 | static void matrix_make(uint8_t code); | ||
| 30 | static void matrix_break(uint8_t code); | ||
| 31 | #ifdef MATRIX_HAS_GHOST | ||
| 32 | static bool matrix_has_ghost_in_row(uint8_t row); | ||
| 33 | #endif | ||
| 34 | |||
| 35 | |||
| 36 | /* | ||
| 37 | * Matrix Array usage: | ||
| 38 | * 'Scan Code Set 3' is assigned into 17x8 cell matrix. | ||
| 39 | * | ||
| 40 | * 8bit wide | ||
| 41 | * +---------+ | ||
| 42 | * 0| | | ||
| 43 | * :| | 0x00-0x87 | ||
| 44 | * ;| | | ||
| 45 | * 17| | | ||
| 46 | * +---------+ | ||
| 47 | */ | ||
| 48 | static uint8_t matrix[MATRIX_ROWS]; | ||
| 49 | #define ROW(code) (code>>3) | ||
| 50 | #define COL(code) (code&0x07) | ||
| 51 | |||
| 52 | static bool is_modified = false; | ||
| 53 | |||
| 54 | |||
| 55 | inline | ||
| 56 | uint8_t matrix_rows(void) | ||
| 57 | { | ||
| 58 | return MATRIX_ROWS; | ||
| 59 | } | ||
| 60 | |||
| 61 | inline | ||
| 62 | uint8_t matrix_cols(void) | ||
| 63 | { | ||
| 64 | return MATRIX_COLS; | ||
| 65 | } | ||
| 66 | |||
| 67 | void matrix_init(void) | ||
| 68 | { | ||
| 69 | print_enable = true; | ||
| 70 | debug_enable = true; | ||
| 71 | //debug_matrix = true; | ||
| 72 | //debug_keyboard = true; | ||
| 73 | //debug_mouse = false; | ||
| 74 | |||
| 75 | ps2_host_init(); | ||
| 76 | // Make and Break code without Typematic | ||
| 77 | while (ps2_host_send(0xF8) != 0xFA) { | ||
| 78 | debug("send F8: failed\n"); | ||
| 79 | _delay_ms(500); | ||
| 80 | } | ||
| 81 | debug("send F8: OK\n"); | ||
| 82 | |||
| 83 | |||
| 84 | // initialize matrix state: all keys off | ||
| 85 | for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; | ||
| 86 | |||
| 87 | return; | ||
| 88 | } | ||
| 89 | |||
| 90 | uint8_t matrix_scan(void) | ||
| 91 | { | ||
| 92 | |||
| 93 | // scan code reading states | ||
| 94 | static enum { | ||
| 95 | INIT, | ||
| 96 | F0, | ||
| 97 | } state = INIT; | ||
| 98 | |||
| 99 | |||
| 100 | is_modified = false; | ||
| 101 | |||
| 102 | uint8_t code; | ||
| 103 | while ((code = ps2_host_recv())) { | ||
| 104 | debug_hex(code); | ||
| 105 | switch (state) { | ||
| 106 | case INIT: | ||
| 107 | switch (code) { | ||
| 108 | case 0xF0: | ||
| 109 | state = F0; | ||
| 110 | debug(" "); | ||
| 111 | break; | ||
| 112 | default: // normal key make | ||
| 113 | if (code < 0x88) { | ||
| 114 | matrix_make(code); | ||
| 115 | } else { | ||
| 116 | debug("unexpected scan code at INIT: "); debug_hex(code); debug("\n"); | ||
| 117 | } | ||
| 118 | state = INIT; | ||
| 119 | debug("\n"); | ||
| 120 | } | ||
| 121 | break; | ||
| 122 | case F0: // Break code | ||
| 123 | switch (code) { | ||
| 124 | default: | ||
| 125 | if (code < 0x88) { | ||
| 126 | matrix_break(code); | ||
| 127 | } else { | ||
| 128 | debug("unexpected scan code at F0: "); debug_hex(code); debug("\n"); | ||
| 129 | } | ||
| 130 | state = INIT; | ||
| 131 | debug("\n"); | ||
| 132 | } | ||
| 133 | break; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | return 1; | ||
| 137 | } | ||
| 138 | |||
| 139 | bool matrix_is_modified(void) | ||
| 140 | { | ||
| 141 | return is_modified; | ||
| 142 | } | ||
| 143 | |||
| 144 | inline | ||
| 145 | bool matrix_has_ghost(void) | ||
| 146 | { | ||
| 147 | #ifdef MATRIX_HAS_GHOST | ||
| 148 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 149 | if (matrix_has_ghost_in_row(i)) | ||
| 150 | return true; | ||
| 151 | } | ||
| 152 | #endif | ||
| 153 | return false; | ||
| 154 | } | ||
| 155 | |||
| 156 | inline | ||
| 157 | bool matrix_is_on(uint8_t row, uint8_t col) | ||
| 158 | { | ||
| 159 | return (matrix[row] & (1<<col)); | ||
| 160 | } | ||
| 161 | |||
| 162 | inline | ||
| 163 | uint8_t matrix_get_row(uint8_t row) | ||
| 164 | { | ||
| 165 | return matrix[row]; | ||
| 166 | } | ||
| 167 | |||
| 168 | void matrix_print(void) | ||
| 169 | { | ||
| 170 | print("\nr/c 01234567\n"); | ||
| 171 | for (uint8_t row = 0; row < matrix_rows(); row++) { | ||
| 172 | phex(row); print(": "); | ||
| 173 | pbin_reverse(matrix_get_row(row)); | ||
| 174 | #ifdef MATRIX_HAS_GHOST | ||
| 175 | if (matrix_has_ghost_in_row(row)) { | ||
| 176 | print(" <ghost"); | ||
| 177 | } | ||
| 178 | #endif | ||
| 179 | print("\n"); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | uint8_t matrix_key_count(void) | ||
| 184 | { | ||
| 185 | uint8_t count = 0; | ||
| 186 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 187 | count += bitpop(matrix[i]); | ||
| 188 | } | ||
| 189 | return count; | ||
| 190 | } | ||
| 191 | |||
| 192 | #ifdef MATRIX_HAS_GHOST | ||
| 193 | inline | ||
| 194 | static bool matrix_has_ghost_in_row(uint8_t row) | ||
| 195 | { | ||
| 196 | // no ghost exists in case less than 2 keys on | ||
| 197 | if (((matrix[row] - 1) & matrix[row]) == 0) | ||
| 198 | return false; | ||
| 199 | |||
| 200 | // ghost exists in case same state as other row | ||
| 201 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | ||
| 202 | if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | ||
| 203 | return true; | ||
| 204 | } | ||
| 205 | return false; | ||
| 206 | } | ||
| 207 | #endif | ||
| 208 | |||
| 209 | |||
| 210 | inline | ||
| 211 | static void matrix_make(uint8_t code) | ||
| 212 | { | ||
| 213 | if (!matrix_is_on(ROW(code), COL(code))) { | ||
| 214 | matrix[ROW(code)] |= 1<<COL(code); | ||
| 215 | is_modified = true; | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | inline | ||
| 220 | static void matrix_break(uint8_t code) | ||
| 221 | { | ||
| 222 | if (matrix_is_on(ROW(code), COL(code))) { | ||
| 223 | matrix[ROW(code)] &= ~(1<<COL(code)); | ||
| 224 | is_modified = true; | ||
| 225 | } | ||
| 226 | } | ||
diff --git a/converter/x68k_usb/Makefile b/converter/x68k_usb/Makefile new file mode 100644 index 000000000..c3b5fa29f --- /dev/null +++ b/converter/x68k_usb/Makefile | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | # | ||
| 2 | # Makefile for PJRC Teensy | ||
| 3 | # | ||
| 4 | |||
| 5 | |||
| 6 | # Target file name (without extension). | ||
| 7 | TARGET = x68k_usb_pjrc | ||
| 8 | |||
| 9 | # Directory common source filess exist | ||
| 10 | TOP_DIR = ../.. | ||
| 11 | |||
| 12 | # Directory keyboard dependent files exist | ||
| 13 | TARGET_DIR = . | ||
| 14 | |||
| 15 | # keyboard dependent files | ||
| 16 | SRC = main.c \ | ||
| 17 | keymap.c \ | ||
| 18 | matrix.c \ | ||
| 19 | led.c \ | ||
| 20 | x68k.c | ||
| 21 | |||
| 22 | CONFIG_H = config_pjrc.h | ||
| 23 | |||
| 24 | |||
| 25 | # MCU name, you MUST set this to match the board you are using | ||
| 26 | # type "make clean" after changing this, so all files will be rebuilt | ||
| 27 | #MCU = at90usb162 # Teensy 1.0 | ||
| 28 | MCU = atmega32u4 # Teensy 2.0 | ||
| 29 | #MCU = at90usb646 # Teensy++ 1.0 | ||
| 30 | #MCU = at90usb1286 # Teensy++ 2.0 | ||
| 31 | |||
| 32 | |||
| 33 | # Processor frequency. | ||
| 34 | # Normally the first thing your program should do is set the clock prescaler, | ||
| 35 | # so your program will run at the correct speed. You should also set this | ||
| 36 | # variable to same clock speed. The _delay_ms() macro uses this, and many | ||
| 37 | # examples use this variable to calculate timings. Do not add a "UL" here. | ||
| 38 | F_CPU = 16000000 | ||
| 39 | |||
| 40 | |||
| 41 | # Build Options | ||
| 42 | # *Comment out* to disable the options. | ||
| 43 | # | ||
| 44 | MOUSEKEY_ENABLE = yes # Mouse keys | ||
| 45 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 46 | NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | #---------------- Programming Options -------------------------- | ||
| 51 | AVRDUDE = avrdude | ||
| 52 | # Type: avrdude -c ? to get a full listing. | ||
| 53 | AVRDUDE_PROGRAMMER = avr109 | ||
| 54 | AVRDUDE_PORT = /dev/ttyACM0 | ||
| 55 | AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex | ||
| 56 | #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep | ||
| 57 | |||
| 58 | # Uncomment the following if you want avrdude's erase cycle counter. | ||
| 59 | # Note that this counter needs to be initialized first using -Yn, | ||
| 60 | # see avrdude manual. | ||
| 61 | #AVRDUDE_ERASE_COUNTER = -y | ||
| 62 | |||
| 63 | # Uncomment the following if you do /not/ wish a verification to be | ||
| 64 | # performed after programming the device. | ||
| 65 | #AVRDUDE_NO_VERIFY = -V | ||
| 66 | |||
| 67 | # Increase verbosity level. Please use this when submitting bug | ||
| 68 | # reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> | ||
| 69 | # to submit bug reports. | ||
| 70 | #AVRDUDE_VERBOSE = -v -v | ||
| 71 | |||
| 72 | AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) | ||
| 73 | #AVRDUDE_FLAGS = -p $(MCU) -c $(AVRDUDE_PROGRAMMER) | ||
| 74 | AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) | ||
| 75 | AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) | ||
| 76 | AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) | ||
| 77 | |||
| 78 | #PROGRAM_CMD = $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) | ||
| 79 | #PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex | ||
| 80 | PROGRAM_CMD = dfu-programmer atmega32u4 flash $(TARGET).hex | ||
| 81 | |||
| 82 | |||
| 83 | |||
| 84 | include $(TOP_DIR)/protocol/pjrc.mk | ||
| 85 | include $(TOP_DIR)/protocol.mk | ||
| 86 | include $(TOP_DIR)/common.mk | ||
| 87 | include $(TOP_DIR)/rules.mk | ||
diff --git a/converter/x68k_usb/README b/converter/x68k_usb/README new file mode 100644 index 000000000..0b61b2c4b --- /dev/null +++ b/converter/x68k_usb/README | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | X68000 to USB keyboard protocol converter | ||
| 2 | ========================================= | ||
| 3 | SHARP X68000 is a hobby computer released in Japan.(1987-93) | ||
| 4 | http://en.wikipedia.org/wiki/Sharp_X68000 | ||
| 5 | |||
| 6 | X68000 keyboard has ALPS linear switches. | ||
| 7 | - DSETK0016CE01 green linear | ||
| 8 | - DSETK0023CE03 yellow linear | ||
| 9 | |||
| 10 | |||
| 11 | Hardware | ||
| 12 | -------- | ||
| 13 | Target MCU is ATMega32u4 but other USB capable AVR will also work. | ||
| 14 | You can use PJRC Teensy as dev board. | ||
| 15 | http://www.pjrc.com/teensy/ | ||
| 16 | |||
| 17 | Wiring: | ||
| 18 | Mini-DIN Teensy | ||
| 19 | ----------------------------------------------------- | ||
| 20 | pin1 +5V VCC | ||
| 21 | pin2 MOUSE - | ||
| 22 | pin3 RXD PD2(RXD) | ||
| 23 | pin4 TXD PD3(TXD) NOTE: Not supported yet. | ||
| 24 | pin5 READY - | ||
| 25 | pin6 REMOTE - | ||
| 26 | pin7 GND GND | ||
| 27 | |||
| 28 | |||
| 29 | Firmware | ||
| 30 | -------- | ||
| 31 | Build: | ||
| 32 | $ cd x68k_usb | ||
| 33 | $ make | ||
| 34 | |||
| 35 | And load the binary to MCU with your favorite programmer. | ||
| 36 | If you use Teensy you can load with PJRC Teensy Loader tool. | ||
| 37 | http://www.pjrc.com/teensy/loader.html | ||
| 38 | |||
| 39 | |||
| 40 | * * * * * * * * * * * * * * * * * * | ||
| 41 | |||
| 42 | |||
| 43 | X68000 Keyboard Protocol | ||
| 44 | ======================== | ||
| 45 | http://kyoutan.jpn.org/uts/pc/pic/x68key/ | ||
| 46 | |||
| 47 | |||
| 48 | Connector | ||
| 49 | --------- | ||
| 50 | Mini DIN 7pin(female connector on computer side) | ||
| 51 | 7 6 5 | ||
| 52 | o o o | ||
| 53 | 4 o = o 3 | ||
| 54 | o o | ||
| 55 | 2 1 | ||
| 56 | |||
| 57 | Mini-DIN | ||
| 58 | ------------- | ||
| 59 | pin1 +5V | ||
| 60 | pin2 MOUSE | ||
| 61 | pin3 RXD | ||
| 62 | pin4 TXD | ||
| 63 | pin5 READY | ||
| 64 | pin6 REMOTE | ||
| 65 | pin7 GND | ||
| 66 | |||
| 67 | |||
| 68 | Signaling | ||
| 69 | --------- | ||
| 70 | - TXD,RXD | ||
| 71 | Asynchronous, 2400baud, 1-startbit(L), 8-databit, 1-stopbit(H) | ||
| 72 | |||
| 73 | - READY | ||
| 74 | ready/not ready(1/0) | ||
| 75 | |||
| 76 | |||
| 77 | Data from keyboard | ||
| 78 | ------------------ | ||
| 79 | bit 7 make/break flag(0/1) | ||
| 80 | bit 6-0 following scan code | ||
| 81 | |||
| 82 | |||
| 83 | Data from computer | ||
| 84 | ------------------ | ||
| 85 | - LED contorol ON/OFF(0/1) | ||
| 86 | bit 7 1(fixed) | ||
| 87 | bit 6 全角 | ||
| 88 | bit 5 ひらがな | ||
| 89 | bit 4 INS | ||
| 90 | bit 3 CAPS | ||
| 91 | bit 2 コード入力 | ||
| 92 | bit 1 ローマ字 | ||
| 93 | bit 0 かな | ||
| 94 | |||
| 95 | - Repeat delay | ||
| 96 | bit 7 0(fixed) | ||
| 97 | bit 6 1(fixed) | ||
| 98 | bit 5 1(fixed) | ||
| 99 | bit 4 0(fixed) | ||
| 100 | bit 3-0 delay | ||
| 101 | REPEAT_DELAY = 200+delay*100 ms | ||
| 102 | default: 500ms | ||
| 103 | |||
| 104 | - Repeat time | ||
| 105 | bit 7 0(fixed) | ||
| 106 | bit 6 1(fixed) | ||
| 107 | bit 5 1(fixed) | ||
| 108 | bit 4 1(fixed) | ||
| 109 | bit 3-0 time | ||
| 110 | REPEAT_TIME = 30+time^2*5 ms | ||
| 111 | default: 110ms | ||
| 112 | |||
| 113 | |||
| 114 | Scan Codes | ||
| 115 | ---------- | ||
| 116 | ,---. ,---. ,-------------------, ,-------------------. ,-----------. ,---------------. | ||
| 117 | | 61| | 62| | 63| 64| 65| 66| 67| | 68| 69| 6A| 6B| 6C| | 5A| 5B| 5C| | 5D| 52| 53| 54| | ||
| 118 | `---' `---' `-------------------' `-------------------' `-----------' `---------------' | ||
| 119 | ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 120 | | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 0E| 0F| | 36| 5E| 37| | 3F| 40| 41| 42| | ||
| 121 | |-----------------------------------------------------------| |------------ |---------------| | ||
| 122 | | 10 | 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| 1C| | | 38| 39| 3A| | 43| 44| 45| 46| | ||
| 123 | |------------------------------------------------------. 1D | `---=====---' |---------------| | ||
| 124 | | 71 | 1E| 1F| 20| 21| 2l| 23| 24| 25| 26| 27| 28| 29| | ___| 3C|___ | 47| 48| 49| 4A| | ||
| 125 | |-----------------------------------------------------------| | 3B|---| 3D| |-----------|---| | ||
| 126 | | 70 | 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 70 | `---| 3E|---' | 4B| 4C| 4D| | | ||
| 127 | `-----------------------------------------------------------| .---=====---. |-----------| 4E| | ||
| 128 | | 5F| 55 | 56 | 35 | 57 | 58 | 59 | 60| | 72 | 73 | | 4F| 50| 51| | | ||
| 129 | `---------------------------------------------' `-----------' `---------------' | ||
diff --git a/converter/x68k_usb/config_pjrc.h b/converter/x68k_usb/config_pjrc.h new file mode 100644 index 000000000..20758bf24 --- /dev/null +++ b/converter/x68k_usb/config_pjrc.h | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef CONFIG_H | ||
| 19 | #define CONFIG_H | ||
| 20 | |||
| 21 | /* controller configuration */ | ||
| 22 | #include "controller_teensy.h" | ||
| 23 | |||
| 24 | #define VENDOR_ID 0xFEED | ||
| 25 | #define PRODUCT_ID 0x6800 | ||
| 26 | #define MANUFACTURER t.m.k. | ||
| 27 | #define PRODUCT SHARP X68000 keyboard converter | ||
| 28 | #define DESCRIPTION converts SHARP X68000 keyboard protocol into USB | ||
| 29 | |||
| 30 | |||
| 31 | /* matrix size */ | ||
| 32 | #define MATRIX_ROWS 16 | ||
| 33 | #define MATRIX_COLS 8 | ||
| 34 | |||
| 35 | |||
| 36 | /* key combination for command */ | ||
| 37 | #define IS_COMMAND() ( \ | ||
| 38 | keyboard_report->mods == (MOD_BIT(KB_LALT) | MOD_BIT(KB_RALT)) || \ | ||
| 39 | keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \ | ||
| 40 | ) | ||
| 41 | |||
| 42 | |||
| 43 | /* mouse keys */ | ||
| 44 | #ifdef MOUSEKEY_ENABLE | ||
| 45 | # define MOUSEKEY_DELAY_TIME 255 | ||
| 46 | #endif | ||
| 47 | |||
| 48 | |||
| 49 | /* USART configuration | ||
| 50 | * asynchronous, 2400baud, 8-data bit, non parity, 1-stop bit, no flow control | ||
| 51 | */ | ||
| 52 | #ifdef __AVR_ATmega32U4__ | ||
| 53 | # define KBD_RX_VECT USART1_RX_vect | ||
| 54 | # define KBD_RX_DATA UDR1 | ||
| 55 | # define KBD_RX_BAUD 2400 | ||
| 56 | # define KBD_RX_UBBR ((F_CPU/(16UL*KBD_RX_BAUD))-1) | ||
| 57 | # define KBD_RX_INIT() do { \ | ||
| 58 | UBRR1L = (uint8_t) KBD_RX_UBBR; \ | ||
| 59 | UBRR1H = (uint8_t) (KBD_RX_UBBR>>8); \ | ||
| 60 | UCSR1B |= (1<<RXCIE1) | (1<<RXEN1); \ | ||
| 61 | } while(0) | ||
| 62 | #else | ||
| 63 | # error "USART configuration is needed." | ||
| 64 | #endif | ||
| 65 | |||
| 66 | #endif | ||
diff --git a/converter/x68k_usb/keymap.c b/converter/x68k_usb/keymap.c new file mode 100644 index 000000000..94c2aeee1 --- /dev/null +++ b/converter/x68k_usb/keymap.c | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdbool.h> | ||
| 20 | #include <avr/pgmspace.h> | ||
| 21 | #include "usb_keycodes.h" | ||
| 22 | #include "util.h" | ||
| 23 | #include "keymap.h" | ||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | // Following macros help you to define a keymap with the form of actual keyboard layout. | ||
| 29 | |||
| 30 | /* X68000 Keyboard Scan codes | ||
| 31 | ,---. ,---. ,-------------------, ,-------------------. ,-----------. ,---------------. | ||
| 32 | | 61| | 62| | 63| 64| 65| 66| 67| | 68| 69| 6A| 6B| 6C| | 5A| 5B| 5C| | 5D| 52| 53| 54| | ||
| 33 | `---' `---' `-------------------' `-------------------' `-----------' `---------------' | ||
| 34 | ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 35 | | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 0E| 0F| | 36| 5E| 37| | 3F| 40| 41| 42| | ||
| 36 | |-----------------------------------------------------------| |------------ |---------------| | ||
| 37 | | 10 | 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| 1C| | | 38| 39| 3A| | 43| 44| 45| 46| | ||
| 38 | |------------------------------------------------------. 1D | `---=====---' |---------------| | ||
| 39 | | 71 | 1E| 1F| 20| 21| 2l| 23| 24| 25| 26| 27| 28| 29| | ___| 3C|___ | 47| 48| 49| 4A| | ||
| 40 | |-----------------------------------------------------------| | 3B|---| 3D| |-----------|---| | ||
| 41 | | 70 | 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 70 | `---| 3E|---' | 4B| 4C| 4D| | | ||
| 42 | `-----------------------------------------------------------| .---=====---. |-----------| 4E| | ||
| 43 | | 5F| 55 | 56 | 35 | 57 | 58 | 59 | 60| | 72 | 73 | | 4F| 50| 51| | | ||
| 44 | `---------------------------------------------' `-----------' `---------------' | ||
| 45 | */ | ||
| 46 | #define KEYMAP( \ | ||
| 47 | K61,K62, K63,K64,K65,K66,K67, K68,K69,K6A,K6B,K6C, K5A,K5B,K5C, K5D,K52,K53,K54, \ | ||
| 48 | K01,K02,K03,K04,K05,K06,K07,K08,K09,K0A,K0B,K0C,K0D,K0E,K0F, K36,K5E,K37, K3F,K40,K41,K42, \ | ||
| 49 | K10,K11,K12,K13,K14,K15,K16,K17,K18,K19,K1A,K1B,K1C, K1D, K38,K39,K3A, K43,K44,K45,K46, \ | ||
| 50 | K71,K1E,K1F,K20,K21,K22,K23,K24,K25,K26,K27,K28,K29, K3C, K47,K48,K49,K4A, \ | ||
| 51 | K70,K2A,K2B,K2C,K2D,K2E,K2F,K30,K31,K32,K33,K34, K3B,K3E,K3D, K4B,K4C,K4D,K4E, \ | ||
| 52 | K5F,K55,K56, K35, K57,K58,K59,K60, K72, K73, K4F,K50,K51 \ | ||
| 53 | ) { \ | ||
| 54 | { KB_NO, KB_##K01, KB_##K02, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \ | ||
| 55 | { KB_##K08, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_##K0F }, \ | ||
| 56 | { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_##K17 }, \ | ||
| 57 | { KB_##K18, KB_##K19, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_##K1F }, \ | ||
| 58 | { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, \ | ||
| 59 | { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, \ | ||
| 60 | { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_##K37 }, \ | ||
| 61 | { KB_##K38, KB_##K39, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_##K3F }, \ | ||
| 62 | { KB_##K40, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_##K47 }, \ | ||
| 63 | { KB_##K48, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_##K4F }, \ | ||
| 64 | { KB_##K50, KB_##K51, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, \ | ||
| 65 | { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_##K5C, KB_##K5D, KB_##K5E, KB_##K5F }, \ | ||
| 66 | { KB_##K60, KB_##K61, KB_##K62, KB_##K63, KB_##K64, KB_##K65, KB_##K66, KB_##K67 }, \ | ||
| 67 | { KB_##K68, KB_##K69, KB_##K6A, KB_##K6B, KB_##K6C, KB_NO, KB_NO, KB_NO }, \ | ||
| 68 | { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_NO, KB_NO, KB_NO, KB_NO, }, \ | ||
| 69 | { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO } \ | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | // Assign Fn key(0-7) to a layer to which switch with the Fn key pressed. | ||
| 74 | static const uint8_t PROGMEM fn_layer[] = { | ||
| 75 | 0, // Fn0 | ||
| 76 | 0, // Fn1 | ||
| 77 | 0, // Fn2 | ||
| 78 | 0, // Fn3 | ||
| 79 | 0, // Fn4 | ||
| 80 | 0, // Fn5 | ||
| 81 | 0, // Fn6 | ||
| 82 | 0 // Fn7 | ||
| 83 | }; | ||
| 84 | |||
| 85 | // Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. | ||
| 86 | // See layer.c for details. | ||
| 87 | static const uint8_t PROGMEM fn_keycode[] = { | ||
| 88 | KB_NO, // Fn0 | ||
| 89 | KB_NO, // Fn1 | ||
| 90 | KB_NO, // Fn2 | ||
| 91 | KB_NO, // Fn3 | ||
| 92 | KB_NO, // Fn4 | ||
| 93 | KB_NO, // Fn5 | ||
| 94 | KB_NO, // Fn6 | ||
| 95 | KB_NO // Fn7 | ||
| 96 | }; | ||
| 97 | |||
| 98 | |||
| 99 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 100 | /* X68000 Keyboard Scan codes | ||
| 101 | ,---. ,---. ,-------------------, ,-------------------. ,-----------. ,---------------. | ||
| 102 | | 61| | 62| | 63| 64| 65| 66| 67| | 68| 69| 6A| 6B| 6C| | 5A| 5B| 5C| | 5D| 52| 53| 54| | ||
| 103 | `---' `---' `-------------------' `-------------------' `-----------' `---------------' | ||
| 104 | ,-----------------------------------------------------------. ,-----------. ,---------------. | ||
| 105 | | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 0E| 0F| | 36| 5E| 37| | 3F| 40| 41| 42| | ||
| 106 | |-----------------------------------------------------------| |------------ |---------------| | ||
| 107 | | 10 | 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| 1C| | | 38| 39| 3A| | 43| 44| 45| 46| | ||
| 108 | |------------------------------------------------------. 1D | `---=====---' |---------------| | ||
| 109 | | 71 | 1E| 1F| 20| 21| 2l| 23| 24| 25| 26| 27| 28| 29| | ___| 3C|___ | 47| 48| 49| 4A| | ||
| 110 | |-----------------------------------------------------------| | 3B|---| 3D| |-----------|---| | ||
| 111 | | 70 | 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 70 | `---| 3E|---' | 4B| 4C| 4D| | | ||
| 112 | `-----------------------------------------------------------| .---=====---. |-----------| 4E| | ||
| 113 | | 5F| 55 | 56 | 35 | 57 | 58 | 59 | 60| | 72 | 73 | | 4F| 50| 51| | | ||
| 114 | `---------------------------------------------' `-----------' `---------------' | ||
| 115 | */ | ||
| 116 | KEYMAP( | ||
| 117 | NO, NO, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, PSCR,SLCK,PAUS, CAPS,NO, NO, NO, | ||
| 118 | ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, | ||
| 119 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, ENT, DEL, END, PGDN, P7, P8, P9, PPLS, | ||
| 120 | LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT,ENT, UP, P4, P5, P6, PEQL, | ||
| 121 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,GRV, LEFT,DOWN,RGHT, P1, P2, P3, PENT, | ||
| 122 | LGUI,LALT,NO, SPC, RALT,RGUI,RCTL,APP, NO, NO, P0, PCMM,PDOT | ||
| 123 | ), | ||
| 124 | }; | ||
| 125 | |||
| 126 | |||
| 127 | uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | ||
| 128 | { | ||
| 129 | return pgm_read_byte(&keymaps[(layer)][(row)][(col)]); | ||
| 130 | } | ||
| 131 | |||
| 132 | uint8_t keymap_fn_layer(uint8_t fn_bits) | ||
| 133 | { | ||
| 134 | return pgm_read_byte(&fn_layer[biton(fn_bits)]); | ||
| 135 | } | ||
| 136 | |||
| 137 | uint8_t keymap_fn_keycode(uint8_t fn_bits) | ||
| 138 | { | ||
| 139 | return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | ||
| 140 | } | ||
diff --git a/converter/x68k_usb/led.c b/converter/x68k_usb/led.c new file mode 100644 index 000000000..40156cf4a --- /dev/null +++ b/converter/x68k_usb/led.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "stdint.h" | ||
| 19 | #include "x68k.h" | ||
| 20 | #include "led.h" | ||
| 21 | |||
| 22 | |||
| 23 | void led_set(uint8_t usb_led) | ||
| 24 | { | ||
| 25 | // not supported now | ||
| 26 | } | ||
diff --git a/converter/x68k_usb/matrix.c b/converter/x68k_usb/matrix.c new file mode 100644 index 000000000..954e7ef12 --- /dev/null +++ b/converter/x68k_usb/matrix.c | |||
| @@ -0,0 +1,141 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdbool.h> | ||
| 20 | #include <avr/io.h> | ||
| 21 | #include <util/delay.h> | ||
| 22 | #include "print.h" | ||
| 23 | #include "util.h" | ||
| 24 | #include "x68k.h" | ||
| 25 | #include "matrix.h" | ||
| 26 | |||
| 27 | |||
| 28 | /* | ||
| 29 | * Matrix Array usage: | ||
| 30 | * | ||
| 31 | * ROW: 16(4bits) | ||
| 32 | * COL: 8(3bits) | ||
| 33 | * | ||
| 34 | * 8bit wide | ||
| 35 | * +---------+ | ||
| 36 | * 0|00 ... 07| | ||
| 37 | * 1|08 ... 0F| | ||
| 38 | * :| ... | | ||
| 39 | * :| ... | | ||
| 40 | * E|70 ... 77| | ||
| 41 | * F|78 ... 7F| | ||
| 42 | * +---------+ | ||
| 43 | * | ||
| 44 | */ | ||
| 45 | static uint8_t matrix[MATRIX_ROWS]; | ||
| 46 | #define ROW(code) ((code>>3)&0xF) | ||
| 47 | #define COL(code) (code&0x07) | ||
| 48 | |||
| 49 | static bool is_modified = false; | ||
| 50 | |||
| 51 | |||
| 52 | inline | ||
| 53 | uint8_t matrix_rows(void) | ||
| 54 | { | ||
| 55 | return MATRIX_ROWS; | ||
| 56 | } | ||
| 57 | |||
| 58 | inline | ||
| 59 | uint8_t matrix_cols(void) | ||
| 60 | { | ||
| 61 | return MATRIX_COLS; | ||
| 62 | } | ||
| 63 | |||
| 64 | void matrix_init(void) | ||
| 65 | { | ||
| 66 | x68k_init(); | ||
| 67 | |||
| 68 | // initialize matrix state: all keys off | ||
| 69 | for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; | ||
| 70 | |||
| 71 | return; | ||
| 72 | } | ||
| 73 | |||
| 74 | uint8_t matrix_scan(void) | ||
| 75 | { | ||
| 76 | is_modified = false; | ||
| 77 | |||
| 78 | uint8_t code; | ||
| 79 | code = x68k_recv(); | ||
| 80 | if (code == 0) { | ||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | phex(code); print(" "); | ||
| 85 | if (code&0x80) { | ||
| 86 | // break code | ||
| 87 | if (matrix_is_on(ROW(code), COL(code))) { | ||
| 88 | matrix[ROW(code)] &= ~(1<<COL(code)); | ||
| 89 | is_modified = true; | ||
| 90 | } | ||
| 91 | } else { | ||
| 92 | // make code | ||
| 93 | if (!matrix_is_on(ROW(code), COL(code))) { | ||
| 94 | matrix[ROW(code)] |= (1<<COL(code)); | ||
| 95 | is_modified = true; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | return code; | ||
| 99 | } | ||
| 100 | |||
| 101 | bool matrix_is_modified(void) | ||
| 102 | { | ||
| 103 | return is_modified; | ||
| 104 | } | ||
| 105 | |||
| 106 | inline | ||
| 107 | bool matrix_has_ghost(void) | ||
| 108 | { | ||
| 109 | return false; | ||
| 110 | } | ||
| 111 | |||
| 112 | inline | ||
| 113 | bool matrix_is_on(uint8_t row, uint8_t col) | ||
| 114 | { | ||
| 115 | return (matrix[row] & (1<<col)); | ||
| 116 | } | ||
| 117 | |||
| 118 | inline | ||
| 119 | uint8_t matrix_get_row(uint8_t row) | ||
| 120 | { | ||
| 121 | return matrix[row]; | ||
| 122 | } | ||
| 123 | |||
| 124 | void matrix_print(void) | ||
| 125 | { | ||
| 126 | print("\nr/c 01234567\n"); | ||
| 127 | for (uint8_t row = 0; row < matrix_rows(); row++) { | ||
| 128 | phex(row); print(": "); | ||
| 129 | pbin_reverse(matrix_get_row(row)); | ||
| 130 | print("\n"); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | uint8_t matrix_key_count(void) | ||
| 135 | { | ||
| 136 | uint8_t count = 0; | ||
| 137 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 138 | count += bitpop(matrix[i]); | ||
| 139 | } | ||
| 140 | return count; | ||
| 141 | } | ||
