diff --git a/.gitmodules b/.gitmodules index 3e34a635..17a20dec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "protocol/usb_hid/USB_Host_Shield_2.0"] path = protocol/usb_hid/USB_Host_Shield_2.0 url = git@github.com:tmk/USB_Host_Shield_2.0.git +[submodule "protocol/lufa/LUFA-git"] + path = protocol/lufa/LUFA-git + url = https://github.com/abcminiuser/lufa.git diff --git a/README.md b/README.md index 536cc753..6596dc33 100644 --- a/README.md +++ b/README.md @@ -33,13 +33,15 @@ You can find some keyboard specific projects under `converter` and `keyboard` di ### converter * [ps2_usb](converter/ps2_usb/) - [PS/2 keyboard to USB][GH_ps2] * [adb_usb](converter/adb_usb/) - [ADB keyboard to USB][GH_adb] -* [m0110_usb](converter/m0110_usb) - [Machintosh 128K/512K/Plus keyboard to USB][GH_m0110] +* [m0110_usb](converter/m0110_usb) - [Macintosh 128K/512K/Plus keyboard to USB][GH_m0110] * [terminal_usb](converter/terminal_usb/) - [IBM Model M terminal keyboard(PS/2 scancode set3) to USB][GH_terminal] * [news_usb](converter/news_usb/) - [Sony NEWS keyboard to USB][GH_news] * [x68k_usb](converter/x68k_usb/) - [Sharp X68000 keyboard to USB][GH_x68k] * [sun_usb](converter/sun_usb/) - [Sun] to USB(type4, 5 and 3?) * [pc98_usb](converter/pc98_usb/) - [PC98] to USB * [usb_usb](converter/usb_usb/) - USB to USB(experimental) +* [ascii_usb](converter/ascii_usb/) - ASCII(Serial console terminal) to USB +* [ibm4704_usb](converter/ibm4704_usb) - [IBM 4704 keyboard Converter][GH_ibm4704] ### keyboard * [hhkb](keyboard/hhkb/) - [Happy Hacking Keyboard pro][GH_hhkb] **my main board** @@ -50,6 +52,7 @@ You can find some keyboard specific projects under `converter` and `keyboard` di * [IIgs_Standard](keyboard/IIgs/) - Apple [IIGS] keyboard mod(by JeffreySung) * [macway](keyboard/macway/) - [Compact keyboard mod][GH_macway] [retired] * [KMAC](keyboard/kmac/) - Korean custom keyboard +* [Lightsaber](keyboard/lightsaber/) - Korean custom keyboard [GH_macway]: http://geekhack.org/showwiki.php?title=Island:11930 [GH_hhkb]: http://geekhack.org/showwiki.php?title=Island:12047 @@ -61,6 +64,7 @@ You can find some keyboard specific projects under `converter` and `keyboard` di [GH_terminal]: http://geekhack.org/showwiki.php?title=Island:27272 [GH_x68k]: http://geekhack.org/showwiki.php?title=Island:29060 [GH_hbkb]: http://geekhack.org/showwiki.php?title=Island:29483 +[GH_ibm4704]: http://geekhack.org/index.php?topic=54706.0 [HID_liber]: http://deskthority.net/wiki/HID_Liberation_Device_-_DIY_Instructions [Phantom]: http://geekhack.org/index.php?topic=26742 [GH60]: http://geekhack.org/index.php?topic=34959 @@ -90,7 +94,7 @@ See [doc/keymap.md](doc/keymap.md). -Magic Comannds +Magic Commands -------------- To see help press `Magic` + `H`. @@ -121,7 +125,7 @@ Following commands can be also executed with `Magic` + key. In console mode `Mag **TBD** ### Boot Magic Configuration - Virtual DIP Switch -Boot Magic are executed during boot up time. Press Magic key below then pulgin keyboard cable. +Boot Magic are executed during boot up time. Press Magic key below then plug in keyboard cable. Note that you must use keys of **Layer 0** as Magic keys. These settings are stored in EEPROM so that retain your configure over power cycles. To avoid configuring accidentally additive salt key `KC_SPACE` also needs to be pressed along with the following configuration keys. The salt key is configurable in `config.h`. See [common/bootmagic.h](common/bootmagic.h). @@ -141,7 +145,7 @@ To avoid configuring accidentally additive salt key `KC_SPACE` also needs to be #### Keymap - Swap Control and CapsLock(`Left Control`) -- Change CapsLock to Control(`Casp Lock`) +- Change CapsLock to Control(`Caps Lock`) - Swap LeftAlt and Gui(`Left Alt`) - Swap RightAlt and Gui(`Right Alt`) - Disable Gui(`Left Gui`) @@ -210,7 +214,7 @@ Architecture -Debuging +Debugging -------- Use PJRC's `hid_listen` to see debug messages. You can use the tool for debug even if firmware use LUFA stack. @@ -227,7 +231,7 @@ Files and Directories * converter/ - protocol converter projects * doc/ - documents * common.mk - Makefile for common -* protoco.mk - Makefile for protocol +* protocol.mk - Makefile for protocol * rules.mk - Makefile for build rules ### Common @@ -263,7 +267,7 @@ Files and Directories -Conding Style +Coding Style ------------- - Doesn't use Tab to indent, use 4-spaces instead. diff --git a/common/action.c b/common/action.c index e6938f5a..fddb97c5 100644 --- a/common/action.c +++ b/common/action.c @@ -294,7 +294,7 @@ void process_action(keyrecord_t *record) #ifdef BACKLIGHT_ENABLE case ACT_BACKLIGHT: if (!event.pressed) { - switch (action.backlight.id) { + switch (action.backlight.opt) { case BACKLIGHT_INCREASE: backlight_increase(); break; @@ -307,6 +307,9 @@ void process_action(keyrecord_t *record) case BACKLIGHT_STEP: backlight_step(); break; + case BACKLIGHT_LEVEL: + backlight_level(action.backlight.level); + break; } } break; diff --git a/common/action_code.h b/common/action_code.h index 8df86b11..50112d4d 100644 --- a/common/action_code.h +++ b/common/action_code.h @@ -87,7 +87,7 @@ along with this program. If not, see . * 1100|1111| id(8) Macro record? * * ACT_BACKLIGHT(1101): - * 1101|xxxx| id(8) Backlight commands + * 1101|opt |level(8) Backlight commands * * ACT_COMMAND(1110): * 1110|opt | id(8) Built-in Command exec @@ -163,7 +163,9 @@ typedef union { uint8_t kind :4; } usage; struct action_backlight { - uint8_t id :8; + uint8_t level :8; + uint8_t opt :4; + uint8_t kind :4; } backlight; struct action_command { uint8_t id :8; @@ -282,21 +284,23 @@ enum layer_pram_tap_op { /* * Extensions */ -enum backlight_id { +enum backlight_opt { BACKLIGHT_INCREASE = 0, BACKLIGHT_DECREASE = 1, BACKLIGHT_TOGGLE = 2, BACKLIGHT_STEP = 3, + BACKLIGHT_LEVEL = 4, }; /* Macro */ #define ACTION_MACRO(id) ACTION(ACT_MACRO, (id)) #define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id)) #define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt)<<8 | (id)) /* Backlight */ -#define ACTION_BACKLIGHT_INCREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_INCREASE) -#define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE) -#define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE) -#define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP) +#define ACTION_BACKLIGHT_INCREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_INCREASE << 8) +#define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE << 8) +#define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE << 8) +#define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP << 8) +#define ACTION_BACKLIGHT_LEVEL(level) ACTION(ACT_BACKLIGHT, BACKLIGHT_LEVEL << 8 | level) /* Command */ #define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (addr)) /* Function */ diff --git a/common/action_macro.c b/common/action_macro.c index cc7ac18a..d85aee37 100644 --- a/common/action_macro.c +++ b/common/action_macro.c @@ -16,6 +16,7 @@ along with this program. If not, see . */ #include #include "action.h" +#include "action_util.h" #include "action_macro.h" #ifdef DEBUG_ACTION @@ -39,12 +40,20 @@ void action_macro_play(const macro_t *macro_p) case KEY_DOWN: MACRO_READ(); dprintf("KEY_DOWN(%02X)\n", macro); - register_code(macro); + if (IS_MOD(macro)) { + add_weak_mods(MOD_BIT(macro)); + } else { + register_code(macro); + } break; case KEY_UP: MACRO_READ(); dprintf("KEY_UP(%02X)\n", macro); - unregister_code(macro); + if (IS_MOD(macro)) { + del_weak_mods(MOD_BIT(macro)); + } else { + unregister_code(macro); + } break; case WAIT: MACRO_READ(); diff --git a/common/backlight.c b/common/backlight.c index a0b2ce50..c3001dd0 100644 --- a/common/backlight.c +++ b/common/backlight.c @@ -104,3 +104,11 @@ void backlight_step(void) dprintf("backlight step: %u\n", backlight_config.level); backlight_set(backlight_config.level); } + +void backlight_level(uint8_t level) +{ + backlight_config.level ^= level; + backlight_config.enable = !!backlight_config.level; + eeconfig_write_backlight(backlight_config.raw); + backlight_set(backlight_config.level); +} diff --git a/common/backlight.h b/common/backlight.h index 685c422a..525ec8bb 100644 --- a/common/backlight.h +++ b/common/backlight.h @@ -24,18 +24,17 @@ along with this program. If not, see . typedef union { uint8_t raw; struct { - bool enable:1; - uint8_t level:7; + bool enable :1; + uint8_t level :7; }; } backlight_config_t; void backlight_init(void); - void backlight_increase(void); void backlight_decrease(void); void backlight_toggle(void); void backlight_step(void); - void backlight_set(uint8_t level); +void backlight_level(uint8_t level); #endif diff --git a/common/command.c b/common/command.c index f6f27695..d2f8eb83 100644 --- a/common/command.c +++ b/common/command.c @@ -301,13 +301,13 @@ static bool command_common(uint8_t code) case KC_S: print("\n\n----- Status -----\n"); print_val_hex8(host_keyboard_leds()); + print_val_hex8(keyboard_protocol); + print_val_hex8(keyboard_idle); #ifdef PROTOCOL_PJRC print_val_hex8(UDCON); print_val_hex8(UDIEN); print_val_hex8(UDINT); print_val_hex8(usb_keyboard_leds); - print_val_hex8(usb_keyboard_protocol); - print_val_hex8(usb_keyboard_idle_config); print_val_hex8(usb_keyboard_idle_count); #endif diff --git a/common/host.c b/common/host.c index 1eafef75..2e56971b 100644 --- a/common/host.c +++ b/common/host.c @@ -24,7 +24,7 @@ along with this program. If not, see . #ifdef NKRO_ENABLE -bool keyboard_nkro = false; +bool keyboard_nkro = true; #endif static host_driver_t *driver; diff --git a/common/host.h b/common/host.h index 8ff26298..a56e6c3b 100644 --- a/common/host.h +++ b/common/host.h @@ -32,6 +32,9 @@ extern "C" { extern bool keyboard_nkro; #endif +uint8_t keyboard_idle; +uint8_t keyboard_protocol; + /* host driver */ void host_set_driver(host_driver_t *driver); diff --git a/common/report.h b/common/report.h index 91982840..71543cc2 100644 --- a/common/report.h +++ b/common/report.h @@ -94,6 +94,26 @@ along with this program. If not, see . extern "C" { #endif +/* + * keyboard report is 8-byte array retains state of 8 modifiers and 6 keys. + * + * byte |0 |1 |2 |3 |4 |5 |6 |7 + * -----+--------+--------+--------+--------+--------+--------+--------+-------- + * desc |mods |reserved|keys[0] |keys[1] |keys[2] |keys[3] |keys[4] |keys[5] + * + * It is exended to 16 bytes to retain 120keys+8mods when NKRO mode. + * + * byte |0 |1 |2 |3 |4 |5 |6 |7 ... |15 + * -----+--------+--------+--------+--------+--------+--------+--------+-------- +-------- + * desc |mods |bits[0] |bits[1] |bits[2] |bits[3] |bits[4] |bits[5] |bits[6] ... |bit[14] + * + * mods retains state of 8 modifiers. + * + * bit |0 |1 |2 |3 |4 |5 |6 |7 + * -----+--------+--------+--------+--------+--------+--------+--------+-------- + * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui + * + */ typedef union { uint8_t raw[REPORT_SIZE]; struct { diff --git a/converter/adb_usb/README.md b/converter/adb_usb/README.md index 5301557d..d9efbfab 100644 --- a/converter/adb_usb/README.md +++ b/converter/adb_usb/README.md @@ -71,8 +71,8 @@ Notes Many ADB keyboards has no discrimination between right modifier and left one, you will always see left control even if you press right control key. Apple Extended Keyboard and Apple Extended Keyboard II are the examples. -Though ADB protocol itsef has the ability of distinction between right and left. -And most ADB keyboard has no NKRO functionality, though ADB protocol itsef has that. +Though ADB protocol itself has the ability of distinction between right and left. +And most ADB keyboard has no NKRO functionality, though ADB protocol itself has that. See protocol/adb.c for more info. EOF diff --git a/converter/ascii_usb/Makefile b/converter/ascii_usb/Makefile new file mode 100644 index 00000000..408aa423 --- /dev/null +++ b/converter/ascii_usb/Makefile @@ -0,0 +1,82 @@ +# Target file name (without extension). +TARGET = ascii_usb + +# Directory common source filess exist +TOP_DIR = ../.. + +# Directory keyboard dependent files exist +TARGET_DIR = . + +# keyboard dependent files +SRC = keymap.c \ + matrix.c \ + led.c \ + protocol/serial_uart.c + +CONFIG_H = config.h + + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +#MCU = at90usb162 # Teensy 1.0 +MCU = atmega32u4 # Teensy 2.0 +#MCU = at90usb646 # Teensy++ 1.0 +#MCU = at90usb1286 # Teensy++ 2.0 + + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + +# Interrupt driven control endpoint task +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT + + +# Build Options +# *Comment out* to disable the options. +# +#MOUSEKEY_ENABLE = yes # Mouse keys +#EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = yes # Console for debug +#NKRO_ENABLE = yes # USB Nkey Rollover + + +# Boot Section Size in bytes +# Teensy halfKay 512 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +OPT_DEFS += -DBOOTLOADER_SIZE=4096 + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + + +include $(TOP_DIR)/protocol/lufa.mk +include $(TOP_DIR)/protocol.mk +include $(TOP_DIR)/common.mk +include $(TOP_DIR)/rules.mk diff --git a/converter/ascii_usb/README b/converter/ascii_usb/README new file mode 100644 index 00000000..02fa064e --- /dev/null +++ b/converter/ascii_usb/README @@ -0,0 +1,38 @@ +ASCII to USB keyboard protocol converter +======================================== +This converts serial console terminal into USB keyboard, tested with TRS-80 model 100 TELCOM application. +Target MCU is ATMega32u4 but other USB capable AVR will also work. + + +Hardware +-------- +Connect RX, TX and GND to UART pin of AVR. Note that you may need line driver/level shifter like MAX232 to interface high voltage of RS-232C. + + + +Build Firmware +-------------- +Configure UART setting and Just use 'make' + + $ cd ascii_usb + $ make + +Then, load the binary to MCU with your favorite programmer. + + + +Limitation +---------- +- This cannot see key up event, you cannot hold a key. +- Alt, Gui(Win/Mac) modifier key are not available. + + + +TRS-80 model 100 +---------------- +Use TELCOM program with setting: 19200bps/8bit/odd parity/1stop bit +To set this configuration push Stat(F3) and input '9801D,10'. Then push Term(F4) to connect. + + + + diff --git a/converter/ascii_usb/config.h b/converter/ascii_usb/config.h new file mode 100644 index 00000000..0908997a --- /dev/null +++ b/converter/ascii_usb/config.h @@ -0,0 +1,70 @@ +/* +Copyright 2014 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x5C01 +#define DEVICE_VER 0x0100 +#define MANUFACTURER t.m.k. +#define PRODUCT ASCII keyboard converter +#define DESCRIPTION converts Serial Console Terminal into USB keyboard + + +/* matrix size */ +#define MATRIX_ROWS 16 +#define MATRIX_COLS 16 + +/* key combination for command */ +#define IS_COMMAND() ( \ + host_get_first_key() == KC_BRK \ +) + + +/* + * Serial(USART) configuration + * asynchronous, positive logic, 19200baud, bit order: LSB first + * 1-start bit, 8-data bit, odd parity, 1-stop bit + */ +#ifdef __AVR_ATmega32U4__ + #define SERIAL_UART_BAUD 19200 + #define SERIAL_UART_DATA UDR1 + #define SERIAL_UART_UBRR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1) + #define SERIAL_UART_RXD_VECT USART1_RX_vect + #define SERIAL_UART_TXD_READY (UCSR1A&(1<>8); /* baud rate */ \ + UCSR1B |= (1< + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include "keycode.h" +#include "action.h" +#include "action_macro.h" +#include "action_util.h" +#include "util.h" +#include "print.h" +#include "keymap.h" + + +// Keymap is not used. See matrix.c. + +/* translates key to keycode */ +uint8_t keymap_key_to_keycode(uint8_t layer, key_t key) +{ + return KC_NO; +} + +/* translates Fn keycode to action */ +action_t keymap_fn_to_action(uint8_t keycode) +{ + return (action_t) { .code = ACTION_NO }; +} diff --git a/converter/ascii_usb/led.c b/converter/ascii_usb/led.c new file mode 100644 index 00000000..d1c39bc6 --- /dev/null +++ b/converter/ascii_usb/led.c @@ -0,0 +1,25 @@ +/* +Copyright 2012 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "stdint.h" +#include "serial.h" +#include "led.h" + + +void led_set(uint8_t usb_led) +{ +} diff --git a/converter/ascii_usb/matrix.c b/converter/ascii_usb/matrix.c new file mode 100644 index 00000000..e1ea8e0a --- /dev/null +++ b/converter/ascii_usb/matrix.c @@ -0,0 +1,195 @@ +/* +Copyright 2014 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include "print.h" +#include "util.h" +#include "matrix.h" +#include "debug.h" +#include "action_util.h" +#include "protocol/serial.h" + + +/* + * Not use Matrix. + * + * ROW: 16(4bits) + * COL: 16(4bits) + * + * 8bit wide + * +---------+ + * 0|00 ... 0F| + * 1|08 ... 1F| + * :| ... | + * :| ... | + * E|E0 ... EF| + * F|F0 ... FF| + * +---------+ + */ + + +inline +uint8_t matrix_rows(void) +{ + return MATRIX_ROWS; +} + +inline +uint8_t matrix_cols(void) +{ + return MATRIX_COLS; +} + +void matrix_init(void) +{ + debug_matrix = true; + serial_init(); + + debug("init\n"); + return; +} + +static void type_key(uint16_t keycode) +{ + if (keycode == 0) return; + + uint8_t mods = keycode>>8; + uint8_t key = keycode&0xFF; + if (mods) { + add_mods(mods); + send_keyboard_report(); + } + + add_key(key); + send_keyboard_report(); + + del_key(key); + send_keyboard_report(); + + if (mods) { + del_mods(mods); + send_keyboard_report(); + } +} +static uint16_t code2key(uint8_t code) +{ + // ASCII to key combination in US laout + switch (code) { + case 0x01 ... 0x08: // Ctrl-[a-z] + return MOD_BIT(KC_LCTRL)<<8 | (KC_A + (code-0x01)); + case 0x09: return KC_TAB; // TAB(Ctrl-i) + case 0x0A ... 0x0C: // Ctrl-[a-z] + return MOD_BIT(KC_LCTRL)<<8 | (KC_A + (code-0x01)); + case 0x0D: return KC_ENTER; // Enter(Ctrl-m) + case 0x0E ... 0x1A: // Ctrl-[a-z] + return MOD_BIT(KC_LCTRL)<<8 | (KC_A + (code-0x01)); + case 0x1B: return KC_ESC; + case 0x1C: return KC_RIGHT; + case 0x1D: return KC_LEFT; + case 0x1E: return KC_UP; + case 0x1F: return KC_DOWN; + case 0x20: return KC_SPACE; + case 0x21: return MOD_BIT(KC_LSHIFT)<<8 | KC_1; // ! + case 0x22: return MOD_BIT(KC_LSHIFT)<<8 | KC_QUOTE; // " + case 0x23: return MOD_BIT(KC_LSHIFT)<<8 | KC_3; // # + case 0x24: return MOD_BIT(KC_LSHIFT)<<8 | KC_4; // $ + case 0x25: return MOD_BIT(KC_LSHIFT)<<8 | KC_5; // % + case 0x26: return MOD_BIT(KC_LSHIFT)<<8 | KC_7; // & + case 0x27: return KC_QUOTE; // ' + case 0x28: return MOD_BIT(KC_LSHIFT)<<8 | KC_9; // ( + case 0x29: return MOD_BIT(KC_LSHIFT)<<8 | KC_0; // ) + case 0x2A: return MOD_BIT(KC_LSHIFT)<<8 | KC_8; // * + case 0x2B: return MOD_BIT(KC_LSHIFT)<<8 | KC_EQUAL; // + + case 0x2C: return KC_COMMA; // , + case 0x2D: return KC_MINUS; // - + case 0x2E: return KC_DOT; // . + case 0x2F: return KC_SLASH; // / + case 0x30: return KC_0; + case 0x31 ... 0x39: // 1-9 + return KC_1 + (code-0x31); + case 0x3A: return MOD_BIT(KC_LSHIFT)<<8 | KC_SCLN; // : + case 0x3B: return KC_SCLN; // ; + case 0x3C: return MOD_BIT(KC_LSHIFT)<<8 | KC_COMMA; // < + case 0x3D: return KC_EQUAL; // = + case 0x3E: return MOD_BIT(KC_LSHIFT)<<8 | KC_DOT; // > + case 0x3F: return MOD_BIT(KC_LSHIFT)<<8 | KC_SLASH; // ? + case 0x40: return MOD_BIT(KC_LSHIFT)<<8 | KC_2; // @ + case 0x41 ... 0x5A: // A-Z + return MOD_BIT(KC_LSHIFT)<<8 | (KC_A + (code-0x41)); + case 0x5B: return KC_LBRACKET; // [ + case 0x5C: return KC_BSLASH; // + case 0x5D: return KC_RBRACKET; // ] + case 0x5E: return MOD_BIT(KC_LSHIFT)<<8 | KC_6; // ^ + case 0x5F: return MOD_BIT(KC_LSHIFT)<<8 | KC_MINUS; // _ + case 0x61 ... 0x7A: // a-z + return KC_A + (code-0x61); + case 0x7B: return MOD_BIT(KC_LSHIFT)<<8 | KC_LBRACKET; // { + case 0x7C: return MOD_BIT(KC_LSHIFT)<<8 | KC_BSLASH; // | + case 0x7D: return MOD_BIT(KC_LSHIFT)<<8 | KC_RBRACKET; // } + case 0x7E: return MOD_BIT(KC_LSHIFT)<<8 | KC_GRAVE; // } + case 0x7F: return KC_DELETE; // + } + return 0; +} + +uint8_t matrix_scan(void) +{ + uint16_t code = serial_recv2(); + if (code == -1) { + return 0; + } + + print_hex8(code); print(" "); + + // echo back + serial_send(code); + type_key(code2key(code)); + + + return code; +} + +inline +bool matrix_has_ghost(void) +{ + return false; +} + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return false; +} + +inline +matrix_row_t matrix_get_row(uint8_t row) +{ + return 0; +} + +void matrix_print(void) +{ + print("\nr/c 0123456789ABCDEF\n"); + for (uint8_t row = 0; row < matrix_rows(); row++) { + phex(row); print(": "); + pbin_reverse(matrix_get_row(row)); + print("\n"); + } +} diff --git a/converter/ibm4704_usb/Makefile b/converter/ibm4704_usb/Makefile new file mode 100644 index 00000000..112b0012 --- /dev/null +++ b/converter/ibm4704_usb/Makefile @@ -0,0 +1,93 @@ +# Target file name (without extension). +TARGET = ibm4704_usb + +# Directory common source filess exist +TOP_DIR = ../.. + +# Directory keyboard dependent files exist +TARGET_DIR = . + +# project specific files +SRC = keymap_common.c \ + matrix.c \ + led.c \ + protocol/ibm4704.c + +ifdef KEYMAP + SRC := keymap_$(KEYMAP).c $(SRC) +else + SRC := keymap_plain.c $(SRC) +endif + +CONFIG_H = config.h + + +# MCU name +#MCU = at90usb1287 +MCU = atmega32u4 + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + +# Interrupt driven control endpoint task(+60) +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT + + +# Boot Section Size in *bytes* +# Teensy halfKay 512 +# Teensy++ halfKay 1024 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +# USBaspLoader 2048 +OPT_DEFS += -DBOOTLOADER_SIZE=4096 + + +# Build Options +# comment out to disable the options. +# +#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = yes # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + +include $(TOP_DIR)/protocol.mk +include $(TOP_DIR)/protocol/lufa.mk +include $(TOP_DIR)/common.mk +include $(TOP_DIR)/rules.mk diff --git a/converter/ibm4704_usb/README.md b/converter/ibm4704_usb/README.md new file mode 100644 index 00000000..a3af4ab3 --- /dev/null +++ b/converter/ibm4704_usb/README.md @@ -0,0 +1,62 @@ +IBM 4704 to USB keyboard converter +================================== +This firmware converts IBM 4704 keyboard protocol to USB HID. + +Keyboard initialization process takes a few seconds at start up. During that you will hear buzzer from the keyboard. **You need to plug USB cable after hooking up your keyboard to the converter.** + + +Supported Keyboard +------------------ +### IBM capacitive switch models: +- 6019273 Model 100 50-key (grid layout) http://kishy.dyndns.org/?p=977 +- 6019284 Model 200 62-key Alpha(60% layout) http://kishy.dyndns.org/?p=894 +- 6019303 Model 300 77-key Expanded Alpha http://kbtalking.cool3c.com/article/23272 +- 6020218 Model 400 107-key Full key http://kishy.dyndns.org/?p=980 + +### Alps switch(vintage Green) models: + +- 5954339 Japanese 102-key http://deskthority.net/post87127.html#p87127 +- 6112883 Japanese 102-key http://geekhack.org/index.php?topic=52888.msg1194489#msg1194489 +- 6112884 Japanese 102-key http://geekhack.org/index.php?topic=50437.msg1193047#msg1193047 +- 6341739 Chinese 102-key http://geekhack.org/index.php?topic=52888.msg1176566#msg1176566 + + +Connector +--------- +Keyboard Plug from front: + + DSUB-9 + ------------- + \ N 2 3 4 5 / + \ N N N N / + --------- + 2 GND + 3 VCC 5V + 4 DATA + 5 CLOCK + N No connection/No pin. + + +Connection +---------- +In case of using ATMega32U4(Teensy2.0): + +1. Supply power with VCC and GND. +2. Connect CLOCK to PD1 and DATA to PD0. You can change pin with config.h. +3. Optionally you may need pull-up register. 1KOhm probably work. + + +Build Firmware +-------------- +Just run `make`: + + $ make + +To select keymap: + + $ make KEYMAP=[plain|...] + + +Keymap +------ +Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `keymap_.c` and see keymap document(you can find in top README.md) and existent keymap files. diff --git a/converter/ibm4704_usb/config.h b/converter/ibm4704_usb/config.h new file mode 100644 index 00000000..4f82f49a --- /dev/null +++ b/converter/ibm4704_usb/config.h @@ -0,0 +1,74 @@ +/* +Copyright 2014 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +#include + +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x4707 +#define DEVICE_VER 0x0001 +#define MANUFACTURER t.m.k. +#define PRODUCT IBM 4704 keyboard converter +#define DESCRIPTION convert IBM 4704 keyboard to USB + + +/* matrix size */ +#define MATRIX_ROWS 16 // keycode bit3-6 +#define MATRIX_COLS 8 // keycode bit0-2 + + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL)) || \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + + + +/* + * Busywait + */ +#define IBM4704_CLOCK_PORT PORTD +#define IBM4704_CLOCK_PIN PIND +#define IBM4704_CLOCK_DDR DDRD +#define IBM4704_CLOCK_BIT 1 +#define IBM4704_DATA_PORT PORTD +#define IBM4704_DATA_PIN PIND +#define IBM4704_DATA_DDR DDRD +#define IBM4704_DATA_BIT 0 + +/* + * Pin interrupt + */ +#ifdef IBM4704_USE_INT +#define IBM4704_INT_INIT() do { \ + EICRA |= ((1<| Z| X| C| V| B| N| M| ,| ,| /|???|Shift | + |-----------------------------------------------------------| + |Reset|blk|Alt | Space |Alt |blk|Enter| + `-----------------------------------------------------------' + +----------+---------------------+----------+----------+ + |` 00|PD1 04|Caps 20|LShift 30|Reset 31| + |1 18|q 05|a 21|<> 3E|Rblank 41| + |2 19|w 06|s 22|z 32|Alt 3F| + |3 1A|e 13|d 23|x 33|Space 40| + |4 10|r 14|f 24|c 34|Alt 3F| + |5 11|t 15|g 25|v 35|Lblank 42| + |6 12|y 16|h 26|b 36|Enter 2F| + |7 08|u 17|j 27|n 37| | + |8 09|i 01|k 28|m 38| | + |9 0A|o 02|l 29|, 39| | + |0 0F|p 03|; 2A|. 3A| | + |- 1F|¢ 1B|' 2B|/ 3B| | + |= 0D|\ 1C|{} 2C|??? 3C| | + |??? 0C|PD2 1D|PD3 2D|RShift 3D| | + |BS 0E| | | | | + +----------+---------------------+----------+----------+ + Bit7 is 'press flag' which set 1 on press and 0 on release when break code is enabled. + +NOTE: When break code is enabled the key sends scancode with setting 7th bit on press +and without it on release. That is, '`' sends 80h on press and 00h on release. + + +Keyboard command +---------------- +Keyboard accepts these commands from host. + + Description Entry point + ----------------------------------------------------------- + FF Soft Reset 0008h + FE Resend 00e8h + FD Buzzer(emits a short beep) 00edh + FC Set Key Flag 00f6h + FB Soft Reset 0008h + FA Reset 0000h + + +Keyboard response +----------------- +Keyobard sends these bytes to host. + + Description Entry point + ----------------------------------------------------------- + FE Overflow(key event/receive data) 00c5h, 0346h + Memory test error 0224h + FD Command out of bound 00d8h + Key out of bound + 7E Read/Parity error in receive from host 00bch + + +Set Key Flag command(FC) +------------------------ +After 'Power on Reset' firmware enters this command mode and waits for data from host, +so that you don't need to send 'FC' and it doesn't send any scancode until you send 'FF'. + +Data sent from host: + + bit: 7 6 ... 0 + en | | + | `-----`--- scan code + `------------- enable bit(0: enable repeat, 1: enable break) + + 00-77 Enable repeat(78-7F: invalid scancode) + 80-F7 Enable break(F8-FF: invalid scancode) + FE Resend(011ah) no need to use + FF End(0114h) exits FC command mode. + +Response from keyboard: + FD Out of bound - Invalid scancode + +Examples: + To enable break code of all keys. + + FC 80 81 ... F7 FF + diff --git a/converter/ibm4704_usb/keymap_common.c b/converter/ibm4704_usb/keymap_common.c new file mode 100644 index 00000000..241d2e33 --- /dev/null +++ b/converter/ibm4704_usb/keymap_common.c @@ -0,0 +1,30 @@ +/* +Copyright 2011,2012,2013 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "keymap_common.h" + + +/* translates key to keycode */ +uint8_t keymap_key_to_keycode(uint8_t layer, key_t key) +{ + return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]); +} + +/* translates Fn keycode to action */ +action_t keymap_fn_to_action(uint8_t keycode) +{ + return (action_t){ .code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]) }; +} diff --git a/converter/ibm4704_usb/keymap_common.h b/converter/ibm4704_usb/keymap_common.h new file mode 100644 index 00000000..c55a8172 --- /dev/null +++ b/converter/ibm4704_usb/keymap_common.h @@ -0,0 +1,73 @@ +/* +Copyright 2011,2012,2013 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef KEYMAP_COMMON_H +#define KEYMAP_COMMON_H + +#include +#include +#include +#include "keycode.h" +#include "action.h" +#include "action_macro.h" +#include "report.h" +#include "print.h" +#include "debug.h" +#include "keymap.h" + + +// 32*8(256) byte array which converts PS/2 code into USB code +extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; +extern const uint16_t fn_actions[]; + + +/* Original keys */ +#define KEYMAP( \ + K00,K18,K19,K1A,K10,K11,K12,K08,K09,K0A,K0F,K1F,K0D,K0C,K0E, \ + K04,K05,K06,K13,K14,K15,K16,K17,K01,K02,K03,K1B,K1C,K1D, \ + K20,K21,K22,K23,K24,K25,K26,K27,K28,K29,K2A,K2B,K2C,K2D, \ + K30,K3E,K32,K33,K34,K35,K36,K37,K38,K39,K3A,K3B,K3C,K3D, \ + K31,K41,K3F, K40, K42,K2F \ +) { \ + { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_NO }, \ + { KC_##K08, KC_##K09, KC_##K0A, KC_NO, KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \ + { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \ + { KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_NO, KC_##K1F }, \ + { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \ + { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_NO, KC_##K2F }, \ + { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \ + { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \ + { KC_##K40, KC_##K41, KC_##K42, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ +} + +#endif + +/* + { K48, K49, K4A, K4B, K4C, K4D, K4E, K4F }, \ + { K50, K51, K52, K53, K54, K55, K56, K57 }, \ + { K58, K59, K5A, K5B, K5C, K5D, K5E, K5F }, \ + { K60, K61, K62, K63, K64, K65, K66, K67 }, \ + { K68, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \ + { K70, K71, K72, K73, K74, K75, K76, K77 }, \ + { K78, K79, K7A, K7B, K7C, K7D, K7E, K7F }, \ +*/ diff --git a/converter/ibm4704_usb/keymap_hasu.c b/converter/ibm4704_usb/keymap_hasu.c new file mode 100644 index 00000000..7545b092 --- /dev/null +++ b/converter/ibm4704_usb/keymap_hasu.c @@ -0,0 +1,85 @@ +#include "keymap_common.h" + + +const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* 0: default + * ,-----------------------------------------------------------. + * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|???|BS | + * |-----------------------------------------------------------| + * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| + * |-----------------------------------------------------------| + * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '|xxx|Ret | + * |-----------------------------------------------------------| + * |Shif|xxx| Z| X| C| V| B| N| M| ,| ,| /|xxx|Shift | + * |-----------------------------------------------------------| + * |Ctrl |Gui|Alt | Space |Alt |Gui|Ctrl | + * `-----------------------------------------------------------' + */ + KEYMAP( + ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \ + TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \ + LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT,NO, ENT, \ + LSFT,NO, Z, X, C, V, B, N, M, COMM,DOT, FN2, NO, FN0, \ + LCTL,LGUI,LALT, FN3, RGUI,RCTL \ + ), + + KEYMAP( + ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + CAPS,NO, NO, NO, NO, NO, NO, NO, PSCR,SLCK,PAUS, UP, NO, BSPC, \ + LCTL,VOLD,VOLU,MUTE,NO, NO, PAST,PSLS,HOME,PGUP,LEFT,RGHT,NO, ENT, \ + LSFT,NO, NO, NO, NO, NO, NO, PPLS,PMNS,END, PGDN,DOWN,NO, TRNS, \ + LCTL,LGUI,LALT, SPC, RGUI,RCTL \ + ), + + KEYMAP( + ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + TAB, NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,WSTP,WBAK,WFWD,BSPC, \ + LCTL,NO, ACL0,ACL1,ACL2,NO, MS_L,MS_D,MS_U,MS_R,TRNS,NO, NO, ENT, \ + LSFT,NO, NO, NO, NO, NO, BTN3,BTN2,BTN1,BTN4,BTN5,NO, NO, RSFT,\ + LCTL,LGUI,LALT, BTN1, RGUI,RCTL \ + ), + + KEYMAP( + ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + TAB, HOME,PGDN,UP, PGUP,END, HOME,PGDN,PGUP,END, NO, NO, NO, BSPC, \ + LCTL,NO, LEFT,DOWN,RGHT,NO, LEFT,DOWN,UP, RGHT,NO, NO, NO, ENT, \ + LSFT,NO, NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, TRNS,NO, RSFT, \ + LCTL,LGUI,LALT, SPC, RGUI,RCTL \ + ), + + KEYMAP( + ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + TAB, NO, NO, NO, NO, NO, WH_L,WH_D,MS_U,WH_U,WH_R,BTN4,BTN5,FN4, \ + LCTL,VOLD,VOLU,MUTE,NO, NO, BTN2,MS_L,MS_D,MS_R,BTN1,NO, NO, ENT, \ + LSFT,NO, NO, NO, NO, NO, BTN3,BTN2,BTN1,BTN4,BTN5,NO, NO, NO, \ + LCTL,LGUI,LALT, TRNS, RGUI,RCTL \ + ), +}; + +enum macro_id { + ALT_TAB, +}; + +const uint16_t PROGMEM fn_actions[] = { + [0] = ACTION_LAYER_MOMENTARY(1), + [1] = ACTION_LAYER_TAP_KEY(2, KC_SCLN), + [2] = ACTION_LAYER_TAP_KEY(3, KC_SLASH), + [3] = ACTION_LAYER_TAP_KEY(4, KC_SPC), + [4] = ACTION_MACRO(ALT_TAB), +}; + +/* + * Macro definition + */ +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) +{ + keyevent_t event = record->event; + + switch (id) { + case ALT_TAB: + return (event.pressed ? + MACRO( D(LALT), D(TAB), END ) : + MACRO( U(TAB), END )); + } + return MACRO_NONE; +} diff --git a/converter/ibm4704_usb/keymap_plain.c b/converter/ibm4704_usb/keymap_plain.c new file mode 100644 index 00000000..a121634e --- /dev/null +++ b/converter/ibm4704_usb/keymap_plain.c @@ -0,0 +1,38 @@ +#include "keymap_common.h" + + +const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* 0: default + * ,-----------------------------------------------------------. + * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|???|BS | + * |-----------------------------------------------------------| + * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| + * |-----------------------------------------------------------| + * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '| #|Ret | + * |-----------------------------------------------------------| + * |Shif| \| Z| X| C| V| B| N| M| ,| ,| /|???|Shift | + * |-----------------------------------------------------------| + * |Ctrl |Gui|Alt | Space |Alt* |Gui|Ctrl | + * `-----------------------------------------------------------' + */ + KEYMAP( + GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,BSPC, \ + TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, \ + LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT,NUHS,ENT, \ + LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH,NO, FN0, \ + LCTL,LGUI,LALT, SPC, RGUI,RCTL \ + ), + + /* 1: HHKB */ + KEYMAP( + ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + CAPS,NO, NO, NO, NO, NO, NO, NO, PSCR,SLCK,PAUS, UP, NO, INS, \ + LCTL,VOLD,VOLU,MUTE,NO, NO, PAST,PSLS,HOME,PGUP,LEFT,RGHT,NO, ENT, \ + LSFT,NO, NO, NO, NO, NO, NO, PPLS,PMNS,END, PGDN,DOWN,NO, TRNS, \ + LCTL,LGUI,LALT, SPC, RGUI,RCTL \ + ), +}; + +const uint16_t PROGMEM fn_actions[] = { + [0] = ACTION_LAYER_MOMENTARY(1), +}; diff --git a/converter/ibm4704_usb/led.c b/converter/ibm4704_usb/led.c new file mode 100644 index 00000000..f76545f0 --- /dev/null +++ b/converter/ibm4704_usb/led.c @@ -0,0 +1,24 @@ +/* +Copyright 2011 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "stdint.h" +#include "led.h" + + +void led_set(uint8_t usb_led) +{ +} diff --git a/converter/ibm4704_usb/matrix.c b/converter/ibm4704_usb/matrix.c new file mode 100644 index 00000000..0bfda2b1 --- /dev/null +++ b/converter/ibm4704_usb/matrix.c @@ -0,0 +1,170 @@ +/* +Copyright 2014 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include "action.h" +#include "print.h" +#include "debug.h" +#include "util.h" +#include "ibm4704.h" +#include "matrix.h" + + +static void matrix_make(uint8_t code); +static void matrix_break(uint8_t code); +static void matrix_clear(void); + + +/* + * Matrix Array usage: + * IBM 4704 scan codes are assigned into 128(16x8)-cell matrix. + * + * 8bit wide + * +---------+ + * 0| | + * :| XX | 00-7F + * f| | + * +---------+ + * + * Exceptions: + */ +static uint8_t matrix[MATRIX_ROWS]; + +// scan code bits 7654 3210 +// R:row/C:column -RRR RCCC +#define ROW(code) ((code>>3)&0x0f) +#define COL(code) (code&0x07) + + +inline +uint8_t matrix_rows(void) +{ + return MATRIX_ROWS; +} + +inline +uint8_t matrix_cols(void) +{ + return MATRIX_COLS; +} + +static void enable_break(void) +{ + uint8_t ret; + print("Enable break: "); + // valid scancode: 00-77h + for (uint8_t code = 0; code < 0x78; code++) { + while (ibm4704_send(0x80|code) != 0) { + print("z"); + _delay_us(500); + } + _delay_us(2000); + ret = ibm4704_recv(); + if (ret != 0xff) { + xprintf("c%02X:r%02X ", code, ret); + } + _delay_us(1000); + } + _delay_us(1000); + while (ibm4704_send(0xFF) != 0) { _delay_us(500); } // End + print("End\n"); +} + +void matrix_init(void) +{ + uint8_t ret; + debug_enable = true; + + ibm4704_init(); + matrix_clear(); + + // read keyboard id + while ((ret = ibm4704_recv()) == 0xFF) { + ibm4704_send(0xFE); + _delay_us(100); + } + + _delay_ms(2000); // wait for starting up debug console + print("IBM 4704 converter\n"); + xprintf("Keyboard ID: %02X\n", ret); + enable_break(); +} + +/* + * IBM 4704 Scan Code + */ +uint8_t matrix_scan(void) +{ + uint8_t code = ibm4704_recv(); + if (code==0xFF) { + // Not receivd + return 0; + } else if ((code&0x78)==0x78) { + // 0xFF-F8 and 0x7F-78 is not scancode + xprintf("Error: %0X\n", code); + matrix_clear(); + return 0; + } else if (code&0x80) { + matrix_make(code); + } else { + matrix_break(code); + } + return 1; +} + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & (1< -Close-up pic of handset cable. You can see one end of plug has reverse color codes against the other. Click to enlarge. +Close-up picture of handset cable. You can see one end of plug has reverse color codes against the other. Click to enlarge. [![4P4C cable](http://i.imgur.com/3S9P1mYm.jpg?1)](http://i.imgur.com/3S9P1mY.jpg?1) [Teensy]: http://www.pjrc.com/teensy/ @@ -43,12 +43,12 @@ Close-up pic of handset cable. You can see one end of plug has reverse color cod ![Jack fig](http://www.kbdbabel.org/conn/kbd_connector_macplus.png) -### Pull-up Registor -You may need pull-up registors on signal lines(`CLOCK`, `DATA`) in particular when you have long or coiled cable. **1k-10k Ohm** will be OK for this purpose. In that case the converter may not read signal from keyboard correctly without pull-up resistors. +### Pull-up Resistor +You may need pull-up resistors on signal lines(`CLOCK`, `DATA`) in particular when you have long or coiled cable. **1k-10k Ohm** will be OK for this purpose. In that case the converter may not read signal from keyboard correctly without pull-up resistors. -Building Frimware +Building Firmware ----------------- To compile firmware you need AVR GCC. You can edit *Makefile* and *config.h* to change compile options and pin configuration. diff --git a/converter/ps2_usb/Makefile.jis b/converter/next_usb/Makefile similarity index 62% rename from converter/ps2_usb/Makefile.jis rename to converter/next_usb/Makefile index 4e091e8e..51d9de6b 100644 --- a/converter/ps2_usb/Makefile.jis +++ b/converter/next_usb/Makefile @@ -1,5 +1,5 @@ # Target file name (without extension). -TARGET = ps2_usb_jis +TARGET = next_usb # Directory common source filess exist TOP_DIR = ../.. @@ -7,6 +7,12 @@ TOP_DIR = ../.. # Directory keyboard dependent files exist TARGET_DIR = . +# keyboard dependent files +SRC = keymap.c \ + matrix.c \ + led.c + +CONFIG_H = config.h # MCU name, you MUST set this to match the board you are using # type "make clean" after changing this, so all files will be rebuilt @@ -24,44 +30,26 @@ MCU = atmega32u4 # Teensy 2.0 F_CPU = 16000000 +# Boot Section Size in *bytes* +# Teensy halfKay 512 +# Teensy++ halfKay 1024 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +# USBaspLoader 2048 +OPT_DEFS += -DBOOTLOADER_SIZE=4096 + + # Build Options # *Comment out* to disable the options. # +#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control -NKRO_ENABLE = yes # USB Nkey Rollover +CONSOLE_ENABLE = yes # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +#NKRO_ENABLE = yes # USB Nkey Rollover -#PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened) -#PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin -PS2_USE_BUSYWAIT = yes # uses primitive reference code - - -# keyboard dependent files -SRC = keymap_jis.c \ - matrix.c \ - led.c - - -ifdef PS2_USE_USART - SRC += protocol/ps2_usart.c - OPT_DEFS += -DPS2_USE_USART -endif -ifdef PS2_USE_INT - SRC += protocol/ps2.c - OPT_DEFS += -DPS2_USE_INT -endif -ifdef PS2_USE_BUSYWAIT - SRC += protocol/ps2.c - OPT_DEFS += -DPS2_USE_BUSYWAIT -endif - - -#CONFIG_H = config_pjrc_usart.h -CONFIG_H = config.h - - -#---------------- Programming Options -------------------------- -PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +SRC += next_kbd.c # Search Path @@ -69,7 +57,7 @@ VPATH += $(TARGET_DIR) VPATH += $(TOP_DIR) -include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk +include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/common.mk include $(TOP_DIR)/rules.mk diff --git a/converter/next_usb/README b/converter/next_usb/README new file mode 100644 index 00000000..07ac89de --- /dev/null +++ b/converter/next_usb/README @@ -0,0 +1,45 @@ +NeXT non-ADB Keyboard Converter +------------------------------- + +Cable connector inside keyboard case: ++-----+ +|Black|\ +|Green|-\ +|Yello|--\-------- to computer via Mini-Din 5a Connector +|Orang|--/-------- +|Red |-/ +|Brown|/ ++-----+ + +Black - Ground to outer metal part of Mini Din 5a connector (not used) +Green - Ground +Yellow - Power button signal +Orange - Keyboard Out +Red - Keyboard In +Brown - Vcc + +ATmega32u4 connections (pinout provided for Arduino Pro Micro): + +Keyboard out (orange) : PD0 (pin 3) +Keyboard in (red) : PD1 (pin 2) +Power Button (yellow) : PD4 (pin 4) +Ground (black) : GND +Vcc (brown) : VCC + +See attached next_timings.jpg file for a detailed illustration of NeXT keyboard protocol timings. + +Power button signal line is normally high when the keyboard is powered/initialized. It is pulled to ground when pressed. The converter automatically translates this to a "normal" keypress with code 0x5A. This connection is technically optional, the only side effect of not making this connection is the power key will do nothing. + +Converter is based heavily on Ladyada's original "USB NeXT Keyboard with Arduino Micro" tutorial (http://learn.adafruit.com/usb-next-keyboard-with-arduino-micro/overview). If you build this converter, show Adafruit some love and do it using an Arduino Micro (http://www.adafruit.com/products/1315) or their ATmega 32u4 Breakout Board (http://www.adafruit.com/products/296). Arduino Micro should work fine using the Arduino Pro Micro configuration above, same pins numbers and everything. + +TODO: +----- + +I believe it might be possible to run the keyboard off of 3V; during testing I observed that the keyboard could sometimes function even without Vcc connected as long as the ground connection was good and the Keyboard In line was connected. If that works it should be easy to do a Bluetooth conversion and run the keyboard right off of a LiPo battery without a boost circuit + +Utilize second LED as status indicator for good initialization; also try to make hot plugging much more robust. + +Figure a better use for the Power button. Too easy to hit it by mistake to use for Suspend or Power Off - maybe move cap to different part of the board and consider that + +Figure out a better use for the lock LEDs. Right now they just light up when you press shift. Lame. Maybe implement proper Caps/Num/Scroll Locks + diff --git a/converter/next_usb/config.h b/converter/next_usb/config.h new file mode 100644 index 00000000..b3d188b0 --- /dev/null +++ b/converter/next_usb/config.h @@ -0,0 +1,150 @@ +/* +NeXT non-ADB Keyboard USB Converter + +Copyright 2013, Benjamin Gould (bgould@github.com) + +Based on: +TMK firmware code Copyright 2011,2012 Jun WAKO +Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license + +Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB +Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html +Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/ + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#define VENDOR_ID 0xBCBC +#define PRODUCT_ID 0xBCBC +#define DEVICE_VER 0x0500 +#define MANUFACTURER t.m.k. +#define PRODUCT NeXT Keyboard to USB converter +#define DESCRIPTION USB converter for NeXT non-ADB Keyboard + +/* matrix size */ +#define MATRIX_ROWS 12 // keycode bit: 3-0 +#define MATRIX_COLS 8 // keycode bit: 6-4 + +//#define DEBUG_ON_INIT 1 + +//#define TEENSY_CONFIG 1 +#define PRO_MICRO_CONFIG 1 + +// comment out if you don't want the keyboard's LEDs to flash upon initialization +#define NEXT_KBD_INIT_FLASH_LEDS + +//============= Start of Arduino Pro Micro Configuration ============== +#ifdef PRO_MICRO_CONFIG + +// this is the debugging LED that flashes when a key is being pressed +// comment out in order to disable debugging LED +#define NEXT_KBD_LED1_PORT PORTD +#define NEXT_KBD_LED1_PIN PIND +#define NEXT_KBD_LED1_DDR DDRD +#define NEXT_KBD_LED1_BIT 5 + +#define NEXT_KBD_LED1_ON NEXT_KBD_LED1_PORT &= ~(1<mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))|| \ + (keyboard_report->mods == (MOD_BIT(KC_RALT) | MOD_BIT(KC_RCTL))) \ +) diff --git a/converter/next_usb/keymap.c b/converter/next_usb/keymap.c new file mode 100644 index 00000000..d844f8a4 --- /dev/null +++ b/converter/next_usb/keymap.c @@ -0,0 +1,177 @@ +/* +NeXT non-ADB Keyboard USB Converter + +Copyright 2013, Benjamin Gould (bgould@github.com) + +Based on: +--------- +* TMK firmware code Copyright 2011,2012 Jun WAKO +* Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/) \ + released under BSD license \ + https://github.com/adafruit/USB-NeXT-Keyboard + +Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB +Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html +Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/ + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include +#include +#include "keycode.h" +#include "print.h" +#include "debug.h" +#include "util.h" +#include "keymap.h" +#include "keycode.h" + +// 32*8(256) byte array which converts PS/2 code into USB code +static const uint16_t PROGMEM fn_actions[] = { + ACTION_LAYER_MOMENTARY(1), // FN0 - left command key + ACTION_LAYER_MOMENTARY(1), // FN1 - right command key + ACTION_KEY(KC_BSLS), // FN2 - number pad slash & backslash + ACTION_MODS_KEY(MOD_LSFT, KC_BSLS), // FN3 - number pad equals & pipe + ACTION_MODS_KEY(MOD_LCTL, KC_Z), // FN4 - cmd+undo on layer 1 + ACTION_MODS_KEY(MOD_LCTL, KC_X), // FN5 - cmd+cut on layer 1 + ACTION_MODS_KEY(MOD_LCTL, KC_C), // FN6 - cmd+copy on layer 1 + ACTION_MODS_KEY(MOD_LCTL, KC_V), // FN7 - cmd+paste on layer 1 +}; + +/* This is the physical layout that I am starting with: + * Note: there is some strangeness on the number pad; + * the equal sign shifts to pipe and forward slash shifts to backslash + * ,-----------------------------------------------------------. ,-----------. ,---------------. + * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| BS | |VUp|Pwr|BrU| |` | =| /| *| + * |-----------------------------------------------------------| |-----------| |---------------| + * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | |VDn| |BrD| | 7| 8| 9| -| + * |------------------------------------------------------ | `---' `---' |-----------|---| + * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '| Return| | 4| 5| 6| +| + * |-----------------------------------------------------------| ,---. |---------------| + * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | |Up | | 1| 2| 3| | + * |-----------------------------------------------------------| ,-----------. |-----------|Ent| + * |Alt |Cmd | Space |Cmd |Alt | |Lef|Dow|Rig| | 0| .| | + * `-----------------------------------------------------------' `-----------' `---------------' + * + * Keymap array: + * 8 bytes + * +---------+ + * 0| | + * :| | 0x00-0x87 + * ;| | + * 11| | + * +---------+ + */ +#define KEYMAP( \ + K49,K4A,K4B,K4C,K4D,K50,K4F,K4E,K1E,K1F,K20,K1D,K1C,K1B, K1A,K58,K19, K26,K27,K28,K25, \ + K41,K42,K43,K44,K45,K48,K47,K46,K06,K07,K08,K05,K04,K03, K02, K01, K21,K22,K23,K24, \ + K57,K39,K3A,K3B,K3C,K3D,K40,K3F,K3E,K2D,K2C,K2B, K2A, K12,K18,K13,K15, \ + K56, K31,K32,K33,K34,K35,K37,K36,K2E,K2F,K30, K55, K16, K11,K17,K14, \ + K52,K54, K38, K53,K51, K09,K0F,K10, K0B, K0C,K0D \ +) { \ + { KC_NO, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \ + { KC_##K08, KC_##K09, KC_##K10, KC_##K0B, KC_##K0C, KC_##K0D, KC_NO, KC_##K0F }, \ + { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \ + { KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F }, \ + { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \ + { KC_##K28, KC_NO, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \ + { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \ + { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \ + { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47 }, \ + { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K4F }, \ + { KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \ + { KC_##K58, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, }, \ +} + + +static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + /* Layer 0: default + * ,-----------------------------------------------------------. ,-----------. ,---------------. + * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| BS | |Ins|Ref|Hom| |` | =| /| *| + * |-----------------------------------------------------------| |-----------| |---------------| + * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | |Del| |End| | 7| 8| 9| -| + * |-----------------------------------------------------' | `---' `---' |-----------|---| + * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '| Return| | 4| 5| 6| +| + * |-----------------------------------------------------------| ,---. |---------------| + * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | |Up | | 1| 2| 3| | + * |-----------------------------------------------------------| ,-----------. |-----------|Ent| + * |Fn0 |Alt | Space |LGui |Fn1 | |Lef|Dow|Rig| | 0| .| | + * `-----------------------------------------------------------' `-----------' `---------------' + */ + KEYMAP( + ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, WREF,HOME, GRV, FN3, FN2, PAST, + TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,NO, DEL, END, P7, P8, P9, PMNS, + LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, + LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, + FN0, LALT, SPC, LGUI,FN1, LEFT,DOWN,RGHT, P0, PDOT,PENT + + ), + + /* Layer 1: extra keys + * ,-----------------------------------------------------------. ,-----------. ,---------------. + * |Grv| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| BS | |VUp|VMu|PgU| |` | =| /| *| + * |-----------------------------------------------------------| |-----------| |---------------| + * |Tab |Pau| W| E| R| T| Y| U| I| O|PSc| \| ]| | |VDn| |PgD| | 7| 8| 9| -| + * |-----------------------------------------------------' | `---' `---' |-----------|---| + * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '| Return| | 4| 5| 6| +| + * |-----------------------------------------------------------| ,---. |---------------| + * |Shift |UND|CUT|COP|PST| B| N| M| ,| .| /|Shift | |Up | | 1| 2| 3| | + * |-----------------------------------------------------------| ,-----------. |-----------|Ent| + * |Fn0 |Alt | Space |RGui |Fn1 | |Lef|Dow|Rig| | 0| .| | + * `-----------------------------------------------------------' `-----------' `---------------' + */ + KEYMAP( + + GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, TRNS, VOLU,MUTE,PGUP, TRNS,TRNS,TRNS,TRNS, + TRNS,PAUS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,FN3, BSLS,TRNS, VOLD, PGDN, BTN1,MS_U,BTN2,WH_U, + TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, MS_L,MS_D,MS_R,WH_D, + TRNS, FN4, FN5, FN6, FN7, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS, TRNS,TRNS,TRNS, + TRNS,RALT, TRNS, RGUI,TRNS, TRNS,TRNS,TRNS, TRNS, TRNS,TRNS + + ) +}; + +/* translates key to keycode */ +uint8_t keymap_key_to_keycode(uint8_t layer, key_t key) +{ + return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]); +} + +/* translates Fn keycode to action */ +action_t keymap_fn_to_action(uint8_t keycode) +{ + return (action_t){ .code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]) }; +} diff --git a/converter/next_usb/led.c b/converter/next_usb/led.c new file mode 100644 index 00000000..24db15e1 --- /dev/null +++ b/converter/next_usb/led.c @@ -0,0 +1,55 @@ +/* +NeXT non-ADB Keyboard USB Converter + +Copyright 2013, Benjamin Gould (bgould@github.com) + +Based on: +TMK firmware code Copyright 2011,2012 Jun WAKO +Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license + +Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB +Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html +Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/ + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "stdint.h" +#include "led.h" + + +void led_set(uint8_t usb_led) +{ + +} diff --git a/converter/next_usb/matrix.c b/converter/next_usb/matrix.c new file mode 100644 index 00000000..fd6eb9d6 --- /dev/null +++ b/converter/next_usb/matrix.c @@ -0,0 +1,269 @@ +/* +NeXT non-ADB Keyboard USB Converter + +Copyright 2013, Benjamin Gould (bgould@github.com) + +Based on: +TMK firmware code Copyright 2011,2012 Jun WAKO +Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license + +Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB +Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html +Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/ + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include +#include +#include +#include "print.h" +#include "util.h" +#include "serial.h" +#include "matrix.h" +#include "debug.h" +#include "matrix.h" +#include "next_kbd.h" + +static void matrix_make(uint8_t code); +static void matrix_break(uint8_t code); + +static uint8_t matrix[MATRIX_ROWS]; +#define ROW(code) ((code>>3)&0xF) +#define COL(code) (code&0x07) + +static bool is_modified = false; + +/* number of matrix rows */ +inline +uint8_t matrix_rows(void) +{ + return MATRIX_ROWS; +} + +/* number of matrix columns */ +inline +uint8_t matrix_cols(void) +{ + return MATRIX_COLS; +} + +#ifndef NEXT_KBD_LED1_ON +#define NEXT_KBD_LED1_ON +#endif + +#ifndef NEXT_KBD_LED1_OFF +#define NEXT_KBD_LED1_OFF +#endif + +#define NEXT_KBD_PWR_READ (NEXT_KBD_PWR_PIN&(1<>1) +#define NEXT_KBD_PRESSED_KEYCODE(response) (uint8_t)(((response)&0xF00)==0x400) +#define NEXT_KBD_PRESSED(response, mask) (uint8_t)(((response)&mask)>0) +#define NEXT_KBD_PRESSED_CONTROL(response) NEXT_KBD_PRESSED(response,0x01000) +#define NEXT_KBD_PRESSED_SHIFT_LEFT(response) NEXT_KBD_PRESSED(response,0x02000) +#define NEXT_KBD_PRESSED_SHIFT_RGHT(response) NEXT_KBD_PRESSED(response,0x04000) +#define NEXT_KBD_PRESSED_CMD_LEFT(response) NEXT_KBD_PRESSED(response,0x08000) +#define NEXT_KBD_PRESSED_CMD_RGHT(response) NEXT_KBD_PRESSED(response,0x10000) +#define NEXT_KBD_PRESSED_ALT_LEFT(response) NEXT_KBD_PRESSED(response,0x20000) +#define NEXT_KBD_PRESSED_ALT_RGHT(response) NEXT_KBD_PRESSED(response,0x40000) +#define NEXT_KBD_MAKE_OR_BREAK(key, code) \ + do { \ + if (NEXT_KBD_PRESSED_##key(resp) > 0) \ + matrix_make(code); \ + else \ + matrix_break(code); \ + } while (0); + +#define NEXT_KBD_PWR_KEYCODE 0x58 + +/* scan all key states on matrix */ +uint8_t matrix_scan(void) +{ + _delay_ms(20); + + //next_kbd_set_leds(false, false); + NEXT_KBD_LED1_OFF; + + is_modified = false; + + if (!NEXT_KBD_PWR_READ) { + matrix_make(NEXT_KBD_PWR_KEYCODE); + power_state = 1; + if (is_modified) + { + dprintf("Power state 1\n"); + + } + } else { + matrix_break(NEXT_KBD_PWR_KEYCODE); + power_state = 0; + if (is_modified) + { + dprintf("Power state 0\n"); + + } + } + + uint32_t resp = (next_kbd_recv()); + + if (resp == NEXT_KBD_KMBUS_IDLE) + { + return 0; + } + + NEXT_KBD_LED1_ON; + + next_kbd_set_leds( + NEXT_KBD_PRESSED_SHIFT_LEFT(resp) ? true : false, + NEXT_KBD_PRESSED_SHIFT_RGHT(resp) ? true : false + ); + + dprintf("[ r=%04lX keycode=%02X pressed=%X CTRL=%X SHIFT_LEFT=%X SHIFT_RGHT=%X CMD_LEFT=%X CMD_RGHT=%X ALT_LEFT=%X ALT_RGHT=%X ]\n", \ + resp, \ + NEXT_KBD_KEYCODE(resp), \ + NEXT_KBD_PRESSED_KEYCODE(resp), \ + NEXT_KBD_PRESSED_CONTROL(resp), \ + NEXT_KBD_PRESSED_SHIFT_LEFT(resp), \ + NEXT_KBD_PRESSED_SHIFT_RGHT(resp), \ + NEXT_KBD_PRESSED_CMD_LEFT(resp), \ + NEXT_KBD_PRESSED_CMD_RGHT(resp), \ + NEXT_KBD_PRESSED_ALT_LEFT(resp), \ + NEXT_KBD_PRESSED_ALT_RGHT(resp) \ + ); + + // Modifier keys don't return keycode; have to check the upper bits + NEXT_KBD_MAKE_OR_BREAK(ALT_RGHT, 0x51); + NEXT_KBD_MAKE_OR_BREAK(ALT_LEFT, 0x52); + NEXT_KBD_MAKE_OR_BREAK(CMD_RGHT, 0x53); + NEXT_KBD_MAKE_OR_BREAK(CMD_LEFT, 0x54); + NEXT_KBD_MAKE_OR_BREAK(SHIFT_RGHT, 0x55); + NEXT_KBD_MAKE_OR_BREAK(SHIFT_LEFT, 0x56); + NEXT_KBD_MAKE_OR_BREAK(CONTROL, 0x57); + NEXT_KBD_MAKE_OR_BREAK(KEYCODE, NEXT_KBD_KEYCODE(resp)); + + return 1; +} + +/* whether modified from previous scan. used after matrix_scan. */ +bool matrix_is_modified() +{ + return is_modified; +} + +/* whether a switch is on */ +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & (1<.c` and see keymap document(you can find in top README.md) and existent keymap files. +Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `keymap_.c` and see keymap document(you can find in README.md of top directory) and existent keymap files. + + +PS/2 signal handling implementations +------------------------------------ +Following three methods can be used to implement PS/2 signal handling. + +### Simple and stupid busy-wait(ps2_busywait.c) + This is expected to implemented with portable C code for reference. +### Interrupt driven(ps2_interrupt.c) + Uses pin interrupt to detect falling edge of clock line. +### USART hardware module(ps2_usart.c) + Uses AVR USART engine to receive PS/2 signal. + +To select method edit Makefile. V-USB Support diff --git a/converter/ps2_usb/config_tmk_rev1.h b/converter/ps2_usb/config_tmk_rev1.h new file mode 100644 index 00000000..75dc97df --- /dev/null +++ b/converter/ps2_usb/config_tmk_rev1.h @@ -0,0 +1,147 @@ +/* +Copyright 2012 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +#include + +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6512 +#define DEVICE_VER 0x0001 +#define MANUFACTURER t.m.k. +#define PRODUCT PS/2 keyboard converter +#define DESCRIPTION convert PS/2 keyboard to USB + + +/* matrix size */ +#define MATRIX_ROWS 32 // keycode bit: 3-0 +#define MATRIX_COLS 8 // keycode bit: 6-4 + + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) || \ + keyboard_report->mods == (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RSHIFT)) \ +) + + +//#define NO_SUSPEND_POWER_DOWN + + +/* + * PS/2 Busywait + */ +#ifdef PS2_USE_BUSYWAIT +#define PS2_CLOCK_PORT PORTD +#define PS2_CLOCK_PIN PIND +#define PS2_CLOCK_DDR DDRD +#define PS2_CLOCK_BIT 5 +#define PS2_DATA_PORT PORTD +#define PS2_DATA_PIN PIND +#define PS2_DATA_DDR DDRD +#define PS2_DATA_BIT 2 +#endif + +/* + * PS/2 USART + */ +#ifdef PS2_USE_USART +#if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) +/* XCK for clock line and RXD for data line */ +#define PS2_CLOCK_PORT PORTD +#define PS2_CLOCK_PIN PIND +#define PS2_CLOCK_DDR DDRD +#define PS2_CLOCK_BIT 5 +#define PS2_DATA_PORT PORTD +#define PS2_DATA_PIN PIND +#define PS2_DATA_DDR DDRD +#define PS2_DATA_BIT 2 +/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */ +/* set DDR of CLOCK as input to be slave */ +#define PS2_USART_INIT() do { \ + PS2_CLOCK_DDR &= ~(1< + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +#include + +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6512 +#define DEVICE_VER 0x0001 +#define MANUFACTURER t.m.k. +#define PRODUCT PS/2 keyboard converter +#define DESCRIPTION convert PS/2 keyboard to USB + + +/* matrix size */ +#define MATRIX_ROWS 32 // keycode bit: 3-0 +#define MATRIX_COLS 8 // keycode bit: 6-4 + + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) || \ + keyboard_report->mods == (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RSHIFT)) \ +) + + +//#define NO_SUSPEND_POWER_DOWN + + +/* + * PS/2 Busywait + */ +#ifdef PS2_USE_BUSYWAIT +#define PS2_CLOCK_PORT PORTD +#define PS2_CLOCK_PIN PIND +#define PS2_CLOCK_DDR DDRD +#define PS2_CLOCK_BIT 1 +#define PS2_DATA_PORT PORTD +#define PS2_DATA_PIN PIND +#define PS2_DATA_DDR DDRD +#define PS2_DATA_BIT 0 +#endif + +/* + * PS/2 Pin interrupt + */ +#ifdef PS2_USE_INT +/* uses INT1 for clock line(ATMega32U4) */ +#define PS2_CLOCK_PORT PORTD +#define PS2_CLOCK_PIN PIND +#define PS2_CLOCK_DDR DDRD +#define PS2_CLOCK_BIT 1 +#define PS2_DATA_PORT PORTD +#define PS2_DATA_PIN PIND +#define PS2_DATA_DDR DDRD +#define PS2_DATA_BIT 0 +#define PS2_INT_INIT() do { \ + EICRA |= ((1<. K63, K64,K65,K66,K67,K68,K69,K6A,K6B,K6C,K6D, K0D,K14,K6E, \ K77,K13, K78, K79, K7A,K43,K62,K18,K1B,K1C \ ) KEYMAP( \ - HELP, K05,K06,K08,K0A, K0C,K0E,K10,K11, K12,K07,K09,K0B, PSCR,SLCK,PAUS, MUTE,VOLD,VOLU,PWR, \ + HELP, K05,K06,K08,K0A, K0C,K0E,K10,K11, K12,K07,K09,K0B, PSCR,SLCK,PAUS, MUTE,VOLD,VOLU,K30, \ K01, AGAIN, K1D,K1E,K1F,K20,K21,K22,K23,K24,K25,K26,K27,K28,K29,K58,K2A, K2C, K34, K60, K62, PSLS,PAST,PMNS, \ MENU, UNDO, K35, K36,K37,K38,K39,K3A,K3B,K3C,K3D,K3E,K3F,K40,K41, K2B, K42, K4A, K7B, P7, P8, P9, PPLS, \ - SELECT, COPY, K4C, K4D,K4E,K4F,K50,K51,K52,K53,K54,K55,K56,K57, K59, P4, P5, P6, \ - EXECUTE,PASTE, K63, K64,K65,K66,K67,K68,K69,K6A,K6B,K6C,K6D, K6E, K14, P1, P2, P3, PENT, \ - FIND, CUT, K77,K13, K78, HENK, K79, MHEN, KANA, K7A,K43,K0D, K18, K1B, K1C, P0, PDOT \ + SELECT, K33, K4C, K4D,K4E,K4F,K50,K51,K52,K53,K54,K55,K56,K57, K59, P4, P5, P6, \ + EXECUTE,K49, K63, K64,K65,K66,K67,K68,K69,K6A,K6B,K6C,K6D, K6E, K14, P1, P2, P3, PENT, \ + FIND, K61, K77,K13, K78, HENK, K79, MHEN, KANA, K7A,K43,K0D, K18, K1B, K1C, P0, PDOT \ ) diff --git a/converter/sun_usb/matrix.c b/converter/sun_usb/matrix.c index 717c131e..988622bc 100644 --- a/converter/sun_usb/matrix.c +++ b/converter/sun_usb/matrix.c @@ -63,7 +63,8 @@ uint8_t matrix_cols(void) void matrix_init(void) { - print_enable = true; + DDRD |= (1<<6); + PORTD |= (1<<6); debug_enable = true; serial_init(); diff --git a/converter/usb_usb/README b/converter/usb_usb/README index 2ffa46ca..d0547cde 100644 --- a/converter/usb_usb/README +++ b/converter/usb_usb/README @@ -6,7 +6,7 @@ Hardware requirement Arduino Leonardo http://arduino.cc/en/Main/ArduinoBoardLeonardo -Circuit@Home USB Host Sheild 2.0 +Circuit@Home USB Host Shield 2.0 http://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-2-0-for-arduino diff --git a/converter/x68k_usb/README b/converter/x68k_usb/README index 5f1c2072..516fcd24 100644 --- a/converter/x68k_usb/README +++ b/converter/x68k_usb/README @@ -12,7 +12,7 @@ X68000 keyboard has ALPS linear switches. Hardware -------- Target MCU is ATMega32u4 but other USB capable AVR will also work. -You can use PJRC Teensy as dev board. +You can use PJRC Teensy as development board. http://www.pjrc.com/teensy/ Wiring: @@ -83,7 +83,7 @@ bit 6-0 following scan code Data from computer ------------------ -- LED contorol ON/OFF(0/1) +- LED control ON/OFF(0/1) bit 7 1(fixed) bit 6 全角 bit 5 ひらがな diff --git a/doc/USB_NKRO.txt b/doc/USB_NKRO.txt index 4751bca8..d9f1d122 100644 --- a/doc/USB_NKRO.txt +++ b/doc/USB_NKRO.txt @@ -14,7 +14,7 @@ dfj's NKRO(2010/06) http://geekhack.org/showthread.php?p=204389#post204389 -Terminogy +Terminology --------- NKRO ghost @@ -26,7 +26,7 @@ membrane OS Support Status ----------------- USB NKRO is possible *without* a custom driver. -At least following OSes supports. +At least following OS's supports. Windows7 64bit WindowsXP Windows2000 SP4 @@ -37,7 +37,7 @@ At least following OSes supports. Custom Driver for USB NKRO -------------------------- NOT NEEDED -at least when using fllowing report formats on Windows, Linux or MacOSX. +at least when using following report formats on Windows, Linux or MacOSX. USB NKRO methods @@ -47,8 +47,8 @@ USB NKRO methods If the keyboard has 2 virtual keyboard with Standard report(6KRO), it gets 12KRO. Using this method means the keyboard is a composite device. -2. Exteded report - It needs large report size for this method to achive NKRO. +2. Extended report + It needs large report size for this method to achieve NKRO. If a keyboard has 101keys, it needs 103byte report. It seems to be inefficient. 3. Bitmap report @@ -122,8 +122,8 @@ Considerations Compatibility boot protocol minor/old system - Some BIOS doesn't send SET_PROTCOL request, a keyboard can't switch to boot protocol mode. - This may cuase a problem on a keyboard which uses other report than Standard. + Some BIOS doesn't send SET_PROTOCOL request, a keyboard can't switch to boot protocol mode. + This may cause a problem on a keyboard which uses other report than Standard. Reactivity USB polling time OS/Driver processing time diff --git a/doc/build.md b/doc/build.md index ae856501..bfe5de9f 100644 --- a/doc/build.md +++ b/doc/build.md @@ -40,7 +40,7 @@ Move to project directory in the firmware source. Build firmware using GNU `make` command. You'll see `_.hex` file in that directory unless something unexpected occurs in build process. - mkae -f Makefile. clean + make -f Makefile. clean make -f Makefile. @@ -71,14 +71,14 @@ Or to program with `dfu-programmer` run: #### FLIP GUI tutorial 1. On menu bar click Device -> Select, then. `ATmega32u4`. 2. On menu bar click Settings -> Communication -> USB, then click 'Open' button on 'USB Port Connection' dialog. -At this point you'll see greyouted widgets on the app get colored and ready. +At this point you'll see grey-outed widgets on the app get colored and ready. 3. On menu bar click File -> Load HEX File, then select your firmware hex file on File Selector dialog. 4. On 'Operations Flow' panel click 'Run' button to load the firmware binary to the chip. Note that you should keep 'Erase', 'Blank Check', 'Program' and 'Verify' check boxes selected. 5. Re-plug USB cord or click 'Start Application' button to restart your controller. Done. -See also these instaructions if you need. +See also these instructions if you need. - - @@ -95,7 +95,7 @@ Or use this command if you have command line version of Teensy Loader installed. ### 4. Program with Other programmer -You may want to use other programmer like `avrdude` with AVRISPmkII, Aruduino or USBasp. In that case you can still use make target `program` for build with configuring `PROGRAM_CMD` in Makefile. +You may want to use other programmer like `avrdude` with AVRISPmkII, Arduino or USBasp. In that case you can still use make target `program` for build with configuring `PROGRAM_CMD` in Makefile. $ make -f Makefile. program @@ -135,7 +135,7 @@ Optional. Note that ***comment out*** to disable them. #BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality ### 3. Programmer -Optional. Set proper command for your controller, bootloader and programmer. This command can be used with `make program`. Not needed if you use `FLIP`, `dfu-programmer` or `Teesy Loader`. +Optional. Set proper command for your controller, bootloader and programmer. This command can be used with `make program`. Not needed if you use `FLIP`, `dfu-programmer` or `Teensy Loader`. # avrdude with AVRISPmkII PROGRAM_CMD = avrdude -p $(MCU) -c avrispmkII -P USB -U flash:w:$(TARGET).hex @@ -158,7 +158,7 @@ Config.h Options /* Mechanical locking CapsLock support. Use KC_LCAP instead of KC_CAPS in keymap */ #define CAPSLOCK_LOCKING_ENABLE - /* Locking CapsLock resynchronize hack */ + /* Locking CapsLock re-synchronize hack */ #define CAPSLOCK_LOCKING_RESYNC_ENABLE ### 3. Disable Debug and Print diff --git a/doc/keymap.md b/doc/keymap.md index 3a549de6..11feeac2 100644 --- a/doc/keymap.md +++ b/doc/keymap.md @@ -68,7 +68,7 @@ On the other hand, you shall change `layer_state` to overlay base layer with som Note that ***higher layer has higher priority on stack of layers***, namely firmware falls down from top layer to bottom to look up keycode. Once it spots keycode other than **`KC_TRNS`**(transparent) on a layer it stops searching and lower layers aren't referred. You can place `KC_TRNS` on overlay layer changes just part of layout to fall back on lower or base layer. -Key with `KC_TRANS` doen't has its own keycode and refers to lower valid layers for keycode, instead. +Key with `KC_TRANS` doesn't has its own keycode and refers to lower valid layers for keycode, instead. See example below. @@ -155,12 +155,12 @@ You can find other keymap definitions in file `keymap.c` located on project dire ## 1. Keycode -See [`common/keycode.h`](../common/keycode.h) or keycode table below for the detail. Keycode is internal **8bit code** to inidicate action performed on key in keymap. Keycode has `KC_` prefixed symbol respectively. Most of keycodes like `KC_A` have simple action registers key to host on press and unregister on release, while some of other keycodes has some special actions like `Fn` keys, Media contorl keys, System control keys and Mousekeys. +See [`common/keycode.h`](../common/keycode.h) or keycode table below for the detail. Keycode is internal **8bit code** to indicate action performed on key in keymap. Keycode has `KC_` prefixed symbol respectively. Most of keycodes like `KC_A` have simple action registers key to host on press and unregister on release, while some of other keycodes has some special actions like `Fn` keys, Media control keys, System control keys and Mousekeys. ***In `KEYMAP()` macro you should omit prefix part `KC_` of keycode to keep keymap compact.*** For example, just use `A` instead you place `KC_A` in `KEYMAP()`. Some keycodes has 4-letter **short name** in addition to descriptive name, you'll prefer short one in `KEYMAP()`. ### 1.0 Other key -- `KC_NO` for no aciton +- `KC_NO` for no action - `KC_TRNS` for layer transparency (See above) ### 1.1 Normal key @@ -192,7 +192,7 @@ There are 8 modifiers which has discrimination between left and right. - `KC_WSCH`, `KC_WHOM`, `KC_WBAK`, `KC_WFWD`, `KC_WSTP`, `KC_WREF`, `KC_WFAV` for web browser operation ### 1.5 Fn key -`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keyocde indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** +`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.*** ### 1.6 Keycode Table See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes. @@ -205,7 +205,7 @@ There are 8 modifiers which has discrimination between left and right. ## 2. Action See [`common/action_code.h`](../common/action_code.h). Action is a **16bit code** and defines function to perform on events of a key like press, release, holding and tapping. -Most of keys just register 8bit scancode to host, but to support other complex features needs 16bit extended action codes internally. However, using 16bit action codes in keymap results in double size in memory compared to using jsut keycodes. To avoid this waste 8bit keycodes are used in `KEYMAP()` instead of action codes. +Most of keys just register 8bit scancode to host, but to support other complex features needs 16bit extended action codes internally. However, using 16bit action codes in keymap results in double size in memory compared to using just keycodes. To avoid this waste 8bit keycodes are used in `KEYMAP()` instead of action codes. ***You can just use keycodes of `Normal key`, `Modifier`, `Mousekey` and `System & Media key` in keymap*** to indicate corresponding actions instead of using action codes. While ***to use other special actions you should use keycode of `Fn` key defined in `fn_actions[]`.*** @@ -230,7 +230,7 @@ You can define these actions on *'A'* key and *'left shift'* modifier with: #### 2.1.2 Modified key This action is comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes. -Say you want to assign a key to `Shift + 1` to get charactor *'!'* or `Alt + Tab` to switch application windows. +Say you want to assign a key to `Shift + 1` to get character *'!'* or `Alt + Tab` to switch application windows. ACTION_MODS_KEY(MOD_LSFT, KC_1) ACTION_MODS_KEY(MOD_LALT, KC_TAB) @@ -269,10 +269,10 @@ Default Layer is a layer which always is valid and referred to when actions is n This sets Default Layer to given parameter `layer` and activate it. - ACTION_DEFAULT_LAYER(layer) + ACTION_DEFAULT_LAYER_SET(layer) -#### 2.2.2 Momentary Switch +#### 2.2.2 Momentary Turns on `layer` momentarily while holding, in other words it activates when key is pressed and deactivate when released. ACTION_LAYER_MOMENTARY(layer) @@ -342,7 +342,7 @@ Turns on layer only and clear all layer on release.. ACTION_LAYER_BIT_XOR(part, bits, on) ACTION_LAYER_BIT_SET(part, bits, on) -These actions works with prameters as following code. +These actions works with parameters as following code. uint8_t shift = part*4; uint32_t mask = (bits&0x10) ? ~(0xf< ## kbdbabel.org[converter][vintage][protocol][8051] -Great resourse of vintage keyboard protocol information and code +Great resource of vintage keyboard protocol information and code - diff --git a/keyboard/IIgs/README b/keyboard/IIgs/README index 4f9cad1c..820d7711 100644 --- a/keyboard/IIgs/README +++ b/keyboard/IIgs/README @@ -1,4 +1,4 @@ -Replacable USB Controller for Apple IIgs/Standard(M0116) +Replaceable USB Controller for Apple IIgs/Standard(M0116) JeffreySung(nattyman@gmail.com) =============================== @@ -32,7 +32,7 @@ PJRC Teensy 1. Bypass #31 pin(from board) to E4(Teensy) 2. Bypass #30 pin(from board) to F2(Teensy) 3. Bypass #6 pin(from board) to A0(Teensy) -4. Refer doc directory +4. Refer to documentation directory To Do ===== diff --git a/keyboard/gh60/README.md b/keyboard/gh60/README.md index 5e0fc244..510cb5c8 100644 --- a/keyboard/gh60/README.md +++ b/keyboard/gh60/README.md @@ -80,7 +80,7 @@ See [keymap_plain.c](keymap_plain.c) for detail. ### 3. Hasu -This is my favourite keymap with HHKB Fn, Vi cursor and Mousekey layer. See [keymap_hasu.c](keymap_hasu.c) for detail. +This is my favorite keymap with HHKB Fn, Vi cursor and Mousekey layer. See [keymap_hasu.c](keymap_hasu.c) for detail. ### 4. SpaceFN diff --git a/keyboard/hhkb/Makefile b/keyboard/hhkb/Makefile index 89d05ba1..0a256874 100644 --- a/keyboard/hhkb/Makefile +++ b/keyboard/hhkb/Makefile @@ -102,7 +102,7 @@ ARCH = AVR8 F_USB = $(F_CPU) # Interrupt driven control endpoint task -OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT +#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT # Boot Section Size in *bytes* diff --git a/keyboard/hhkb/README.md b/keyboard/hhkb/README.md index 92136482..7ea9843a 100644 --- a/keyboard/hhkb/README.md +++ b/keyboard/hhkb/README.md @@ -24,7 +24,7 @@ See README of [tmk_keyboard] for more. * No risks: Everything is all reversible * No need for PCB trace patching, case cutting or any other destructive mod * Can keep original controller intact -* Can change all HHKB behaviour as you like +* Can change all HHKB behavior as you like ###Cons * Void your warranty @@ -54,11 +54,11 @@ Several version of keymap are available in advance but you are recommended to de ### Program First, push reset button on board to start bootloader. -This command programs the controller with [dfu-programmer] if the tool is intalled and configured properly. +This command programs the controller with [dfu-programmer] if the tool is installed and configured properly. $ make dfu -Or you can also use [FLIP] command to program. Also the tool should be intalled and configured properly. FLIP GUI app is also available. +Or you can also use [FLIP] command to program. Also the tool should be installed and configured properly. FLIP GUI application is also available. $ make flip @@ -70,7 +70,7 @@ To define your own keymap create file named `keymap_.c` and see keymap doc ##Hardware -You have some options for hardware. Development boards with USB AVR family(ATMega32U4, AT90USB1286) like Teensy will work while MegaAVR with [V-USB] library is also cheapear option for DIY. +You have some options for hardware. Development boards with USB AVR family(ATMega32U4, AT90USB1286) like Teensy will work while MegaAVR with [V-USB] library is also cheaper option for DIY. ###1. TMK Alt Controller Board TMK designed [Keyboard Controller Board for HHKB Pro2(KiCad project)](https://github.com/tmk/HHKB_controller). diff --git a/keyboard/hhkb/keymap_hasu.c b/keyboard/hhkb/keymap_hasu.c index 0297d3b7..2f6be63e 100644 --- a/keyboard/hhkb/keymap_hasu.c +++ b/keyboard/hhkb/keymap_hasu.c @@ -25,7 +25,7 @@ const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = { KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \ TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \ LCTL,A, S, D, F, G, H, J, K, L, FN3, QUOT,FN4, \ - FN5, Z, X, C, V, B, N, M, COMM,DOT, FN2, RSFT,FN1, \ + FN11,Z, X, C, V, B, N, M, COMM,DOT, FN2, RSFT,FN1, \ LGUI,LALT, FN6, RALT,RGUI), /* Layer 1: HHKB mode (HHKB Fn) @@ -131,12 +131,9 @@ const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = { /* id for user defined functions */ enum function_id { LSHIFT_LPAREN, - RSHIFT_RPAREN, }; enum macro_id { - LSHIFT_PAREN, - RSHIFT_PAREN, HELLO, VOLUP, }; @@ -163,10 +160,7 @@ const uint16_t fn_actions[] PROGMEM = { // [8] = ACTION_LMOD_TAP_KEY(KC_LCTL, KC_BSPC), // LControl with tap Backspace // [9] = ACTION_LMOD_TAP_KEY(KC_LCTL, KC_ESC), // LControl with tap Esc - [11] = ACTION_FUNCTION_TAP(LSHIFT_LPAREN), // Function: LShift with tap '(' - [12] = ACTION_FUNCTION_TAP(RSHIFT_RPAREN), // Function: RShift with tap ')' -// [13] = ACTION_MACRO_TAP(LSHIFT_PAREN), // Macro: LShift with tap '(' -// [14] = ACTION_MACRO_TAP(RSHIFT_PAREN), // Macro: RShift with tap ')' + [11] = ACTION_FUNCTION_TAP(LSHIFT_LPAREN), // Function: LShift with tap '(' // [15] = ACTION_MACRO(HELLO), // Macro: say hello // [9] = ACTION_MACRO(VOLUP), // Macro: media key }; @@ -177,32 +171,13 @@ const uint16_t fn_actions[] PROGMEM = { */ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { - keyevent_t event = record->event; - tap_t tap = record->tap; - switch (id) { - case LSHIFT_PAREN: - if (tap.count > 0 && !tap.interrupted) { - return (event.pressed ? - MACRO( D(LSHIFT), D(9), U(9), U(LSHIFT), END ) : MACRO_NONE); - } else { - return (event.pressed ? - MACRO( D(LSHIFT), END ) : MACRO( U(LSHIFT), END ) ); - } - case RSHIFT_PAREN: - if (tap.count > 0 && !tap.interrupted) { - return (event.pressed ? - MACRO( D(RSHIFT), D(0), U(0), U(RSHIFT), END ) : MACRO_NONE); - } else { - return (event.pressed ? - MACRO( D(RSHIFT), END ) : MACRO( U(RSHIFT), END ) ); - } case HELLO: - return (event.pressed ? + return (record->event.pressed ? MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) : MACRO_NONE ); case VOLUP: - return (event.pressed ? + return (record->event.pressed ? MACRO( D(VOLU), U(VOLU), END ) : MACRO_NONE ); } @@ -216,48 +191,36 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) */ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { - keyevent_t event = record->event; - tap_t tap = record->tap; + if (record->event.pressed) dprint("P"); else dprint("R"); + dprintf("%d", record->tap.count); + if (record->tap.interrupted) dprint("i"); + dprint("\n"); switch (id) { case LSHIFT_LPAREN: - // LShft + tap '(' - // NOTE: cant use register_code to avoid conflicting with magic key bind - if (event.pressed) { - if (tap.count == 0 || tap.interrupted) { - //add_mods(MOD_BIT(KC_LSHIFT)); - layer_on(1); + // Shift parentheses example: LShft + tap '(' + // http://stevelosh.com/blog/2012/10/a-modern-space-cadet/#shift-parentheses + // http://geekhack.org/index.php?topic=41989.msg1304899#msg1304899 + if (record->event.pressed) { + if (record->tap.count > 0 && !record->tap.interrupted) { + if (record->tap.interrupted) { + dprint("tap interrupted\n"); + register_mods(MOD_BIT(KC_LSHIFT)); + } } else { - add_mods(MOD_BIT(KC_LSHIFT)); - add_key(KC_9); - send_keyboard_report(); - del_mods(MOD_BIT(KC_LSHIFT)); - del_key(KC_9); - send_keyboard_report(); + register_mods(MOD_BIT(KC_LSHIFT)); } } else { - if (tap.count == 0 || tap.interrupted) { - //del_mods(MOD_BIT(KC_LSHIFT)); - layer_off(1); - } - } - break; - case RSHIFT_RPAREN: - // RShift + tap ')' - if (event.pressed) { - if (tap.count == 0 || tap.interrupted) { - add_mods(MOD_BIT(KC_RSHIFT)); + if (record->tap.count > 0 && !(record->tap.interrupted)) { + add_weak_mods(MOD_BIT(KC_LSHIFT)); + send_keyboard_report(); + register_code(KC_9); + unregister_code(KC_9); + del_weak_mods(MOD_BIT(KC_LSHIFT)); + send_keyboard_report(); + record->tap.count = 0; // ad hoc: cancel tap } else { - add_mods(MOD_BIT(KC_RSHIFT)); - add_key(KC_0); - send_keyboard_report(); - del_mods(MOD_BIT(KC_RSHIFT)); - del_key(KC_0); - send_keyboard_report(); - } - } else { - if (tap.count == 0 || tap.interrupted) { - del_mods(MOD_BIT(KC_RSHIFT)); + unregister_mods(MOD_BIT(KC_LSHIFT)); } } break; diff --git a/keyboard/kmac/README.md b/keyboard/kmac/README.md index 8cfe0971..dc35870c 100644 --- a/keyboard/kmac/README.md +++ b/keyboard/kmac/README.md @@ -18,7 +18,7 @@ Move to this directory then just run `make` like: Use `Makefile.pjrc` if you want to use PJRC stack or use `Makefile.lufa` for LUFA stack. -Booloader +Bootloader --------- The PCB is hardwired to run the bootloader if the key at the `Caps Lock` position is held down when connecting the keyboard. diff --git a/keyboard/lightsaber/Makefile.lufa b/keyboard/lightsaber/Makefile.lufa new file mode 100644 index 00000000..b430efd2 --- /dev/null +++ b/keyboard/lightsaber/Makefile.lufa @@ -0,0 +1,126 @@ +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device. +# Please customize your programmer settings(PROGRAM_CMD) +# +# make teensy = Download the hex file to the device, using teensy_loader_cli. +# (must have teensy_loader_cli installed). +# +# make dfu = Download the hex file to the device, using dfu-programmer (must +# have dfu-programmer installed). +# +# make flip = Download the hex file to the device, using Atmel FLIP (must +# have Atmel FLIP installed). +# +# make dfu-ee = Download the eeprom file to the device, using dfu-programmer +# (must have dfu-programmer installed). +# +# make flip-ee = Download the eeprom file to the device, using Atmel FLIP +# (must have Atmel FLIP installed). +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name (without extension). +TARGET = lightsaber_lufa + +# Directory common source filess exist +TOP_DIR = ../.. + +# Directory keyboard dependent files exist +TARGET_DIR = . + + +# List C source files here. (C dependencies are automatically generated.) +SRC = keymap.c \ + matrix.c \ + led.c \ + backlight.c + +CONFIG_H = config.h + + +# MCU name +MCU = atmega32u4 + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 8000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + + +# Build Options +# comment out to disable the options. +# +BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) +#MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = yes # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend +#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA +BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality + + +# Boot Section Size in bytes +# Teensy halfKay 512 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +OPT_DEFS += -DBOOTLOADER_SIZE=4096 + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + +include $(TOP_DIR)/protocol/lufa.mk +include $(TOP_DIR)/common.mk +include $(TOP_DIR)/rules.mk + +winkey: OPT_DEFS += -DLAYOUT_WINKEY +winkey: all diff --git a/keyboard/lightsaber/Makefile.pjrc b/keyboard/lightsaber/Makefile.pjrc new file mode 100644 index 00000000..58735a7e --- /dev/null +++ b/keyboard/lightsaber/Makefile.pjrc @@ -0,0 +1,94 @@ +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device. +# Please customize your programmer settings(PROGRAM_CMD) +# +# make teensy = Download the hex file to the device, using teensy_loader_cli. +# (must have teensy_loader_cli installed). +# +# make dfu = Download the hex file to the device, using dfu-programmer (must +# have dfu-programmer installed). +# +# make flip = Download the hex file to the device, using Atmel FLIP (must +# have Atmel FLIP installed). +# +# make dfu-ee = Download the eeprom file to the device, using dfu-programmer +# (must have dfu-programmer installed). +# +# make flip-ee = Download the eeprom file to the device, using Atmel FLIP +# (must have Atmel FLIP installed). +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name (without extension). +TARGET = lightsaber_pjrc + +# Directory common source filess exist +TOP_DIR = ../.. + +# Directory keyboard dependent files exist +TARGET_DIR = . + +# keyboard dependent files +SRC = keymap.c \ + matrix.c \ + led.c \ + backlight.c + +CONFIG_H = config.h + + +# MCU name +MCU = atmega32u4 + + +# Processor frequency. +# Normally the first thing your program should do is set the clock prescaler, +# so your program will run at the correct speed. You should also set this +# variable to same clock speed. The _delay_ms() macro uses this, and many +# examples use this variable to calculate timings. Do not add a "UL" here. +F_CPU = 8000000 + + +# Build Options +# comment out to disable the options. +# +BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) +#MOUSEKEY_ENABLE = yes # Mouse keys(+5000) +EXTRAKEY_ENABLE = yes # Audio control and System control(+600) +CONSOLE_ENABLE = yes # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend +#NKRO_ENABLE = yes # USB Nkey Rollover(+500) +#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support +BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + +include $(TOP_DIR)/protocol/pjrc.mk +include $(TOP_DIR)/common.mk +include $(TOP_DIR)/rules.mk + +winkey: OPT_DEFS += -DLAYOUT_WINKEY +winkey: all diff --git a/keyboard/lightsaber/README.md b/keyboard/lightsaber/README.md new file mode 100644 index 00000000..9dcd6930 --- /dev/null +++ b/keyboard/lightsaber/README.md @@ -0,0 +1,26 @@ +Lightsaber keyboard firmware +====================== +Korean custom keyboard designed by Duck. + +*Note that this is not the official firmware* + +Supported models +---------------- +All pcb options are supported. + + +Build +----- +Move to this directory then just run `make` like: + + $ make -f Makefile.[pjrc|lufa] + +Use `Makefile.pjrc` if you want to use PJRC stack or use `Makefile.lufa` for LUFA stack. + + +Bootloader +--------- +The PCB is hardwired to run the bootloader if the key at the `one above backspace` position is held down when connecting the keyboard. + +It is still possible to use Boot Magic and Command to access the bootloader though. + diff --git a/keyboard/lightsaber/backlight.c b/keyboard/lightsaber/backlight.c new file mode 100644 index 00000000..59b8b4a6 --- /dev/null +++ b/keyboard/lightsaber/backlight.c @@ -0,0 +1,86 @@ +/* +Copyright 2014 Ralf Schmitt + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include "backlight.h" + +/* Backlight pin configuration + * + * Alphas PB1 (high) + * Numeric PB2 (high) + * Mod+Num PB3 (high) + * Backside PD6 (high) + * TopRight PD7 (low) + * F-Row PE6 (high) + */ + +void backlight_set(uint8_t level) +{ + // Set as output. + DDRB |= (1<<1) | (1<<2) | (1<<3); + DDRD |= (1<<6) | (1<<7); + DDRE |= (1<<6); + + if (level & BACKLIGHT_ALPHA) + { + PORTB |= (1<<1); + } + else + { + PORTB &= ~(1<<1); + } + if (level & BACKLIGHT_NUMERIC) + { + PORTB |= (1<<2); + } + else + { + PORTB &= ~(1<<2); + } + if (level & BACKLIGHT_MODNUM) + { + PORTB |= (1<<3); + } + else + { + PORTB &= ~(1<<3); + } + if (level & BACKLIGHT_BACKSIDE) + { + PORTD |= (1<<6); + } + else + { + PORTD &= ~(1<<6); + } + if (level & BACKLIGHT_TOPRIGHT) + { + PORTD &= ~(1<<7); + } + else + { + PORTD |= (1<<7); + } + if (level & BACKLIGHT_FROW) + { + PORTE |= (1<<6); + } + else + { + PORTE &= ~(1<<6); + } +} diff --git a/keyboard/lightsaber/backlight.h b/keyboard/lightsaber/backlight.h new file mode 100644 index 00000000..6dc7967a --- /dev/null +++ b/keyboard/lightsaber/backlight.h @@ -0,0 +1,9 @@ + +enum backlight_level { + BACKLIGHT_ALPHA = 0b0000001, + BACKLIGHT_NUMERIC = 0b0000010, + BACKLIGHT_MODNUM = 0b0000100, + BACKLIGHT_BACKSIDE = 0b0001000, + BACKLIGHT_TOPRIGHT = 0b0010000, + BACKLIGHT_FROW = 0b0100000, +}; diff --git a/keyboard/lightsaber/config.h b/keyboard/lightsaber/config.h new file mode 100644 index 00000000..d971d038 --- /dev/null +++ b/keyboard/lightsaber/config.h @@ -0,0 +1,46 @@ +/* +Copyright 2013 Mathias Andersson + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6050 +#define DEVICE_VER 0x0104 +#define MANUFACTURER Duck +#define PRODUCT Lightsaber + +/* message strings */ +#define DESCRIPTION t.m.k. keyboard firmware for Lightsaber + +/* matrix size */ +#define MATRIX_ROWS 6 +#define MATRIX_COLS 18 + +/* number of backlight levels */ +#define BACKLIGHT_LEVELS 1 + +/* Set 0 if need no debouncing */ +#define DEBOUNCE 5 + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + +#endif diff --git a/keyboard/lightsaber/keymap.c b/keyboard/lightsaber/keymap.c new file mode 100644 index 00000000..398e51ec --- /dev/null +++ b/keyboard/lightsaber/keymap.c @@ -0,0 +1,77 @@ +/* +Copyright 2014 Ralf Schmitt + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +/* + * Keymap for Lightsaber controller + */ +#include +#include +#include +#include "keycode.h" +#include "action.h" +#include "action_macro.h" +#include "report.h" +#include "host.h" +#include "debug.h" +#include "keymap.h" + +// Convert physical keyboard layout to matrix array. +// This is a macro to define keymap easily in keyboard layout form. +#define KEYMAP( \ + K5A, K5B, K5C, K5D, K5E, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K5N, K5O, K5P, K5Q, K5R, \ + K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, K4N, K4O, K4P, K4Q, K4R, \ + K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3N, K3O, K3P, K3Q, K3R, \ + K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2M, K2N, K2O, K2P, K2Q, K2R, \ + K1A, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1L, K1M, K1N, K1O, K1P, K1Q, K1R, \ + K0A, K0B, K0C, K0G, K0K, K0L, K0M, K0N, K0O, K0P, K0Q, K0R \ +) { \ +/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 */ \ +/* 5 */ { KC_##K5A, KC_##K5B, KC_##K5C, KC_##K5D, KC_##K5E, KC_##K5F, KC_##K5G, KC_##K5H, KC_##K5I, KC_##K5J, KC_##K5K, KC_##K5L, KC_##K5M, KC_##K5N, KC_##K5O, KC_##K5P, KC_##K5Q, KC_##K5R}, \ +/* 4 */ { KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K4F, KC_##K4G, KC_##K4H, KC_##K4I, KC_##K4J, KC_##K4K, KC_##K4L, KC_##K4M, KC_##K4N, KC_##K4O, KC_##K4P, KC_##K4Q, KC_##K4R}, \ +/* 3 */ { KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F, KC_##K3G, KC_##K3H, KC_##K3I, KC_##K3J, KC_##K3K, KC_##K3L, KC_##K3M, KC_##K3N, KC_##K3O, KC_##K3P, KC_##K3Q, KC_##K3R}, \ +/* 2 */ { KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F, KC_##K2G, KC_##K2H, KC_##K2I, KC_##K2J, KC_##K2K, KC_##K2L, KC_##K2M, KC_##K2N, KC_##K2O, KC_##K2P, KC_##K2Q, KC_##K2R}, \ +/* 1 */ { KC_##K1A, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F, KC_##K1G, KC_##K1H, KC_##K1I, KC_##K1J, KC_##K1K, KC_##K1L, KC_NO, KC_##K1M, KC_##K1N, KC_##K1O, KC_##K1P, KC_##K1Q, KC_##K1R}, \ +/* 0 */ { KC_##K0A, KC_##K0B, KC_##K0C, KC_NO, KC_NO, KC_##K0G, KC_NO, KC_NO, KC_##K0K, KC_NO, KC_##K0L, KC_NO, KC_##K0M, KC_##K0N, KC_##K0O, KC_##K0P, KC_##K0Q, KC_##K0R} \ +} + +#include "keymap_winkey.h" + +#define KEYMAPS_SIZE (sizeof(keymaps) / sizeof(keymaps[0])) +#define FN_ACTIONS_SIZE (sizeof(fn_actions) / sizeof(fn_actions[0])) + +/* translates key to keycode */ +uint8_t keymap_key_to_keycode(uint8_t layer, key_t key) +{ + if (layer < KEYMAPS_SIZE) { + return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]); + } else { + // fall back to layer 0 + return pgm_read_byte(&keymaps[0][(key.row)][(key.col)]); + } +} + +/* translates Fn keycode to action */ +action_t keymap_fn_to_action(uint8_t keycode) +{ + action_t action; + if (FN_INDEX(keycode) < FN_ACTIONS_SIZE) { + action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]); + } else { + action.code = ACTION_NO; + } + return action; +} diff --git a/keyboard/lightsaber/keymap_winkey.h b/keyboard/lightsaber/keymap_winkey.h new file mode 100644 index 00000000..3e836708 --- /dev/null +++ b/keyboard/lightsaber/keymap_winkey.h @@ -0,0 +1,29 @@ +#include "backlight.h" + +static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + KEYMAP(\ + ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, INS, PSCR, SLCK, BRK, \ + GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, NUMLOCK,KP_SLASH,KP_ASTERISK,KP_MINUS, \ + TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, KP_7, KP_8, KP_9, KP_PLUS, \ + CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT,FN0, ENT, KP_4, KP_5, KP_6, NO, \ + LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH,NO, RSFT, KP_1, KP_2, KP_3, KP_ENTER, \ + LCTL,LGUI,LALT, SPC, NO, RALT,RGUI,RCTL, KP_0, NO, KP_DOT, NO), \ + KEYMAP(\ + CALC,MYCM,WSCH,WHOM,MAIL,MUTE,VOLD,VOLU,MSEL,MSTP,MPLY,MPRV,MNXT,TRNS, TRNS, WAKE, PWR, SLEP, \ + FN1, FN2, FN3, FN4, FN5, FN6, FN7, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS, TRNS, TRNS, \ + TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS, TRNS, TRNS, \ + TRNS,TRNS,TRNS,TRNS,PGDN,TRNS,LEFT,DOWN,UP ,RGHT,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS, TRNS, TRNS, \ + TRNS, TRNS,TRNS,TRNS,TRNS,PGUP,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS, TRNS, TRNS, \ + TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS, TRNS, TRNS, TRNS, TRNS) +}; + +static const uint16_t PROGMEM fn_actions[] = { + [0] = ACTION_LAYER_MOMENTARY(1), + [1] = ACTION_BACKLIGHT_TOGGLE(), + [2] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_ALPHA), + [3] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_MODNUM), + [4] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_NUMERIC), + [5] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_FROW), + [6] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_BACKSIDE), + [7] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_TOPRIGHT) +}; diff --git a/keyboard/lightsaber/led.c b/keyboard/lightsaber/led.c new file mode 100644 index 00000000..c3f85427 --- /dev/null +++ b/keyboard/lightsaber/led.c @@ -0,0 +1,54 @@ +/* +Copyright 2014 Ralf Schmitt + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include "stdint.h" +#include "led.h" + +/* LED pin configuration + * + * Caps PB0 (low) + * NumLock PB4 (low) + * + */ +void led_set(uint8_t usb_led) +{ + // Set as output. + DDRB |= (1<<0) | (1<<4); + + if (usb_led & (1< + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include "print.h" +#include "debug.h" +#include "util.h" +#include "matrix.h" + + +#ifndef DEBOUNCE +# define DEBOUNCE 0 +#endif +static uint8_t debouncing = DEBOUNCE; + +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +static uint8_t read_rows(void); +static uint8_t read_fwkey(void); +static void init_rows(void); +static void unselect_cols(void); +static void select_col(uint8_t col); + +inline +uint8_t matrix_rows(void) +{ + return MATRIX_ROWS; +} + +inline +uint8_t matrix_cols(void) +{ + return MATRIX_COLS; +} + +void matrix_init(void) +{ + unselect_cols(); + init_rows(); + // initialize matrix state: all keys off + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + matrix_debouncing[i] = 0; + } +} + +uint8_t matrix_scan(void) +{ + for (uint8_t col = 0; col < MATRIX_COLS; col++) { // 0-17 + select_col(col); + _delay_us(3); // TODO: Determine the correct value needed here. + uint8_t rows = read_rows(); + // Use the otherwise unused col: 12 row: 3 for firmware. + if(col == 12) { + rows |= read_fwkey(); + } + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { // 0-5 + bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1< +*/ +#include +#include +#include "debug.h" +#include "ibm4704.h" + + +#define WAIT(stat, us, err) do { \ + if (!wait_##stat(us)) { \ + ibm4704_error = err; \ + goto ERROR; \ + } \ +} while (0) + + +uint8_t ibm4704_error = 0; + + +void ibm4704_init(void) +{ + inhibit(); +} + +/* +Host to Keyboard +---------------- +Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part. + + ____ __ __ __ __ __ __ __ __ __ ________ +Clock \______/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ + ^ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___ +Data ____|__/ X____X____X____X____X____X____X____X____X____X \___ + | Start 0 1 2 3 4 5 6 7 P Stop + Request by host + +Start bit: can be long as 300-350us. +Request: Host pulls Clock line down to request to send a command. +Timing: After Request keyboard pull up Data and down Clock line to low for start bit. + After request host release Clock line once Data line becomes hi. + Host writes a bit while Clock is hi and Keyboard reads while low. +Stop bit: Host releases or pulls up Data line to hi after 9th clock and waits for keyboard pull down the line to lo. +*/ +uint8_t ibm4704_send(uint8_t data) +{ + bool parity = true; // odd parity + ibm4704_error = 0; + + /* Request to send */ + idle(); + clock_lo(); + + /* wait for Start bit(Clock:lo/Data:hi) */ + WAIT(data_hi, 300, 0x30); + + /* Data bit */ + for (uint8_t i = 0; i < 8; i++) { + WAIT(clock_hi, 100, 0x40+i); + //_delay_us(5); + if (data&(1<= 0x30) { + xprintf("x%02X ", ibm4704_error); + } + _delay_us(200); // wait to recover clock to hi + return -1; +} + +/* receive data when host want else inhibit communication */ +uint8_t ibm4704_recv_response(void) +{ + // 250 * 100us(wait start bit in ibm4704_recv) + uint8_t data = 0; + uint8_t try = 250; + do { + data = ibm4704_recv(); + } while (try-- && ibm4704_error); + return data; +} + +/* +Keyboard to Host +---------------- +Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part. + + ____ __ __ __ __ __ __ __ __ __ ________ +Clock \____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ + ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ +Data ____/ X____X____X____X____X____X____X____X____X____X________ + Start 0 1 2 3 4 5 6 7 P Stop + +Start bit: can be long as 300-350us. +Inhibit: Pull Data line down to inhibit keyboard to send. +Timing: Host reads bit while Clock is hi. +Stop bit: Keyboard pulls down Data line to lo after 9th clock. +*/ +uint8_t ibm4704_recv(void) +{ + uint8_t data = 0; + bool parity = true; // odd parity + ibm4704_error = IBM4704_ERR_NONE; + + idle(); + _delay_us(5); // wait for line settles + + /* start bit */ + WAIT(clock_lo, 100, 0x11); // wait for keyboard to send + WAIT(data_hi, 100, 0x12); // can be delayed that long + + WAIT(clock_hi, 100, 0x13); // first rising edge which can take longer + /* data */ + for (uint8_t i = 0; i < 8; i++) { + WAIT(clock_hi, 100, 0x20+i); + //_delay_us(5); + if (data_in()) { + parity = !parity; + data |= (1< 0x12) { + xprintf("x%02X ", ibm4704_error); + } + inhibit(); + _delay_us(200); // wait to recover clock to hi + return -1; +} diff --git a/protocol/ibm4704.h b/protocol/ibm4704.h new file mode 100644 index 00000000..618cce6b --- /dev/null +++ b/protocol/ibm4704.h @@ -0,0 +1,110 @@ +/* +Copyright 2014 Jun WAKO +*/ +#ifndef IBM4704_H +#define IBM4704_H + +#define IBM4704_ERR_NONE 0 +#define IBM4704_ERR_PARITY 0x70 + + +void ibm4704_init(void); +uint8_t ibm4704_send(uint8_t data); +uint8_t ibm4704_recv_response(void); +uint8_t ibm4704_recv(void); + + +/* Check pin configuration */ +#if !(defined(IBM4704_CLOCK_PORT) && \ + defined(IBM4704_CLOCK_PIN) && \ + defined(IBM4704_CLOCK_DDR) && \ + defined(IBM4704_CLOCK_BIT)) +# error "ibm4704 clock pin configuration is required in config.h" +#endif + +#if !(defined(IBM4704_DATA_PORT) && \ + defined(IBM4704_DATA_PIN) && \ + defined(IBM4704_DATA_DDR) && \ + defined(IBM4704_DATA_BIT)) +# error "ibm4704 data pin configuration is required in config.h" +#endif + + +/*-------------------------------------------------------------------- + * static functions + *------------------------------------------------------------------*/ +static inline void clock_lo(void) +{ + IBM4704_CLOCK_PORT &= ~(1< 4 +# error "Endpoints are not available enough to support all functions. Remove some in Makefile.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO)" +# endif #endif @@ -159,4 +163,14 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const void** const DescriptorAddress) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); + +/* new API */ +#if LUFA_VERSION_INTEGER < 0x140302 + #undef VERSION_BCD + #define VERSION_BCD(Major, Minor, Revision) \ + CPU_TO_LE16( ((Major & 0xFF) << 8) | \ + ((Minor & 0x0F) << 4) | \ + (Revision & 0x0F) ) +#endif + #endif diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c index eca51c87..d60aecc3 100644 --- a/protocol/lufa/lufa.c +++ b/protocol/lufa/lufa.c @@ -52,8 +52,8 @@ #include "descriptor.h" #include "lufa.h" -static uint8_t idle_duration = 0; -static uint8_t protocol_report = 1; +uint8_t keyboard_idle = 0; +uint8_t keyboard_protocol = 1; static uint8_t keyboard_led_stats = 0; static report_keyboard_t keyboard_report_sent; @@ -184,15 +184,6 @@ void EVENT_USB_Device_StartOfFrame(void) /** Event handler for the USB_ConfigurationChanged event. * This is fired when the host sets the current configuration of the USB device after enumeration. */ -#if LUFA_VERSION_INTEGER < 0x120730 - /* old API 120219 */ - #define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint(epnum, eptype, epdir, epsize, epbank) -#else - /* new API >= 120730 */ - #define ENDPOINT_BANK_SINGLE 1 - #define ENDPOINT_BANK_DOUBLE 2 - #define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint((epdir) | (epnum) , eptype, epsize, epbank) -#endif void EVENT_USB_Device_ConfigurationChanged(void) { bool ConfigSuccess = true; @@ -217,9 +208,11 @@ void EVENT_USB_Device_ConfigurationChanged(void) /* Setup Console HID Report Endpoints */ ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, CONSOLE_EPSIZE, ENDPOINT_BANK_DOUBLE); +#if 0 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); #endif +#endif #ifdef NKRO_ENABLE /* Setup NKRO HID Report Endpoints */ @@ -279,6 +272,7 @@ void EVENT_USB_Device_ControlRequest(void) // Interface switch (USB_ControlRequest.wIndex) { case KEYBOARD_INTERFACE: + case NKRO_INTERFACE: Endpoint_ClearSETUP(); while (!(Endpoint_IsOUTReceived())) { @@ -299,21 +293,29 @@ void EVENT_USB_Device_ControlRequest(void) case HID_REQ_GetProtocol: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { - Endpoint_ClearSETUP(); - while (!(Endpoint_IsINReady())); - Endpoint_Write_8(protocol_report); - Endpoint_ClearIN(); - Endpoint_ClearStatusStage(); + if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { + Endpoint_ClearSETUP(); + while (!(Endpoint_IsINReady())); + Endpoint_Write_8(keyboard_protocol); + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + } } break; case HID_REQ_SetProtocol: if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { - Endpoint_ClearSETUP(); - Endpoint_ClearStatusStage(); + if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); - protocol_report = ((USB_ControlRequest.wValue & 0xFF) != 0x00); + keyboard_protocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00); +#ifdef NKRO_ENABLE + keyboard_nkro = !!keyboard_protocol; +#endif + clear_keyboard(); + } } break; @@ -323,7 +325,7 @@ void EVENT_USB_Device_ControlRequest(void) Endpoint_ClearSETUP(); Endpoint_ClearStatusStage(); - idle_duration = ((USB_ControlRequest.wValue & 0xFF00) >> 8); + keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); } break; @@ -332,7 +334,7 @@ void EVENT_USB_Device_ControlRequest(void) { Endpoint_ClearSETUP(); while (!(Endpoint_IsINReady())); - Endpoint_Write_8(idle_duration); + Endpoint_Write_8(keyboard_idle); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } @@ -351,7 +353,7 @@ static uint8_t keyboard_leds(void) static void send_keyboard(report_keyboard_t *report) { - uint8_t timeout = 0; + uint8_t timeout = 255; if (USB_DeviceState != DEVICE_STATE_Configured) return; @@ -359,26 +361,27 @@ static void send_keyboard(report_keyboard_t *report) /* Select the Keyboard Report Endpoint */ #ifdef NKRO_ENABLE if (keyboard_nkro) { + /* Report protocol - NKRO */ Endpoint_SelectEndpoint(NKRO_IN_EPNUM); - } - else -#endif - { - Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM); - } - /* Check if Keyboard Endpoint Ready for Read/Write */ - while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + /* Check if write ready for a polling interval around 1ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4); + if (!Endpoint_IsReadWriteAllowed()) return; - /* Write Keyboard Report Data */ -#ifdef NKRO_ENABLE - if (keyboard_nkro) { + /* Write Keyboard Report Data */ Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL); } else #endif { - /* boot mode */ + /* Boot protocol */ + Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM); + + /* Check if write ready for a polling interval around 10ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + if (!Endpoint_IsReadWriteAllowed()) return; + + /* Write Keyboard Report Data */ Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL); } @@ -391,7 +394,7 @@ static void send_keyboard(report_keyboard_t *report) static void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE - uint8_t timeout = 0; + uint8_t timeout = 255; if (USB_DeviceState != DEVICE_STATE_Configured) return; @@ -399,8 +402,9 @@ static void send_mouse(report_mouse_t *report) /* Select the Mouse Report Endpoint */ Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); - /* Check if Mouse Endpoint Ready for Read/Write */ - while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + /* Check if write ready for a polling interval around 10ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + if (!Endpoint_IsReadWriteAllowed()) return; /* Write Mouse Report Data */ Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL); @@ -412,7 +416,7 @@ static void send_mouse(report_mouse_t *report) static void send_system(uint16_t data) { - uint8_t timeout = 0; + uint8_t timeout = 255; if (USB_DeviceState != DEVICE_STATE_Configured) return; @@ -422,14 +426,18 @@ static void send_system(uint16_t data) .usage = data }; Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); - while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + + /* Check if write ready for a polling interval around 10ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + if (!Endpoint_IsReadWriteAllowed()) return; + Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); Endpoint_ClearIN(); } static void send_consumer(uint16_t data) { - uint8_t timeout = 0; + uint8_t timeout = 255; if (USB_DeviceState != DEVICE_STATE_Configured) return; @@ -439,7 +447,11 @@ static void send_consumer(uint16_t data) .usage = data }; Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); - while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + + /* Check if write ready for a polling interval around 10ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + if (!Endpoint_IsReadWriteAllowed()) return; + Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); Endpoint_ClearIN(); } diff --git a/protocol/lufa/lufa.h b/protocol/lufa/lufa.h index bcee060d..195123c0 100644 --- a/protocol/lufa/lufa.h +++ b/protocol/lufa/lufa.h @@ -66,4 +66,15 @@ typedef struct { uint16_t usage; } __attribute__ ((packed)) report_extra_t; + +#if LUFA_VERSION_INTEGER < 0x120730 + /* old API 120219 */ + #define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint(epnum, eptype, epdir, epsize, epbank) +#else + /* new API >= 120730 */ + #define ENDPOINT_BANK_SINGLE 1 + #define ENDPOINT_BANK_DOUBLE 2 + #define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint((epdir) | (epnum) , eptype, epsize, epbank) +#endif + #endif diff --git a/protocol/next_kbd.c b/protocol/next_kbd.c new file mode 100644 index 00000000..a5a07a7a --- /dev/null +++ b/protocol/next_kbd.c @@ -0,0 +1,204 @@ +/* + +NeXT non-ADB Keyboard Protocol + +Copyright 2013, Benjamin Gould (bgould@github.com) + +Based on: +TMK firmware code Copyright 2011,2012 Jun WAKO +Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license + +Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB +Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html +Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/ + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include +#include +#include +#include "next_kbd.h" +#include "debug.h" + +static inline void out_lo(void); +static inline void out_hi(void); +static inline void query(void); +static inline void reset(void); +static inline uint32_t response(void); + +#define out_hi_delay(intervals) do { out_hi(); _delay_us(NEXT_KBD_TIMING * intervals); } while (0); +#define out_lo_delay(intervals) do { out_lo(); _delay_us(NEXT_KBD_TIMING * intervals); } while (0); +#define query_delay(intervals) do { query(); _delay_us(NEXT_KBD_TIMING * intervals); } while (0); +#define reset_delay(intervals) do { reset(); _delay_us(NEXT_KBD_TIMING * intervals); } while (0); + +void next_kbd_init(void) +{ + out_hi(); + NEXT_KBD_IN_DDR &= ~(1< +Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license + +Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB +Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html +Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/ + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include + +#ifndef NEXT_KBD_H +#define NEXT_KBD_H + +#define NEXT_KBD_KMBUS_IDLE 0x300600 +#define NEXT_KBD_TIMING 50 + +extern uint8_t next_kbd_error; + +/* host role */ +void next_kbd_init(void); +void next_kbd_set_leds(bool left, bool right); +uint32_t next_kbd_recv(void); + +#endif diff --git a/protocol/pjrc/usb.c b/protocol/pjrc/usb.c index 393b36f7..1e6ba871 100644 --- a/protocol/pjrc/usb.c +++ b/protocol/pjrc/usb.c @@ -38,6 +38,7 @@ #include "sleep_led.h" #endif #include "suspend.h" +#include "action.h" #include "action_util.h" @@ -628,6 +629,7 @@ uint8_t usb_configured(void) void usb_remote_wakeup(void) { UDCON |= (1<mods; UEDATX = 0; - uint8_t keys = usb_keyboard_protocol ? KBD_REPORT_KEYS : 6; + uint8_t keys = keyboard_protocol ? KBD_REPORT_KEYS : 6; for (uint8_t i=0; ikeys[i]; } @@ -901,13 +903,13 @@ ISR(USB_COM_vect) } if (bRequest == HID_GET_IDLE) { usb_wait_in_ready(); - UEDATX = usb_keyboard_idle_config; + UEDATX = keyboard_idle; usb_send_in(); return; } if (bRequest == HID_GET_PROTOCOL) { usb_wait_in_ready(); - UEDATX = usb_keyboard_protocol; + UEDATX = keyboard_protocol; usb_send_in(); return; } @@ -921,14 +923,18 @@ ISR(USB_COM_vect) return; } if (bRequest == HID_SET_IDLE) { - usb_keyboard_idle_config = (wValue >> 8); + keyboard_idle = (wValue >> 8); usb_keyboard_idle_count = 0; //usb_wait_in_ready(); usb_send_in(); return; } if (bRequest == HID_SET_PROTOCOL) { - usb_keyboard_protocol = wValue; + keyboard_protocol = wValue; +#ifdef NKRO_ENABLE + keyboard_nkro = !!keyboard_protocol; +#endif + clear_keyboard(); //usb_wait_in_ready(); usb_send_in(); return; diff --git a/protocol/pjrc/usb_keyboard.c b/protocol/pjrc/usb_keyboard.c index de798fcc..d1683318 100644 --- a/protocol/pjrc/usb_keyboard.c +++ b/protocol/pjrc/usb_keyboard.c @@ -34,12 +34,12 @@ // protocol setting from the host. We use exactly the same report // either way, so this variable only stores the setting since we // are required to be able to report which setting is in use. -uint8_t usb_keyboard_protocol=1; +uint8_t keyboard_protocol=1; // the idle configuration, how often we send the report to the // host (ms * 4) even when it hasn't changed // Windows and Linux set 0 while OS X sets 6(24ms) by SET_IDLE request. -uint8_t usb_keyboard_idle_config=125; +uint8_t keyobard_idle=125; // count until idle timeout uint8_t usb_keyboard_idle_count=0; @@ -61,10 +61,7 @@ int8_t usb_keyboard_send_report(report_keyboard_t *report) else #endif { - if (usb_keyboard_protocol) - result = send_report(report, KBD_ENDPOINT, 0, KBD_SIZE); - else - result = send_report(report, KBD_ENDPOINT, 0, 6); + result = send_report(report, KBD_ENDPOINT, 0, KBD_SIZE); } if (result) return result; diff --git a/protocol/pjrc/usb_keyboard.h b/protocol/pjrc/usb_keyboard.h index c362ca3b..9b798e9a 100644 --- a/protocol/pjrc/usb_keyboard.h +++ b/protocol/pjrc/usb_keyboard.h @@ -30,8 +30,6 @@ #include "host.h" -extern uint8_t usb_keyboard_protocol; -extern uint8_t usb_keyboard_idle_config; extern uint8_t usb_keyboard_idle_count; extern volatile uint8_t usb_keyboard_leds;