Merge remote-tracking branch 'tmk/master'
This commit is contained in:
commit
2ac00aa8a1
96 changed files with 15031 additions and 7760 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -1,3 +1,3 @@
|
|||
[submodule "tmk_core/protocol/usb_hid/USB_Host_Shield_2.0-git"]
|
||||
path = tmk_core/protocol/usb_hid/USB_Host_Shield_2.0-git
|
||||
url = https://github.com/felis/USB_Host_Shield_2.0.git
|
||||
[submodule "tmk_core/protocol/usb_hid/USB_Host_Shield_2.0-tmk"]
|
||||
path = tmk_core/protocol/usb_hid/USB_Host_Shield_2.0-tmk
|
||||
url = https://github.com/tmk/USB_Host_Shield_2.0.git
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
ADB keyboard handle id
|
||||
======================
|
||||
0x01 Apple Standard keyboard M0116 ANSI
|
||||
0x01 Apple Desktop Bus keyboard 658-4081 ANSI
|
||||
0x02 Apple Extended Keyboard M0115 ANSI
|
||||
0x02 Apple Extended Keyboard II M3501 ANSI
|
||||
0x03 Logical id for Extended Protocol
|
||||
0x10 Apple Adjustable keyboard M1242 ANSI
|
||||
|
||||
|
||||
Adjustable Keyboard media key
|
||||
=============================
|
||||
Media key part has different address than the main keyboard(0x02).
|
||||
|
||||
Device Address: 0x07(Appliances/Misc devices)
|
||||
Handler ID: 0x02
|
||||
|
||||
Scan Codes
|
||||
----------
|
||||
Media key ADB Code Code in Matix
|
||||
-----------------------------------------
|
||||
Volume Up: 0x03 0x48
|
||||
Volume Down: 0x02 0x49
|
||||
Mute: 0x01 0x4a
|
||||
Mic: 0x00 0x42
|
||||
|
||||
As for these keys raw ADB codes are translate into logical codes in matrix.
|
||||
|
|
@ -9,7 +9,6 @@ TARGET_DIR ?= .
|
|||
|
||||
# project specific files
|
||||
SRC ?= matrix.c \
|
||||
led.c \
|
||||
adb.c
|
||||
|
||||
CONFIG_H = config.h
|
||||
|
|
@ -64,26 +63,27 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
|||
# Atmel DFU loader 4096 for TMK Converter rev.1/rev.2
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
BOOTLOADER_SIZE ?= 4096
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=$(BOOTLOADER_SIZE)
|
||||
|
||||
|
||||
# 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
|
||||
ADB_MOUSE_ENABLE = yes
|
||||
#UNIMAP_ENABLE = yes
|
||||
#ACTIONMAP_ENABLE = yes # Use 16bit actionmap instead of 8bit keymap
|
||||
#KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor
|
||||
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE ?= yes # Console for debug(+400)
|
||||
COMMAND_ENABLE ?= yes # Commands for debug and configuration
|
||||
NKRO_ENABLE ?= no # USB Nkey Rollover
|
||||
ADB_MOUSE_ENABLE ?= yes # ADB Mouse support
|
||||
UNIMAP_ENABLE ?= yes # Use unimap
|
||||
ACTIONMAP_ENABLE ?= no # Use 16bit actionmap instead of 8bit keymap
|
||||
KEYMAP_SECTION_ENABLE ?= yes # fixed address keymap for keymap editor
|
||||
|
||||
# ADB Mice need acceleration for todays much bigger screens.
|
||||
OPT_DEFS += -DADB_MOUSE_MAXACC=8
|
||||
ADB_MOUSE_MAXACC ?= 8
|
||||
OPT_DEFS += -DADB_MOUSE_MAXACC=$(ADB_MOUSE_MAXACC)
|
||||
|
||||
|
||||
# Optimize size but this may cause error "relocation truncated to fit"
|
||||
|
|
@ -93,10 +93,10 @@ OPT_DEFS += -DADB_MOUSE_MAXACC=8
|
|||
#
|
||||
# Keymap file
|
||||
#
|
||||
ifdef UNIMAP_ENABLE
|
||||
ifeq (yes,$(strip $(UNIMAP_ENABLE)))
|
||||
KEYMAP_FILE = unimap
|
||||
else
|
||||
ifdef ACTIONMAP_ENABLE
|
||||
ifeq (yes,$(strip $(ACTIONMAP_ENABLE)))
|
||||
KEYMAP_FILE = actionmap
|
||||
else
|
||||
KEYMAP_FILE = keymap
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
TARGET = adb_usb_rev1_unimap
|
||||
UNIMAP_ENABLE = yes
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
MCU = atmega32u4
|
||||
include Makefile
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
TARGET = adb_usb_rev2_unimap
|
||||
UNIMAP_ENABLE = yes
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
MCU = atmega32u2
|
||||
include Makefile
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
ADB to USB keyboard converter
|
||||
=============================
|
||||
This firmware converts Apple ADB keyboard protocol to USB, you can use it to plug old ADB keyboard into modern computer. It works on TMK ADB-USB Converter, PJRC Teensy2.0 and other USB AVR MCU(ATMega32U4, AT90USB64/128 or etc) and needs more than 10KB flash at least.
|
||||
This firmware converts Apple ADB keyboard/mouse protocol to USB, you can use it to plug old ADB keyboard/mouse into modern computer. It works on prebuilt TMK ADB-USB Converter or generic dev board with USB AVR MCU(ATMega32U4/2) like Teensy2.0.
|
||||
|
||||
Discuss here: http://geekhack.org/showwiki.php?title=Island:14290
|
||||
Discuss about this here: http://geekhack.org/showwiki.php?title=Island:14290
|
||||
|
||||
You can buy a TMK converter here: https://geekhack.org/index.php?topic=72052.0
|
||||
Prebuilt TMK ADB-USB converter is available here: https://geekhack.org/index.php?topic=72052.0
|
||||
|
||||
|
||||
|
||||
|
|
@ -16,18 +16,20 @@ https://github.com/tmk/tmk_keyboard/tree/master/converter/adb_usb
|
|||
Also check these when you are in trouble.
|
||||
|
||||
https://github.com/tmk/tmk_keyboard/wiki
|
||||
https://github.com/tmk/tmk_keyboard/labels/NOTE
|
||||
https://github.com/tmk/tmk_keyboard/issues
|
||||
|
||||
|
||||
Wiring
|
||||
------
|
||||
Connect ADB pins to controller just by 3 lines(Vcc, GND, Data). By default Data line uses port PD0.
|
||||
If you build this yourself you have to solder some wires.
|
||||
Connect ADB pins to controller just by 3 lines(Vcc, GND, Data) at least. By default Data line uses port PD0.
|
||||
This is not needed but you can connect PSW to PD1 optionally.
|
||||
|
||||
ADB female socket from the front:
|
||||
|
||||
,--_--.
|
||||
/ o4 3o \ 1: DATA
|
||||
| o2 1o | 2: Power SW
|
||||
| o2 1o | 2: PSW(Power SW)
|
||||
- === - 3: VCC
|
||||
`-___-' 4: GND
|
||||
|
||||
|
|
@ -36,13 +38,13 @@ https://github.com/tmk/tmk_keyboard/wiki/FAQ#pull-up-resistor
|
|||
|
||||
Pull-up resister:
|
||||
|
||||
Keyboard Conveter
|
||||
Keyboard AVR MCU
|
||||
,------.
|
||||
5V------+------|VCC |
|
||||
| | |
|
||||
[R] | |
|
||||
| | |
|
||||
Signal--+------|PD0 |
|
||||
DATA----+------|PD0 |
|
||||
| |
|
||||
GND------------|GND |
|
||||
`------'
|
||||
|
|
@ -58,59 +60,60 @@ Build firmware and Program microcontroller
|
|||
------------------------------------------
|
||||
See [doc/build.md](../../tmk_core/doc/build.md).
|
||||
|
||||
To build firmware and program TMK Converter run these commands:
|
||||
To build firmware and program TMK ADB-USB Converter run these commands:
|
||||
|
||||
$ make -f Makefile clean
|
||||
$ make -f Makefile [KEYMAP=(plain|ansi|iso|hasu)]
|
||||
$ make -f Makefile [KEYMAP=(plain|ansi|iso|hasu)] dfu
|
||||
$ make -f Makefile [KEYMAP=yourname]
|
||||
$ make -f Makefile [KEYMAP=yourname] dfu
|
||||
|
||||
You can select keymap with optional `KEYMAP=` (plain is default). Push button on the converter before running `dfu` target.
|
||||
You can select keymap name with optional `KEYMAP=` ('plain' is default name). Push button on the converter before running `dfu` target.
|
||||
|
||||
Use **Makefile.rev1** for old TMK Converter rev.1 and **Makefile.teensy** for Teensy2.0 instead of **Makefile**. For TMK Converter rev.2 just use **Makefile**.
|
||||
|
||||
To program Teensy you can use `teensy` target:
|
||||
|
||||
$ make -f Makefile.teensy [KEYMAP=(plain|ansi|iso|hasu)] teensy
|
||||
Use **Makefile.rev1** for old TMK Converter rev.1 and Teensy2.0 instead of **Makefile**.
|
||||
|
||||
|
||||
|
||||
Keymap
|
||||
------
|
||||
You can change a keymap by editing code of keymap_[plain|ansi|iso|hasu|yours].c.
|
||||
You can change keymap by editing code of unimap_plain.c directly, or copy it to your own keymap file like unimap_yourname.c and edit the file.
|
||||
How to define the keymap is probably obvious. You can find key symbols in common/keycode.h. And see [doc/keymap.md](../../tmk_core/doc/keymap.md) for more detail.
|
||||
|
||||
|
||||
Magic command
|
||||
-------------
|
||||
To get help press `h` holding Magic key. Magic key is `Power key`.
|
||||
To get help message in hid_listen press `h` holding Magic key. Magic key is `Power key`.
|
||||
|
||||
https://github.com/tmk/tmk_keyboard/wiki#debug
|
||||
|
||||
|
||||
Locking CapsLock
|
||||
----------------
|
||||
Many of old ADB keyboards have mechanical push-lock switch for Capslock key and this converter supports the locking Capslock key by default. See README in top directory for more detail about this feature.
|
||||
Many of old ADB keyboards have mechanical push-lock switch for Capslock key and this converter supports the locking Capslock key by default. Use keycode `LCAP` instead of `CAPS` in your keymap in short. See README in top directory for more detail.
|
||||
https://github.com/tmk/tmk_keyboard/blob/master/README.md#mechanical-locking-support
|
||||
|
||||
Also you may want to remove locking pin from the push-lock switch to use capslock as a normal momentary switch.
|
||||
If you want to remap Capslock key you will have to remove locking pin or just replace with normal momentary switch. Some keyboards like Apple Adujstable keyboard use firmware-base locking with momentary switch for Capslock and remapping it won't be useful in most cases.
|
||||
|
||||
|
||||
Mouse support
|
||||
-------------
|
||||
ADB mouse support was added by @mek-apelsin on Apr,2015. It supports only one button as of now.
|
||||
https://github.com/tmk/tmk_keyboard/pull/207
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
Notes for keyboard
|
||||
------------------
|
||||
Not-extended ADB keyboards have 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 can discriminate both side
|
||||
modifiers except for GUI key(Windows/Command).
|
||||
|
||||
And most ADB keyboard has no diodes in its matrix so they are not NKRO,
|
||||
though ADB protocol itself supports it. See protocol/adb.c for more info.
|
||||
And most of ADB keyboards have no diodes in its matrix so they are not NKRO unfortunately,
|
||||
though ADB protocol itself supports it. See tmk_core/protocol/adb.c for more info.
|
||||
|
||||
If keyboard has ISO layout you may have swapped keys problem, see this for the detail.
|
||||
|
||||
https://github.com/tmk/tmk_keyboard/issues/35
|
||||
Notes for mouse
|
||||
---------------
|
||||
ADB mouse support was added by @mek-apelsin on Apr,2015.
|
||||
https://github.com/tmk/tmk_keyboard/pull/207
|
||||
|
||||
All one-button mouses should be supported.
|
||||
|
||||
As of 2019 June, the converter can handle multi-button mice and trackball up to eight buttons if the pointing device supports Apple Extended Mouse protocol. But some devices use their own specific protocol unfortunately and they will work as one-button mouse unless device specific code is added.
|
||||
|
||||
Kensington Turbo Mouse 5(#64210) is supported now.
|
||||
https://github.com/tmk/tmk_keyboard/issues/274#issuecomment-504726633
|
||||
|
||||
EOF
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <util/delay.h>
|
||||
#include "adb.h"
|
||||
#include "led.h"
|
||||
|
||||
|
||||
void led_set(uint8_t usb_led)
|
||||
{
|
||||
adb_host_kbd_led(ADB_ADDR_KEYBOARD, ~usb_led);
|
||||
}
|
||||
|
|
@ -21,7 +21,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "print.h"
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
|
|
@ -31,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "host.h"
|
||||
#include "led.h"
|
||||
#include "timer.h"
|
||||
#include "wait.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -38,31 +38,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
static bool has_media_keys = false;
|
||||
static bool is_iso_layout = false;
|
||||
|
||||
#if ADB_MOUSE_ENABLE
|
||||
#define dmprintf(fmt, ...) do { if (debug_mouse) xprintf(fmt, ##__VA_ARGS__); } while (0)
|
||||
static uint16_t mouse_cpi = 100;
|
||||
static void mouse_init(uint8_t addr);
|
||||
#endif
|
||||
|
||||
// matrix state buffer(1:on, 0:off)
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
|
||||
static void register_key(uint8_t key);
|
||||
|
||||
static void device_scan(void)
|
||||
{
|
||||
xprintf("\nScan:\n");
|
||||
for (uint8_t addr = 0; addr < 16; addr++) {
|
||||
uint16_t reg3 = adb_host_talk(addr, ADB_REG_3);
|
||||
if (reg3) {
|
||||
xprintf(" addr:%d, reg3:%04X\n", addr, reg3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_init(void)
|
||||
{
|
||||
debug_enable = true;
|
||||
//debug_matrix = true;
|
||||
//debug_keyboard = true;
|
||||
//debug_mouse = true;
|
||||
|
||||
// LED on
|
||||
DDRD |= (1<<6); PORTD |= (1<<6);
|
||||
|
||||
adb_host_init();
|
||||
// wait for keyboard to boot up and receive command
|
||||
_delay_ms(2000);
|
||||
|
||||
// device scan
|
||||
xprintf("Before init:\n");
|
||||
for (uint8_t addr = 1; addr < 16; addr++) {
|
||||
uint16_t reg3 = adb_host_talk(addr, ADB_REG_3);
|
||||
if (reg3) {
|
||||
xprintf("Scan: addr:%d, reg3:%04X\n", addr, reg3);
|
||||
}
|
||||
_delay_ms(20);
|
||||
}
|
||||
// wait for line and device to be stable
|
||||
wait_ms(100);
|
||||
|
||||
device_scan();
|
||||
|
||||
//
|
||||
// Keyboard
|
||||
//
|
||||
xprintf("\nKeyboard:\n");
|
||||
// Determine ISO keyboard by handler id
|
||||
// http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L815
|
||||
uint8_t handler_id = (uint8_t) adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_3);
|
||||
|
|
@ -76,47 +94,169 @@ void matrix_init(void)
|
|||
is_iso_layout = false;
|
||||
break;
|
||||
}
|
||||
xprintf("hadler_id: %02X, is_iso_layout: %s\n", handler_id, (is_iso_layout ? "yes" : "no"));
|
||||
xprintf("hadler: %02X, ISO: %s\n", handler_id, (is_iso_layout ? "yes" : "no"));
|
||||
|
||||
// Adjustable keyboard media keys: address=0x07 and handlerID=0x02
|
||||
has_media_keys = (0x02 == (adb_host_talk(ADB_ADDR_APPLIANCE, ADB_REG_3) & 0xff));
|
||||
if (has_media_keys) {
|
||||
xprintf("Found: media keys\n");
|
||||
xprintf("Media keys\n");
|
||||
}
|
||||
|
||||
// Enable keyboard left/right modifier distinction
|
||||
// Listen Register3
|
||||
// upper byte: reserved bits 0000, keyboard address 0010
|
||||
// lower byte: device handler 00000011
|
||||
adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_3, ADB_ADDR_KEYBOARD, ADB_HANDLER_EXTENDED_PROTOCOL);
|
||||
adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_3, ADB_ADDR_KEYBOARD, ADB_HANDLER_EXTENDED_KEYBOARD);
|
||||
|
||||
// device scan
|
||||
xprintf("After init:\n");
|
||||
for (uint8_t addr = 1; addr < 16; addr++) {
|
||||
uint16_t reg3 = adb_host_talk(addr, ADB_REG_3);
|
||||
if (reg3) {
|
||||
xprintf("Scan: addr:%d, reg3:%04X\n", addr, reg3);
|
||||
}
|
||||
_delay_ms(20);
|
||||
}
|
||||
|
||||
//
|
||||
// Mouse
|
||||
//
|
||||
// https://developer.apple.com/library/archive/technotes/hw/hw_01.html#Extended
|
||||
#ifdef ADB_MOUSE_ENABLE
|
||||
xprintf("\nMouse:\n");
|
||||
|
||||
// Check device on addr3
|
||||
mouse_init(ADB_ADDR_MOUSE);
|
||||
#endif
|
||||
|
||||
device_scan();
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
|
||||
|
||||
led_set(host_keyboard_leds());
|
||||
|
||||
debug_enable = true;
|
||||
//debug_matrix = true;
|
||||
//debug_keyboard = true;
|
||||
//debug_mouse = true;
|
||||
print("debug enabled.\n");
|
||||
|
||||
// LED off
|
||||
DDRD |= (1<<6); PORTD &= ~(1<<6);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ADB_MOUSE_ENABLE
|
||||
static void mouse_init(uint8_t orig_addr)
|
||||
{
|
||||
uint16_t reg3;
|
||||
uint8_t mouse_handler;
|
||||
uint8_t addr;
|
||||
|
||||
again:
|
||||
mouse_handler = (reg3 = adb_host_talk(orig_addr, ADB_REG_3)) & 0xFF;
|
||||
if (!reg3) return;
|
||||
dmprintf("addr%d reg3: %02X\n", orig_addr, reg3);
|
||||
|
||||
// Move device to tmp address
|
||||
adb_host_flush(orig_addr);
|
||||
adb_host_listen(orig_addr, ADB_REG_3, ((reg3 >> 8) & 0xF0) | ADB_ADDR_TMP, 0xFE);
|
||||
adb_host_flush(ADB_ADDR_TMP);
|
||||
|
||||
mouse_handler = (reg3 = adb_host_talk(ADB_ADDR_TMP, ADB_REG_3)) & 0xFF;
|
||||
if (!reg3) {
|
||||
dmprintf("move fail\n");
|
||||
goto again;
|
||||
}
|
||||
addr = ADB_ADDR_TMP;
|
||||
dmprintf("addr%d reg3: %02X\n", addr, reg3);
|
||||
|
||||
|
||||
detect_again:
|
||||
if (mouse_handler == ADB_HANDLER_CLASSIC1_MOUSE || mouse_handler == ADB_HANDLER_CLASSIC2_MOUSE) {
|
||||
adb_host_flush(addr);
|
||||
adb_host_listen(addr, ADB_REG_3, (reg3 >> 8), ADB_HANDLER_EXTENDED_MOUSE);
|
||||
|
||||
mouse_handler = (reg3 = adb_host_talk(addr, ADB_REG_3)) & 0xFF;
|
||||
|
||||
|
||||
if (mouse_handler == ADB_HANDLER_CLASSIC1_MOUSE) {
|
||||
adb_host_flush(addr);
|
||||
adb_host_listen(addr, ADB_REG_3, (reg3 >> 8), ADB_HANDLER_CLASSIC2_MOUSE);
|
||||
|
||||
mouse_handler = (reg3 = adb_host_talk(addr, ADB_REG_3)) & 0xFF;
|
||||
}
|
||||
|
||||
if (mouse_handler == ADB_HANDLER_CLASSIC1_MOUSE) {
|
||||
xprintf("Classic 100cpi\n");
|
||||
mouse_cpi = 100;
|
||||
}
|
||||
if (mouse_handler == ADB_HANDLER_CLASSIC2_MOUSE) {
|
||||
xprintf("Classic 200cpi\n");
|
||||
mouse_cpi = 200;
|
||||
}
|
||||
}
|
||||
|
||||
// Extended Mouse Protocol
|
||||
if (mouse_handler == ADB_HANDLER_EXTENDED_MOUSE) {
|
||||
// Device info format(reg1 8-byte data)
|
||||
// 0-3: device id
|
||||
// 4-5: resolution in units/inch (0xC8=200upi)
|
||||
// 6 : device class (0: Tablet, 1: Mouse, 2: Trackball)
|
||||
// 7 : num of buttons
|
||||
uint8_t len;
|
||||
uint8_t buf[8];
|
||||
len = adb_host_talk_buf(addr, ADB_REG_1, buf, sizeof(buf));
|
||||
|
||||
if (len > 5) {
|
||||
mouse_cpi = (buf[4]<<8) | buf[5];
|
||||
} else {
|
||||
mouse_cpi = 100;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
xprintf("Ext: [", len);
|
||||
for (int8_t i = 0; i < len; i++) xprintf("%02X ", buf[i]);
|
||||
xprintf("] cpi=%d\n", mouse_cpi);
|
||||
}
|
||||
|
||||
|
||||
// Kensington Turbo Mouse 5: default device
|
||||
if (buf[0] == 0x4B && buf[1] == 0x4D && buf[2] == 0x4C && buf[3] == 0x31) {
|
||||
xprintf("TM5: default\n");
|
||||
// Move it to addr0 to remove this device and get new device with handle id 50 on addr 3
|
||||
// and the new device on address 3 should be handled with command sequence later.
|
||||
//
|
||||
// Turbo Mouse 5 has one default device on addr3 as normal mouse at first, and another device
|
||||
// with hander id 50 appears after the default device is moved from addr3.
|
||||
// The mouse has the two devices at same time transiently in the result. The default device is
|
||||
// removed automatically after the another device receives command sequence.
|
||||
// NOTE: The mouse hangs if you try moving the two deivces to same address.
|
||||
adb_host_flush(addr);
|
||||
adb_host_listen(addr, ADB_REG_3, ((reg3 >> 8) & 0xF0) | ADB_ADDR_0, 0xFE);
|
||||
} else {
|
||||
xprintf("Unknown\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse_handler == ADB_HANDLER_TURBO_MOUSE) {
|
||||
xprintf("TM5: ext\n");
|
||||
|
||||
// Kensington Turbo Mouse 5 command sequence to enable four buttons
|
||||
// https://elixir.bootlin.com/linux/v4.4/source/drivers/macintosh/adbhid.c#L1176
|
||||
// https://github.com/NetBSD/src/blob/64b8a48e1288eb3902ed73113d157af50b2ec596/sys/arch/macppc/dev/ams.c#L261
|
||||
static uint8_t cmd1[] = { 0xE7, 0x8C, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x94 };
|
||||
static uint8_t cmd2[] = { 0xA5, 0x14, 0x00, 0x00, 0x69, 0xFF, 0xFF, 0x27 };
|
||||
|
||||
adb_host_flush(addr);
|
||||
adb_host_listen_buf(addr, ADB_REG_2, cmd1, sizeof(cmd1));
|
||||
adb_host_flush(addr);
|
||||
adb_host_listen_buf(addr, ADB_REG_2, cmd2, sizeof(cmd2));
|
||||
}
|
||||
|
||||
|
||||
// Move all mouses to a address after init to be polled
|
||||
adb_host_flush(addr);
|
||||
adb_host_listen(addr, ADB_REG_3, ((reg3 >> 8) & 0xF0) | ADB_ADDR_MOUSE_POLL, 0xFE);
|
||||
adb_host_flush(ADB_ADDR_MOUSE_POLL);
|
||||
|
||||
mouse_handler = (reg3 = adb_host_talk(addr, ADB_REG_3)) & 0xFF;
|
||||
if (reg3) {
|
||||
dmprintf("detect again\n");
|
||||
goto detect_again;
|
||||
}
|
||||
|
||||
goto again;
|
||||
|
||||
// dmprintf("handler: %d\n", mouse_handler);
|
||||
// dmprintf("cpi: %d\n", mouse_cpi);
|
||||
}
|
||||
|
||||
#ifdef MAX
|
||||
#undef MAX
|
||||
|
|
@ -127,7 +267,8 @@ static report_mouse_t mouse_report = {};
|
|||
|
||||
void adb_mouse_task(void)
|
||||
{
|
||||
uint16_t codes;
|
||||
uint8_t len;
|
||||
uint8_t buf[5];
|
||||
int16_t x, y;
|
||||
static int8_t mouseacc;
|
||||
|
||||
|
|
@ -138,47 +279,92 @@ void adb_mouse_task(void)
|
|||
if (timer_elapsed(tick_ms) < 12) return;
|
||||
tick_ms = timer_read();
|
||||
|
||||
codes = adb_host_mouse_recv();
|
||||
static uint16_t detect_ms;
|
||||
if (timer_elapsed(detect_ms) > 1000) {
|
||||
detect_ms = timer_read();
|
||||
// check new device on addr3
|
||||
mouse_init(ADB_ADDR_MOUSE);
|
||||
}
|
||||
|
||||
// Extended Mouse Protocol data can be 2-5 bytes
|
||||
// https://developer.apple.com/library/archive/technotes/hw/hw_01.html#Extended
|
||||
//
|
||||
// Byte 0: b00 y06 y05 y04 y03 y02 y01 y00
|
||||
// Byte 1: b01 x06 x05 x04 x03 x02 x01 x00
|
||||
// Byte 2: b02 y09 y08 y07 b03 x09 x08 x07
|
||||
// Byte 3: b04 y12 y11 y10 b05 x12 x11 x10
|
||||
// Byte 4: b06 y15 y14 y13 b07 x15 x14 x13
|
||||
//
|
||||
// b--: Button state.(0: on, 1: off)
|
||||
// x--: X axis movement.
|
||||
// y--: Y axis movement.
|
||||
len = adb_host_talk_buf(ADB_ADDR_MOUSE_POLL, ADB_REG_0, buf, sizeof(buf));
|
||||
|
||||
// If nothing received reset mouse acceleration, and quit.
|
||||
if (!codes) {
|
||||
if (len < 2) {
|
||||
mouseacc = 1;
|
||||
return;
|
||||
};
|
||||
// Bit sixteen is button.
|
||||
if (~codes & (1 << 15))
|
||||
mouse_report.buttons |= MOUSE_BTN1;
|
||||
if (codes & (1 << 15))
|
||||
mouse_report.buttons &= ~MOUSE_BTN1;
|
||||
// lower seven bits are movement, as signed int_7.
|
||||
// low byte is X-axis, high byte is Y.
|
||||
y = (codes>>8 & 0x3F);
|
||||
x = (codes>>0 & 0x3F);
|
||||
// bit seven and fifteen is negative
|
||||
// usb does not use int_8, but int_7 (measuring distance) with sign-bit.
|
||||
if (codes & (1 << 6))
|
||||
x = (x-0x40);
|
||||
if (codes & (1 << 14))
|
||||
y = (y-0x40);
|
||||
|
||||
// Store off-buttons and 0-movements in unused bytes
|
||||
bool xneg = false;
|
||||
bool yneg = false;
|
||||
if (len == 2) {
|
||||
if (buf[0] & 0x40) yneg = true;
|
||||
if (buf[1] & 0x40) xneg = true;
|
||||
} else {
|
||||
if (buf[len - 1] & 0x40) yneg = true;
|
||||
if (buf[len - 1] & 0x04) xneg = true;
|
||||
}
|
||||
|
||||
for (int8_t i = len; i < sizeof(buf); i++) {
|
||||
buf[i] = 0x88;
|
||||
if (yneg) buf[i] |= 0x70;
|
||||
if (xneg) buf[i] |= 0x07;
|
||||
}
|
||||
|
||||
// 8 buttons at max
|
||||
// TODO: Fix HID report descriptor for mouse to support button6-8
|
||||
uint8_t buttons = 0;
|
||||
if (!(buf[4] & 0x08)) buttons |= MOUSE_BTN8;
|
||||
if (!(buf[4] & 0x80)) buttons |= MOUSE_BTN7;
|
||||
if (!(buf[3] & 0x08)) buttons |= MOUSE_BTN6;
|
||||
if (!(buf[3] & 0x80)) buttons |= MOUSE_BTN5;
|
||||
if (!(buf[2] & 0x08)) buttons |= MOUSE_BTN4;
|
||||
if (!(buf[2] & 0x80)) buttons |= MOUSE_BTN3;
|
||||
if (!(buf[1] & 0x80)) buttons |= MOUSE_BTN2;
|
||||
if (!(buf[0] & 0x80)) buttons |= MOUSE_BTN1;
|
||||
mouse_report.buttons = buttons;
|
||||
|
||||
int16_t xx, yy;
|
||||
yy = (buf[0] & 0x7F) | (buf[2] & 0x70) << 3 | (buf[3] & 0x70) << 6 | (buf[4] & 0x70) << 9;
|
||||
xx = (buf[1] & 0x7F) | (buf[2] & 0x07) << 7 | (buf[3] & 0x07) << 10 | (buf[4] & 0x07) << 13;
|
||||
|
||||
// Accelerate mouse. (They weren't meant to be used on screens larger than 320x200).
|
||||
x *= mouseacc;
|
||||
y *= mouseacc;
|
||||
x = xx * mouseacc;
|
||||
y = yy * mouseacc;
|
||||
|
||||
// TODO: Fix HID report descriptor for mouse to support finer resolution
|
||||
// Cap our two bytes per axis to one byte.
|
||||
// Easier with a MIN-function, but since -MAX(-a,-b) = MIN(a,b)...
|
||||
// I.E. MIN(MAX(x,-127),127) = -MAX(-MAX(x, -127), -127) = MIN(-MIN(-x,127),127)
|
||||
// I.E. MIN(MAX(x,-127),127) = -MAX(-MAX(x, -127), -127) = MIN(-MIN(-x,127),127)
|
||||
mouse_report.x = -MAX(-MAX(x, -127), -127);
|
||||
mouse_report.y = -MAX(-MAX(y, -127), -127);
|
||||
|
||||
if (debug_mouse) {
|
||||
print("adb_host_mouse_recv: "); print_bin16(codes); print("\n");
|
||||
print("adb_mouse raw: [");
|
||||
phex(mouseacc); print(" ");
|
||||
phex(mouse_report.buttons); print("|");
|
||||
print_decs(mouse_report.x); print(" ");
|
||||
print_decs(mouse_report.y); print("]\n");
|
||||
xprintf("Mouse: [");
|
||||
for (int8_t i = 0; i < len; i++) xprintf("%02X ", buf[i]);
|
||||
xprintf("] ");
|
||||
xprintf("[B:%02X, X:%d(%d), Y:%d(%d), A:%d]\n", mouse_report.buttons, mouse_report.x, xx, mouse_report.y, yy, mouseacc);
|
||||
}
|
||||
|
||||
// Send result by usb.
|
||||
host_mouse_send(&mouse_report);
|
||||
|
||||
// TODO: acceleration curve is needed for precise operation?
|
||||
// increase acceleration of mouse
|
||||
mouseacc += ( mouseacc < ADB_MOUSE_MAXACC ? 1 : 0 );
|
||||
mouseacc += ( mouseacc < (mouse_cpi < 200 ? ADB_MOUSE_MAXACC : ADB_MOUSE_MAXACC/2) ? 1 : 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -265,12 +451,14 @@ uint8_t matrix_scan(void)
|
|||
register_key(0x7F);
|
||||
} else if (codes == 0xFFFF) { // power key release
|
||||
register_key(0xFF);
|
||||
} else if (key0 == 0xFF) { // error
|
||||
xprintf("adb_host_kbd_recv: ERROR(%d)\n", codes);
|
||||
// something wrong or plug-in
|
||||
matrix_init();
|
||||
return key1;
|
||||
} else {
|
||||
// Macally keyboard sends keys inversely against ADB protocol
|
||||
// https://deskthority.net/workshop-f7/macally-mk96-t20116.html
|
||||
if (key0 == 0xFF) {
|
||||
key0 = key1;
|
||||
key1 = 0xFF;
|
||||
}
|
||||
|
||||
/* Swap codes for ISO keyboard
|
||||
* https://github.com/tmk/tmk_keyboard/issues/35
|
||||
*
|
||||
|
|
@ -337,3 +525,8 @@ static void register_key(uint8_t key)
|
|||
matrix[row] |= (1<<col);
|
||||
}
|
||||
}
|
||||
|
||||
void led_set(uint8_t usb_led)
|
||||
{
|
||||
adb_host_kbd_led(ADB_ADDR_KEYBOARD, ~usb_led);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -243,50 +243,3 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
ADB ANSI/ISO Keymapping Note
|
||||
============================
|
||||
ANSI
|
||||
,----------- ----------.
|
||||
| *a| 1| 2 =|Backspa|
|
||||
|----------- ----------|
|
||||
|Tab | Q| | ]| *c|
|
||||
|----------- ----------|
|
||||
|CapsLo| A| '|Return |
|
||||
|----------- ----------|
|
||||
|Shift | Shift |
|
||||
`----------- ----------'
|
||||
|
||||
ISO
|
||||
,----------- ----------.
|
||||
| *a| 1| 2 =|Backspa|
|
||||
|----------- ----------|
|
||||
|Tab | Q| | ]|Retur|
|
||||
|----------- -----` |
|
||||
|CapsLo| A| '| *c| |
|
||||
|----------- ----------|
|
||||
|Shif| *b| Shift |
|
||||
`----------- ----------'
|
||||
|
||||
ADB Keyboard scan code:
|
||||
ADB scan code USB usage
|
||||
------------- ---------
|
||||
Key ANSI ISO ANSI ISO
|
||||
---------------------------------------------
|
||||
*a 0x32 0x0A 0x35 0x35
|
||||
*b ---- 0x32 ---- 0x64
|
||||
*c 0x2A 0x2A 0x31 0x31(or 0x32)
|
||||
|
||||
|
||||
TMK ADB-USB mapping:
|
||||
ADB USB(ANSI) USB(ISO)
|
||||
---------------------------------
|
||||
0x32 0x35 0x64
|
||||
0x0A ---- 0x35
|
||||
0x2A 0x31 0x31(or 0x32)
|
||||
|
||||
Note that mappings of ADB code 0x32 are diffrent between ANSI and ISO keyboard.
|
||||
https://github.com/tmk/tmk_keyboard/issues/35
|
||||
*/
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016 Jun Wako <wakojun@gmail.com>
|
||||
Copyright 2016-19 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -22,26 +22,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "unimap.h"
|
||||
|
||||
|
||||
/* Apple Extended Keyboard Common layout: ANSI+ISO
|
||||
* ,---. .---------------. ,---------------. ,---------------. ,-----------. ,---------------.
|
||||
* |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |VDn|VUp|Mut|F24|
|
||||
* `---' `---------------' `---------------' `---------------' `-----------' `---------------'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| =| /| *|
|
||||
* |-----------------------------------------------------------| |-----------| |---------------|
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| -|
|
||||
* |-----------------------------------------------------------| `-----------' |---------------|
|
||||
* |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| +|
|
||||
* |-----------------------------------------------------------| ,---. |---------------|
|
||||
/* ADB Keyboard unified layout
|
||||
* ,---. .---------------. ,---------------. ,---------------. ,-----------. ,---.
|
||||
* |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|
|
||||
* `---' `---------------' `---------------' `---------------' `-----------' `---'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------. ,---.
|
||||
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| =| /| *| |VUp|
|
||||
* |-----------------------------------------------------------| |-----------| |---------------| |---|
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| -| |VDn|
|
||||
* |-----------------------------------------------------------| `-----------' |---------------| |---|
|
||||
* |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| +| |Mut|
|
||||
* |-----------------------------------------------------------| ,---. |---------------| `---'
|
||||
* |Shif|\ | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
|
||||
* |-----------------------------------------------------------| ,-----------. |-----------|Ent|
|
||||
* |Ctrl |Alt |Gui | Space |Gui |Alt |Ctrl | |Lef|Dow|Rig| | 0| .| |
|
||||
* `-----------------------------------------------------------' `-----------' `---------------'
|
||||
* Command = Gui
|
||||
* Option = Alt
|
||||
* Power key = F24
|
||||
* Mic = F13(Adjustable keyboard)
|
||||
* |-----------------------------------------------------------| ,-----------. |-----------|Ent| ,---.
|
||||
* |Ctrl |Opt |Gui | Space |Gui* |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| | |Ply|
|
||||
* `-----------------------------------------------------------' `-----------' `---------------' `---'
|
||||
* NOTE: Not-extended ADB keyboards have no discrimination between left and right modifiers.
|
||||
* Use left ones for mapping. Right modifier always sends same code as left one.
|
||||
* Apple Extended Keyboard can discriminate the modifiers except for Command(GUI) key.
|
||||
*/
|
||||
#define UNIMAP_ADB( \
|
||||
K29, K3A,K3B,K3C,K3D,K3E,K3F,K40,K41,K42,K43,K44,K45, K46,K47,K48, K73, \
|
||||
K35,K1E,K1F,K20,K21,K22,K23,K24,K25,K26,K27,K2D,K2E, K2A, K49,K4A,K4B, K53,K54,K55,K56, K02, \
|
||||
K2B,K14,K1A,K08,K15,K17,K1C,K18,K0C,K12,K13,K2F,K30, K31, K4C,K4D,K4E, K5F,K60,K61,K57, K01, \
|
||||
K39,K04,K16,K07,K09,K0A,K0B,K0D,K0E,K0F,K33,K34, K32,K28, K5C,K5D,K5E,K66, K03, \
|
||||
K79,K64,K1D,K1B,K06,K19,K05,K11,K10,K36,K37,K38, K7D, K52, K59,K5A,K5B,K58, \
|
||||
K78,K7A,K7B, K2C, K7E,K7C, K50,K51,K4F, K62,K63, K68 \
|
||||
) UNIMAP( \
|
||||
K68, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, K73, \
|
||||
K29, K3A, K3B, K3C, K3D, K3E, K3F, K40, K41, K42, K43, K44, K45, K46, K47, K48, K01, K02, K03, \
|
||||
K35, K1E, K1F, K20, K21, K22, K23, K24, K25, K26, K27, K2D, K2E, JYEN,K2A, K49, K4A, K4B, K53, K54, K55, K56, \
|
||||
K2B, K14, K1A, K08, K15, K17, K1C, K18, K0C, K12, K13, K2F, K30, K31, K4C, K4D, K4E, K5F, K60, K61, K57, \
|
||||
K39, K04, K16, K07, K09, K0A, K0B, K0D, K0E, K0F, K33, K34, K32, K28, K5C, K5D, K5E, K66, \
|
||||
K79, K64, K1D, K1B, K06, K19, K05, K11, K10, K36, K37, K38, RO, K7D, K52, K59, K5A, K5B, K58, \
|
||||
K78, K7B, K7A, MHEN, K2C, HENK,KANA,K7E, RGUI,APP, K7C, K50, K51, K4F, K62, K63, PEQL \
|
||||
)
|
||||
|
||||
|
||||
// http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c
|
||||
// http://opensource.apple.com//source/IOHIDFamily/IOHIDFamily-701.20.10/IOHIDFamily/Cosmo_USB2ADB.c
|
||||
// http://m0115.web.fc2.com/m0115.jpg
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016 Jun Wako <wakojun@gmail.com>
|
||||
Copyright 2016-19 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
#define AC_FN0 ACTION_LAYER_TAP_KEY(1, KC_GRV)
|
||||
#define AC_FN1 ACTION_LAYER_TAP_KEY(1, KC_BSLS)
|
||||
#define AC_FN1 ACTION_LAYER_TAP_KEY(2, KC_BSLS)
|
||||
#define AC_PKEY ACTION_MODS_TAP_KEY(MOD_NONE, KC_POWER)
|
||||
|
||||
#ifdef KEYMAP_SECTION_ENABLE
|
||||
|
|
@ -26,22 +26,81 @@ const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] __attribute__ ((section ("
|
|||
#else
|
||||
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
|
||||
#endif
|
||||
UNIMAP(
|
||||
MPLY,NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, PKEY,
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, VOLD,VOLU,MUTE,
|
||||
FN0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, NO, BSPC, INS, HOME,PGUP, NLCK,PEQL,PSLS,PAST,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, FN1, DEL, END, PGDN, P7, P8, P9, PMNS,
|
||||
LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, P4, P5, P6, PPLS,
|
||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, NO, RSFT, UP, P1, P2, P3, PENT,
|
||||
LCTL,LGUI,LALT,NO, SPC, NO, NO, RALT,RGUI,NO, RCTL, LEFT,DOWN,RGHT, P0, PDOT,NO
|
||||
/* ADB Keyboard unified layout
|
||||
* ,---. .---------------. ,---------------. ,---------------. ,-----------. ,---.
|
||||
* |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|
|
||||
* `---' `---------------' `---------------' `---------------' `-----------' `---'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------. ,---.
|
||||
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| =| /| *| |VUp|
|
||||
* |-----------------------------------------------------------| |-----------| |---------------| |---|
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| -| |VDn|
|
||||
* |-----------------------------------------------------------| `-----------' |---------------| |---|
|
||||
* |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|# |Retn| | 4| 5| 6| +| |Mut|
|
||||
* |-----------------------------------------------------------| ,---. |---------------| `---'
|
||||
* |Shif|\ | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
|
||||
* |-----------------------------------------------------------| ,-----------. |-----------|Ent| ,---.
|
||||
* |Ctrl |Opt |Gui | Space |Gui* |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| | |Ply|
|
||||
* `-----------------------------------------------------------' `-----------' `---------------' `---'
|
||||
* NOTE: Not-extended ADB keyboards have no discrimination between left and right modifiers.
|
||||
* Use left ones for mapping. Right modifier always sends same code as left one.
|
||||
* Apple Extended Keyboard can discriminate the modifiers except for Command(GUI) key.
|
||||
*/
|
||||
[0] = UNIMAP_ADB(
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, PKEY,
|
||||
FN0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PEQL,PSLS,PAST, VOLU,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, FN1, DEL, END, PGDN, P7, P8, P9, PMNS, VOLD,
|
||||
LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, P4, P5, P6, PPLS, MUTE,
|
||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, PENT,
|
||||
LCTL,LALT,LGUI, SPC, RALT,RCTL, LEFT,DOWN,RGHT, P0, PDOT, MPLY
|
||||
),
|
||||
UNIMAP(
|
||||
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,F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, TRNS,DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS,TRNS, PGUP, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, HOME,PGDN,END, TRNS, TRNS,TRNS
|
||||
|
||||
/*
|
||||
* ,---. .---------------. ,---------------. ,---------------. ,-----------. ,---.
|
||||
* | `| | | | | | | | | | | | | | | | | | | | | |
|
||||
* `---' `---------------' `---------------' `---------------' `-----------' `---'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------. ,---.
|
||||
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | | | | | | | | | | |
|
||||
* |-----------------------------------------------------------| |-----------| |---------------| |---|
|
||||
* | | | | | | | | |PrS|ScL|Pau|Up |INS| | | | | | | | | | | | |
|
||||
* |-----------------------------------------------------------| `-----------' |---------------| |---|
|
||||
* |CapsLo|VoD|VoU|Mut| | | | |Hom|PgU|Lef|Rig|# |Retn| | | | | | | |
|
||||
* |-----------------------------------------------------------| ,---. |---------------| `---'
|
||||
* | | | | | | | | | |End|PgD|Dow|Shift | |PgU| | | | | |
|
||||
* |-----------------------------------------------------------| ,-----------. |-----------| | ,---.
|
||||
* | | | | | | | | |Hom|PgD|End| | | | | | |
|
||||
* `-----------------------------------------------------------' `-----------' `---------------' `---'
|
||||
*/
|
||||
[1] = UNIMAP_ADB(
|
||||
GRV, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS, TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS, TRNS,
|
||||
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, TRNS,TRNS,TRNS,TRNS, TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS, PGUP, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS, HOME,PGDN,END, TRNS, TRNS, TRNS
|
||||
),
|
||||
|
||||
/*
|
||||
* ,---. .---------------. ,---------------. ,---------------. ,-----------. ,---.
|
||||
* | `| | | | | | | | | | | | | | | | | | | | | |
|
||||
* `---' `---------------' `---------------' `---------------' `-----------' `---'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------. ,---.
|
||||
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | | | | | | | | | | |
|
||||
* |-----------------------------------------------------------| |-----------| |---------------| |---|
|
||||
* | | | | | | | | |PrS|ScL|Pau|Up |INS| | | | | | | | | | | | |
|
||||
* |-----------------------------------------------------------| `-----------' |---------------| |---|
|
||||
* |CapsLo|VoD|VoU|Mut| | | | |Hom|PgU|Lef|Rig|# |Retn| | | | | | | |
|
||||
* |-----------------------------------------------------------| ,---. |---------------| `---'
|
||||
* | | | | | | | | | |End|PgD|Dow|Shift | |PgU| | | | | |
|
||||
* |-----------------------------------------------------------| ,-----------. |-----------| | ,---.
|
||||
* | | | | | | | | |Hom|PgD|End| | | | | | |
|
||||
* `-----------------------------------------------------------' `-----------' `---------------' `---'
|
||||
*/
|
||||
[2] = UNIMAP_ADB(
|
||||
GRV, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS, TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS, TRNS,
|
||||
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, TRNS,TRNS,TRNS,TRNS, TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS, PGUP, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS, HOME,PGDN,END, TRNS, TRNS, TRNS
|
||||
),
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
115
converter/ibmpc_usb/Makefile
Normal file
115
converter/ibmpc_usb/Makefile
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
# Target file name (without extension).
|
||||
TARGET ?= ibmpc_usb
|
||||
|
||||
# Directory common source filess exist
|
||||
TMK_DIR ?= ../../tmk_core
|
||||
|
||||
# Directory keyboard dependent files exist
|
||||
TARGET_DIR ?= .
|
||||
|
||||
# project specific files
|
||||
SRC ?= protocol/ibmpc.c \
|
||||
ibmpc_usb.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 ?= 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
|
||||
# Not work with suart debug
|
||||
#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
|
||||
# This improves response of keyboard when wakeup
|
||||
OPT_DEFS += -DSUSPEND_MODE_STANDBY
|
||||
|
||||
# Boot Section Size in *bytes*
|
||||
# Teensy halfKay 512
|
||||
# Teensy++ halfKay 1024
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
# Bootloader size can be calculated from fuse bits
|
||||
#BOOTLOADER_SIZE ?= 4096
|
||||
#OPT_DEFS += -DBOOTLOADER_SIZE=$(BOOTLOADER_SIZE)
|
||||
|
||||
|
||||
# Build Options
|
||||
# comment out to disable the options.
|
||||
#
|
||||
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE ?= no # 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
|
||||
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
UNIMAP_ENABLE = yes
|
||||
|
||||
|
||||
# Optimize size but this may cause error "relocation truncated to fit"
|
||||
#EXTRALDFLAGS = -Wl,--relax
|
||||
|
||||
|
||||
#
|
||||
# Keymap file
|
||||
#
|
||||
ifdef UNIMAP_ENABLE
|
||||
KEYMAP_FILE = unimap
|
||||
else
|
||||
ifdef ACTIONMAP_ENABLE
|
||||
KEYMAP_FILE = actionmap
|
||||
else
|
||||
KEYMAP_FILE = keymap
|
||||
endif
|
||||
endif
|
||||
ifdef KEYMAP
|
||||
SRC := $(KEYMAP_FILE)_$(KEYMAP).c $(SRC)
|
||||
else
|
||||
SRC := $(KEYMAP_FILE)_plain.c $(SRC)
|
||||
endif
|
||||
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TMK_DIR)
|
||||
|
||||
include $(TMK_DIR)/protocol.mk
|
||||
include $(TMK_DIR)/protocol/lufa.mk
|
||||
include $(TMK_DIR)/common.mk
|
||||
include $(TMK_DIR)/rules.mk
|
||||
4
converter/ibmpc_usb/Makefile.at90usb1286
Normal file
4
converter/ibmpc_usb/Makefile.at90usb1286
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
TARGET = ibmpc_usb_at90usb1286
|
||||
MCU = at90usb1286
|
||||
|
||||
include Makefile
|
||||
4
converter/ibmpc_usb/Makefile.atmega32u2
Normal file
4
converter/ibmpc_usb/Makefile.atmega32u2
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
TARGET = ibmpc_usb_atmega32u2
|
||||
MCU = atmega32u2
|
||||
|
||||
include Makefile
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
TARGET = adb_usb_teensy
|
||||
TARGET = ibmpc_usb_atmega32u4
|
||||
MCU = atmega32u4
|
||||
|
||||
include Makefile
|
||||
168
converter/ibmpc_usb/README.md
Normal file
168
converter/ibmpc_usb/README.md
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
IBM PC Keyboard Converter
|
||||
=========================
|
||||
The converter translates IBM PC keyboard protocols to use classic keyboards with modern computer with USB ports.
|
||||
It supports both IBM XT and AT protocols, and all of scan code set 1, 2 and 3 with one firmware.
|
||||
|
||||
This is not finish project and still work in progress as of 2019-12-02. Test in the field and feedback from users are needed to improve
|
||||
|
||||
This project is intended to integrated existent TMK XT, PS/2 and Terminal converters.
|
||||
|
||||
- IBM XT converter: https://geekhack.org/index.php?topic=94649.0
|
||||
- PS/2 converter: https://geekhack.org/index.php?topic=14618.0
|
||||
- IBM Terminal converter: http://geekhack.org/index.php?topic=27272.0
|
||||
|
||||
|
||||
|
||||
Keyboard supported
|
||||
------------------
|
||||
- PC XT keyboard of IBM 5150 5160
|
||||
- 83-key: 1501100 1501105
|
||||
- PC AT keyboard of IBM 5170
|
||||
- 84-key: 6450200 6450225
|
||||
- PC Terminal keyboard of IBM 5271(3270 PC)
|
||||
- 122-key: 6110344 6110345 1397000
|
||||
- 102-key: 1390680 1395764 1392595
|
||||
- PS/2 keyboards(AT+CodeSet2)
|
||||
- Clones of above models
|
||||
|
||||
|
||||
|
||||
Hardware
|
||||
--------
|
||||
Firmware supports ATMega32u4 and ATMega32u2 by default, Teensy2 or ProMicro can be used.
|
||||
Wire controller pins below to keyboard signals, besides VCC and GND. This is compatible for Soarer's converter.
|
||||
|
||||
- Data PD0
|
||||
- Clock PD1
|
||||
- Reset PB6 or PB7 (For some of XT keyboards. Not needed for AT, PS/2 and Terminal)
|
||||
|
||||
Pull up resistors of 1-4.7K Ohm on both Data and Clock line are recommended, without them it won't work in some cases.
|
||||
|
||||
### Reset
|
||||
Old Type-1 IBM XT keyboard and some of XT clones need this to reset its controller on startup. Many of IBM XT keyboards available are Type-2 and don't need the reset pin.
|
||||
|
||||
See this for Type-1 vs Type-2:
|
||||
https://vintagecomputer.ca/ibm-pc-model-f-keyboard-type-1-vs-type-2/
|
||||
|
||||
As for clones Zenith Z-150 XT and Leading Edge DC-2014 are known to need this.
|
||||
|
||||
### Connector pinouts
|
||||
#### XT
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibmpc.png
|
||||
- https://allpinouts.org/pinouts/connectors/input_device/keyboard-xt-5-pin/
|
||||
|
||||
#### AT
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ps2.png
|
||||
- https://old.pinouts.ru/InputCables/KeyboardPC5_pinout.shtml
|
||||
|
||||
#### PS/2
|
||||
- https://pinouts.ru/InputCables/KeyboardPC6_pinout.shtml
|
||||
|
||||
#### Terminal
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibmterm.png
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibm3179_318x_319x.png
|
||||
|
||||
|
||||
|
||||
Source Code
|
||||
-----------
|
||||
https://github.com/tmk/tmk_keyboard/tree/master/converter/ibmpc_usb
|
||||
|
||||
|
||||
|
||||
Build Firmware
|
||||
--------------
|
||||
|
||||
$ cd converter/ibmpc_usb
|
||||
$ make clean
|
||||
$ make
|
||||
|
||||
|
||||
|
||||
Keyboard discrimination
|
||||
-----------------------
|
||||
This section explains how the converter determines proper protocol and scan code set for keyboard. The converter need to do that before starting to receive and translate scan codes from keyboard.
|
||||
|
||||
### Keyboard ID
|
||||
After startup the converter sends 0xF2 command to get keyboard ID and sees how the keyboard responds to the command.
|
||||
|
||||
Response from keyboard:
|
||||
|
||||
- XT keyboard doesn't support any command and returns no response.
|
||||
- AT keyboard should respond with 0xFA to the command but returns no keyboard ID.
|
||||
- PS/2 keyboard should respond with 0xFA to the command, followd by keyboard ID, such as 0xAB86.
|
||||
- Terminal keyboard should respond with 0xFA to the command, followed by keyboard ID, such as 0xBFBF.
|
||||
|
||||
Now we can dscriminate the keyboard and determine suitable protocol and scan code set as described below.
|
||||
|
||||
### Protocol
|
||||
- Signals from XT keyboard are recognized by XT protocol.
|
||||
- Signals from AT, PS/2 and Terminal keyboard are recognized by AT protocol.
|
||||
|
||||
### Scan code Set
|
||||
- Scan codes from XT keyboard are handled as CodeSet1.
|
||||
- Scan codes from AT and PS/2 keyboard are handled as CodeSet2.
|
||||
- Scan codes from Terminal keyhboard are handled as CodeSet3.
|
||||
|
||||
|
||||
|
||||
Debug
|
||||
-----
|
||||
Use hid_listen to see debug outputs from the converter.
|
||||
|
||||
https://www.pjrc.com/teensy/hid_listen.html
|
||||
|
||||
|
||||
|
||||
Resources
|
||||
---------
|
||||
IBM PC Keyboard Protocol Resources:
|
||||
|
||||
[a] [Microsoft USB HID to PS/2 Translation Table - Scan Code Set 1 and 2](
|
||||
http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf)
|
||||
|
||||
[b] [Microsoft Keyboard Scan Code Specification - Special rules of Scan Code Set 1 and 2](
|
||||
http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc)
|
||||
|
||||
[1] [PS/2 Reference Manuals - Collection of IBM Personal System/2 documents](
|
||||
http://www.mcamafia.de/pdf/pdfref.htm)
|
||||
|
||||
[2] [Keyboard and Auxiliary Device Controller - Signal Timing and Format](
|
||||
http://www.mcamafia.de/pdf/ibm_hitrc07.pdf)
|
||||
|
||||
[3] [Keyboards(101- and 102-key) - Keyboard Layout, Scan Code Set, POR, and Commands](
|
||||
http://www.mcamafia.de/pdf/ibm_hitrc11.pdf)
|
||||
|
||||
[4] [IBM PC XT Keyboard Protocol](
|
||||
https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol)
|
||||
|
||||
[5] [IBM Keyboard Scan Code by John Elliott - 83-key, 84-key, 102-key and 122-key](
|
||||
https://www.seasip.info/VintagePC/index.html)
|
||||
|
||||
[6] [IBM 1391406 Keyboard - Scan Code Set 2 of 102-key PS/2 keyboard](
|
||||
https://www.seasip.info/VintagePC/ibm_1391406.html)
|
||||
|
||||
[7] [The IBM 6110344 Keyboard - Scan Code Set 3 of 122-key terminal keyboard](
|
||||
https://www.seasip.info/VintagePC/ibm_6110344.html)
|
||||
|
||||
[y] [TrackPoint Engineering Specifications for version 3E](
|
||||
https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html)
|
||||
|
||||
[z] [Soarer's XT/AT/PS2/Terminal to USB converter](
|
||||
https://geekhack.org/index.php?topic=17458.0)
|
||||
|
||||
|
||||
|
||||
TODO
|
||||
----
|
||||
### Reset method for rescue
|
||||
For converter without accesible reset button when magickey combo doesn't work.
|
||||
|
||||
Check pin status at powerup:
|
||||
|
||||
- if Data and/or Clock are pull down to GND
|
||||
|
||||
### Force protocol and scan code set
|
||||
Keyboard discrimination may fail and you have to configure them by hand.
|
||||
|
||||
### Add AT90usb1286 support for Teensy2++
|
||||
1187
converter/ibmpc_usb/binary/ibmpc_usb_at90usb1286.hex
Normal file
1187
converter/ibmpc_usb/binary/ibmpc_usb_at90usb1286.hex
Normal file
File diff suppressed because it is too large
Load diff
1186
converter/ibmpc_usb/binary/ibmpc_usb_atmega32u4.hex
Normal file
1186
converter/ibmpc_usb/binary/ibmpc_usb_atmega32u4.hex
Normal file
File diff suppressed because it is too large
Load diff
92
converter/ibmpc_usb/config.h
Normal file
92
converter/ibmpc_usb/config.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
Copyright 2019 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x1bee
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER t.m.k.
|
||||
#define PRODUCT IBM PC keyboard converter
|
||||
#define DESCRIPTION convert IBM PC keyboard to USB
|
||||
|
||||
|
||||
/* matrix size */
|
||||
#define MATRIX_ROWS 16 // keycode bit: 6-3
|
||||
#define MATRIX_COLS 8 // keycode bit: 2-0
|
||||
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) || \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) \
|
||||
)
|
||||
|
||||
|
||||
/*
|
||||
* Pin and interrupt configuration
|
||||
*/
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB1286__)
|
||||
/* uses INT1 for clock line */
|
||||
#define IBMPC_CLOCK_PORT PORTD
|
||||
#define IBMPC_CLOCK_PIN PIND
|
||||
#define IBMPC_CLOCK_DDR DDRD
|
||||
#define IBMPC_CLOCK_BIT 1
|
||||
#define IBMPC_DATA_PORT PORTD
|
||||
#define IBMPC_DATA_PIN PIND
|
||||
#define IBMPC_DATA_DDR DDRD
|
||||
#define IBMPC_DATA_BIT 0
|
||||
#define IBMPC_RST_PORT PORTB
|
||||
#define IBMPC_RST_PIN PINB
|
||||
#define IBMPC_RST_DDR DDRB
|
||||
#define IBMPC_RST_BIT1 6
|
||||
#define IBMPC_RST_BIT2 7
|
||||
|
||||
/* reset for XT keyboard: low pulse for 500ms and after that HiZ for safety */
|
||||
#define IBMPC_RESET() do { \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_DDR |= (1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT2); \
|
||||
IBMPC_RST_DDR |= (1<<IBMPC_RST_BIT2); \
|
||||
_delay_ms(500); \
|
||||
IBMPC_RST_DDR &= ~(1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_DDR &= ~(1<<IBMPC_RST_BIT2); \
|
||||
} while (0)
|
||||
|
||||
#define IBMPC_INT_INIT() do { \
|
||||
EICRA |= ((1<<ISC11) | \
|
||||
(0<<ISC10)); \
|
||||
} while (0)
|
||||
|
||||
#define IBMPC_INT_ON() do { \
|
||||
EIMSK |= (1<<INT1); \
|
||||
} while (0)
|
||||
|
||||
#define IBMPC_INT_OFF() do { \
|
||||
EIMSK &= ~(1<<INT1); \
|
||||
} while (0)
|
||||
|
||||
#define IBMPC_INT_VECT INT1_vect
|
||||
|
||||
#else
|
||||
#error "No pin configuration in config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
853
converter/ibmpc_usb/ibmpc_usb.c
Normal file
853
converter/ibmpc_usb/ibmpc_usb.c
Normal file
|
|
@ -0,0 +1,853 @@
|
|||
/*
|
||||
Copyright 2019 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "print.h"
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
#include "ibmpc.h"
|
||||
#include "host.h"
|
||||
#include "led.h"
|
||||
#include "matrix.h"
|
||||
#include "timer.h"
|
||||
#include "action.h"
|
||||
#include "ibmpc_usb.h"
|
||||
|
||||
|
||||
static void matrix_make(uint8_t code);
|
||||
static void matrix_break(uint8_t code);
|
||||
|
||||
static int8_t process_cs1(void);
|
||||
static int8_t process_cs2(void);
|
||||
static int8_t process_cs3(void);
|
||||
|
||||
|
||||
static uint8_t matrix[MATRIX_ROWS];
|
||||
#define ROW(code) ((code>>3)&0x0F)
|
||||
#define COL(code) (code&0x07)
|
||||
|
||||
static int16_t read_wait(uint16_t wait_ms)
|
||||
{
|
||||
uint16_t start = timer_read();
|
||||
int16_t code;
|
||||
while ((code = ibmpc_host_recv()) == -1 && timer_elapsed(start) < wait_ms);
|
||||
return code;
|
||||
}
|
||||
|
||||
static uint16_t read_keyboard_id(void)
|
||||
{
|
||||
uint16_t id = 0;
|
||||
int16_t code = 0;
|
||||
|
||||
// Disable
|
||||
code = ibmpc_host_send(0xF5);
|
||||
|
||||
// Read ID
|
||||
code = ibmpc_host_send(0xF2);
|
||||
if (code == -1) return 0xFFFF; // XT or No keyboard
|
||||
if (code != 0xFA) return 0xFFFE; // Broken PS/2?
|
||||
|
||||
code = read_wait(1000);
|
||||
if (code == -1) return 0x0000; // AT
|
||||
id = (code & 0xFF)<<8;
|
||||
|
||||
code = read_wait(1000);
|
||||
id |= code & 0xFF;
|
||||
|
||||
// Enable
|
||||
code = ibmpc_host_send(0xF4);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void matrix_init(void)
|
||||
{
|
||||
debug_enable = true;
|
||||
ibmpc_host_init();
|
||||
|
||||
// hard reset for XT keyboard
|
||||
IBMPC_RESET();
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* keyboard recognition
|
||||
*
|
||||
* 1. Send F2 to get keyboard ID
|
||||
* a. no ACK(FA): XT keyobard
|
||||
* b. ACK but no ID: 84-key AT keyboard CodeSet2
|
||||
* c. ID is AB 83: PS/2 keyboard CodeSet2
|
||||
* d. ID is BF BF: Terminal keyboard CodeSet3
|
||||
* e. error on recv: maybe broken PS/2
|
||||
*/
|
||||
uint16_t keyboard_id = 0x0000;
|
||||
keyboard_kind_t keyboard_kind = NONE;
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
// scan code reading states
|
||||
static enum {
|
||||
INIT,
|
||||
WAIT_STARTUP,
|
||||
READ_ID,
|
||||
LED_SET,
|
||||
LOOP,
|
||||
END
|
||||
} state = INIT;
|
||||
static uint16_t last_time;
|
||||
|
||||
|
||||
if (ibmpc_error) {
|
||||
xprintf("err: %02X\n", ibmpc_error);
|
||||
|
||||
// when recv error, neither send error nor buffer full
|
||||
if (!(ibmpc_error & (IBMPC_ERR_SEND | IBMPC_ERR_FULL))) {
|
||||
// keyboard init again
|
||||
if (state == LOOP) {
|
||||
xprintf("init\n");
|
||||
state = INIT;
|
||||
}
|
||||
}
|
||||
|
||||
// clear or process error
|
||||
ibmpc_error = IBMPC_ERR_NONE;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case INIT:
|
||||
ibmpc_protocol = IBMPC_PROTOCOL_AT;
|
||||
keyboard_kind = NONE;
|
||||
keyboard_id = 0x0000;
|
||||
last_time = timer_read();
|
||||
state = WAIT_STARTUP;
|
||||
matrix_clear();
|
||||
clear_keyboard();
|
||||
break;
|
||||
case WAIT_STARTUP:
|
||||
// read and ignore BAT code and other codes when power-up
|
||||
ibmpc_host_recv();
|
||||
if (timer_elapsed(last_time) > 1000) {
|
||||
state = READ_ID;
|
||||
}
|
||||
break;
|
||||
case READ_ID:
|
||||
keyboard_id = read_keyboard_id();
|
||||
if (ibmpc_error) {
|
||||
xprintf("err: %02X\n", ibmpc_error);
|
||||
ibmpc_error = IBMPC_ERR_NONE;
|
||||
}
|
||||
xprintf("ID: %04X\n", keyboard_id);
|
||||
if (0xAB00 == (keyboard_id & 0xFF00)) {
|
||||
// CodeSet2 PS/2
|
||||
keyboard_kind = PC_AT;
|
||||
} else if (0xBF00 == (keyboard_id & 0xFF00)) {
|
||||
// CodeSet3 Terminal
|
||||
keyboard_kind = PC_TERMINAL;
|
||||
} else if (0x0000 == keyboard_id) {
|
||||
// CodeSet2 AT
|
||||
keyboard_kind = PC_AT;
|
||||
} else if (0xFFFF == keyboard_id) {
|
||||
// CodeSet1 XT
|
||||
keyboard_kind = PC_XT;
|
||||
} else if (0xFFFE == keyboard_id) {
|
||||
// CodeSet2 PS/2 fails to response?
|
||||
keyboard_kind = PC_AT;
|
||||
} else if (0x00FF == keyboard_id) {
|
||||
// Mouse is not supported
|
||||
xprintf("Mouse: not supported\n");
|
||||
keyboard_kind = NONE;
|
||||
} else {
|
||||
keyboard_kind = PC_AT;
|
||||
}
|
||||
|
||||
// protocol
|
||||
if (keyboard_kind == PC_XT) {
|
||||
xprintf("kbd: XT\n");
|
||||
ibmpc_protocol = IBMPC_PROTOCOL_XT;
|
||||
} else if (keyboard_kind == PC_AT) {
|
||||
xprintf("kbd: AT\n");
|
||||
ibmpc_protocol = IBMPC_PROTOCOL_AT;
|
||||
} else if (keyboard_kind == PC_TERMINAL) {
|
||||
xprintf("kbd: Terminal\n");
|
||||
ibmpc_protocol = IBMPC_PROTOCOL_AT;
|
||||
// Set all keys - make/break [3]p.23
|
||||
ibmpc_host_send(0xF8);
|
||||
} else {
|
||||
xprintf("kbd: Unknown\n");
|
||||
ibmpc_protocol = IBMPC_PROTOCOL_AT;
|
||||
}
|
||||
state = LED_SET;
|
||||
break;
|
||||
case LED_SET:
|
||||
led_set(host_keyboard_leds());
|
||||
state = LOOP;
|
||||
case LOOP:
|
||||
switch (keyboard_kind) {
|
||||
case PC_XT:
|
||||
process_cs1();
|
||||
break;
|
||||
case PC_AT:
|
||||
process_cs2();
|
||||
break;
|
||||
case PC_TERMINAL:
|
||||
process_cs3();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline
|
||||
bool matrix_is_on(uint8_t row, uint8_t col)
|
||||
{
|
||||
return (matrix[row] & (1<<col));
|
||||
}
|
||||
|
||||
inline
|
||||
uint8_t matrix_get_row(uint8_t row)
|
||||
{
|
||||
return matrix[row];
|
||||
}
|
||||
|
||||
uint8_t matrix_key_count(void)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
count += bitpop(matrix[i]);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
static void matrix_make(uint8_t code)
|
||||
{
|
||||
if (!matrix_is_on(ROW(code), COL(code))) {
|
||||
matrix[ROW(code)] |= 1<<COL(code);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
static void matrix_break(uint8_t code)
|
||||
{
|
||||
if (matrix_is_on(ROW(code), COL(code))) {
|
||||
matrix[ROW(code)] &= ~(1<<COL(code));
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_clear(void)
|
||||
{
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
|
||||
}
|
||||
|
||||
void led_set(uint8_t usb_led)
|
||||
{
|
||||
if (keyboard_kind != PC_AT) return;
|
||||
|
||||
uint8_t ibmpc_led = 0;
|
||||
if (usb_led & (1<<USB_LED_SCROLL_LOCK))
|
||||
ibmpc_led |= (1<<IBMPC_LED_SCROLL_LOCK);
|
||||
if (usb_led & (1<<USB_LED_NUM_LOCK))
|
||||
ibmpc_led |= (1<<IBMPC_LED_NUM_LOCK);
|
||||
if (usb_led & (1<<USB_LED_CAPS_LOCK))
|
||||
ibmpc_led |= (1<<IBMPC_LED_CAPS_LOCK);
|
||||
ibmpc_host_set_led(ibmpc_led);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* XT: Scan Code Set 1
|
||||
*
|
||||
* See [3], [a]
|
||||
*
|
||||
* E0-escaped scan codes are translated into unused range of the matrix.(54-7F)
|
||||
*
|
||||
* 01-53: Normal codes used in original XT keyboard
|
||||
* 54-7F: Not used in original XT keyboard
|
||||
*
|
||||
* 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
* 50 - - - - * * x x x x * * * * * *
|
||||
* 60 * * * * x x x x x x x x x x x *
|
||||
* 70 x * * x * * x * * x * x * x x *
|
||||
*
|
||||
* -: codes existed in original XT keyboard
|
||||
* *: E0-escaped codes translated
|
||||
* x: Non-espcaped codes(Some are not used in real keyboards probably)
|
||||
*
|
||||
* Codes assigned in range 54-7F:
|
||||
*
|
||||
* 50 - 60 Up* 70 KANAx
|
||||
* 51 - 61 Left* 71 Insert*
|
||||
* 52 - 62 Down* 72 Delete*
|
||||
* 53 - 63 Right* 73 ROx
|
||||
* 54 PrintScr* 64 F13x 74 Home*
|
||||
* 55 Pause* 65 F14x 75 End*
|
||||
* 56 Euro2x 66 F15x 76 F24x
|
||||
* 57 F11x 67 F16x 77 PageUp*
|
||||
* 58 F12x 68 F17x 78 PageDown*
|
||||
* 59 Keypad=x 69 F18x 79 HENKANx
|
||||
* 5A LGUI* 6A F19x 7A RCTL*
|
||||
* 5B RGUI* 6B F20x 7B MUHENKANx
|
||||
* 5C APP* 6C F21x 7C RALT*
|
||||
* 5D Mute* 6D F22x 7D JPYx
|
||||
* 5E Volume Down* 6E F23x 7E Keypad,x
|
||||
* 5F Volume Up* 6F Keypad Enter* 7F Keypad/ *
|
||||
*/
|
||||
static uint8_t cs1_e0code(uint8_t code) {
|
||||
switch(code) {
|
||||
// Original IBM XT keyboard doesn't use E0-codes probably
|
||||
// Some XT compatilble keyobards need these keys?
|
||||
case 0x37: return 0x54; // Print Screen
|
||||
case 0x46: return 0x55; // Ctrl + Pause
|
||||
case 0x5B: return 0x5A; // Left GUI
|
||||
case 0x5C: return 0x5B; // Right GUI
|
||||
case 0x5D: return 0x5C; // Application
|
||||
case 0x20: return 0x5D; // Mute
|
||||
case 0x2E: return 0x5E; // Volume Down
|
||||
case 0x30: return 0x5F; // Volume Up
|
||||
case 0x48: return 0x60; // Up
|
||||
case 0x4B: return 0x61; // Left
|
||||
case 0x50: return 0x62; // Down
|
||||
case 0x4D: return 0x63; // Right
|
||||
case 0x1C: return 0x6F; // Keypad Enter
|
||||
case 0x52: return 0x71; // Insert
|
||||
case 0x53: return 0x72; // Delete
|
||||
case 0x47: return 0x74; // Home
|
||||
case 0x4F: return 0x75; // End
|
||||
case 0x49: return 0x77; // Page Up
|
||||
case 0x51: return 0x78; // Page Down
|
||||
case 0x1D: return 0x7A; // Right Ctrl
|
||||
case 0x38: return 0x7C; // Right Alt
|
||||
case 0x35: return 0x7F; // Keypad /
|
||||
|
||||
// Shared matrix cell with other keys
|
||||
case 0x5E: return 0x70; // Power (KANA)
|
||||
case 0x5F: return 0x79; // Sleep (HENKAN)
|
||||
case 0x63: return 0x7B; // Wake (MUHENKAN)
|
||||
|
||||
default:
|
||||
xprintf("!CS1_?!\n");
|
||||
return code;
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static int8_t process_cs1(void)
|
||||
{
|
||||
static enum {
|
||||
INIT,
|
||||
E0,
|
||||
// Pause: E1 1D 45, E1 9D C5
|
||||
E1,
|
||||
E1_1D,
|
||||
E1_9D,
|
||||
} state = INIT;
|
||||
|
||||
uint16_t code = ibmpc_host_recv();
|
||||
if (code == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case INIT:
|
||||
switch (code) {
|
||||
case 0xE0:
|
||||
state = E0;
|
||||
break;
|
||||
case 0xE1:
|
||||
state = E1;
|
||||
break;
|
||||
default:
|
||||
if (code < 0x80)
|
||||
matrix_make(code);
|
||||
else
|
||||
matrix_break(code & 0x7F);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case E0:
|
||||
switch (code) {
|
||||
case 0x2A:
|
||||
case 0xAA:
|
||||
case 0x36:
|
||||
case 0xB6:
|
||||
//ignore fake shift
|
||||
state = INIT;
|
||||
break;
|
||||
default:
|
||||
if (code < 0x80)
|
||||
matrix_make(cs1_e0code(code));
|
||||
else
|
||||
matrix_break(cs1_e0code(code & 0x7F));
|
||||
state = INIT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case E1:
|
||||
switch (code) {
|
||||
case 0x1D:
|
||||
state = E1_1D;
|
||||
break;
|
||||
case 0x9D:
|
||||
state = E1_9D;
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case E1_1D:
|
||||
switch (code) {
|
||||
case 0x45:
|
||||
matrix_make(0x55);
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case E1_9D:
|
||||
switch (code) {
|
||||
case 0x45:
|
||||
matrix_break(0x55);
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* AT, PS/2: Scan Code Set 2
|
||||
*
|
||||
* Exceptional Handling
|
||||
* --------------------
|
||||
* Some keys should be handled exceptionally. See [b].
|
||||
*
|
||||
* Scan codes are varied or prefix/postfix'd depending on modifier key state.
|
||||
*
|
||||
* 1) Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left
|
||||
* a) when Num Lock is off
|
||||
* modifiers | make | break
|
||||
* ----------+---------------------------+----------------------
|
||||
* Ohter | <make> | <break>
|
||||
* LShift | E0 F0 12 <make> | <break> E0 12
|
||||
* RShift | E0 F0 59 <make> | <break> E0 59
|
||||
* L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
|
||||
*
|
||||
* b) when Num Lock is on
|
||||
* modifiers | make | break
|
||||
* ----------+---------------------------+----------------------
|
||||
* Other | E0 12 <make> | <break> E0 F0 12
|
||||
* Shift'd | <make> | <break>
|
||||
*
|
||||
* Handling: These prefix/postfix codes are ignored.
|
||||
*
|
||||
*
|
||||
* 2) Keypad /
|
||||
* modifiers | make | break
|
||||
* ----------+---------------------------+----------------------
|
||||
* Ohter | <make> | <break>
|
||||
* LShift | E0 F0 12 <make> | <break> E0 12
|
||||
* RShift | E0 F0 59 <make> | <break> E0 59
|
||||
* L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
|
||||
*
|
||||
* Handling: These prefix/postfix codes are ignored.
|
||||
*
|
||||
*
|
||||
* 3) PrintScreen
|
||||
* modifiers | make | break
|
||||
* ----------+--------------+-----------------------------------
|
||||
* Other | E0 12 E0 7C | E0 F0 7C E0 F0 12
|
||||
* Shift'd | E0 7C | E0 F0 7C
|
||||
* Control'd | E0 7C | E0 F0 7C
|
||||
* Alt'd | 84 | F0 84
|
||||
*
|
||||
* Handling: These prefix/postfix codes are ignored, and both scan codes
|
||||
* 'E0 7C' and 84 are seen as PrintScreen.
|
||||
*
|
||||
* 4) Pause
|
||||
* modifiers | make(no break code)
|
||||
* ----------+--------------------------------------------------
|
||||
* Other | E1 14 77 E1 F0 14 F0 77
|
||||
* Control'd | E0 7E E0 F0 7E
|
||||
*
|
||||
* Handling: Both code sequences are treated as a whole.
|
||||
* And we need a ad hoc 'pseudo break code' hack to get the key off
|
||||
* because it has no break code.
|
||||
*
|
||||
* Notes:
|
||||
* 'Hanguel/English'(F1) and 'Hanja'(F2) have no break code. See [a].
|
||||
* These two Korean keys need exceptional handling and are not supported for now.
|
||||
*
|
||||
*/
|
||||
static uint8_t cs2_e0code(uint8_t code) {
|
||||
switch(code) {
|
||||
// E0 prefixed codes translation See [a].
|
||||
case 0x11: return 0x0F; // right alt
|
||||
case 0x14: return 0x17; // right control
|
||||
case 0x1F: return 0x19; // left GUI
|
||||
case 0x27: return 0x1F; // right GUI
|
||||
case 0x2F: return 0x5C; // apps
|
||||
case 0x4A: return 0x60; // keypad /
|
||||
case 0x5A: return 0x62; // keypad enter
|
||||
case 0x69: return 0x27; // end
|
||||
case 0x6B: return 0x53; // cursor left
|
||||
case 0x6C: return 0x2F; // home
|
||||
case 0x70: return 0x39; // insert
|
||||
case 0x71: return 0x37; // delete
|
||||
case 0x72: return 0x3F; // cursor down
|
||||
case 0x74: return 0x47; // cursor right
|
||||
case 0x75: return 0x4F; // cursor up
|
||||
case 0x7A: return 0x56; // page down
|
||||
case 0x7D: return 0x5E; // page up
|
||||
case 0x7C: return 0x6F; // Print Screen
|
||||
case 0x7E: return 0x00; // Control'd Pause
|
||||
|
||||
case 0x21: return 0x65; // volume down
|
||||
case 0x32: return 0x6E; // volume up
|
||||
case 0x23: return 0x7F; // mute
|
||||
case 0x10: return 0x08; // (WWW search) -> F13
|
||||
case 0x18: return 0x10; // (WWW favourites) -> F14
|
||||
case 0x20: return 0x18; // (WWW refresh) -> F15
|
||||
case 0x28: return 0x20; // (WWW stop) -> F16
|
||||
case 0x30: return 0x28; // (WWW forward) -> F17
|
||||
case 0x38: return 0x30; // (WWW back) -> F18
|
||||
case 0x3A: return 0x38; // (WWW home) -> F19
|
||||
case 0x40: return 0x40; // (my computer) -> F20
|
||||
case 0x48: return 0x48; // (email) -> F21
|
||||
case 0x2B: return 0x50; // (calculator) -> F22
|
||||
case 0x34: return 0x08; // (play/pause) -> F13
|
||||
case 0x3B: return 0x10; // (stop) -> F14
|
||||
case 0x15: return 0x18; // (previous track) -> F15
|
||||
case 0x4D: return 0x20; // (next track) -> F16
|
||||
case 0x50: return 0x28; // (media select) -> F17
|
||||
case 0x5E: return 0x50; // (ACPI wake) -> F22
|
||||
case 0x3F: return 0x57; // (ACPI sleep) -> F23
|
||||
case 0x37: return 0x5F; // (ACPI power) -> F24
|
||||
|
||||
// https://github.com/tmk/tmk_keyboard/pull/636
|
||||
case 0x03: return 0x18; // Help DEC LK411 -> F15
|
||||
case 0x04: return 0x08; // F13 DEC LK411
|
||||
case 0x0B: return 0x20; // Do DEC LK411 -> F16
|
||||
case 0x0C: return 0x10; // F14 DEC LK411
|
||||
case 0x0D: return 0x19; // LCompose DEC LK411 -> LGUI
|
||||
case 0x79: return 0x6D; // KP- DEC LK411 -> PCMM
|
||||
case 0x83: return 0x28; // F17 DEC LK411
|
||||
default: return (code & 0x7F);
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t process_cs2(void)
|
||||
{
|
||||
// scan code reading states
|
||||
static enum {
|
||||
INIT,
|
||||
F0,
|
||||
E0,
|
||||
E0_F0,
|
||||
// Pause
|
||||
E1,
|
||||
E1_14,
|
||||
E1_F0,
|
||||
E1_F0_14,
|
||||
E1_F0_14_F0,
|
||||
} state = INIT;
|
||||
|
||||
uint16_t code = ibmpc_host_recv();
|
||||
if (code == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case INIT:
|
||||
switch (code) {
|
||||
case 0xE0:
|
||||
state = E0;
|
||||
break;
|
||||
case 0xF0:
|
||||
state = F0;
|
||||
break;
|
||||
case 0xE1:
|
||||
state = E1;
|
||||
break;
|
||||
case 0x83: // F7
|
||||
matrix_make(0x02);
|
||||
state = INIT;
|
||||
break;
|
||||
case 0x84: // Alt'd PrintScreen
|
||||
matrix_make(0x6F);
|
||||
state = INIT;
|
||||
break;
|
||||
case 0x00: // Overrun [3]p.26
|
||||
matrix_clear();
|
||||
xprintf("!CS2_OVERRUN!\n");
|
||||
state = INIT;
|
||||
break;
|
||||
case 0xAA: // Self-test passed
|
||||
case 0xFC: // Self-test failed
|
||||
// reset or plugin-in new keyboard
|
||||
state = INIT;
|
||||
return -1;
|
||||
break;
|
||||
default: // normal key make
|
||||
if (code < 0x80) {
|
||||
matrix_make(code);
|
||||
} else {
|
||||
matrix_clear();
|
||||
xprintf("!CS2_INIT!\n");
|
||||
}
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
case E0: // E0-Prefixed
|
||||
switch (code) {
|
||||
case 0x12: // to be ignored
|
||||
case 0x59: // to be ignored
|
||||
state = INIT;
|
||||
break;
|
||||
case 0xF0:
|
||||
state = E0_F0;
|
||||
break;
|
||||
default:
|
||||
if (code < 0x80) {
|
||||
matrix_make(cs2_e0code(code));
|
||||
} else {
|
||||
matrix_clear();
|
||||
xprintf("!CS2_E0!\n");
|
||||
}
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
case F0: // Break code
|
||||
switch (code) {
|
||||
case 0x83: // F7
|
||||
matrix_break(0x02);
|
||||
state = INIT;
|
||||
break;
|
||||
case 0x84: // Alt'd PrintScreen
|
||||
matrix_break(0x6F);
|
||||
state = INIT;
|
||||
break;
|
||||
default:
|
||||
if (code < 0x80) {
|
||||
matrix_break(code);
|
||||
} else {
|
||||
matrix_clear();
|
||||
xprintf("!CS2_F0!\n");
|
||||
}
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
case E0_F0: // Break code of E0-prefixed
|
||||
switch (code) {
|
||||
case 0x12: // to be ignored
|
||||
case 0x59: // to be ignored
|
||||
state = INIT;
|
||||
break;
|
||||
default:
|
||||
if (code < 0x80) {
|
||||
matrix_break(cs2_e0code(code));
|
||||
} else {
|
||||
matrix_clear();
|
||||
xprintf("!CS2_E0_F0!\n");
|
||||
}
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
// Pause make: E1 14 77
|
||||
case E1:
|
||||
switch (code) {
|
||||
case 0x14:
|
||||
state = E1_14;
|
||||
break;
|
||||
case 0xF0:
|
||||
state = E1_F0;
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
case E1_14:
|
||||
switch (code) {
|
||||
case 0x77:
|
||||
matrix_make(0x00);
|
||||
state = INIT;
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
// Pause break: E1 F0 14 F0 77
|
||||
case E1_F0:
|
||||
switch (code) {
|
||||
case 0x14:
|
||||
state = E1_F0_14;
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
case E1_F0_14:
|
||||
switch (code) {
|
||||
case 0xF0:
|
||||
state = E1_F0_14_F0;
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
case E1_F0_14_F0:
|
||||
switch (code) {
|
||||
case 0x77:
|
||||
matrix_break(0x00);
|
||||
state = INIT;
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
state = INIT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Terminal: Scan Code Set 3
|
||||
*
|
||||
* See [3], [7]
|
||||
*
|
||||
* Scan code 0x83 and 0x84 are handled exceptioanally to fit into 1-byte range index.
|
||||
*/
|
||||
static int8_t process_cs3(void)
|
||||
{
|
||||
static enum {
|
||||
READY,
|
||||
F0,
|
||||
} state = READY;
|
||||
|
||||
uint16_t code = ibmpc_host_recv();
|
||||
if (code == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case READY:
|
||||
switch (code) {
|
||||
case 0x00:
|
||||
case 0xff:
|
||||
xprintf("!CS3_%02X!\n", code);
|
||||
break;
|
||||
case 0xF0:
|
||||
state = F0;
|
||||
break;
|
||||
case 0x83: // F7
|
||||
matrix_make(0x02);
|
||||
break;
|
||||
case 0x84: // keypad -
|
||||
matrix_make(0x7F);
|
||||
break;
|
||||
default: // normal key make
|
||||
if (code < 0x80) {
|
||||
matrix_make(code);
|
||||
} else {
|
||||
xprintf("!CS3_%02X!\n", code);
|
||||
}
|
||||
state = READY;
|
||||
}
|
||||
break;
|
||||
case F0: // Break code
|
||||
switch (code) {
|
||||
case 0x00:
|
||||
case 0xff:
|
||||
xprintf("!CS3_F0_%02X!\n", code);
|
||||
state = READY;
|
||||
break;
|
||||
case 0x83: // F7
|
||||
matrix_break(0x02);
|
||||
state = READY;
|
||||
break;
|
||||
case 0x84: // keypad -
|
||||
matrix_break(0x7F);
|
||||
state = READY;
|
||||
break;
|
||||
default:
|
||||
if (code < 0x80) {
|
||||
matrix_break(code);
|
||||
} else {
|
||||
xprintf("!CS3_F0_%02X!\n", code);
|
||||
}
|
||||
state = READY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* IBM PC Keyboard Protocol Resources:
|
||||
*
|
||||
* [a] Microsoft USB HID to PS/2 Translation Table - Scan Code Set 1 and 2
|
||||
* http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
|
||||
*
|
||||
* [b] Microsoft Keyboard Scan Code Specification - Special rules of Scan Code Set 1 and 2
|
||||
* http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
|
||||
*
|
||||
* [1] PS/2 Reference Manuals - Collection of IBM Personal System/2 documents.
|
||||
* http://www.mcamafia.de/pdf/pdfref.htm
|
||||
*
|
||||
* [2] Keyboard and Auxiliary Device Controller - Signal Timing and Format
|
||||
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
|
||||
*
|
||||
* [3] Keyboards(101- and 102-key) - Keyboard Layout, Scan Code Set, POR, and Commands.
|
||||
* http://www.mcamafia.de/pdf/ibm_hitrc11.pdf
|
||||
*
|
||||
* [4] IBM PC XT Keyboard Protocol
|
||||
* https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol
|
||||
*
|
||||
* [5] IBM Keyboard Scan Code by John Elliott - 83-key, 84-key, 102-key and 122-key
|
||||
* https://www.seasip.info/VintagePC/index.html
|
||||
*
|
||||
* [6] IBM 1391406 Keyboard - Scan Code Set 2 of 102-key PS/2 keyboard
|
||||
* https://www.seasip.info/VintagePC/ibm_1391406.html
|
||||
*
|
||||
* [7] The IBM 6110344 Keyboard - Scan Code Set 3 of 122-key terminal keyboard
|
||||
* https://www.seasip.info/VintagePC/ibm_6110344.html
|
||||
*
|
||||
* [y] TrackPoint Engineering Specifications for version 3E
|
||||
* https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
|
||||
*
|
||||
* [z] [Soarer's XT/AT/PS2/Terminal to USB converter]
|
||||
* https://geekhack.org/index.php?topic=17458.0
|
||||
*
|
||||
*/
|
||||
9
converter/ibmpc_usb/ibmpc_usb.h
Normal file
9
converter/ibmpc_usb/ibmpc_usb.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef IBMPC_USB_H
|
||||
#define IBMPC_USB_H
|
||||
|
||||
typedef enum { NONE, PC_XT, PC_AT, PC_TERMINAL } keyboard_kind_t;
|
||||
|
||||
extern uint16_t keyboard_id;
|
||||
extern keyboard_kind_t keyboard_kind;
|
||||
|
||||
#endif
|
||||
45
converter/ibmpc_usb/unimap_plain.c
Normal file
45
converter/ibmpc_usb/unimap_plain.c
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2016 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "unimap_trans.h"
|
||||
|
||||
|
||||
#define AC_FN0 ACTION_LAYER_MOMENTARY(1)
|
||||
|
||||
#ifdef KEYMAP_SECTION_ENABLE
|
||||
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
|
||||
#else
|
||||
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
|
||||
#endif
|
||||
UNIMAP(
|
||||
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, VOLD,VOLU,MUTE,
|
||||
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS,
|
||||
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, P4, P5, P6, PCMM,
|
||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RO, RSFT, UP, P1, P2, P3, PENT,
|
||||
LCTL,LGUI,LALT,MHEN, SPC, HENK,KANA,RALT,RGUI,FN0, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PEQL
|
||||
),
|
||||
UNIMAP(
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
|
||||
GRV, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS,TRNS, PGUP, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, HOME,PGDN,END, TRNS,TRNS,TRNS
|
||||
),
|
||||
};
|
||||
237
converter/ibmpc_usb/unimap_trans.h
Normal file
237
converter/ibmpc_usb/unimap_trans.h
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
Copyright 2019 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef UNIMAP_TRANS_H
|
||||
#define UNIMAP_TRANS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "unimap.h"
|
||||
#include "action.h"
|
||||
#include "ibmpc_usb.h"
|
||||
|
||||
|
||||
|
||||
/* Mapping to Universal keyboard layout
|
||||
*
|
||||
* Universal keyboard layout
|
||||
* ,-----------------------------------------------.
|
||||
* |F13|F14|F15|F16|F17|F18|F19|F20|F21|F22|F23|F24|
|
||||
* ,---. |-----------------------------------------------| ,-----------. ,-----------.
|
||||
* |Esc| |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12| |PrS|ScL|Pau| |VDn|VUp|Mut|
|
||||
* `---' `-----------------------------------------------' `-----------' `-----------'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|JPY|Bsp| |Ins|Hom|PgU| |NmL| /| *| -|
|
||||
* |-----------------------------------------------------------| |-----------| |---------------|
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ | |Del|End|PgD| | 7| 8| 9| +|
|
||||
* |-----------------------------------------------------------| `-----------' |---------------|
|
||||
* |CapsL | A| S| D| F| G| H| J| K| L| ;| '| ^a|Retn| | 4| 5| 6|KP,|
|
||||
* |-----------------------------------------------------------| ,---. |---------------|
|
||||
* |Shft| <| Z| X| C| V| B| N| M| ,| .| /| RO|Shift | |Up | | 1| 2| 3|KP=|
|
||||
* |-----------------------------------------------------------| ,-----------. |---------------|
|
||||
* |Ctl|Gui|Alt|MHEN| Space |HENK|KANA|Alt|Gui|App|Ctl| |Lef|Dow|Rig| | #| 0| .|Ent|
|
||||
* `-----------------------------------------------------------' `-----------' `---------------'
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Scan Code Set 1:
|
||||
* ,-------. ,--------------------------------------------------------------------------.
|
||||
* | F1| F2| |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| BS |NumLck |ScrLck |
|
||||
* |-------| |--------------------------------------------------------------------------|
|
||||
* | F3| F4| | Tab | Q| W| E| R| T| Y| U| I| O| P| [| ] | | 7| 8| 9| -|
|
||||
* |-------| |------------------------------------------------------|Ent|---------------|
|
||||
* | F5| F6| | Ctrl | A| S| D| F| G| H| J| K| L| ;| '| `| | 4| 5| 6| |
|
||||
* |-------| |----------------------------------------------------------------------| |
|
||||
* | F7| F8| |Shif| \| Z| X| C| V| B| N| M| ,| .| /|Shift| *| 1| 2| 3| +|
|
||||
* |-------| |----------------------------------------------------------------------| |
|
||||
* | F9|F10| | Alt | Space |CapsLck| 0 | . | |
|
||||
* `-------' `--------------------------------------------------------------------------'
|
||||
*
|
||||
* ,-------. ,--------------------------------------------------------------------------.
|
||||
* | 3B| 3C| | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 0E | 45 | 46 |
|
||||
* |-------| |--------------------------------------------------------------------------|
|
||||
* | 3D| 3E| | 0F | 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B | | 47| 48| 49| 4A|
|
||||
* |-------| |------------------------------------------------------| 1C|---------------|
|
||||
* | 3F| 40| | 1D | 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| | 4B| 4C| 4D| |
|
||||
* |-------| |----------------------------------------------------------------------| |
|
||||
* | 41| 42| | 2A | 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35| 36 | 37| 4F| 50| 51| 4E|
|
||||
* |-------| |----------------------------------------------------------------------| |
|
||||
* | 43| 44| | 38 | 39 | 3A | 52 | 53 | |
|
||||
* `-------' `--------------------------------------------------------------------------'
|
||||
* [3], [a]
|
||||
*/
|
||||
const uint8_t PROGMEM unimap_cs1[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
{ UNIMAP_NO, UNIMAP_ESC, UNIMAP_1, UNIMAP_2, UNIMAP_3, UNIMAP_4, UNIMAP_5, UNIMAP_6 }, /* 00-07 */
|
||||
{ UNIMAP_7, UNIMAP_8, UNIMAP_9, UNIMAP_0, UNIMAP_MINUS, UNIMAP_EQUAL, UNIMAP_BSPACE,UNIMAP_TAB }, /* 08-0F */
|
||||
{ UNIMAP_Q, UNIMAP_W, UNIMAP_E, UNIMAP_R, UNIMAP_T, UNIMAP_Y, UNIMAP_U, UNIMAP_I }, /* 10-17 */
|
||||
{ UNIMAP_O, UNIMAP_P, UNIMAP_LBRC, UNIMAP_RBRC, UNIMAP_ENTER, UNIMAP_LCTL, UNIMAP_A, UNIMAP_S, }, /* 18-1F */
|
||||
{ UNIMAP_D, UNIMAP_F, UNIMAP_G, UNIMAP_H, UNIMAP_J, UNIMAP_K, UNIMAP_L, UNIMAP_SCLN }, /* 20-27 */
|
||||
{ UNIMAP_QUOTE, UNIMAP_GRAVE, UNIMAP_LSHIFT,UNIMAP_BSLASH,UNIMAP_Z, UNIMAP_X, UNIMAP_C, UNIMAP_V, }, /* 28-2F */
|
||||
{ UNIMAP_B, UNIMAP_N, UNIMAP_M, UNIMAP_COMMA, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_RSHIFT,UNIMAP_PAST }, /* 30-37 */
|
||||
{ UNIMAP_LALT, UNIMAP_SPACE, UNIMAP_CAPS, UNIMAP_F1, UNIMAP_F2, UNIMAP_F3, UNIMAP_F4, UNIMAP_F5 }, /* 38-3F */
|
||||
{ UNIMAP_F6, UNIMAP_F7, UNIMAP_F8, UNIMAP_F9, UNIMAP_F10, UNIMAP_NLCK, UNIMAP_SLCK, UNIMAP_P7 }, /* 40-47 */
|
||||
{ UNIMAP_P8, UNIMAP_P9, UNIMAP_PMNS, UNIMAP_P4, UNIMAP_P5, UNIMAP_P6, UNIMAP_PPLS, UNIMAP_P1 }, /* 48-4F */
|
||||
{ UNIMAP_P2, UNIMAP_P3, UNIMAP_P0, UNIMAP_PDOT, UNIMAP_PSCR, UNIMAP_PAUSE, UNIMAP_NUHS, UNIMAP_F11 }, /* 50-57 */
|
||||
{ UNIMAP_F12, UNIMAP_PEQL, UNIMAP_LGUI, UNIMAP_RGUI, UNIMAP_APP, UNIMAP_MUTE, UNIMAP_VOLD, UNIMAP_VOLU }, /* 58-5F */
|
||||
{ UNIMAP_UP, UNIMAP_LEFT, UNIMAP_DOWN, UNIMAP_RIGHT, UNIMAP_F13, UNIMAP_F14, UNIMAP_F15, UNIMAP_F16 }, /* 60-67 */
|
||||
{ UNIMAP_F17, UNIMAP_F18, UNIMAP_F19, UNIMAP_F20, UNIMAP_F21, UNIMAP_F22, UNIMAP_F23, UNIMAP_PENT }, /* 68-6F */
|
||||
{ UNIMAP_KANA, UNIMAP_INSERT,UNIMAP_DELETE,UNIMAP_RO, UNIMAP_HOME, UNIMAP_END, UNIMAP_F24, UNIMAP_PGUP }, /* 70-77 */
|
||||
{ UNIMAP_PGDN, UNIMAP_HENK, UNIMAP_RCTL, UNIMAP_MHEN, UNIMAP_RALT, UNIMAP_JYEN, UNIMAP_PCMM, UNIMAP_PSLS }, /* 78-7F */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Scan Code Set 2:
|
||||
* ,-----------------------------------------------.
|
||||
* |F13|F14|F15|F16|F17|F18|F19|F20|F21|F22|F23|F24|
|
||||
* ,---. |-----------------------------------------------| ,-----------. ,-----------.
|
||||
* |Esc| |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12| |PrS|ScL|Pau| |VDn|VUp|Mut|
|
||||
* `---' `-----------------------------------------------' `-----------' `-----------'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|JPY|Bsp| |Ins|Hom|PgU| |NmL| /| *| -|
|
||||
* |-----------------------------------------------------------| |-----------| |---------------|
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ | |Del|End|PgD| | 7| 8| 9| +|
|
||||
* |-----------------------------------------------------------| `-----------' |---------------|
|
||||
* |CapsL | A| S| D| F| G| H| J| K| L| ;| '| ^a|Entr| | 4| 5| 6|KP,|
|
||||
* |-----------------------------------------------------------| ,---. |---------------|
|
||||
* |Shft| <| Z| X| C| V| B| N| M| ,| .| /| RO|Shift | |Up | | 1| 2| 3|Ent|
|
||||
* |-----------------------------------------------------------| ,-----------. |---------------|
|
||||
* |Ctl|Gui|Alt|MHEN| Space |HENK|KANA|Alt|Gui|App|Ctl| |Lef|Dow|Rig| | #| 0| .|KP=|
|
||||
* `-----------------------------------------------------------' `-----------' `---------------'
|
||||
*
|
||||
* ,-----------------------------------------------.
|
||||
* | 08| 10| 18| 20| 28| 30| 38| 40| 48| 50| 57| 5F|
|
||||
* ,---. |-----------------------------------------------| ,-----------. ,-----------.
|
||||
* | 76| | 05| 06| 04| 0C| 03| 0B| 83| 0A| 01| 09| 78| 07| |+7C| 7E|+77| |*21|*32|*23|
|
||||
* `---' `-----------------------------------------------' `-----------' `-----------'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||
* | 0E| 16| 1E| 26| 25| 2E| 36| 3D| 3E| 46| 45| 4E| 55| 6A| 66| |*70|*6C|*7D| | 77|*4A| 7C| 7B|
|
||||
* |-----------------------------------------------------------| |-----------| |---------------|
|
||||
* | 0D | 15| 1D| 24| 2D| 2C| 35| 3C| 43| 44| 4D| 54| 5B| 5D | |*71|*69|*7A| | 6C| 75| 7D| 79|
|
||||
* |-----------------------------------------------------------| `-----------' |---------------|
|
||||
* | 58 | 1C| 1B| 23| 2B| 34| 33| 3B| 42| 4B| 4C| 52| ^a| 5A | | 6B| 73| 74| 6D|
|
||||
* |-----------------------------------------------------------| ,---. |---------------|
|
||||
* | 12 | 61| 1A| 22| 21| 2A| 32| 31| 3A| 41| 49| 4A| 51| 59 | |*75| | 69| 72| 7A|*5A|
|
||||
* |-----------------------------------------------------------| ,-----------. |---------------|
|
||||
* | 14|*1F| 11| 67 | 29 | 64 | 13 |*11|*27|*2F|*14| |*6B|*72|*74| | 68| 70| 71| 63|
|
||||
* `-----------------------------------------------------------' `-----------' `---------------'
|
||||
* *: E0-prefixed codes
|
||||
* +: Special codes sequence
|
||||
* ^a: ISO hash key uses identical scancode 5D to US backslash.
|
||||
* 51, 63, 68, 6A, 6D: Hidden keys in IBM model M [6]
|
||||
*/
|
||||
const uint8_t PROGMEM unimap_cs2[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
{ UNIMAP_PAUS, UNIMAP_F9, UNIMAP_F7, UNIMAP_F5, UNIMAP_F3, UNIMAP_F1, UNIMAP_F2, UNIMAP_F12 }, /* 00-07 */
|
||||
{ UNIMAP_F13, UNIMAP_F10, UNIMAP_F8, UNIMAP_F6, UNIMAP_F4, UNIMAP_TAB, UNIMAP_GRV, UNIMAP_RALT }, /* 08-0F */
|
||||
{ UNIMAP_F14, UNIMAP_LALT, UNIMAP_LSHIFT,UNIMAP_KANA, UNIMAP_LCTL, UNIMAP_Q, UNIMAP_1, UNIMAP_RCTL }, /* 10-17 */
|
||||
{ UNIMAP_F15, UNIMAP_LGUI, UNIMAP_Z, UNIMAP_S, UNIMAP_A, UNIMAP_W, UNIMAP_2, UNIMAP_RGUI }, /* 18-1F */
|
||||
{ UNIMAP_F16, UNIMAP_C, UNIMAP_X, UNIMAP_D, UNIMAP_E, UNIMAP_4, UNIMAP_3, UNIMAP_END }, /* 20-27 */
|
||||
{ UNIMAP_F17, UNIMAP_SPACE, UNIMAP_V, UNIMAP_F, UNIMAP_T, UNIMAP_R, UNIMAP_5, UNIMAP_HOME }, /* 28-2F */
|
||||
{ UNIMAP_F18, UNIMAP_N, UNIMAP_B, UNIMAP_H, UNIMAP_G, UNIMAP_Y, UNIMAP_6, UNIMAP_DEL }, /* 30-37 */
|
||||
{ UNIMAP_F19, UNIMAP_INS, UNIMAP_M, UNIMAP_J, UNIMAP_U, UNIMAP_7, UNIMAP_8, UNIMAP_DOWN }, /* 38-3F */
|
||||
{ UNIMAP_F20, UNIMAP_COMMA, UNIMAP_K, UNIMAP_I, UNIMAP_O, UNIMAP_0, UNIMAP_9, UNIMAP_RIGHT }, /* 40-47 */
|
||||
{ UNIMAP_F21, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_L, UNIMAP_SCOLON,UNIMAP_P, UNIMAP_MINUS, UNIMAP_UP }, /* 48-4F */
|
||||
{ UNIMAP_F22, UNIMAP_RO, UNIMAP_QUOTE, UNIMAP_LEFT, UNIMAP_LBRC, UNIMAP_EQUAL, UNIMAP_PGDN, UNIMAP_F23 }, /* 50-57 */
|
||||
{ UNIMAP_CAPS, UNIMAP_RSHIFT,UNIMAP_ENTER, UNIMAP_RBRC, UNIMAP_APP, UNIMAP_BSLASH,UNIMAP_PGUP, UNIMAP_F24 }, /* 58-5F */
|
||||
{ UNIMAP_PSLS, UNIMAP_NUBS, UNIMAP_PENT, UNIMAP_PEQL, UNIMAP_HENK, UNIMAP_VOLD, UNIMAP_BSPACE,UNIMAP_MHEN }, /* 60-67 */
|
||||
{ UNIMAP_NUHS, UNIMAP_P1, UNIMAP_JYEN, UNIMAP_P4, UNIMAP_P7, UNIMAP_PCMM, UNIMAP_VOLU, UNIMAP_PSCR }, /* 68-6F */
|
||||
{ UNIMAP_P0, UNIMAP_PDOT, UNIMAP_P2, UNIMAP_P5, UNIMAP_P6, UNIMAP_P8, UNIMAP_ESC, UNIMAP_NLCK }, /* 70-77 */
|
||||
{ UNIMAP_F11, UNIMAP_PPLS, UNIMAP_P3, UNIMAP_PMNS, UNIMAP_PAST, UNIMAP_P9, UNIMAP_SLCK, UNIMAP_MUTE }, /* 78-7F */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Scan Code Set 3:
|
||||
* ,-----------------------------------------------.
|
||||
* |F13|F14|F15|F16|F17|F18|F19|F20|F21|F22|F23|F24|
|
||||
* |-----------------------------------------------|
|
||||
* |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|
|
||||
* `-----------------------------------------------'
|
||||
* ,-------. ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||
* |PrS|Esc| | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Yen| BS| |Ins|Hom|PgU| |NmL| /| *| -|
|
||||
* |-------| |-----------------------------------------------------------| |-----------| |---------------|
|
||||
* |ScL|Hen| |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| +|
|
||||
* |-------| |-----------------------------------------------------------| `-----------' |-----------|---|
|
||||
* |Pau|Muh| |CapsLo| A| S| D| F| G| H| J| K| L| ;| '| #| Ret| |Up | | 4| 5| 6| ,|
|
||||
* |-------| |-----------------------------------------------------------| ,-----------. |---------------|
|
||||
* |VoD|VoU| |Shif| \| Z| X| C| V| B| N| M| ,| ,| /| RO| Shift| |Lef|App|Rig| | 1| 2| 3|Ent|
|
||||
* |-------| |-----------------------------------------------------------| `-----------' |-----------|---|
|
||||
* |Gui|Gui| |Ctrl| |Alt | Space |Alt | |Ctrl| |Dow| |Kan| 0| .| =|
|
||||
* `-------' `----' `---------------------------------------' `----' `---' `---------------'
|
||||
*
|
||||
* ,-----------------------------------------------.
|
||||
* | 08| 10| 18| 20| 28| 30| 38| 40| 48| 50| 57| 5F|
|
||||
* |-----------------------------------------------|
|
||||
* | 07| 0F| 17| 1F| 27| 2F| 37| 3F| 47| 4F| 56| 5E|
|
||||
* `-----------------------------------------------'
|
||||
* ,-------. ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||
* | 05| 06| | 0E| 16| 1E| 26| 25| 2E| 36| 3D| 3E| 46| 45| 4E| 55| 5D| 66| | 67| 6E| 6F| | 76| 77| 7E|*84|
|
||||
* |-------| |-----------------------------------------------------------| |-----------| |---------------|
|
||||
* | 04| 0C| | 0D | 15| 1D| 24| 2D| 2C| 35| 3C| 43| 44| 4D| 54| 5B| 5C | | 64| 65| 6D| | 6C| 75| 7D| 7C|
|
||||
* |-------| |-----------------------------------------------------------| `-----------' |---------------|
|
||||
* | 03| 0B| | 58 | 1C| 1B| 23| 2B| 34| 33| 3B| 42| 4B| 4C| 52| 53| 5A | | 63| | 6B| 73| 74| 7B|
|
||||
* |-------| |-----------------------------------------------------------| ,-----------. |---------------|
|
||||
* |*83| 0A| | 12 | 13| 1A| 22| 21| 2A| 32| 31| 3A| 41| 49| 4A| 51| 59 | | 61| 62| 6A| | 69| 72| 7A| 79|
|
||||
* |-------| |-----------------------------------------------------------| `-----------' |---------------|
|
||||
* | 01| 09| | 11 | |19 | 29 |39 | | 58 | | 60| | 68| 70| 71| 78|
|
||||
* `-------' `-----' `---------------------------------------' `-----' `---' `---------------'
|
||||
* *: 83=02, 84=7F
|
||||
* 51, 5C, 5D, 68, 78: Hidden keys in IBM 122-key terminal keyboard [7]
|
||||
*/
|
||||
const uint8_t PROGMEM unimap_cs3[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
{ UNIMAP_NO, UNIMAP_LGUI, UNIMAP_VOLD, UNIMAP_PAUSE, UNIMAP_SLCK, UNIMAP_PSCR, UNIMAP_ESC, UNIMAP_F1 }, /* 00-07 */
|
||||
{ UNIMAP_F13, UNIMAP_RGUI, UNIMAP_VOLU, UNIMAP_MHEN, UNIMAP_HENK, UNIMAP_TAB, UNIMAP_GRV, UNIMAP_F2 }, /* 08-0F */
|
||||
{ UNIMAP_F14, UNIMAP_LCTL, UNIMAP_LSHIFT,UNIMAP_NUBS, UNIMAP_CAPS, UNIMAP_Q, UNIMAP_1, UNIMAP_F3 }, /* 10-17 */
|
||||
{ UNIMAP_F15, UNIMAP_LALT, UNIMAP_Z, UNIMAP_S, UNIMAP_A, UNIMAP_W, UNIMAP_2, UNIMAP_F4 }, /* 18-1F */
|
||||
{ UNIMAP_F16, UNIMAP_C, UNIMAP_X, UNIMAP_D, UNIMAP_E, UNIMAP_4, UNIMAP_3, UNIMAP_F5 }, /* 20-27 */
|
||||
{ UNIMAP_F17, UNIMAP_SPACE, UNIMAP_V, UNIMAP_F, UNIMAP_T, UNIMAP_R, UNIMAP_5, UNIMAP_F6 }, /* 28-2F */
|
||||
{ UNIMAP_F18, UNIMAP_N, UNIMAP_B, UNIMAP_H, UNIMAP_G, UNIMAP_Y, UNIMAP_6, UNIMAP_F7 }, /* 30-37 */
|
||||
{ UNIMAP_F19, UNIMAP_RALT, UNIMAP_M, UNIMAP_J, UNIMAP_U, UNIMAP_7, UNIMAP_8, UNIMAP_F8 }, /* 38-3F */
|
||||
{ UNIMAP_F20, UNIMAP_COMMA, UNIMAP_K, UNIMAP_I, UNIMAP_O, UNIMAP_0, UNIMAP_9, UNIMAP_F9 }, /* 40-47 */
|
||||
{ UNIMAP_F21, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_L, UNIMAP_SCOLON,UNIMAP_P, UNIMAP_MINUS, UNIMAP_F10 }, /* 48-4F */
|
||||
{ UNIMAP_F22, UNIMAP_RO, UNIMAP_QUOTE, UNIMAP_NUHS, UNIMAP_LBRC, UNIMAP_EQUAL, UNIMAP_F11, UNIMAP_F23 }, /* 50-57 */
|
||||
{ UNIMAP_RCTL, UNIMAP_RSHIFT,UNIMAP_ENTER, UNIMAP_RBRC, UNIMAP_BSLASH,UNIMAP_JYEN, UNIMAP_F12, UNIMAP_F24 }, /* 58-5F */
|
||||
{ UNIMAP_DOWN, UNIMAP_LEFT, UNIMAP_APP, UNIMAP_UP, UNIMAP_DEL, UNIMAP_END, UNIMAP_BSPACE,UNIMAP_INS }, /* 60-67 */
|
||||
{ UNIMAP_KANA, UNIMAP_P1, UNIMAP_RIGHT, UNIMAP_P4, UNIMAP_P7, UNIMAP_PGDN, UNIMAP_HOME, UNIMAP_PGUP }, /* 68-6F */
|
||||
{ UNIMAP_P0, UNIMAP_PDOT, UNIMAP_P2, UNIMAP_P5, UNIMAP_P6, UNIMAP_P8, UNIMAP_NLCK, UNIMAP_PSLS }, /* 70-77 */
|
||||
{ UNIMAP_PEQL, UNIMAP_PENT, UNIMAP_P3, UNIMAP_PCMM, UNIMAP_PPLS, UNIMAP_P9, UNIMAP_PAST, UNIMAP_PMNS }, /* 78-7F */
|
||||
};
|
||||
|
||||
|
||||
extern const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS];
|
||||
action_t action_for_key(uint8_t layer, keypos_t key)
|
||||
{
|
||||
uint8_t unimap_pos;
|
||||
switch (keyboard_kind) {
|
||||
case PC_XT:
|
||||
unimap_pos = pgm_read_byte(&unimap_cs1[key.row][key.col]);
|
||||
break;
|
||||
case PC_AT:
|
||||
unimap_pos = pgm_read_byte(&unimap_cs2[key.row][key.col]);
|
||||
break;
|
||||
case PC_TERMINAL:
|
||||
unimap_pos = pgm_read_byte(&unimap_cs3[key.row][key.col]);
|
||||
break;
|
||||
default:
|
||||
return (action_t)ACTION_NO;
|
||||
}
|
||||
|
||||
if (unimap_pos == UNIMAP_NO) return (action_t)ACTION_NO;
|
||||
|
||||
return (action_t)pgm_read_word(&actionmaps[(layer)][(unimap_pos & 0x70) >> 4][(unimap_pos & 0x0f)]);
|
||||
}
|
||||
#endif
|
||||
101
converter/pc88_usb/Makefile
Normal file
101
converter/pc88_usb/Makefile
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Target file name (without extension).
|
||||
TARGET ?= pc88_usb
|
||||
|
||||
# Directory common source filess exist
|
||||
TMK_DIR ?= ../../tmk_core
|
||||
|
||||
# Directory keyboard dependent files exist
|
||||
TARGET_DIR ?= .
|
||||
|
||||
# keyboard dependent files
|
||||
# Add one of lines below to select serial protocol implementation
|
||||
# protocol/serial_uart.c
|
||||
# protocol/serial_soft.c
|
||||
SRC ?= matrix.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 ?= atmega32u2 # TMK Converter
|
||||
|
||||
|
||||
# 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
|
||||
COMMAND_ENABLE ?= yes # Commands for debug and configuration
|
||||
#NKRO_ENABLE ?= yes # USB Nkey Rollover
|
||||
##UNIMAP_ENABLE ?= yes
|
||||
|
||||
|
||||
# Boot Section Size in bytes
|
||||
# Teensy halfKay 512
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
|
||||
#
|
||||
# Keymap file
|
||||
#
|
||||
ifeq (yes,$(strip $(UNIMAP_ENABLE)))
|
||||
KEYMAP_FILE = unimap
|
||||
else
|
||||
ifeq (yes,$(strip $(ACTIONMAP_ENABLE)))
|
||||
KEYMAP_FILE = actionmap
|
||||
else
|
||||
KEYMAP_FILE = keymap
|
||||
endif
|
||||
endif
|
||||
ifdef KEYMAP
|
||||
SRC := $(KEYMAP_FILE)_$(KEYMAP).c $(SRC)
|
||||
else
|
||||
SRC := $(KEYMAP_FILE).c $(SRC)
|
||||
endif
|
||||
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TMK_DIR)
|
||||
|
||||
|
||||
include $(TMK_DIR)/protocol/lufa.mk
|
||||
include $(TMK_DIR)/protocol.mk
|
||||
include $(TMK_DIR)/common.mk
|
||||
include $(TMK_DIR)/rules.mk
|
||||
4
converter/pc88_usb/Makefile.32u4
Normal file
4
converter/pc88_usb/Makefile.32u4
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
TARGET ?= pc88_usb_32u4
|
||||
MCU ?= atmega32u4
|
||||
|
||||
include Makefile
|
||||
101
converter/pc88_usb/Makefile.unimap
Normal file
101
converter/pc88_usb/Makefile.unimap
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Target file name (without extension).
|
||||
TARGET ?= pc88_usb_unimap
|
||||
|
||||
# Directory common source filess exist
|
||||
TMK_DIR ?= ../../tmk_core
|
||||
|
||||
# Directory keyboard dependent files exist
|
||||
TARGET_DIR ?= .
|
||||
|
||||
# keyboard dependent files
|
||||
# Add one of lines below to select serial protocol implementation
|
||||
# protocol/serial_uart.c
|
||||
# protocol/serial_soft.c
|
||||
SRC ?= matrix.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 ?= atmega32u2 # TMK Converter
|
||||
|
||||
|
||||
# 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
|
||||
COMMAND_ENABLE ?= yes # Commands for debug and configuration
|
||||
#NKRO_ENABLE ?= yes # USB Nkey Rollover
|
||||
UNIMAP_ENABLE ?= yes
|
||||
|
||||
|
||||
# Boot Section Size in bytes
|
||||
# Teensy halfKay 512
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
|
||||
#
|
||||
# Keymap file
|
||||
#
|
||||
ifeq (yes,$(strip $(UNIMAP_ENABLE)))
|
||||
KEYMAP_FILE = unimap
|
||||
else
|
||||
ifeq (yes,$(strip $(ACTIONMAP_ENABLE)))
|
||||
KEYMAP_FILE = actionmap
|
||||
else
|
||||
KEYMAP_FILE = keymap
|
||||
endif
|
||||
endif
|
||||
ifdef KEYMAP
|
||||
SRC := $(KEYMAP_FILE)_$(KEYMAP).c $(SRC)
|
||||
else
|
||||
SRC := $(KEYMAP_FILE).c $(SRC)
|
||||
endif
|
||||
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TMK_DIR)
|
||||
|
||||
|
||||
include $(TMK_DIR)/protocol/lufa.mk
|
||||
include $(TMK_DIR)/protocol.mk
|
||||
include $(TMK_DIR)/common.mk
|
||||
include $(TMK_DIR)/rules.mk
|
||||
4
converter/pc88_usb/Makefile.unimap.32u4
Normal file
4
converter/pc88_usb/Makefile.unimap.32u4
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
TARGET ?= pc88_usb_32u4_unimap
|
||||
MCU ?= atmega32u4
|
||||
|
||||
include Makefile.unimap
|
||||
73
converter/pc88_usb/README
Normal file
73
converter/pc88_usb/README
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
PC88(Late type) to USB keyboard protocol converter
|
||||
=======================================
|
||||
Target MCU is ATMega32u2 but other USB capable AVR will also work.
|
||||
|
||||
|
||||
README FIRST
|
||||
---------
|
||||
This converter is for TYPE-B keyboard. For keyboards other than TYPE-B,
|
||||
change the mode switch on the back of the keyboard.
|
||||
|
||||
Stand the left foot on the back of the keyboard and there are two slits.
|
||||
There is a mode change switch in the back of it.
|
||||
|
||||
When this switch is up, TYPE-B mode is set.
|
||||
|
||||
When connecting a keyboard to this adapter, be sure to set to TYPE-B mode.
|
||||
|
||||
|
||||
|
||||
Connector
|
||||
---------
|
||||
On host/converter:
|
||||
|
||||
5Pin mini DIN
|
||||
___ ___
|
||||
/ |_| \
|
||||
/ 5 4 \
|
||||
| 3 | 2 |
|
||||
\_ 1 _/
|
||||
\_____/
|
||||
(receptacle)
|
||||
|
||||
|
||||
Wiring: You can change this with editing config.h.
|
||||
|
||||
Pin mini DIN MCU
|
||||
----------------------------------
|
||||
1 5V VCC
|
||||
2 GND GND
|
||||
3 DATA RD2
|
||||
4 NC
|
||||
5 NC
|
||||
|
||||
|
||||
|
||||
|
||||
Protocol
|
||||
--------
|
||||
Signal: Asynchronous, Positive logic, 20800bps, Least bit first
|
||||
Frame format: 1-Start bit(Lo), 8-Data bits, non-Parity, 1-Stop bit
|
||||
|
||||
|
||||
|
||||
Build Firmware
|
||||
--------------
|
||||
Just use 'make' to bild firmware for TMK PC88 converter.
|
||||
|
||||
$ make -f Makefile.unimap clean
|
||||
$ make -f Makefile.unimap
|
||||
|
||||
To flash firmware
|
||||
|
||||
$ make -f Makefile.unimap dfu
|
||||
|
||||
then push button on converter to flash firmware.
|
||||
|
||||
If you are using ATMega32u4 based board instead of premade TMK PC88 converter(ATMega32u2) use following commands.
|
||||
|
||||
$ make -f Makefile.unimap.32u4 clean
|
||||
$ make -f Makefile.unimap.32u4
|
||||
$ make -f Makefile.unimap.32u4 dfu
|
||||
|
||||
|
||||
121
converter/pc88_usb/config.h
Normal file
121
converter/pc88_usb/config.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x8801
|
||||
#define DEVICE_VER 0x0101
|
||||
#define MANUFACTURER t.m.k.
|
||||
#define PRODUCT PC88 keyboard converter
|
||||
#define DESCRIPTION converts PC88 keyboard protocol into USB
|
||||
|
||||
|
||||
/* matrix size */
|
||||
#define MATRIX_ROWS 16
|
||||
#define MATRIX_COLS 8
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->keys[0] == KC_STOP || \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) \
|
||||
)
|
||||
|
||||
|
||||
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
||||
#define LOCKING_SUPPORT_ENABLE
|
||||
/* Locking resynchronize hack */
|
||||
#define LOCKING_RESYNC_ENABLE
|
||||
|
||||
|
||||
/*
|
||||
* PC88 Serial(USART) configuration
|
||||
* asynchronous, positive logic, 20800baud, bit order: LSB first
|
||||
* 1-start bit, 8-data bit, non parity, 1-stop bit
|
||||
*/
|
||||
|
||||
/*
|
||||
* Software Serial
|
||||
* Add protocol/serial_soft.c to SRC in Makefile
|
||||
*/
|
||||
#define SERIAL_SOFT_BAUD 20800
|
||||
#define SERIAL_SOFT_PARITY_NONE
|
||||
#define SERIAL_SOFT_BIT_ORDER_LSB
|
||||
#define SERIAL_SOFT_LOGIC_POSITIVE
|
||||
/* RXD Port */
|
||||
#define SERIAL_SOFT_RXD_DDR DDRD
|
||||
#define SERIAL_SOFT_RXD_PORT PORTD
|
||||
#define SERIAL_SOFT_RXD_PIN PIND
|
||||
#define SERIAL_SOFT_RXD_BIT 2
|
||||
#define SERIAL_SOFT_RXD_READ() (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT))
|
||||
/* RXD Interupt */
|
||||
#define SERIAL_SOFT_RXD_VECT INT2_vect
|
||||
#define SERIAL_SOFT_RXD_INIT() do { \
|
||||
/* pin configuration: input with pull-up */ \
|
||||
SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \
|
||||
SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \
|
||||
/* enable interrupt: INT2(falling edge) */ \
|
||||
EICRA |= ((1<<ISC21)|(0<<ISC20)); \
|
||||
EIMSK |= (1<<INT2); \
|
||||
sei(); \
|
||||
} while (0)
|
||||
#define SERIAL_SOFT_RXD_INT_ENTER()
|
||||
#define SERIAL_SOFT_RXD_INT_EXIT() do { \
|
||||
/* clear interrupt flag */ \
|
||||
EIFR = (1<<INTF2); \
|
||||
} while (0)
|
||||
/* TXD Port */
|
||||
#define SERIAL_SOFT_TXD_DDR DDRD
|
||||
#define SERIAL_SOFT_TXD_PORT PORTD
|
||||
#define SERIAL_SOFT_TXD_PIN PIND
|
||||
#define SERIAL_SOFT_TXD_BIT 3
|
||||
#define SERIAL_SOFT_TXD_HI() do { SERIAL_SOFT_TXD_PORT |= (1<<SERIAL_SOFT_TXD_BIT); } while (0)
|
||||
#define SERIAL_SOFT_TXD_LO() do { SERIAL_SOFT_TXD_PORT &= ~(1<<SERIAL_SOFT_TXD_BIT); } while (0)
|
||||
#define SERIAL_SOFT_TXD_INIT() do { \
|
||||
/* pin configuration: output */ \
|
||||
SERIAL_SOFT_TXD_DDR |= (1<<SERIAL_SOFT_TXD_BIT); \
|
||||
/* idle */ \
|
||||
SERIAL_SOFT_TXD_ON(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Hardware Serial(UART)
|
||||
* Add protocol/serial_uart.c to SRC in Makefile
|
||||
*/
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__)
|
||||
#define SERIAL_UART_BAUD 20800
|
||||
#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<<UDRE1))
|
||||
#define SERIAL_UART_INIT() do { \
|
||||
UBRR1L = (uint8_t) SERIAL_UART_UBRR; /* baud rate */ \
|
||||
UBRR1H = (uint8_t) (SERIAL_UART_UBRR>>8); /* baud rate */ \
|
||||
UCSR1B |= (1<<RXCIE1) | (1<<RXEN1); /* RX interrupt, RX: enable */ \
|
||||
UCSR1B |= (0<<TXCIE1) | (1<<TXEN1); /* TX interrupt, TX: enable */ \
|
||||
UCSR1C |= (0<<UPM11) | (0<<UPM10); /* parity: none(00), even(01), odd(11) */ \
|
||||
DDRD &= ~(1<<2); PORTD |= (1<<2); /* Pull-up RXD pin */ \
|
||||
sei(); \
|
||||
} while(0)
|
||||
#else
|
||||
#error "USART configuration is needed."
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
130
converter/pc88_usb/keymap.c
Normal file
130
converter/pc88_usb/keymap.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "keycode.h"
|
||||
#include "action.h"
|
||||
#include "util.h"
|
||||
#include "serial.h"
|
||||
#include "keymap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
// Following macros help you to define a keymap with the form of actual keyboard layout.
|
||||
|
||||
/* Keyboard Scan codes
|
||||
* ,---. ,---. ,------------------------. ,------------------------. ,-------.
|
||||
* | 60| | 61| | 62 | 63 | 64 | 65 | 66 | | 67 | 68 | 69 | 6A | 6B | | 36| 37|
|
||||
* `---' `---' `------------------------' `------------------------' `-------'
|
||||
* ,---------------------------------------------------------------. ,-------. ,---------------.
|
||||
* | 00 | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 0E | | 38| 39| | 3E| 3F| 4D| 41|
|
||||
* |---------------------------------------------------------------| `-------' |---------------|
|
||||
* | 0F | 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| | | 42| 43| 44| 45|
|
||||
* |--------------------------------------------------------` 1C | ,-------. |---------------|
|
||||
* | 74| 71| 1D| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| | | 3A | | 46| 47| 48| 49|
|
||||
* |---------------------------------------------------------------| |-------| |---------------|
|
||||
* | 70 | 29| 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 78 | | 3B| 3C| | 4A| 4B| 4C| 4D|
|
||||
* `---------------------------------------------------------------' |-------| |---------------|
|
||||
* | 72| 73| 51 | 34 | 35 | 7A| 7B| | 3D | | 4E| 4F| 50| 79|
|
||||
* `-------------------------------------------' `-------' `---------------'
|
||||
*/
|
||||
|
||||
#define KEYMAP( \
|
||||
K60, K61, K62, K63, K64, K65, K66, K67, K68, K69, K6A, K6B, K36, K37, \
|
||||
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K38, K39, K3E, K3F, K40, K41, \
|
||||
K0F, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K42, K43, K44, K45, \
|
||||
K74, K71, K1D, K1E, K1F, K20, K21, K22, K23, K24, K25, K26, K27,K28, K3A, K46, K47, K48, K49, \
|
||||
K70, K29, K2A, K2B, K2C, K2D, K2E, K2F, K30, K31, K32, K33, K78, K3B, K3C, K4A, K4B, K4C, K4D, \
|
||||
K72, K73, K51, K34, K35, K7A, K7B, K3D, K4E, K4F, K50, K79 \
|
||||
) { \
|
||||
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
|
||||
{ KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, 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_##K1E, 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_##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_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_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
|
||||
{ KC_##K68, KC_##K69, KC_##K6A, KC_##K6B, KC_NO, KC_NO, KC_NO, KC_NO }, \
|
||||
{ KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_NO, KC_NO, KC_NO }, \
|
||||
{ KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_NO, KC_NO, KC_NO, KC_NO } \
|
||||
}
|
||||
|
||||
|
||||
const action_t fn_actions[] PROGMEM = {
|
||||
[0] = ACTION_FUNCTION(0), // toggle all LEDs
|
||||
};
|
||||
|
||||
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
{
|
||||
static bool led = false;
|
||||
switch (id) {
|
||||
case 0:
|
||||
if (record->event.pressed) {
|
||||
if ((led = !led))
|
||||
serial_send(0x80); // all on
|
||||
else
|
||||
serial_send(0xff); // all off
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Keyboard Scan codes
|
||||
* ,---. ,---. ,------------------------. ,------------------------. ,-------.
|
||||
* | 60| | 61| | 62 | 63 | 64 | 65 | 66 | | 67 | 68 | 69 | 6A | 6B | | 36| 37|
|
||||
* `---' `---' `------------------------' `------------------------' `-------'
|
||||
* ,---------------------------------------------------------------. ,-------. ,---------------.
|
||||
* | 00 | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 0E | | 38| 39| | 3E| 3F| 4D| 41|
|
||||
* |---------------------------------------------------------------| `-------' |---------------|
|
||||
* | 0F | 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| | | 42| 43| 44| 45|
|
||||
* |--------------------------------------------------------` 1C | ,-------. |---------------|
|
||||
* | 74| 71| 1D| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| | | 3A | | 46| 47| 48| 49|
|
||||
* |---------------------------------------------------------------| |-------| |---------------|
|
||||
* | 70 | 29| 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 78 | | 3B| 3C| | 4A| 4B| 4C| 4D|
|
||||
* `---------------------------------------------------------------' |-------| |---------------|
|
||||
* | 72| 73| 51 | 34 | 35 | 7A| 7B| | 3D | | 4E| 4F| 50| 79|
|
||||
* `-------------------------------------------' `-------' `---------------'
|
||||
*/
|
||||
/* ANSI */
|
||||
KEYMAP(
|
||||
PAUS,PSCR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, PGDN,PGUP,
|
||||
ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL, BSLS,BSPC, INS, DEL, HOME, END,PMNS,PSLS,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, ENT, P7, P8, P9, PAST,
|
||||
LCTL,LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT,F18, UP, P4, P5, P6, PPLS,
|
||||
LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH,GRV, RSFT, LEFT,RGHT, P1, P2, P3, PEQL,
|
||||
F19, LGUI,LALT, SPC, RALT, APP, RGUI, DOWN, P0, PCMM,PDOT,PENT
|
||||
),
|
||||
/* JIS */
|
||||
KEYMAP(
|
||||
PAUS, PSCR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, PGDN,PGUP,
|
||||
ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL, JYEN,BSPC, INS, DEL, HOME, END,PMNS,PSLS,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, ENT, P7, P8, P9, PAST,
|
||||
LCTL,LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT,NUHS, UP, P4, P5, P6, PPLS,
|
||||
LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH,RO, RSFT, LEFT,RGHT, P1, P2, P3, PEQL,
|
||||
KANA,LALT,MHEN, SPC, HENK, RGUI,ZKHK, DOWN, P0, PCMM,PDOT,PENT
|
||||
),
|
||||
};
|
||||
95
converter/pc88_usb/matrix.c
Normal file
95
converter/pc88_usb/matrix.c
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "print.h"
|
||||
#include "util.h"
|
||||
#include "matrix.h"
|
||||
#include "led.h"
|
||||
#include "debug.h"
|
||||
#include "protocol/serial.h"
|
||||
|
||||
|
||||
/*
|
||||
* Matrix Array usage:
|
||||
*
|
||||
* ROW: 16(4bits)
|
||||
* COL: 8(3bits)
|
||||
*
|
||||
* 8bit wide
|
||||
* +---------+
|
||||
* 0|00 ... 07|
|
||||
* 1|08 ... 0F|
|
||||
* :| ... |
|
||||
* :| ... |
|
||||
* E|70 ... 77|
|
||||
* F|78 ... 7F|
|
||||
* +---------+
|
||||
*/
|
||||
static uint8_t matrix[MATRIX_ROWS];
|
||||
#define ROW(code) ((code>>3)&0xF)
|
||||
#define COL(code) (code&0x07)
|
||||
|
||||
void matrix_init(void)
|
||||
{
|
||||
debug_keyboard = true;
|
||||
|
||||
serial_init();
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
|
||||
|
||||
print("matrix_init done.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
uint16_t code;
|
||||
code = serial_recv2();
|
||||
if (code == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
print_hex8(code); print(" ");
|
||||
|
||||
if (code&0x80) {
|
||||
// break code
|
||||
if (matrix_is_on(ROW(code), COL(code))) {
|
||||
matrix[ROW(code)] &= ~(1<<COL(code));
|
||||
}
|
||||
} else {
|
||||
// make code
|
||||
if (!matrix_is_on(ROW(code), COL(code))) {
|
||||
matrix[ROW(code)] |= (1<<COL(code));
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
inline
|
||||
uint8_t matrix_get_row(uint8_t row)
|
||||
{
|
||||
return matrix[row];
|
||||
}
|
||||
|
||||
void led_set(uint8_t usb_led)
|
||||
{
|
||||
}
|
||||
45
converter/pc88_usb/unimap.c
Normal file
45
converter/pc88_usb/unimap.c
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2017 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "unimap_trans.h"
|
||||
|
||||
|
||||
#define AC_FN0 ACTION_LAYER_MOMENTARY(1)
|
||||
|
||||
#ifdef KEYMAP_SECTION_ENABLE
|
||||
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
|
||||
#else
|
||||
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
|
||||
#endif
|
||||
UNIMAP(
|
||||
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, VOLD,VOLU,MUTE,
|
||||
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS,
|
||||
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, P4, P5, P6, COMM,
|
||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RO, RSFT, UP, P1, P2, P3, PENT,
|
||||
LCTL,LGUI,LALT,MHEN, SPC, HENK,KANA,RALT,RGUI,FN0, RCTL, LEFT,DOWN,RGHT, P0, DOT, PEQL
|
||||
),
|
||||
UNIMAP(
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
|
||||
GRV, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS,TRNS, PGUP, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, HOME,PGDN,END, TRNS, TRNS,TRNS
|
||||
),
|
||||
};
|
||||
64
converter/pc88_usb/unimap_trans.h
Normal file
64
converter/pc88_usb/unimap_trans.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2018 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _TRANS_H
|
||||
#define _TRANS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "unimap.h"
|
||||
|
||||
|
||||
/* Mapping PC88 scan codes to UNIMAP layout codes
|
||||
*
|
||||
* PC88 scan codes
|
||||
* ,---. ,---. ,------------------------. ,------------------------. ,-------.
|
||||
* | 60| | 61| | 62 | 63 | 64 | 65 | 66 | | 67 | 68 | 69 | 6A | 6B | | 36| 37|
|
||||
* `---' `---' `------------------------' `------------------------' `-------'
|
||||
* ,---------------------------------------------------------------. ,-------. ,---------------.
|
||||
* | 00 | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| 0D| 0E | | 38| 39| | 3E| 3F| 4D| 41|
|
||||
* |---------------------------------------------------------------| `-------' |---------------|
|
||||
* | 0F | 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| | | 42| 43| 44| 45|
|
||||
* |--------------------------------------------------------` 1C | ,-------. |---------------|
|
||||
* | 74| 71| 1D| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| 28| | | 3A | | 46| 47| 48| 49|
|
||||
* |---------------------------------------------------------------| |-------| |---------------|
|
||||
* | 70 | 29| 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 78 | | 3B| 3C| | 4A| 4B| 4C| 4D|
|
||||
* `---------------------------------------------------------------' |-------| |---------------|
|
||||
* | 72| 73| 51 | 34 | 35 | 7A| 7B| | 3D | | 4E| 4F| 50| 79|
|
||||
* `-------------------------------------------' `-------' `---------------'
|
||||
*
|
||||
*
|
||||
*/
|
||||
const uint8_t PROGMEM unimap_trans[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
{ UNIMAP_ESC, UNIMAP_1, UNIMAP_2, UNIMAP_3, UNIMAP_4, UNIMAP_5, UNIMAP_6, UNIMAP_7 }, /* 00-07 */
|
||||
{ UNIMAP_8, UNIMAP_9, UNIMAP_0, UNIMAP_MINS, UNIMAP_EQL, UNIMAP_JYEN, UNIMAP_BSPC, UNIMAP_TAB }, /* 08-0F */
|
||||
{ UNIMAP_Q, UNIMAP_W, UNIMAP_E, UNIMAP_R, UNIMAP_T, UNIMAP_Y, UNIMAP_U, UNIMAP_I }, /* 10-17 */
|
||||
{ UNIMAP_O, UNIMAP_P, UNIMAP_LBRC, UNIMAP_RBRC, UNIMAP_ENT, UNIMAP_A, UNIMAP_S, UNIMAP_D }, /* 18-1F */
|
||||
{ UNIMAP_F, UNIMAP_G, UNIMAP_H, UNIMAP_J, UNIMAP_K, UNIMAP_L, UNIMAP_SCLN, UNIMAP_QUOT }, /* 20-27 */
|
||||
{ UNIMAP_BSLS, UNIMAP_Z, UNIMAP_X, UNIMAP_C, UNIMAP_V, UNIMAP_B, UNIMAP_N, UNIMAP_M }, /* 28-2F */
|
||||
{ UNIMAP_COMM, UNIMAP_DOT, UNIMAP_SLSH, UNIMAP_RO, UNIMAP_SPC, UNIMAP_HENK, UNIMAP_PGDN, UNIMAP_PGUP }, /* 30-37 */
|
||||
{ UNIMAP_INS, UNIMAP_DEL, UNIMAP_UP, UNIMAP_LEFT, UNIMAP_RGHT, UNIMAP_DOWN, UNIMAP_HOME, UNIMAP_END }, /* 38-3F */
|
||||
{ UNIMAP_PMNS, UNIMAP_PSLS, UNIMAP_P7, UNIMAP_P8, UNIMAP_P9, UNIMAP_PAST, UNIMAP_P4, UNIMAP_P5 }, /* 40-47 */
|
||||
{ UNIMAP_P6, UNIMAP_PPLS, UNIMAP_P1, UNIMAP_P2, UNIMAP_P3, UNIMAP_PEQL, UNIMAP_P0, UNIMAP_PCMM }, /* 48-4F */
|
||||
{ UNIMAP_PDOT, UNIMAP_MHEN, UNIMAP_F11, UNIMAP_F12, UNIMAP_F13, UNIMAP_F14, UNIMAP_F15, UNIMAP_NO }, /* 50-57 */
|
||||
{ UNIMAP_F21, UNIMAP_F22, UNIMAP_F23, UNIMAP_F24, UNIMAP_NO, UNIMAP_NO, UNIMAP_APP, UNIMAP_NO }, /* 58-5F */
|
||||
{ UNIMAP_PAUS, UNIMAP_PSCR, UNIMAP_F1, UNIMAP_F2, UNIMAP_F3, UNIMAP_F4, UNIMAP_F5, UNIMAP_F6 }, /* 60-67 */
|
||||
{ UNIMAP_F7, UNIMAP_F8, UNIMAP_F9, UNIMAP_F10, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO }, /* 68-6F */
|
||||
{ UNIMAP_LSFT, UNIMAP_CAPS, UNIMAP_KANA, UNIMAP_LALT, UNIMAP_LCTL, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO }, /* 70-77 */
|
||||
{ UNIMAP_RSFT, UNIMAP_PENT, UNIMAP_RGUI, UNIMAP_GRV, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO } /* 78-7F */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -50,7 +50,7 @@ ARCH ?= AVR8
|
|||
F_USB ?= $(F_CPU)
|
||||
|
||||
# Interrupt driven control endpoint task
|
||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
|
||||
|
||||
# Build Options
|
||||
|
|
|
|||
|
|
@ -64,23 +64,23 @@ If you are using ATMega32u4 based board instead of premade TMK PC98 converter(AT
|
|||
PC98 Scan Codes
|
||||
---------------
|
||||
,---. ,---. ,------------------------. ,------------------------. ,------------------------.
|
||||
|Pau| |PrS| | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10| | F11| F12| F13| F14| F15|
|
||||
|Stp| |Cpy| | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10| | F11| F12| F13| F14| F15|
|
||||
`---' `---' `------------------------' `------------------------' `------------------------'
|
||||
,-------------------------------------------------------------. ,-------. ,---------------.
|
||||
| Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|JPY|Bspc| |Ins|Del| |Hom|End| -| /|
|
||||
| Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|JPY|Bspc| |Ins|Del| |Hom|Hlp| -| /|
|
||||
|-------------------------------------------------------------| |-------| |---------------|
|
||||
| Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | |PgD|PgU| | 7| 8| 9| *|
|
||||
| Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | |RUp|RDn| | 7| 8| 9| *|
|
||||
|-------------------------------------------------------`Enter| |-------| |---------------|
|
||||
|Ctl|Cap| A| S| D| F| G| H| J| K| L| ;| '| \| | | Up | | 4| 5| 6| +|
|
||||
|-------------------------------------------------------------| |-------| |---------------|
|
||||
| Shift | Z| X| C| V| B| N| M| ,| .| /| RO| Shift | |Lef|Rig| | 1| 2| 3| =|
|
||||
`-------------------------------------------------------------' |-------| |---------------|
|
||||
^3|Kana|Gui|Alt|MHEN| Space |HENK|Alt|Gui|App|^2 | Down | | 0| ,| .| ^1|
|
||||
|Kana|Win|GRP|NFER| Space |XFER| ^2|Win| ^3| | Down | | 0| ,| .| ^1|
|
||||
`-------------------------------------------------------' `-------' `---------------'
|
||||
^1: Enter on keypad is identical to Enter on alphanumeric portion.
|
||||
^2: Right Alt is ALT on DIGITAL WAVE Dboard while Menu on PC-9821 keyboard.
|
||||
App is HOME key on PC98XL keyboard.
|
||||
^3: Caps and Kana are locking keys, either mechanically or by firmware emulation.
|
||||
^1: Enter on keypad is identical to Enter on alphanumeric portion
|
||||
^2: ALT on DIGITAL WAVE Dboard while Menu on PC-9821 keyboard
|
||||
^3: HOME on PC98XL keyboard
|
||||
^4: CAPS and Kana are locking keys, either mechanically or by firmware emulation
|
||||
|
||||
|
||||
,---. ,---. ,------------------------. ,------------------------. ,------------------------.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->keys[0] == KC_STOP || \
|
||||
matrix_is_on(12, 0) || /* STOP */ \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) \
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -71,12 +71,12 @@ static void pc98_inhibit_repeat(void)
|
|||
RETRY:
|
||||
pc98_send(0x9C);
|
||||
code = pc98_wait_response();
|
||||
if (code != -1) xprintf("send 9C: %02X\n", code);
|
||||
if (code != -1) dprintf("send 9C: %02X\n", code);
|
||||
if (code != 0xFA) return;
|
||||
|
||||
pc98_send(0x70);
|
||||
code = pc98_wait_response();
|
||||
if (code != -1) xprintf("send 70: %02X\n", code);
|
||||
if (code != -1) dprintf("send 70: %02X\n", code);
|
||||
if (code != 0xFA) goto RETRY;
|
||||
}
|
||||
|
||||
|
|
@ -87,18 +87,17 @@ static void pc98_led_set(void)
|
|||
RETRY:
|
||||
pc98_send(0x9D);
|
||||
code = pc98_wait_response();
|
||||
if (code != -1) xprintf("send 9D: %02X\n", code);
|
||||
if (code != -1) dprintf("send 9D: %02X\n", code);
|
||||
if (code != 0xFA) return;
|
||||
|
||||
pc98_send(pc98_led);
|
||||
code = pc98_wait_response();
|
||||
if (code != -1) xprintf("send %02X: %02X\n", pc98_led, code);
|
||||
if (code != -1) dprintf("send %02X: %02X\n", pc98_led, code);
|
||||
if (code != 0xFA) goto RETRY;
|
||||
}
|
||||
|
||||
void matrix_init(void)
|
||||
{
|
||||
debug_keyboard = true;
|
||||
PC98_RST_DDR |= (1<<PC98_RST_BIT);
|
||||
PC98_RDY_DDR |= (1<<PC98_RDY_BIT);
|
||||
PC98_RTY_DDR |= (1<<PC98_RTY_BIT);
|
||||
|
|
@ -125,7 +124,6 @@ void matrix_init(void)
|
|||
// ready to receive from keyboard
|
||||
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); // RDY: low
|
||||
|
||||
print("matrix_init done.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +143,7 @@ uint8_t matrix_scan(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
print_hex8(code); print(" ");
|
||||
dprintf("%02X ", code);
|
||||
|
||||
if (code&0x80) {
|
||||
// break code
|
||||
|
|
@ -180,6 +178,6 @@ void led_set(uint8_t usb_led)
|
|||
pc98_led = 0x70;
|
||||
if (usb_led & (1<<USB_LED_NUM_LOCK)) pc98_led |= (1<<0);
|
||||
if (usb_led & (1<<USB_LED_CAPS_LOCK)) pc98_led |= (1<<2);
|
||||
xprintf("usb_led: %02X\n", usb_led);
|
||||
xprintf("pc98_led: %02X\n", pc98_led);
|
||||
dprintf("usb_led: %02X\n", usb_led);
|
||||
dprintf("pc98_led: %02X\n", pc98_led);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
|
|||
#endif
|
||||
/*
|
||||
,---. ,---. ,------------------------. ,------------------------. ,------------------------.
|
||||
|Pau| |PrS| | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10| | F11| F12| F13| F14| F15|
|
||||
| | |PrS| | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10| | F11| F12| F13| F14| F15|
|
||||
`---' `---' `------------------------' `------------------------' `------------------------'
|
||||
,-------------------------------------------------------------. ,-------. ,---------------.
|
||||
| Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|JPY|Bspc| |Ins|Del| |Hom|End| -| /|
|
||||
|
|
@ -42,7 +42,7 @@ const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
|
|||
Caps and Kana are locking keys.
|
||||
*/
|
||||
UNIMAP_PC98(
|
||||
PAUS,PSCR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,
|
||||
NO, PSCR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,
|
||||
ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, DEL, HOME,END, PMNS,PSLS,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, PGDN,PGUP, P7, P8, P9, PAST,
|
||||
LCTL,LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT,BSLS,ENT, UP, P4, P5, P6, PPLS,
|
||||
|
|
|
|||
20
converter/ps2_usb/Makefile.32u4
Normal file
20
converter/ps2_usb/Makefile.32u4
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
TARGET ?= ps2_usb_32u4
|
||||
MCU = atmega32u4
|
||||
CONFIG_H = config.h
|
||||
BOOTLOADER_SIZE = 4096
|
||||
|
||||
BOOTMAGIC_ENABLE ?= no
|
||||
MOUSEKEY_ENABLE ?= yes
|
||||
EXTRAKEY_ENABLE ?= yes
|
||||
CONSOLE_ENABLE ?= yes
|
||||
COMMAND_ENABLE ?= yes
|
||||
NKRO_ENABLE ?= yes
|
||||
|
||||
PS2_USE_USART = no
|
||||
PS2_USE_INT = yes
|
||||
PS2_USE_BUSYWAIT = no
|
||||
|
||||
UNIMAP_ENABLE = yes
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
|
||||
include Makefile
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
TARGET ?= ps2_usb_rev1
|
||||
TARGET ?= ps2_usb_rev1_unimap
|
||||
MCU = atmega32u4
|
||||
CONFIG_H = config_rev1.h
|
||||
CONFIG_H = config.h
|
||||
BOOTLOADER_SIZE = 4096
|
||||
|
||||
BOOTMAGIC_ENABLE ?= no
|
||||
|
|
@ -14,4 +14,7 @@ PS2_USE_USART = yes
|
|||
PS2_USE_INT = no
|
||||
PS2_USE_BUSYWAIT = no
|
||||
|
||||
UNIMAP_ENABLE = yes
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
|
||||
include Makefile
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
TARGET ?= ps2_usb_rev2
|
||||
TARGET ?= ps2_usb_rev2_unimap
|
||||
MCU = atmega32u2
|
||||
CONFIG_H = config_rev2.h
|
||||
CONFIG_H = config.h
|
||||
BOOTLOADER_SIZE = 4096
|
||||
|
||||
BOOTMAGIC_ENABLE ?= no
|
||||
|
|
@ -14,4 +14,7 @@ PS2_USE_USART = no
|
|||
PS2_USE_INT = yes
|
||||
PS2_USE_BUSYWAIT = no
|
||||
|
||||
UNIMAP_ENABLE = yes
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
|
||||
include Makefile
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
TARGET = ps2_usb_rev1_unimap
|
||||
UNIMAP_ENABLE = yes
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
|
||||
include Makefile.rev1
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
TARGET = ps2_usb_rev2_unimap
|
||||
UNIMAP_ENABLE = yes
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
#LUFA_DEBUG_SUART = yes
|
||||
|
||||
include Makefile.rev2
|
||||
|
|
@ -2,17 +2,14 @@ PS/2 to USB keyboard converter
|
|||
==============================
|
||||
This firmware converts PS/2 keyboard protocol to USB.(It supports Scan Code Set 2.)
|
||||
|
||||
You can discuss about this converter here.
|
||||
|
||||
Connect Wires
|
||||
-------------
|
||||
1. Connect **Vcc** and **GND**.
|
||||
2. Connect **Clock** and **Data** line.
|
||||
- **Interrupt**: **Clock** is on `PD1` and **Data** on `PD0`.(Recommended. Soarer's converter compatible)
|
||||
- **Busywait**: **Clock** is on `PD1` and **Data** on `PD0`.
|
||||
- **USART**: **Clock** is on `PD5` and **Data** on `PD2`.
|
||||
3. You need pull-up resistors. 1K-10K Ohm would be fine.
|
||||
https://geekhack.org/index.php?topic=14618.0
|
||||
|
||||
To change pin configuration edit **config.h** and **Makefile**.
|
||||
|
||||
Preassembled TMK PS/2-USB converter is available here.
|
||||
|
||||
https://geekhack.org/index.php?topic=72052.0
|
||||
|
||||
|
||||
Build Firmware
|
||||
|
|
@ -27,32 +24,47 @@ To program firmware push the button on converter and run:
|
|||
$ make -f Makefile.rev2 KEYMAP=plain dfu
|
||||
|
||||
|
||||
- For **TMK converter Rev.1** use `make -f Makefile.rev1` instead.
|
||||
- To select keymap use `jis`, `spacefn` or your own in place of `plain`.
|
||||
For **TMK converter Rev.1** use `Makefile.rev1` instead.
|
||||
|
||||
If your use DIY converter with ATMega32u4 board you can use `Makefile.32u4`, but note that progarmming with 'dfu' may not work for your converter.
|
||||
|
||||
|
||||
Build your own converter
|
||||
------------------------
|
||||
Use ATMega32u4 as controller and Makefile.32u4 to build firmware.
|
||||
|
||||
1. Wire **Vcc** and **GND** properly.
|
||||
2. Connect **Clock** to `PD1` and **Data** to `PD0` line. (Compatible to Soarer's converter pin configuration)
|
||||
3. You need pull-up resistors on both signal lines. 1K-10K Ohm would be fine.
|
||||
|
||||
You can configure controller and pin configurations in Makefile and config.h.
|
||||
|
||||
|
||||
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_<name>.c` and see keymap document(you can find in README.md of top directory) and existent keymap files.
|
||||
To define your own keymap copy `unimap_plain.c` to `unimap_<name>.c` and edit it. Or just edit `unimap_plain.c` directly.
|
||||
|
||||
See wiki pages and documents.
|
||||
|
||||
https://github.com/tmk/tmk_keyboard/wiki
|
||||
|
||||
|
||||
PS/2 signal handling implementations
|
||||
------------------------------------
|
||||
Following three methods can be used to implement PS/2 signal handling.
|
||||
Following three methods are available 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.
|
||||
- **Interrupt** Uses pin interrupt to detect falling edge of clock line. **Recommended.** (ps2_interrupt.c)
|
||||
- **Busywait** Implementation with portable C code for reference. (ps2_busywait.c)
|
||||
- **USART** Uses AVR USART hardware engine to receive PS/2 signal. You must use this fothis for V-USB. (ps2_usart.c)
|
||||
|
||||
To select method edit Makefile.
|
||||
TMK converter rev1 uses **USART** and rev2 uses **Interrupt** for reference.
|
||||
|
||||
You can change method by editing `Makefile` but not needed in most case.
|
||||
|
||||
|
||||
V-USB Support
|
||||
-------------
|
||||
With V-USB you can use this converter on ATmega(168/328) but it doesn't support NKRO at this time.
|
||||
With V-USB you can use this converter on ATmega(168/328). Use Makefile.vusb to build firmeware. Not supported actively anymore.
|
||||
|
||||
Circuit:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#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_LALT) | MOD_BIT(KC_RALT)) \
|
||||
)
|
||||
|
||||
|
||||
//#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<<PS2_CLOCK_BIT); \
|
||||
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
|
||||
UCSR1C = ((1 << UMSEL10) | \
|
||||
(3 << UPM10) | \
|
||||
(0 << USBS1) | \
|
||||
(3 << UCSZ10) | \
|
||||
(0 << UCPOL1)); \
|
||||
UCSR1A = 0; \
|
||||
UBRR1H = 0; \
|
||||
UBRR1L = 0; \
|
||||
} while (0)
|
||||
#define PS2_USART_RX_INT_ON() do { \
|
||||
UCSR1B = ((1 << RXCIE1) | \
|
||||
(1 << RXEN1)); \
|
||||
} while (0)
|
||||
#define PS2_USART_RX_POLL_ON() do { \
|
||||
UCSR1B = (1 << RXEN1); \
|
||||
} while (0)
|
||||
#define PS2_USART_OFF() do { \
|
||||
UCSR1C = 0; \
|
||||
UCSR1B &= ~((1 << RXEN1) | \
|
||||
(1 << TXEN1)); \
|
||||
} while (0)
|
||||
#define PS2_USART_RX_READY (UCSR1A & (1<<RXC1))
|
||||
#define PS2_USART_RX_DATA UDR1
|
||||
#define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
|
||||
#define PS2_USART_RX_VECT USART1_RX_vect
|
||||
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
|
||||
/* 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 4
|
||||
#define PS2_DATA_PORT PORTD
|
||||
#define PS2_DATA_PIN PIND
|
||||
#define PS2_DATA_DDR DDRD
|
||||
#define PS2_DATA_BIT 0
|
||||
/* 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<<PS2_CLOCK_BIT); \
|
||||
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
|
||||
UCSR0C = ((1 << UMSEL00) | \
|
||||
(3 << UPM00) | \
|
||||
(0 << USBS0) | \
|
||||
(3 << UCSZ00) | \
|
||||
(0 << UCPOL0)); \
|
||||
UCSR0A = 0; \
|
||||
UBRR0H = 0; \
|
||||
UBRR0L = 0; \
|
||||
} while (0)
|
||||
#define PS2_USART_RX_INT_ON() do { \
|
||||
UCSR0B = ((1 << RXCIE0) | \
|
||||
(1 << RXEN0)); \
|
||||
} while (0)
|
||||
#define PS2_USART_RX_POLL_ON() do { \
|
||||
UCSR0B = (1 << RXEN0); \
|
||||
} while (0)
|
||||
#define PS2_USART_OFF() do { \
|
||||
UCSR0C = 0; \
|
||||
UCSR0B &= ~((1 << RXEN0) | \
|
||||
(1 << TXEN0)); \
|
||||
} while (0)
|
||||
#define PS2_USART_RX_READY (UCSR0A & (1<<RXC0))
|
||||
#define PS2_USART_RX_DATA UDR0
|
||||
#define PS2_USART_ERROR (UCSR0A & ((1<<FE0) | (1<<DOR0) | (1<<UPE0)))
|
||||
#define PS2_USART_RX_VECT USART_RX_vect
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#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_LALT) | MOD_BIT(KC_RALT)) \
|
||||
)
|
||||
|
||||
|
||||
//#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<<ISC11) | \
|
||||
(0<<ISC10)); \
|
||||
} while (0)
|
||||
#define PS2_INT_ON() do { \
|
||||
EIMSK |= (1<<INT1); \
|
||||
} while (0)
|
||||
#define PS2_INT_OFF() do { \
|
||||
EIMSK &= ~(1<<INT1); \
|
||||
} while (0)
|
||||
#define PS2_INT_VECT INT1_vect
|
||||
#endif
|
||||
|
||||
#ifdef LUFA_DEBUG_SUART
|
||||
# define SUART_OUT_DDR DDRD
|
||||
# define SUART_OUT_PORT PORTD
|
||||
# define SUART_OUT_BIT 4
|
||||
# define SUART_IN_DDR DDRD
|
||||
# define SUART_IN_PIN PIND
|
||||
# define SUART_IN_BIT 4
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -15,6 +15,7 @@ Data: PD0
|
|||
Clock: PD1
|
||||
|
||||
And VCC and GND, of course. See RESOURCE for keyboard connector pin assign.
|
||||
Use 1K ohm pull-up resisters on the signal lines.
|
||||
|
||||
|
||||
BUILD
|
||||
|
|
@ -27,10 +28,21 @@ $ make
|
|||
RESOURCE
|
||||
--------
|
||||
Soarer's Converter: http://geekhack.org/index.php?topic=17458.0
|
||||
102keys(1392595): http://geekhack.org/index.php?topic=10737.0
|
||||
122keys(1390876): http://www.seasip.info/VintagePC/ibm_1390876.html
|
||||
KbdBabel: http://www.kbdbabel.org/
|
||||
RJ45 Connector: http://www.kbdbabel.org/conn/kbd_connector_ibmterm.png
|
||||
DIN Connector: http://www.kbdbabel.org/conn/kbd_connector_ibm3179_318x_319x.png
|
||||
|
||||
|
||||
Terminal keyboards
|
||||
------------------
|
||||
122-key
|
||||
1390876 http://www.seasip.info/VintagePC/ibm_1390876.html
|
||||
6110344 http://www.seasip.info/VintagePC/ibm_6110344.html
|
||||
|
||||
102-key
|
||||
1392595 https://deskthority.net/viewtopic.php?t=8371 https://geekhack.org/index.php?topic=10737.0
|
||||
1386303 https://geekhack.org/index.php?topic=66959.0
|
||||
1391406 http://www.seasip.info/VintagePC/ibm_1391406.html
|
||||
|
||||
|
||||
EOF
|
||||
|
|
|
|||
|
|
@ -26,19 +26,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
|
||||
/*
|
||||
* IBM Terminal keyboard 6110345(122keys)/1392595(102keys)
|
||||
* http://geekhack.org/showthread.php?10737-What-Can-I-Do-With-a-Terminal-Model-M
|
||||
/*
|
||||
* IBM Terminal keyboard 122-key
|
||||
* http://www.seasip.info/VintagePC/ibm_1391406.html
|
||||
*
|
||||
* Keymap array:
|
||||
* 8 bytes
|
||||
* +---------+
|
||||
* 0| |
|
||||
* :| | 0x00-0x87
|
||||
* ;| |
|
||||
* 17| |
|
||||
* +---------+
|
||||
*/
|
||||
#define KEYMAP( \
|
||||
K08,K10,K18,K20,K28,K30,K38,K40,K48,K50,K57,K5F, \
|
||||
|
|
@ -69,21 +59,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
{ KC_NO, KC_NO, KC_NO, KC_##K83, KC_##K84, KC_NO, KC_NO, KC_NO, }, \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IBM Terminal keyboard 1399625, 101-key
|
||||
* IBM Terminal keyboard 102-key
|
||||
* http://www.seasip.info/VintagePC/ibm_1391406.html
|
||||
*/
|
||||
#define KEYMAP_101( \
|
||||
K08, K07,K0F,K17,K1F,K27,K2F,K37,K3F,K47,K4F,K56,K5E, K57,K5F,K62, \
|
||||
\
|
||||
K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, K67,K6E,K6F, K76,K77,K7E,K84, \
|
||||
K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5C, K64,K65,K6D, K6C,K75,K7D, \
|
||||
K14,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K7C, \
|
||||
K12, K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, K63, K69,K72,K7A, \
|
||||
K11, K19, K29, K39, K58, K61,K60,K6A, K70, K71,K79 \
|
||||
#define KEYMAP_102( \
|
||||
K08, K07,K0F,K17,K1F,K27,K2F,K37,K3F,K47,K4F,K56,K5E, K57,K5F,K62, \
|
||||
\
|
||||
K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K5D,K66, K67,K6E,K6F, K76,K77,K7E,K84, \
|
||||
K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, K5C, K64,K65,K6D, K6C,K75,K7D,K7C, \
|
||||
K14,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K53,K5A, K6B,K73,K74,K7B, \
|
||||
K12,K13,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K51,K59, K63, K69,K72,K7A,K79, \
|
||||
K11, K19, K29, K39, K58, K61,K60,K6A, K68,K70,K71,K78 \
|
||||
) { \
|
||||
{ KC_NO, KC_NO , KC_NO, KC_NO , KC_NO , KC_NO , KC_NO , KC_##K07 }, \
|
||||
{ KC_##K08, KC_NO , KC_NO , KC_NO , KC_NO , KC_##K0D, KC_##K0E, KC_##K0F }, \
|
||||
{ KC_NO , KC_##K11, KC_##K12, KC_NO , KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
|
||||
{ KC_NO , KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
|
||||
{ KC_NO , KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F }, \
|
||||
{ KC_NO , KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
|
||||
{ KC_NO , KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \
|
||||
|
|
@ -91,12 +83,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
{ KC_NO , KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
|
||||
{ KC_NO , KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47 }, \
|
||||
{ KC_NO , KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K4F }, \
|
||||
{ KC_NO , KC_NO , KC_##K52, KC_NO , KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
|
||||
{ KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_##K5C, KC_NO , KC_##K5E, KC_##K5F }, \
|
||||
{ KC_NO , KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
|
||||
{ KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_##K5C, KC_##K5D, KC_##K5E, KC_##K5F }, \
|
||||
{ KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
|
||||
{ KC_NO , KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C, KC_##K6D, KC_##K6E, KC_##K6F }, \
|
||||
{ KC_##K68, KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C, KC_##K6D, KC_##K6E, KC_##K6F }, \
|
||||
{ KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
|
||||
{ KC_NO , KC_##K79, KC_##K7A, KC_NO , KC_##K7C, KC_##K7D, KC_##K7E, KC_NO }, \
|
||||
{ KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_##K7E, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_NO, KC_NO , KC_##K84, KC_NO, KC_NO, KC_NO, }, \
|
||||
}
|
||||
|
||||
|
|
@ -127,27 +119,25 @@ const uint8_t PROGMEM fn_keycode[] = {
|
|||
|
||||
|
||||
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* 0: default
|
||||
*
|
||||
/*
|
||||
* ,-----------------------------------------------.
|
||||
* |F13|F14|F15|F16|F17|F18|F19|F20|F21|F22|F23|F24|
|
||||
* `-----------------------------------------------'
|
||||
* `-----------------------------------------------'
|
||||
* ,-----------------------------------------------.
|
||||
* |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|
|
||||
* `-----------------------------------------------'
|
||||
* `-----------------------------------------------'
|
||||
* ,-------. ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||
* |PrS|Esc| | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \|BS | |Ins|Hom|PgU| |NmL| /| *| -|
|
||||
* |PrS|Esc| | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| BS| |Ins|Hom|PgU| |NmL| /| *| -|
|
||||
* |-------| |-----------------------------------------------------------| |-----------| |---------------|
|
||||
* |ScL|In4| |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
|
||||
* |-------| |-----------------------------------------------------------| `-----------' |-----------| +|
|
||||
* |Pau|In5| |CapsLo| A| S| D| F| G| H| J| K| L| ;| '| #|Retu| |Up | | 4| 5| 6| |
|
||||
* |ScL|In4| |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| +|
|
||||
* |-------| |-----------------------------------------------------------| `-----------' |-----------|---|
|
||||
* |Pau|In5| |CapsLo| A| S| D| F| G| H| J| K| L| ;| '| #| Ret| |Up | | 4| 5| 6| ,|
|
||||
* |-------| |-----------------------------------------------------------| ,-----------. |---------------|
|
||||
* |App|In6| |Shif| \| Z| X| C| V| B| N| M| ,| ,| /|Shift | |Lef|In2|Rig| | 1| 2| 3| |
|
||||
* |-------| |-----------------------------------------------------------| `-----------' |-----------|Ent|
|
||||
* |Gui|Gui| |Ctrl| |Alt | Space |Alt | |Ctrl| |Dow| | 0| .| |
|
||||
* |App|In6| |Shif| \| Z| X| C| V| B| N| M| ,| ,| /| RO| Shift| |Lef|In2|Rig| | 1| 2| 3|Ent|
|
||||
* |-------| |-----------------------------------------------------------| `-----------' |-----------|---|
|
||||
* |Gui|Gui| |Ctrl| |Alt | Space |Alt | |Ctrl| |Dow| | 00| 0| .| =|
|
||||
* `-------' `----' `---------------------------------------' `----' `---' `---------------'
|
||||
*/
|
||||
/*
|
||||
KEYMAP(
|
||||
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
|
|
@ -156,48 +146,35 @@ const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|||
SLCK,INT4, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS,
|
||||
PAUS,INT5, CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, UP, P4, P5, P6, PCMM,
|
||||
APP, INT6, LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RO, RSFT, LEFT,INT2,RGHT, P1, P2, P3, PENT,
|
||||
RGUI,LGUI, LCTL, LALT, SPC, RALT, RCTL, DOWN, NO, P0, PDOT,NO
|
||||
),
|
||||
*/
|
||||
// pseudo ANSI
|
||||
KEYMAP(
|
||||
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
|
||||
PSCR,ESC, GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, NO, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||
SLCK,INT4, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, NO, DEL, END, PGDN, P7, P8, P9, PPLS,
|
||||
PAUS,INT5, CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, BSLS,ENT, UP, P4, P5, P6, PCMM,
|
||||
APP, INT6, LSFT,LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, NO, RSFT, LEFT,INT2,RGHT, P1, P2, P3, PENT,
|
||||
RGUI,LGUI, LCTL, LALT, SPC, RALT, RCTL, DOWN, NO, P0, PDOT,NO
|
||||
RGUI,LGUI, LCTL, LALT, SPC, RALT, RCTL, DOWN, P00, P0, PDOT,PEQL
|
||||
),
|
||||
|
||||
/* 101-key keymaps
|
||||
*/
|
||||
/* 0: default
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* ,---. ,---------------. ,---------------. ,---------------. ,-----------.
|
||||
* |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|
|
||||
* `---' `---------------' `---------------' `---------------' `-----------'
|
||||
* ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| /| *| -|
|
||||
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| BS| |Ins|Hom|PgU| |NmL| /| *| -|
|
||||
* |-----------------------------------------------------------| |-----------| |---------------|
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
|
||||
* |-----------------------------------------------------------| `-----------' |-----------| +|
|
||||
* |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| |
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| +|
|
||||
* |-----------------------------------------------------------| `-----------' |-----------|---|
|
||||
* |CapsLo| A| S| D| F| G| H| J| K| L| ;| '| #| Ret| | 4| 5| 6| ,|
|
||||
* |-----------------------------------------------------------| ,---. |---------------|
|
||||
* |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
|
||||
* |-----------------------------------------------------------| ,-----------. |-----------|Ent|
|
||||
* |Ctrl| |Alt | Space |Alt | |Ctrl| |Lef|Dow|Rig| | 0| .| |
|
||||
* |Shift | Z| X| C| V| B| N| M| ,| ,| /| RO| Shift| |Up | | 1| 2| 3|Ent|
|
||||
* |-----------------------------------------------------------| ,-----------. |-----------|---|
|
||||
* |Ctrl| |Alt | Space |Alt | |Ctrl| |Lef|Dow|Rig| | 00| 0| .| =|
|
||||
* `----' `---------------------------------------' `----' `-----------' `---------------'
|
||||
*/
|
||||
/*
|
||||
KEYMAP_101(
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK, BRK,
|
||||
KEYMAP_102(
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS,
|
||||
|
||||
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,MINS, EQL,BSPC, INS,HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P,LBRC,RBRC,BSLS, DEL, END,PGDN, P7, P8, P9,
|
||||
CAPS, 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,
|
||||
LCTL, LALT, SPC, RALT, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
|
||||
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS,
|
||||
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, P4, P5, P6, PCMM,
|
||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RO, RSFT, UP, P1, P2, P3, PENT,
|
||||
LCTL, LALT, SPC, RALT, RCTL, LEFT,DOWN,RGHT, P00, P0, PDOT,PEQL
|
||||
),
|
||||
*/
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,20 @@
|
|||
TARGET = usb_usb_debug
|
||||
UNIMAP_ENABLE = yes
|
||||
|
||||
#UNIMAP_ENABLE = yes
|
||||
#KEYMAP_SECTION_ENABLE = yes
|
||||
#LUFA_DEBUG = yes
|
||||
OPT_DEFS += -DDEBUG_USB_HOST
|
||||
|
||||
# LUFA debug print
|
||||
# This may prevent USB enumeration and keyboard init
|
||||
LUFA_DEBUG = yes
|
||||
# Select one of outputs for debug print
|
||||
LUFA_DEBUG_UART = yes
|
||||
#LUFA_DEBUG_SUART = yes
|
||||
|
||||
# USB_Host_Shield_2.0 debug print
|
||||
# This may prevent USB enumeration and keyboard init
|
||||
#OPT_DEFS += -DDEBUG_USB_HOST
|
||||
|
||||
CONSOLE_ENABLE = yes
|
||||
MOUSEKEY_ENABLE = no
|
||||
EXTRAKEY_ENABLE = no
|
||||
include Makefile
|
||||
|
|
|
|||
|
|
@ -2,4 +2,6 @@ TARGET = usb_usb_unimap
|
|||
UNIMAP_ENABLE = yes
|
||||
KEYMAP_SECTION_ENABLE = yes
|
||||
#LUFA_DEBUG = yes
|
||||
#CONSOLE_ENABLE = no
|
||||
NO_DEBUG = yes
|
||||
include Makefile
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
USB to USB keyboard protocol converter
|
||||
======================================
|
||||
See for detail and discussion.
|
||||
https://geekhack.org/index.php?topic=69169.0
|
||||
|
||||
|
||||
Hardware requirement
|
||||
--------------------
|
||||
There are two options.
|
||||
|
||||
### TMK USB-USB Converter
|
||||
You can buy a fully assembled converter from me here.
|
||||
|
||||
https://geekhack.org/index.php?topic=69169.0
|
||||
|
||||
### Arduino Leonardo + Circuit@Home USB Host Shield 2.0
|
||||
Buying Arduino Leonardo and USB Host Shield 2.0(from Circuit@home) will be better, you won't need even soldering iron.
|
||||
|
||||
http://arduino.cc/en/Main/ArduinoBoardLeonardo
|
||||
https://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-2-0-for-arduino-assembled/
|
||||
|
||||
Other compatible boards like Arduino's Shield will also work well but I think Sparkfun's needs to be modified.
|
||||
|
||||
http://arduino.cc/en/Main/ArduinoUSBHostShield
|
||||
https://www.sparkfun.com/products/9947
|
||||
|
||||
Also Pro Micro 3.3V(not Mini) or Teensy with mini host shield will work with some fixes on signal/power routing.
|
||||
|
||||
https://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-for-arduino-pro-mini
|
||||
https://www.sparkfun.com/products/12587
|
||||
https://www.pjrc.com/teensy/td_libs_USBHostShield.html
|
||||
|
||||
|
||||
|
||||
Build firmware
|
||||
--------------
|
||||
Build.
|
||||
|
||||
$ git clone https://github.com/tmk/tmk_keyboard.git
|
||||
$ cd tmk_keyboard
|
||||
$ git submodule init
|
||||
$ git submodule update
|
||||
$ cd converter/usb_usb
|
||||
$ make
|
||||
|
||||
And Program converter. Push button on TMK converter and just run this.
|
||||
|
||||
$ make dfu
|
||||
|
||||
|
||||
In case of Leonardo push reset button then run command. Serial port name(COM17) depends your system. On Linux I got /dev/ttyACM0.
|
||||
|
||||
$ DEV=COM17 make program
|
||||
or
|
||||
$ avrdude -patmega32u4 -cavr109 -b57600 -Uflash:w:usb_usb.hex -PCOM17
|
||||
|
||||
|
||||
|
||||
Limitation
|
||||
----------
|
||||
Only supports 'HID Boot protocol'.
|
||||
|
||||
Note that the converter can host only USB "boot protocol" keyboard(6KRO), not NKRO, it is possible to support NKRO keyboard but you will need to write HID report parser for that. Every NKRO keyboard can have different HID report and it is difficult to support all kind of NKRO keyboards in the market.
|
||||
|
||||
|
||||
|
||||
Keymap editor
|
||||
-------------
|
||||
You can editor keymap and download firmware with web brwoser.
|
||||
|
||||
- http://www.tmk-kbd.com/tmk_keyboard/editor/unimap/?usb_usb
|
||||
|
||||
|
||||
|
||||
Update
|
||||
------
|
||||
2014/12/11 Added Hub support(confirmed with HHKB pro2)
|
||||
2016/09/10 Unimap editor support
|
||||
2016/10/18 Fix LED state at startup
|
||||
2017/05/xx Fix startup code for FC660C(3eae475)
|
||||
2018/02/xx Add Korean and Brazilian specific keys(ab6ddac,b2fa0ffa)
|
||||
2018/07/xx Fix startup issue(c2ce617)
|
||||
2018/10/xx Use fixed LUFA stack and update USB_Host_Shield_2.0
|
||||
|
||||
|
||||
|
||||
Resource
|
||||
--------
|
||||
USB Host Sheild 2.0
|
||||
https://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-2-0-for-arduino
|
||||
https://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-for-arduino-pro-mini
|
||||
USB Host Sheild 2.0 source
|
||||
https://github.com/felis/USB_Host_Shield_2.0
|
||||
Arduino USB Host Shield(with bootst converter)
|
||||
http://arduino.cc/en/Main/ArduinoUSBHostShield
|
||||
Arduino source
|
||||
https://github.com/arduino/Arduino/hardware/arduino/{cores,variants}
|
||||
Initial release of TMK USB-USB converter
|
||||
https://geekhack.org/index.php?topic=33057.msg653549#msg653549
|
||||
http://deskthority.net/workshop-f7/is-remapping-a-usb-keyboard-using-teensy-possible-t2841-30.html#p74854
|
||||
Arduino-based hardware keyboard remapper - Colemak forum
|
||||
http://forum.colemak.com/viewtopic.php?id=1561
|
||||
Teensy + Host Shield
|
||||
http://www.pjrc.com/teensy/td_libs_USBHostShield.html
|
||||
96
converter/usb_usb/README.md
Normal file
96
converter/usb_usb/README.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
USB to USB keyboard protocol converter
|
||||
======================================
|
||||
See for detail and discussion here.
|
||||
|
||||
- https://geekhack.org/index.php?topic=69169.0
|
||||
|
||||
|
||||
Hardware requirement
|
||||
--------------------
|
||||
There are two options.
|
||||
|
||||
### TMK USB-USB Converter
|
||||
You can buy a fully preassembled converter from me here.
|
||||
|
||||
- https://geekhack.org/index.php?topic=72052.0
|
||||
|
||||
### Arduino Leonardo + USB Host Shield
|
||||
Buying Arduino Leonardo and USB Host Shield.
|
||||
|
||||
- https://store.arduino.cc/usa/leonardo
|
||||
- https://store.arduino.cc/usa/arduino-usb-host-shield
|
||||
- https://www.sparkfun.com/products/9947
|
||||
|
||||
|
||||
Build firmware
|
||||
--------------
|
||||
Build.
|
||||
|
||||
$ git clone https://github.com/tmk/tmk_keyboard.git
|
||||
$ cd tmk_keyboard
|
||||
$ git submodule init
|
||||
$ git submodule update
|
||||
$ cd converter/usb_usb
|
||||
$ make
|
||||
|
||||
And Program converter. Push button on TMK converter and just run this.
|
||||
|
||||
$ make dfu
|
||||
|
||||
|
||||
In case of Leonardo push reset button then run command. Serial port name(COM17) depends your system. On Linux I got /dev/ttyACM0.
|
||||
|
||||
$ DEV=COM17 make program
|
||||
or
|
||||
$ avrdude -patmega32u4 -cavr109 -b57600 -Uflash:w:usb_usb.hex -PCOM17
|
||||
|
||||
|
||||
|
||||
Limitation
|
||||
----------
|
||||
Only supports 'HID Boot protocol'.
|
||||
|
||||
Note that the converter can host only USB "boot protocol" keyboard(6KRO), not NKRO, it is possible to support NKRO keyboard but you will need to write HID report parser for that. Every NKRO keyboard can have different HID report and it is difficult to support all kind of NKRO keyboards in the market.
|
||||
|
||||
|
||||
|
||||
Keymap editor
|
||||
-------------
|
||||
You can editor keymap and download firmware with web brwoser.
|
||||
|
||||
- http://www.tmk-kbd.com/tmk_keyboard/editor/unimap/?usb_usb
|
||||
|
||||
|
||||
|
||||
Update
|
||||
------
|
||||
- 2014/12/11 Added Hub support(confirmed with HHKB pro2)
|
||||
- 2016/09/10 Unimap editor support
|
||||
- 2016/10/18 Fix LED state at startup
|
||||
- 2017/05/xx Fix startup code for FC660C(3eae475)
|
||||
- 2018/02/xx Add Korean and Brazilian specific keys(ab6ddac,b2fa0ffa)
|
||||
- 2018/07/xx Fix startup issue(c2ce617)
|
||||
- 2018/10/xx Use fixed LUFA stack and update USB_Host_Shield_2.0
|
||||
- 2019/09/18 Add BTLD(bootlader jump) key to unimap
|
||||
|
||||
|
||||
|
||||
Resource
|
||||
--------
|
||||
### USB Host Sheild 2.0
|
||||
- https://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-2-0-for-arduino
|
||||
|
||||
### USB Host Sheild 2.0 source
|
||||
- https://github.com/felis/USB_Host_Shield_2.0
|
||||
|
||||
### Arduino USB Host Shield(with bootst converter)
|
||||
- http://arduino.cc/en/Main/ArduinoUSBHostShield
|
||||
|
||||
### Arduino source
|
||||
- https://github.com/arduino/Arduino/hardware/arduino/{cores,variants}
|
||||
|
||||
### Arduino-based hardware keyboard remapper - Colemak forum
|
||||
- http://forum.colemak.com/viewtopic.php?id=1561
|
||||
|
||||
### Teensy + Host Shield
|
||||
- http://www.pjrc.com/teensy/td_libs_USBHostShield.html
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -36,4 +36,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
/* key combination for command */
|
||||
#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
|
||||
|
||||
|
||||
// Disable power saving in USB suspend loop but remote wakeup is still valid.
|
||||
// This allows keep USB::Task() going during suspend without power down time delay.
|
||||
//#define NO_SUSPEND_POWER_DOWN
|
||||
|
||||
|
||||
// Disable USB startup wait, which can delays starting UHS2 Task() for 350-600ms.
|
||||
//#define NO_USB_STARTUP_WAIT_LOOP
|
||||
|
||||
// Disable USB suspend loop, which blocks UHS2 Task() while power saving.
|
||||
// Note that this also disables power saving and remote wakeup from keyboard completely.
|
||||
//#define NO_USB_SUSPEND_LOOP
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
|
|||
),
|
||||
UNIMAP(
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
|
||||
GRV, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,
|
||||
GRV, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,BTLD, TRNS,TRNS,TRNS,
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "host.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
#include "hook.h"
|
||||
#include "suspend.h"
|
||||
#include "lufa.h"
|
||||
|
||||
|
||||
/* KEY CODE to Matrix
|
||||
*
|
||||
|
|
@ -71,8 +75,6 @@ static bool matrix_is_mod =false;
|
|||
* This supports two cascaded hubs and four keyboards
|
||||
*/
|
||||
USB usb_host;
|
||||
USBHub hub1(&usb_host);
|
||||
USBHub hub2(&usb_host);
|
||||
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd1(&usb_host);
|
||||
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd2(&usb_host);
|
||||
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd3(&usb_host);
|
||||
|
|
@ -81,6 +83,8 @@ KBDReportParser kbd_parser1;
|
|||
KBDReportParser kbd_parser2;
|
||||
KBDReportParser kbd_parser3;
|
||||
KBDReportParser kbd_parser4;
|
||||
USBHub hub1(&usb_host);
|
||||
USBHub hub2(&usb_host);
|
||||
|
||||
|
||||
uint8_t matrix_rows(void) { return MATRIX_ROWS; }
|
||||
|
|
@ -136,12 +140,6 @@ uint8_t matrix_scan(void) {
|
|||
or_report(kbd_parser4.report);
|
||||
|
||||
matrix_is_mod = true;
|
||||
|
||||
dprintf("state: %02X %02X", keyboard_report.mods, keyboard_report.reserved);
|
||||
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
|
||||
dprintf(" %02X", keyboard_report.keys[i]);
|
||||
}
|
||||
dprint("\r\n");
|
||||
} else {
|
||||
matrix_is_mod = false;
|
||||
}
|
||||
|
|
@ -151,17 +149,17 @@ uint8_t matrix_scan(void) {
|
|||
usb_host.Task();
|
||||
timer = timer_elapsed(timer);
|
||||
if (timer > 100) {
|
||||
dprintf("host.Task: %d\n", timer);
|
||||
xprintf("host.Task: %d\n", timer);
|
||||
}
|
||||
|
||||
static uint8_t usb_state = 0;
|
||||
if (usb_state != usb_host.getUsbTaskState()) {
|
||||
usb_state = usb_host.getUsbTaskState();
|
||||
dprintf("usb_state: %02X\n", usb_state);
|
||||
xprintf("usb_state: %02X\n", usb_state);
|
||||
|
||||
// restore LED state when keyboard comes up
|
||||
if (usb_state == USB_STATE_RUNNING) {
|
||||
dprintf("speed: %s\n", usb_host.getVbusState()==FSHOST ? "full" : "low");
|
||||
xprintf("speed: %s\n", usb_host.getVbusState()==FSHOST ? "full" : "low");
|
||||
keyboard_set_leds(host_keyboard_leds());
|
||||
}
|
||||
}
|
||||
|
|
@ -218,12 +216,6 @@ uint8_t matrix_key_count(void) {
|
|||
}
|
||||
|
||||
void matrix_print(void) {
|
||||
print("\nr/c 0123456789ABCDEF\n");
|
||||
for (uint8_t row = 0; row < matrix_rows(); row++) {
|
||||
xprintf("%02d: ", row);
|
||||
print_bin_reverse16(matrix_get_row(row));
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void led_set(uint8_t usb_led)
|
||||
|
|
@ -233,3 +225,28 @@ void led_set(uint8_t usb_led)
|
|||
if (kbd3.isReady()) kbd3.SetReport(0, 0, 2, 0, 1, &usb_led);
|
||||
if (kbd4.isReady()) kbd4.SetReport(0, 0, 2, 0, 1, &usb_led);
|
||||
}
|
||||
|
||||
// We need to keep doing UHS2 USB::Task() to initialize keyboard
|
||||
// even before USB is not configured.
|
||||
void hook_usb_startup_wait_loop(void)
|
||||
{
|
||||
matrix_scan();
|
||||
}
|
||||
|
||||
// We need to keep doing UHS2 USB::Task() to initialize keyboard
|
||||
// even during USB bus is suspended and remote wakeup is not enabled yet on LUFA side.
|
||||
// This situation can happen just after pluging converter into USB port.
|
||||
void hook_usb_suspend_loop(void)
|
||||
{
|
||||
#ifndef LUFA_DEBUG_UART
|
||||
// This corrupts debug print when suspend
|
||||
suspend_power_down();
|
||||
#endif
|
||||
if (USB_Device_RemoteWakeupEnabled) {
|
||||
if (suspend_wakeup_condition()) {
|
||||
USB_Device_SendRemoteWakeup();
|
||||
}
|
||||
} else {
|
||||
matrix_scan();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
TARGET = alps64_editor
|
||||
KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor
|
||||
KEYMAP = editor
|
||||
include Makefile
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -25,13 +25,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "timer.h"
|
||||
#include "matrix.h"
|
||||
|
||||
|
||||
#ifndef DEBOUNCE
|
||||
# define DEBOUNCE 5
|
||||
#endif
|
||||
static uint8_t debouncing = DEBOUNCE;
|
||||
static bool debouncing = false;
|
||||
static uint16_t debouncing_time = 0;
|
||||
|
||||
/* matrix state(1:on, 0:off) */
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
|
|
@ -70,26 +72,24 @@ uint8_t matrix_scan(void)
|
|||
{
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
select_row(i);
|
||||
_delay_us(30); // without this wait read unstable value.
|
||||
_delay_us(30); // delay for settling
|
||||
matrix_row_t cols = read_cols();
|
||||
if (matrix_debouncing[i] != cols) {
|
||||
matrix_debouncing[i] = cols;
|
||||
if (debouncing) {
|
||||
debug("bounce!: "); debug_hex(debouncing); debug("\n");
|
||||
dprintf("bounce: %d %d@%02X\n", timer_elapsed(debouncing_time), i, matrix_debouncing[i]^cols);
|
||||
}
|
||||
debouncing = DEBOUNCE;
|
||||
matrix_debouncing[i] = cols;
|
||||
debouncing = true;
|
||||
debouncing_time = timer_read();
|
||||
}
|
||||
unselect_rows();
|
||||
}
|
||||
|
||||
if (debouncing) {
|
||||
if (--debouncing) {
|
||||
_delay_ms(1);
|
||||
} else {
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = matrix_debouncing[i];
|
||||
}
|
||||
if (debouncing && timer_elapsed(debouncing_time) >= DEBOUNCE) {
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = matrix_debouncing[i];
|
||||
}
|
||||
debouncing = false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -17,9 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "unimap_trans.h"
|
||||
|
||||
|
||||
#define AC_L1 ACTION_LAYER_TAP_KEY(1, KC_RGUI)
|
||||
|
||||
|
||||
#ifdef KEYMAP_SECTION_ENABLE
|
||||
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
|
||||
#else
|
||||
|
|
@ -41,14 +38,7 @@ const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
|
|||
[0] = UNIMAP_ALPS64( \
|
||||
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, NUHS,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, ENT, \
|
||||
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, \
|
||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT,ESC, \
|
||||
LCTL,LGUI,LALT, SPC, APP, RALT,L1, RCTL),
|
||||
|
||||
[1] = UNIMAP_ALPS64( \
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
|
||||
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS, UP, TRNS, BSPC, \
|
||||
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT, PENT, \
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN, TRNS,TRNS, \
|
||||
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS),
|
||||
LCTL,LALT,LGUI, SPC, RGUI,RALT,APP, RCTL),
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -51,7 +51,7 @@ void matrix_init(void)
|
|||
|
||||
// LEDs on NumLock, CapsLock and ScrollLock(PB4, PB5, PB6)
|
||||
DDRB |= (1<<4) | (1<<5) | (1<<6);
|
||||
PORTB |= (1<<4) | (1<<5) | (1<<6);
|
||||
PORTB &= ~((1<<4) | (1<<5) | (1<<6));
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00;
|
||||
|
|
|
|||
|
|
@ -25,13 +25,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "timer.h"
|
||||
#include "matrix.h"
|
||||
|
||||
|
||||
#ifndef DEBOUNCE
|
||||
# define DEBOUNCE 5
|
||||
#endif
|
||||
static uint8_t debouncing = DEBOUNCE;
|
||||
static bool debouncing = false;
|
||||
static uint16_t debouncing_time = 0;
|
||||
|
||||
|
||||
/* matrix state(1:on, 0:off) */
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
|
|
@ -60,26 +63,24 @@ uint8_t matrix_scan(void)
|
|||
{
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
select_row(i);
|
||||
_delay_us(30); // without this wait read unstable value.
|
||||
_delay_us(1); // delay for settling
|
||||
matrix_row_t cols = read_cols();
|
||||
if (matrix_debouncing[i] != cols) {
|
||||
matrix_debouncing[i] = cols;
|
||||
if (debouncing) {
|
||||
debug("bounce!: "); debug_hex(debouncing); debug("\n");
|
||||
dprintf("bounce: %d %d@%02X\n", timer_elapsed(debouncing_time), i, matrix_debouncing[i]^cols);
|
||||
}
|
||||
debouncing = DEBOUNCE;
|
||||
matrix_debouncing[i] = cols;
|
||||
debouncing = true;
|
||||
debouncing_time = timer_read();
|
||||
}
|
||||
unselect_rows();
|
||||
}
|
||||
|
||||
if (debouncing) {
|
||||
if (--debouncing) {
|
||||
_delay_ms(1);
|
||||
} else {
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = matrix_debouncing[i];
|
||||
}
|
||||
if (debouncing && timer_elapsed(debouncing_time) >= DEBOUNCE) {
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = matrix_debouncing[i];
|
||||
}
|
||||
debouncing = false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -50,10 +50,22 @@ endif
|
|||
ifeq (yes,$(strip $(CONSOLE_ENABLE)))
|
||||
OPT_DEFS += -DCONSOLE_ENABLE
|
||||
else
|
||||
OPT_DEFS += -DNO_PRINT
|
||||
# Remove print functions when console is disabled and
|
||||
# no other print method like UART is available
|
||||
ifneq (yes, $(strip $(DEBUG_PRINT_AVAILABLE)))
|
||||
OPT_DEFS += -DNO_PRINT
|
||||
OPT_DEFS += -DNO_DEBUG
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(NO_DEBUG)))
|
||||
OPT_DEFS += -DNO_DEBUG
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(NO_PRINT)))
|
||||
OPT_DEFS += -DNO_PRINT
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(COMMAND_ENABLE)))
|
||||
SRC += $(COMMON_DIR)/command.c
|
||||
OPT_DEFS += -DCOMMAND_ENABLE
|
||||
|
|
@ -89,14 +101,16 @@ ifeq (yes,$(strip $(KEYMAP_SECTION_ENABLE)))
|
|||
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr35.x
|
||||
else ifeq ($(strip $(MCU)),atmega32u4)
|
||||
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr5.x
|
||||
else ifeq ($(strip $(MCU)),at90usb1286)
|
||||
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr51.x
|
||||
else
|
||||
EXTRALDFLAGS = $(error no ldscript for keymap section)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Version string
|
||||
VERSION := $(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null)
|
||||
OPT_DEFS += -DVERSION=$(VERSION)
|
||||
TMK_VERSION := $(shell (git describe --always --dirty=+ || echo 'unknown') 2> /dev/null)
|
||||
OPT_DEFS += -DTMK_VERSION=$(TMK_VERSION)
|
||||
|
||||
|
||||
# Search Path
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "action.h"
|
||||
#include "hook.h"
|
||||
#include "wait.h"
|
||||
#include "bootloader.h"
|
||||
|
||||
#ifdef DEBUG_ACTION
|
||||
#include "debug.h"
|
||||
|
|
@ -58,6 +59,8 @@ void action_exec(keyevent_t event)
|
|||
|
||||
void process_action(keyrecord_t *record)
|
||||
{
|
||||
if (hook_process_action(record)) return;
|
||||
|
||||
keyevent_t event = record->event;
|
||||
#ifndef NO_ACTION_TAPPING
|
||||
uint8_t tap_count = record->tap.count;
|
||||
|
|
@ -339,6 +342,15 @@ void process_action(keyrecord_t *record)
|
|||
break;
|
||||
#endif
|
||||
case ACT_COMMAND:
|
||||
switch (action.command.id) {
|
||||
case COMMAND_BOOTLOADER:
|
||||
if (event.pressed) {
|
||||
clear_keyboard();
|
||||
wait_ms(50);
|
||||
bootloader_jump();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#ifndef NO_ACTION_FUNCTION
|
||||
case ACT_FUNCTION:
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* 0100|10| usage(10) (reserved)
|
||||
* 0100|11| usage(10) (reserved)
|
||||
*
|
||||
* ACT_MOUSEKEY(0110): TODO: Not needed?
|
||||
* ACT_MOUSEKEY(0101): TODO: Not needed?
|
||||
* 0101|xxxx| keycode Mouse key
|
||||
*
|
||||
* 011x|xxxx xxxx xxxx (reseved)
|
||||
|
|
@ -290,6 +290,12 @@ enum layer_pram_tap_op {
|
|||
/*
|
||||
* Extensions
|
||||
*/
|
||||
/* 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 */
|
||||
enum backlight_opt {
|
||||
BACKLIGHT_INCREASE = 0,
|
||||
BACKLIGHT_DECREASE = 1,
|
||||
|
|
@ -297,18 +303,18 @@ enum backlight_opt {
|
|||
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 << 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))
|
||||
enum command_ids {
|
||||
COMMAND_BOOTLOADER, // jump to bootloader
|
||||
};
|
||||
#define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (id))
|
||||
|
||||
/* Function */
|
||||
enum function_opts {
|
||||
FUNC_TAP = 0x8, /* indciates function is tappable */
|
||||
|
|
|
|||
|
|
@ -283,43 +283,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define AC_WWW_STOP ACTION_USAGE_CONSUMER(APPCONTROL_STOP)
|
||||
#define AC_WWW_REFRESH ACTION_USAGE_CONSUMER(APPCONTROL_REFRESH)
|
||||
#define AC_WWW_FAVORITES ACTION_USAGE_CONSUMER(APPCONTROL_BOOKMARKS)
|
||||
/* Jump to bootloader */
|
||||
#define AC_BOOTLOADER ACTION_KEY(KC_BOOTLOADER)
|
||||
/* Fn key */
|
||||
/*
|
||||
#define AC_FN0 ACTION_KEY(KC_FN0)
|
||||
#define AC_FN1 ACTION_KEY(KC_FN1)
|
||||
#define AC_FN2 ACTION_KEY(KC_FN2)
|
||||
#define AC_FN3 ACTION_KEY(KC_FN3)
|
||||
#define AC_FN4 ACTION_KEY(KC_FN4)
|
||||
#define AC_FN5 ACTION_KEY(KC_FN5)
|
||||
#define AC_FN6 ACTION_KEY(KC_FN6)
|
||||
#define AC_FN7 ACTION_KEY(KC_FN7)
|
||||
#define AC_FN8 ACTION_KEY(KC_FN8)
|
||||
#define AC_FN9 ACTION_KEY(KC_FN9)
|
||||
#define AC_FN10 ACTION_KEY(KC_FN10)
|
||||
#define AC_FN11 ACTION_KEY(KC_FN11)
|
||||
#define AC_FN12 ACTION_KEY(KC_FN12)
|
||||
#define AC_FN13 ACTION_KEY(KC_FN13)
|
||||
#define AC_FN14 ACTION_KEY(KC_FN14)
|
||||
#define AC_FN15 ACTION_KEY(KC_FN15)
|
||||
#define AC_FN16 ACTION_KEY(KC_FN16)
|
||||
#define AC_FN17 ACTION_KEY(KC_FN17)
|
||||
#define AC_FN18 ACTION_KEY(KC_FN18)
|
||||
#define AC_FN19 ACTION_KEY(KC_FN19)
|
||||
#define AC_FN20 ACTION_KEY(KC_FN20)
|
||||
#define AC_FN21 ACTION_KEY(KC_FN21)
|
||||
#define AC_FN22 ACTION_KEY(KC_FN22)
|
||||
#define AC_FN23 ACTION_KEY(KC_FN23)
|
||||
#define AC_FN24 ACTION_KEY(KC_FN24)
|
||||
#define AC_FN25 ACTION_KEY(KC_FN25)
|
||||
#define AC_FN26 ACTION_KEY(KC_FN26)
|
||||
#define AC_FN27 ACTION_KEY(KC_FN27)
|
||||
#define AC_FN28 ACTION_KEY(KC_FN28)
|
||||
#define AC_FN29 ACTION_KEY(KC_FN29)
|
||||
#define AC_FN30 ACTION_KEY(KC_FN30)
|
||||
#define AC_FN31 ACTION_KEY(KC_FN31)
|
||||
*/
|
||||
|
||||
/* Mousekey */
|
||||
#define AC_MS_UP ACTION_MOUSEKEY(KC_MS_UP)
|
||||
#define AC_MS_DOWN ACTION_MOUSEKEY(KC_MS_DOWN)
|
||||
|
|
@ -338,6 +302,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define AC_MS_ACCEL1 ACTION_MOUSEKEY(KC_MS_ACCEL1)
|
||||
#define AC_MS_ACCEL2 ACTION_MOUSEKEY(KC_MS_ACCEL2)
|
||||
|
||||
/* Command */
|
||||
#define AC_BOOTLOADER ACTION_COMMAND(COMMAND_BOOTLOADER, 0)
|
||||
|
||||
|
||||
/*
|
||||
* Short names
|
||||
*/
|
||||
|
|
@ -396,6 +364,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define AC_P8 ACTION_KEY(KC_KP_8)
|
||||
#define AC_P9 ACTION_KEY(KC_KP_9)
|
||||
#define AC_P0 ACTION_KEY(KC_KP_0)
|
||||
#define AC_P00 ACTION_KEY(KC_KP_00)
|
||||
#define AC_P000 ACTION_KEY(KC_KP_000)
|
||||
#define AC_PDOT ACTION_KEY(KC_KP_DOT)
|
||||
#define AC_PCMM ACTION_KEY(KC_KP_COMMA)
|
||||
#define AC_PSLS ACTION_KEY(KC_KP_SLASH)
|
||||
|
|
@ -447,9 +417,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define AC_WSTP ACTION_USAGE_CONSUMER(APPCONTROL_STOP)
|
||||
#define AC_WREF ACTION_USAGE_CONSUMER(APPCONTROL_REFRESH)
|
||||
#define AC_WFAV ACTION_USAGE_CONSUMER(APPCONTROL_BOOKMARKS)
|
||||
/* Jump to bootloader */
|
||||
#define AC_BTLD ACTION_KEY(KC_BOOTLOADER)
|
||||
/* Transparent */
|
||||
#define AC_TRNS ACTION_KEY(KC_TRANSPARENT)
|
||||
|
||||
/* Command */
|
||||
#define AC_BTLD AC_BOOTLOADER
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <util/delay.h>
|
||||
#include "bootloader.h"
|
||||
|
||||
|
|
@ -16,8 +17,8 @@
|
|||
* AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet.
|
||||
* Note that 'Word'(2 bytes) size and address are used in datasheet while TMK uses 'Byte'.
|
||||
*
|
||||
*
|
||||
* Size of Bootloaders in bytes:
|
||||
* Atmel DFU loader(ATmega32U2) 4096
|
||||
* Atmel DFU loader(ATmega32U4) 4096
|
||||
* Atmel DFU loader(AT90USB128) 8192
|
||||
* LUFA bootloader(ATmega32U4) 4096
|
||||
|
|
@ -27,45 +28,60 @@
|
|||
* Teensy++ halfKay(AT90USB128) 1024
|
||||
*
|
||||
*
|
||||
* AVR Boot section is located at the end of Flash memory like the followings.
|
||||
* AVR Boot section is located at the end of Flash memory.
|
||||
*
|
||||
*
|
||||
* byte Atmel/LUFA(ATMega32u4) byte Atmel(AT90SUB128)
|
||||
* 0x0000 +---------------+ 0x00000 +---------------+
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | Application | | Application |
|
||||
* | | | |
|
||||
* = = = =
|
||||
* | | 32KB-4KB | | 128KB-8KB
|
||||
* 0x6000 +---------------+ 0x1FC00 +---------------+
|
||||
* | Bootloader | 4KB | Bootloader | 8KB
|
||||
* 0x7FFF +---------------+ 0x1FFFF +---------------+
|
||||
*
|
||||
*
|
||||
* byte Teensy(ATMega32u4) byte Teensy++(AT90SUB128)
|
||||
* 0x0000 +---------------+ 0x00000 +---------------+
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | Application | | Application |
|
||||
* | | | |
|
||||
* = = = =
|
||||
* | | 32KB-512B | | 128KB-1KB
|
||||
* 0x7E00 +---------------+ 0x1FC00 +---------------+
|
||||
* | Bootloader | 512B | Bootloader | 1KB
|
||||
* 0x7FFF +---------------+ 0x1FFFF +---------------+
|
||||
* byte ATMega32u4 with 4096-byte Boot section
|
||||
* 0x0000 +---------------+
|
||||
* | |
|
||||
* | |
|
||||
* | Application | 28KB
|
||||
* | |
|
||||
* = =
|
||||
* | |
|
||||
* 0x7000 +---------------+ <---- BOOTLOADER_START
|
||||
* | Bootloader | 4KB BOOTLOADER_SIZE
|
||||
* 0x7FFF +---------------+ <---- FLASHEND
|
||||
*/
|
||||
#ifndef BOOTLOADER_SIZE
|
||||
#warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h.
|
||||
#define BOOTLOADER_SIZE 4096
|
||||
|
||||
/* bootloader start address in byte */
|
||||
#define BOOTLOADER_START (FLASHEND - bootloader_size() + 1)
|
||||
|
||||
/* boot section size in byte */
|
||||
static inline uint16_t bootloader_size(void)
|
||||
{
|
||||
#if defined(BOOTLOADER_SIZE)
|
||||
return BOOTLOADER_SIZE;
|
||||
#else
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || \
|
||||
defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega16U2__) || \
|
||||
defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
|
||||
uint8_t hfuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
|
||||
switch ((hfuse >> 1) & 3) {
|
||||
case 0: return 4096;
|
||||
case 1: return 2048;
|
||||
case 2: return 1024;
|
||||
case 3: return 512;
|
||||
}
|
||||
return 4096;
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || \
|
||||
defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
|
||||
uint8_t hfuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
|
||||
switch ((hfuse >> 1) & 3) {
|
||||
case 0: return 8192;
|
||||
case 1: return 4096;
|
||||
case 2: return 2048;
|
||||
case 3: return 1024;
|
||||
}
|
||||
return 8192;
|
||||
#else
|
||||
#error Set Boot section size to BOOTLOADER_SIZE in config.h
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FLASH_SIZE (FLASHEND + 1L)
|
||||
#define BOOTLOADER_START (FLASH_SIZE - BOOTLOADER_SIZE)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Entering the Bootloader via Software
|
||||
/*
|
||||
* Entering the Bootloader via Software
|
||||
* http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
|
||||
*/
|
||||
#define BOOTLOADER_RESET_KEY 0xB007B007
|
||||
|
|
@ -76,7 +92,6 @@ void bootloader_jump(void) {
|
|||
#ifdef PROTOCOL_LUFA
|
||||
USB_Disable();
|
||||
cli();
|
||||
_delay_ms(2000);
|
||||
#endif
|
||||
|
||||
#ifdef PROTOCOL_PJRC
|
||||
|
|
@ -87,6 +102,14 @@ void bootloader_jump(void) {
|
|||
_delay_ms(5);
|
||||
#endif
|
||||
|
||||
#ifndef NO_BOOTLOADER_CATERINA_BOOTKEY
|
||||
// Set bootkey for Arduino Leonardo and Pro Micro bootloader
|
||||
// Watchdog reset with bootkey causes the bootloader to enter program mode instead of starting application.
|
||||
// https://github.com/arduino/ArduinoCore-avr/blob/master/bootloaders/caterina/Caterina.c#L68-L69
|
||||
// https://github.com/sparkfun/SF32u4_boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina.c#L88-L89
|
||||
*(volatile uint16_t *)0x0800 = 0x7777;
|
||||
#endif
|
||||
|
||||
// watchdog reset
|
||||
reset_key = BOOTLOADER_RESET_KEY;
|
||||
wdt_enable(WDTO_250MS);
|
||||
|
|
@ -101,85 +124,20 @@ void bootloader_jump_after_watchdog_reset(void)
|
|||
if ((MCUSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
|
||||
reset_key = 0;
|
||||
|
||||
// My custom USBasploader requires this to come up.
|
||||
// some of bootloaders may need to preseve?
|
||||
MCUSR = 0;
|
||||
|
||||
// Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog.
|
||||
MCUSR &= ~(1<<WDRF);
|
||||
// disable watchdog timer
|
||||
wdt_disable();
|
||||
|
||||
#ifndef NO_BOOTLOADER_CATERINA_BOOTKEY
|
||||
// Clear bootkey of Caterina bootloader for other bootloaders
|
||||
// Leonardo and Pro Micro with Arduino default fuse setting don't reach here
|
||||
// because bootloader section are executed before application everytime.
|
||||
*(volatile uint16_t *)0x0800 = 0;
|
||||
#endif
|
||||
|
||||
// This is compled into 'icall', address should be in word unit, not byte.
|
||||
((void (*)(void))(BOOTLOADER_START/2))();
|
||||
((void (*)(void))( (uint16_t)(BOOTLOADER_START / 2) ))();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* Jumping To The Bootloader
|
||||
* http://www.pjrc.com/teensy/jump_to_bootloader.html
|
||||
*
|
||||
* This method doen't work when using LUFA. idk why.
|
||||
* - needs to initialize more regisers or interrupt setting?
|
||||
*/
|
||||
void bootloader_jump(void) {
|
||||
#ifdef PROTOCOL_LUFA
|
||||
USB_Disable();
|
||||
cli();
|
||||
_delay_ms(2000);
|
||||
#endif
|
||||
|
||||
#ifdef PROTOCOL_PJRC
|
||||
cli();
|
||||
UDCON = 1;
|
||||
USBCON = (1<<FRZCLK);
|
||||
UCSR1B = 0;
|
||||
_delay_ms(5);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize
|
||||
*/
|
||||
#if defined(__AVR_AT90USB162__)
|
||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
|
||||
TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
|
||||
DDRB = 0; DDRC = 0; DDRD = 0;
|
||||
PORTB = 0; PORTC = 0; PORTD = 0;
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
|
||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
|
||||
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
|
||||
PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
|
||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
|
||||
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
|
||||
PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
|
||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
|
||||
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
|
||||
PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* USBaspLoader
|
||||
*/
|
||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
|
||||
// This makes custom USBasploader come up.
|
||||
MCUSR = 0;
|
||||
|
||||
// initialize ports
|
||||
PORTB = 0; PORTC= 0; PORTD = 0;
|
||||
DDRB = 0; DDRC= 0; DDRD = 0;
|
||||
|
||||
// disable interrupts
|
||||
EIMSK = 0; EECR = 0; SPCR = 0;
|
||||
ACSR = 0; SPMCSR = 0; WDTCSR = 0; PCICR = 0;
|
||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0;
|
||||
ADCSRA = 0; TWCR = 0; UCSR0B = 0;
|
||||
#endif
|
||||
|
||||
// This is compled into 'icall', address should be in word unit, not byte.
|
||||
((void (*)(void))(BOOTLOADER_START/2))();
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// TODO: Teensy support(ATMega32u4/AT90USB128)
|
||||
// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
|
||||
/* UART Example for Teensy USB Development Board
|
||||
* http://www.pjrc.com/teensy/
|
||||
|
|
@ -32,9 +31,42 @@
|
|||
|
||||
#include "uart.h"
|
||||
|
||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
|
||||
# define UDRn UDR0
|
||||
# define UBRRn UBRR0
|
||||
# define UCSRnA UCSR0A
|
||||
# define UCSRnB UCSR0B
|
||||
# define UCSRnC UCSR0C
|
||||
# define U2Xn U2X0
|
||||
# define RXENn RXEN0
|
||||
# define TXENn TXEN0
|
||||
# define RXCIEn RXCIE0
|
||||
# define UCSZn1 UCSZ01
|
||||
# define UCSZn0 UCSZ00
|
||||
# define UDRIEn UDRIE0
|
||||
# define UDRE_vect USART_UDRE_vect
|
||||
# define RX_vect USART_RX_vect
|
||||
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
|
||||
# define UDRn UDR1
|
||||
# define UBRRn UBRR1
|
||||
# define UCSRnA UCSR1A
|
||||
# define UCSRnB UCSR1B
|
||||
# define UCSRnC UCSR1C
|
||||
# define U2Xn U2X1
|
||||
# define RXENn RXEN1
|
||||
# define TXENn TXEN1
|
||||
# define RXCIEn RXCIE1
|
||||
# define UCSZn1 UCSZ11
|
||||
# define UCSZn0 UCSZ10
|
||||
# define UDRIEn UDRIE1
|
||||
# define UDRE_vect USART1_UDRE_vect
|
||||
# define RX_vect USART1_RX_vect
|
||||
#endif
|
||||
|
||||
|
||||
// These buffers may be any size from 2 to 256 bytes.
|
||||
#define RX_BUFFER_SIZE 64
|
||||
#define TX_BUFFER_SIZE 40
|
||||
#define TX_BUFFER_SIZE 256
|
||||
|
||||
static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx_buffer_head;
|
||||
|
|
@ -47,10 +79,10 @@ static volatile uint8_t rx_buffer_tail;
|
|||
void uart_init(uint32_t baud)
|
||||
{
|
||||
cli();
|
||||
UBRR0 = (F_CPU / 4 / baud - 1) / 2;
|
||||
UCSR0A = (1<<U2X0);
|
||||
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
|
||||
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
|
||||
UBRRn = (F_CPU / 4 / baud - 1) / 2;
|
||||
UCSRnA = (1<<U2Xn);
|
||||
UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn);
|
||||
UCSRnC = (1<<UCSZn1) | (1<<UCSZn0);
|
||||
tx_buffer_head = tx_buffer_tail = 0;
|
||||
rx_buffer_head = rx_buffer_tail = 0;
|
||||
sei();
|
||||
|
|
@ -63,11 +95,13 @@ void uart_putchar(uint8_t c)
|
|||
|
||||
i = tx_buffer_head + 1;
|
||||
if (i >= TX_BUFFER_SIZE) i = 0;
|
||||
// return immediately to avoid deadlock when interrupt is disabled(called from ISR)
|
||||
if (tx_buffer_tail == i && (SREG & (1<<SREG_I)) == 0) return;
|
||||
while (tx_buffer_tail == i) ; // wait until space in buffer
|
||||
//cli();
|
||||
tx_buffer[i] = c;
|
||||
tx_buffer_head = i;
|
||||
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<<UDRIE0);
|
||||
UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn) | (1<<UDRIEn);
|
||||
//sei();
|
||||
}
|
||||
|
||||
|
|
@ -98,27 +132,27 @@ uint8_t uart_available(void)
|
|||
}
|
||||
|
||||
// Transmit Interrupt
|
||||
ISR(USART_UDRE_vect)
|
||||
ISR(UDRE_vect)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (tx_buffer_head == tx_buffer_tail) {
|
||||
// buffer is empty, disable transmit interrupt
|
||||
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
|
||||
UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn);
|
||||
} else {
|
||||
i = tx_buffer_tail + 1;
|
||||
if (i >= TX_BUFFER_SIZE) i = 0;
|
||||
UDR0 = tx_buffer[i];
|
||||
UDRn = tx_buffer[i];
|
||||
tx_buffer_tail = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Receive Interrupt
|
||||
ISR(USART_RX_vect)
|
||||
ISR(RX_vect)
|
||||
{
|
||||
uint8_t c, i;
|
||||
|
||||
c = UDR0;
|
||||
c = UDRn;
|
||||
i = rx_buffer_head + 1;
|
||||
if (i >= RX_BUFFER_SIZE) i = 0;
|
||||
if (i != rx_buffer_tail) {
|
||||
|
|
@ -284,7 +284,7 @@ static bool command_common(uint8_t code)
|
|||
print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
|
||||
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
|
||||
"VER: " STR(DEVICE_VER) "\n");
|
||||
print("BUILD: " STR(VERSION) " (" __TIME__ " " __DATE__ ")\n");
|
||||
print("BUILD: " STR(TMK_VERSION) " (" __TIME__ " " __DATE__ ")\n");
|
||||
/* build options */
|
||||
print("OPTIONS:"
|
||||
#ifdef PROTOCOL_PJRC
|
||||
|
|
|
|||
|
|
@ -47,3 +47,8 @@ void hook_keyboard_leds_change(uint8_t led_status) {
|
|||
|
||||
__attribute__((weak))
|
||||
void hook_bootmagic(void) {}
|
||||
|
||||
__attribute__((weak))
|
||||
bool hook_process_action(keyrecord_t *record) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include "keyboard.h"
|
||||
#include "led.h"
|
||||
#include "action.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* -------------------------------------
|
||||
* Protocol hooks
|
||||
|
|
@ -47,6 +52,10 @@ void hook_usb_suspend_loop(void);
|
|||
* the "normal" indicator LED status by default. */
|
||||
void hook_usb_wakeup(void);
|
||||
|
||||
/* Called repeatedly until getting to CONFIGURED state */
|
||||
/* Default behaviour: do nothing. */
|
||||
void hook_usb_startup_wait_loop(void);
|
||||
|
||||
|
||||
/* -------------------------------------
|
||||
* Keyboard hooks
|
||||
|
|
@ -76,5 +85,12 @@ void hook_keyboard_leds_change(uint8_t led_status);
|
|||
/* Default behaviour: do nothing. */
|
||||
void hook_bootmagic(void);
|
||||
|
||||
/* Called on before processing key event */
|
||||
/* returns true if the event is consumed and default action is not needed. */
|
||||
bool hook_process_action(keyrecord_t *record);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HOOKS_H_ */
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define KC_P8 KC_KP_8
|
||||
#define KC_P9 KC_KP_9
|
||||
#define KC_P0 KC_KP_0
|
||||
#define KC_P00 KC_KP_00
|
||||
#define KC_P000 KC_KP_000
|
||||
#define KC_PDOT KC_KP_DOT
|
||||
#define KC_PCMM KC_KP_COMMA
|
||||
#define KC_PSLS KC_KP_SLASH
|
||||
|
|
|
|||
|
|
@ -155,9 +155,7 @@ static action_t keycode_to_action(uint8_t keycode)
|
|||
return (action_t)ACTION_TRANSPARENT;
|
||||
break;
|
||||
case KC_BOOTLOADER:
|
||||
clear_keyboard();
|
||||
wait_ms(50);
|
||||
bootloader_jump(); // not return
|
||||
return (action_t)ACTION_COMMAND(COMMAND_BOOTLOADER, 0);
|
||||
break;
|
||||
default:
|
||||
return (action_t)ACTION_NO;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define MOUSE_BTN3 (1<<2)
|
||||
#define MOUSE_BTN4 (1<<3)
|
||||
#define MOUSE_BTN5 (1<<4)
|
||||
#define MOUSE_BTN6 (1<<5)
|
||||
#define MOUSE_BTN7 (1<<6)
|
||||
#define MOUSE_BTN8 (1<<7)
|
||||
|
||||
/* Consumer Page(0x0C)
|
||||
* following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx
|
||||
|
|
|
|||
|
|
@ -5,9 +5,17 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void suspend_idle(uint8_t timeout);
|
||||
void suspend_power_down(void);
|
||||
bool suspend_wakeup_condition(void);
|
||||
void suspend_wakeup_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,17 +6,19 @@ The following hooks are available available:
|
|||
|
||||
Hook function | Timing
|
||||
--------------------------------|-----------------------------------------------
|
||||
`hook_early_init(void)` | Early in the boot process, before the matrix is initialized and before a connection is made with the host. Thus, this hook has access to very few parameters, but it is a good place to define any custom parameters needed by other early processes.
|
||||
`hook_late_init(void)` | Near the end of the boot process, after Boot Magic has run and LEDs have been initialized.
|
||||
`hook_bootmagic(void)` | During the Boot Magic window, after EEPROM and Bootloader checks are made, but before any other built-in Boot Magic checks are made.
|
||||
`hook_usb_wakeup(void)` | When the device wakes up from USB suspend state.
|
||||
`hook_usb_suspend_entry(void)` | When the device enters USB suspend state.
|
||||
`hook_usb_suspend_loop(void)` | Continuously, while the device is in USB suspend state. *Default action:* power down and periodically check the matrix, causing wakeup if needed.
|
||||
`hook_keyboard_loop(void)` | Continuously, during the main loop, after the matrix is checked.
|
||||
`hook_matrix_change(keyevent_t event)` | When a matrix state change is detected, before any other actions are processed.
|
||||
`hook_layer_change(uint32_t layer_state)` | When any layer is changed.
|
||||
`hook_default_layer_change(uint32_t default_layer_state)` | When any default layer is changed.
|
||||
`hook_keyboard_leds_change(uint8_t led_status)` | Whenever a change in the LED status is performed. *Default action:* call `keyboard_set_leds(led_status)`
|
||||
`void hook_early_init(void)` | Early in the boot process, before the matrix is initialized and before a connection is made with the host. Thus, this hook has access to very few parameters, but it is a good place to define any custom parameters needed by other early processes.
|
||||
`void hook_late_init(void)` | Near the end of the boot process, after Boot Magic has run and LEDs have been initialized.
|
||||
`void hook_bootmagic(void)` | During the Boot Magic window, after EEPROM and Bootloader checks are made, but before any other built-in Boot Magic checks are made.
|
||||
`void hook_usb_startup_wait_loop(void)` | Continuously, until the device gets ready and into USB configured state.
|
||||
`void hook_usb_wakeup(void)` | When the device wakes up from USB suspend state.
|
||||
`void hook_usb_suspend_entry(void)` | When the device enters USB suspend state.
|
||||
`void hook_usb_suspend_loop(void)` | Continuously, while the device is in USB suspend state. *Default action:* power down and periodically check the matrix, causing wakeup if needed.
|
||||
`void hook_keyboard_loop(void)` | Continuously, during the main loop, after the matrix is checked.
|
||||
`void hook_matrix_change(keyevent_t event)` | When a matrix state change is detected, before any other actions are processed.
|
||||
`void hook_layer_change(uint32_t layer_state)` | When any layer is changed.
|
||||
`void hook_default_layer_change(uint32_t default_layer_state)` | When any default layer is changed.
|
||||
`void hook_keyboard_leds_change(uint8_t led_status)` | Whenever a change in the LED status is performed. *Default action:* call `keyboard_set_leds(led_status)`
|
||||
`bool hook_process_action(keyrecord_t *record)` | Before key event is processed by tmk_core. Return true if the event is consumed and default action is not needed.
|
||||
|
||||
|
||||
|
||||
322
tmk_core/ldscript_keymap_avr51.x
Normal file
322
tmk_core/ldscript_keymap_avr51.x
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
/* Default linker script, for normal executables */
|
||||
/* Copyright (C) 2014-2015 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
|
||||
OUTPUT_ARCH(avr:51)
|
||||
__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
|
||||
__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xff00;
|
||||
__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K;
|
||||
__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K;
|
||||
__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K;
|
||||
__SIGNATURE_REGION_LENGTH__ = DEFINED(__SIGNATURE_REGION_LENGTH__) ? __SIGNATURE_REGION_LENGTH__ : 1K;
|
||||
__USER_SIGNATURE_REGION_LENGTH__ = DEFINED(__USER_SIGNATURE_REGION_LENGTH__) ? __USER_SIGNATURE_REGION_LENGTH__ : 1K;
|
||||
MEMORY
|
||||
{
|
||||
/* With keymap section
|
||||
*
|
||||
* TODO: should be as below
|
||||
* Flash Map of AT90USB(128KB)
|
||||
* +------------+ 0x0000
|
||||
* | .vectors |
|
||||
* | .progmem |
|
||||
* | .init0-9 | > text region
|
||||
* | .text |
|
||||
* | .fini9-0 |
|
||||
* | |
|
||||
* |------------| _etext
|
||||
* | .data |
|
||||
* | .bss | > data region
|
||||
* | .noinit |
|
||||
* | |
|
||||
* |------------| 0x1D800
|
||||
* | .keymap | > keymap region(2KB)
|
||||
* |------------| 0x1E000
|
||||
* | bootloader | 8KB
|
||||
* +------------+ 0x1FFFF
|
||||
*
|
||||
* FIXME: Use this To fit to ATMega32U4 unimap address
|
||||
* Flash Map of AT90USB(128KB)
|
||||
* +------------+ 0x0000
|
||||
* | .vectors |
|
||||
* | .progmem |
|
||||
* | .init0-9 | > text region
|
||||
* | .text |
|
||||
* | .fini9-0 |
|
||||
* | |
|
||||
* |------------| _etext
|
||||
* | .data |
|
||||
* | .bss | > data region
|
||||
* | .noinit |
|
||||
* | |
|
||||
* |------------| 0x6800
|
||||
* | .keymap | > keymap region(2KB)
|
||||
* |------------| 0x7000
|
||||
* ~ ~
|
||||
* ~ ~
|
||||
* |------------| 0x1E000
|
||||
* | bootloader | 8KB
|
||||
* +------------+ 0x1FFFF
|
||||
*/
|
||||
text (rx) : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
|
||||
keymap (rw!x) : ORIGIN = 0x6800, LENGTH = 2K
|
||||
data (rw!x) : ORIGIN = 0x800100, LENGTH = __DATA_REGION_LENGTH__
|
||||
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
|
||||
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
|
||||
lock (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__
|
||||
signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__
|
||||
user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.text :
|
||||
{
|
||||
*(.rel.text)
|
||||
*(.rel.text.*)
|
||||
*(.rel.gnu.linkonce.t*)
|
||||
}
|
||||
.rela.text :
|
||||
{
|
||||
*(.rela.text)
|
||||
*(.rela.text.*)
|
||||
*(.rela.gnu.linkonce.t*)
|
||||
}
|
||||
.rel.fini : { *(.rel.fini) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rel.rodata :
|
||||
{
|
||||
*(.rel.rodata)
|
||||
*(.rel.rodata.*)
|
||||
*(.rel.gnu.linkonce.r*)
|
||||
}
|
||||
.rela.rodata :
|
||||
{
|
||||
*(.rela.rodata)
|
||||
*(.rela.rodata.*)
|
||||
*(.rela.gnu.linkonce.r*)
|
||||
}
|
||||
.rel.data :
|
||||
{
|
||||
*(.rel.data)
|
||||
*(.rel.data.*)
|
||||
*(.rel.gnu.linkonce.d*)
|
||||
}
|
||||
.rela.data :
|
||||
{
|
||||
*(.rela.data)
|
||||
*(.rela.data.*)
|
||||
*(.rela.gnu.linkonce.d*)
|
||||
}
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
/* Internal text space or external memory. */
|
||||
.text :
|
||||
{
|
||||
*(.vectors)
|
||||
KEEP(*(.vectors))
|
||||
/* For data that needs to reside in the lower 64k of progmem. */
|
||||
*(.progmem.gcc*)
|
||||
/* PR 13812: Placing the trampolines here gives a better chance
|
||||
that they will be in range of the code that uses them. */
|
||||
. = ALIGN(2);
|
||||
__trampolines_start = . ;
|
||||
/* The jump trampolines for the 16-bit limited relocs will reside here. */
|
||||
*(.trampolines)
|
||||
*(.trampolines*)
|
||||
__trampolines_end = . ;
|
||||
/* avr-libc expects these data to reside in lower 64K. */
|
||||
*libprintf_flt.a:*(.progmem.data)
|
||||
*libc.a:*(.progmem.data)
|
||||
*(.progmem*)
|
||||
. = ALIGN(2);
|
||||
/* For future tablejump instruction arrays for 3 byte pc devices.
|
||||
We don't relax jump/call instructions within these sections. */
|
||||
*(.jumptables)
|
||||
*(.jumptables*)
|
||||
/* For code that needs to reside in the lower 128k progmem. */
|
||||
*(.lowtext)
|
||||
*(.lowtext*)
|
||||
__ctors_start = . ;
|
||||
*(.ctors)
|
||||
__ctors_end = . ;
|
||||
__dtors_start = . ;
|
||||
*(.dtors)
|
||||
__dtors_end = . ;
|
||||
KEEP(SORT(*)(.ctors))
|
||||
KEEP(SORT(*)(.dtors))
|
||||
/* From this point on, we don't bother about wether the insns are
|
||||
below or above the 16 bits boundary. */
|
||||
*(.init0) /* Start here after reset. */
|
||||
KEEP (*(.init0))
|
||||
*(.init1)
|
||||
KEEP (*(.init1))
|
||||
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
|
||||
KEEP (*(.init2))
|
||||
*(.init3)
|
||||
KEEP (*(.init3))
|
||||
*(.init4) /* Initialize data and BSS. */
|
||||
KEEP (*(.init4))
|
||||
*(.init5)
|
||||
KEEP (*(.init5))
|
||||
*(.init6) /* C++ constructors. */
|
||||
KEEP (*(.init6))
|
||||
*(.init7)
|
||||
KEEP (*(.init7))
|
||||
*(.init8)
|
||||
KEEP (*(.init8))
|
||||
*(.init9) /* Call main(). */
|
||||
KEEP (*(.init9))
|
||||
*(.text)
|
||||
. = ALIGN(2);
|
||||
*(.text.*)
|
||||
. = ALIGN(2);
|
||||
*(.fini9) /* _exit() starts here. */
|
||||
KEEP (*(.fini9))
|
||||
*(.fini8)
|
||||
KEEP (*(.fini8))
|
||||
*(.fini7)
|
||||
KEEP (*(.fini7))
|
||||
*(.fini6) /* C++ destructors. */
|
||||
KEEP (*(.fini6))
|
||||
*(.fini5)
|
||||
KEEP (*(.fini5))
|
||||
*(.fini4)
|
||||
KEEP (*(.fini4))
|
||||
*(.fini3)
|
||||
KEEP (*(.fini3))
|
||||
*(.fini2)
|
||||
KEEP (*(.fini2))
|
||||
*(.fini1)
|
||||
KEEP (*(.fini1))
|
||||
*(.fini0) /* Infinite loop after program termination. */
|
||||
KEEP (*(.fini0))
|
||||
_etext = . ;
|
||||
} > text
|
||||
.data :
|
||||
{
|
||||
PROVIDE (__data_start = .) ;
|
||||
*(.data)
|
||||
*(.data*)
|
||||
*(.gnu.linkonce.d*)
|
||||
*(.rodata) /* We need to include .rodata here if gcc is used */
|
||||
*(.rodata*) /* with -fdata-sections. */
|
||||
*(.gnu.linkonce.r*)
|
||||
. = ALIGN(2);
|
||||
_edata = . ;
|
||||
PROVIDE (__data_end = .) ;
|
||||
} > data AT> text
|
||||
.bss ADDR(.data) + SIZEOF (.data) : AT (ADDR (.bss))
|
||||
{
|
||||
PROVIDE (__bss_start = .) ;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
PROVIDE (__bss_end = .) ;
|
||||
} > data
|
||||
__data_load_start = LOADADDR(.data);
|
||||
__data_load_end = __data_load_start + SIZEOF(.data);
|
||||
/* Global data not cleared after reset. */
|
||||
.noinit ADDR(.bss) + SIZEOF (.bss) : AT (ADDR (.noinit))
|
||||
{
|
||||
PROVIDE (__noinit_start = .) ;
|
||||
*(.noinit*)
|
||||
PROVIDE (__noinit_end = .) ;
|
||||
_end = . ;
|
||||
PROVIDE (__heap_start = .) ;
|
||||
} > data
|
||||
/* keymap region is located at end of flash
|
||||
* .fn_actions Fn actions definitions
|
||||
* .keymaps Mapping layers
|
||||
*/
|
||||
.keymap :
|
||||
{
|
||||
PROVIDE(__keymap_start = .) ;
|
||||
*(.keymap.fn_actions) /* 32*actions = 64bytes */
|
||||
. = ALIGN(0x40);
|
||||
*(.keymap.keymaps) /* rest of .keymap section */
|
||||
*(.keymap*)
|
||||
/* . = ALIGN(0x800); */ /* keymap section takes 2KB- */
|
||||
} > keymap = 0x00 /* zero fill */
|
||||
.eeprom :
|
||||
{
|
||||
/* See .data above... */
|
||||
KEEP(*(.eeprom*))
|
||||
__eeprom_end = . ;
|
||||
} > eeprom
|
||||
.fuse :
|
||||
{
|
||||
KEEP(*(.fuse))
|
||||
KEEP(*(.lfuse))
|
||||
KEEP(*(.hfuse))
|
||||
KEEP(*(.efuse))
|
||||
} > fuse
|
||||
.lock :
|
||||
{
|
||||
KEEP(*(.lock*))
|
||||
} > lock
|
||||
.signature :
|
||||
{
|
||||
KEEP(*(.signature*))
|
||||
} > signature
|
||||
.user_signatures :
|
||||
{
|
||||
KEEP(*(.user_signatures*))
|
||||
} > user_signatures
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2011 Jun WAKO <wakojun@gmail.com>
|
||||
Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
|
||||
Copyright 2013 Shay Green <gblargg@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
|
|
@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "adb.h"
|
||||
#include "print.h"
|
||||
|
||||
|
||||
// GCC doesn't inline functions normally
|
||||
|
|
@ -92,81 +93,164 @@ uint16_t adb_host_kbd_recv(uint8_t addr)
|
|||
}
|
||||
|
||||
#ifdef ADB_MOUSE_ENABLE
|
||||
__attribute__ ((weak))
|
||||
void adb_mouse_init(void) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t adb_host_mouse_recv(void)
|
||||
{
|
||||
return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0);
|
||||
__attribute__ ((weak))
|
||||
void adb_mouse_task(void) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg)
|
||||
// This sends Talk command to read data from register and returns length of the data.
|
||||
uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
for (int8_t i =0; i < len; i++) buf[i] = 0;
|
||||
|
||||
cli();
|
||||
attention();
|
||||
send_byte((addr<<4) | (ADB_CMD_TALK<<2) | reg);
|
||||
send_byte((addr<<4) | ADB_CMD_TALK | reg);
|
||||
place_bit0(); // Stopbit(0)
|
||||
// TODO: Service Request(Srq):
|
||||
// Device holds low part of comannd stopbit for 140-260us
|
||||
//
|
||||
// Command:
|
||||
// ......._ ______________________ ___ ............_ -------
|
||||
// | | | | | | |
|
||||
// Command | | | | | Data bytes | |
|
||||
// ........|___| | 140-260 |__| |_............|___|
|
||||
// |stop0 | Tlt Stop-to-Start |start1| |stop0 |
|
||||
//
|
||||
// Command without data:
|
||||
// ......._ __________________________
|
||||
// | |
|
||||
// Command | |
|
||||
// ........|___| | 140-260 |
|
||||
// |stop0 | Tlt Stop-to-Start |
|
||||
//
|
||||
// Service Request:
|
||||
// ......._ ______ ___ ............_ -------
|
||||
// | 140-260 | | | | | |
|
||||
// Command | Service Request | | | | Data bytes | |
|
||||
// ........|___________________| |__| |_............|___|
|
||||
// |stop0 | |start1| |stop0 |
|
||||
// ......._ __________
|
||||
// | 140-260 |
|
||||
// Command | Service Request |
|
||||
// ........|___________________|
|
||||
// |stop0 |
|
||||
// This can be happened?
|
||||
// ......._ ______________________ ___ ............_ -----
|
||||
// | | | | | | 140-260 |
|
||||
// Command | | | | | Data bytes | Service Request |
|
||||
// ........|___| | 140-260 |__| |_............|_________________|
|
||||
// |stop0 | Tlt Stop-to-Start |start1| |stop0 |
|
||||
//
|
||||
// "Service requests are issued by the devices during a very specific time at the
|
||||
// end of the reception of the command packet.
|
||||
// If a device in need of service issues a service request, it must do so within
|
||||
// the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."
|
||||
//
|
||||
// "A device sends a Service Request signal by holding the bus low during the low
|
||||
// portion of the stop bit of any command or data transaction. The device must lengthen
|
||||
// the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
|
||||
// http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
|
||||
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
|
||||
xprintf("R");
|
||||
sei();
|
||||
return -30; // something wrong
|
||||
return 0;
|
||||
}
|
||||
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
|
||||
sei();
|
||||
return 0; // No data to send
|
||||
return 0; // No data from device(not error);
|
||||
}
|
||||
|
||||
uint8_t n = 17; // start bit + 16 data bits
|
||||
// start bit(1)
|
||||
if (!wait_data_hi(40)) {
|
||||
xprintf("S");
|
||||
sei();
|
||||
return 0;
|
||||
}
|
||||
if (!wait_data_lo(100)) {
|
||||
xprintf("s");
|
||||
sei();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t n = 0; // bit count
|
||||
do {
|
||||
//
|
||||
// |<- bit_cell_max(130) ->|
|
||||
// | |<- lo ->|
|
||||
// | | |<-hi->|
|
||||
// _______
|
||||
// | | |
|
||||
// | 130-lo | lo-hi |
|
||||
// |________| |
|
||||
//
|
||||
uint8_t lo = (uint8_t) wait_data_hi(130);
|
||||
if (!lo)
|
||||
goto error;
|
||||
goto error; // no more bit or after stop bit
|
||||
|
||||
uint8_t hi = (uint8_t) wait_data_lo(lo);
|
||||
if (!hi)
|
||||
goto error;
|
||||
goto error; // stop bit extedned by Srq?
|
||||
|
||||
hi = lo - hi;
|
||||
lo = 130 - lo;
|
||||
if (n/8 >= len) continue; // can't store in buf
|
||||
|
||||
data <<= 1;
|
||||
if (lo < hi) {
|
||||
data |= 1;
|
||||
}
|
||||
else if (n == 17) {
|
||||
sei();
|
||||
return -20;
|
||||
buf[n/8] <<= 1;
|
||||
if ((130 - lo) < (lo - hi)) {
|
||||
buf[n/8] |= 1;
|
||||
}
|
||||
}
|
||||
while ( --n );
|
||||
|
||||
// Stop bit can't be checked normally since it could have service request lenghtening
|
||||
// and its high state never goes low.
|
||||
if (!wait_data_hi(351) || wait_data_lo(91)) {
|
||||
sei();
|
||||
return -21;
|
||||
}
|
||||
sei();
|
||||
return data;
|
||||
while ( ++n );
|
||||
|
||||
error:
|
||||
sei();
|
||||
return -n;
|
||||
return n/8;
|
||||
}
|
||||
|
||||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg)
|
||||
{
|
||||
uint8_t len;
|
||||
uint8_t buf[8];
|
||||
len = adb_host_talk_buf(addr, reg, buf, 8);
|
||||
if (len != 2) return 0;
|
||||
return (buf[0]<<8 | buf[1]);
|
||||
}
|
||||
|
||||
void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
cli();
|
||||
attention();
|
||||
send_byte((addr<<4) | ADB_CMD_LISTEN | reg);
|
||||
place_bit0(); // Stopbit(0)
|
||||
// TODO: Service Request
|
||||
_delay_us(200); // Tlt/Stop to Start
|
||||
place_bit1(); // Startbit(1)
|
||||
for (int8_t i = 0; i < len; i++) {
|
||||
send_byte(buf[i]);
|
||||
//xprintf("%02X ", buf[i]);
|
||||
}
|
||||
place_bit0(); // Stopbit(0);
|
||||
sei();
|
||||
}
|
||||
|
||||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l)
|
||||
{
|
||||
uint8_t buf[2] = { data_h, data_l };
|
||||
adb_host_listen_buf(addr, reg, buf, 2);
|
||||
}
|
||||
|
||||
void adb_host_flush(uint8_t addr)
|
||||
{
|
||||
cli();
|
||||
attention();
|
||||
send_byte((addr<<4) | (ADB_CMD_LISTEN<<2) | reg);
|
||||
send_byte((addr<<4) | ADB_CMD_FLUSH);
|
||||
place_bit0(); // Stopbit(0)
|
||||
_delay_us(200); // Tlt/Stop to Start
|
||||
place_bit1(); // Startbit(1)
|
||||
send_byte(data_h);
|
||||
send_byte(data_l);
|
||||
place_bit0(); // Stopbit(0);
|
||||
sei();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2011 Jun WAKO <wakojun@gmail.com>
|
||||
Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
|
||||
|
|
@ -54,16 +54,28 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
/* ADB commands */
|
||||
// Default Address
|
||||
#define ADB_ADDR_0 0
|
||||
#define ADB_ADDR_DONGLE 1
|
||||
#define ADB_ADDR_KEYBOARD 2
|
||||
#define ADB_ADDR_MOUSE 3
|
||||
#define ADB_ADDR_TABLET 4
|
||||
#define ADB_ADDR_APPLIANCE 7
|
||||
#define ADB_ADDR_8 8
|
||||
#define ADB_ADDR_9 9
|
||||
#define ADB_ADDR_10 10
|
||||
#define ADB_ADDR_11 11
|
||||
#define ADB_ADDR_12 12
|
||||
#define ADB_ADDR_13 13
|
||||
#define ADB_ADDR_14 14
|
||||
#define ADB_ADDR_15 15
|
||||
// for temporary purpose, do not use for polling
|
||||
#define ADB_ADDR_TMP 15
|
||||
#define ADB_ADDR_MOUSE_POLL 10
|
||||
// Command Type
|
||||
#define ADB_CMD_RESET 0
|
||||
#define ADB_CMD_FLUSH 1
|
||||
#define ADB_CMD_LISTEN 2
|
||||
#define ADB_CMD_TALK 3
|
||||
#define ADB_CMD_LISTEN 8
|
||||
#define ADB_CMD_TALK 12
|
||||
// Register
|
||||
#define ADB_REG_0 0
|
||||
#define ADB_REG_1 1
|
||||
|
|
@ -76,16 +88,22 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define ADB_HANDLER_M0115 0x02
|
||||
#define ADB_HANDLER_M3501 0x02
|
||||
#define ADB_HANDLER_M1242_ANSI 0x10
|
||||
#define ADB_HANDLER_EXTENDED_PROTOCOL 0x03
|
||||
#define ADB_HANDLER_EXTENDED_KEYBOARD 0x03
|
||||
#define ADB_HANDLER_CLASSIC1_MOUSE 0x01
|
||||
#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
|
||||
#define ADB_HANDLER_EXTENDED_MOUSE 0x04
|
||||
#define ADB_HANDLER_TURBO_MOUSE 0x32
|
||||
|
||||
|
||||
// ADB host
|
||||
void adb_host_init(void);
|
||||
bool adb_host_psw(void);
|
||||
uint16_t adb_host_kbd_recv(uint8_t addr);
|
||||
uint16_t adb_host_mouse_recv(void);
|
||||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
|
||||
uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
|
||||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
|
||||
void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
|
||||
void adb_host_flush(uint8_t addr);
|
||||
void adb_host_kbd_led(uint8_t addr, uint8_t led);
|
||||
void adb_mouse_task(void);
|
||||
void adb_mouse_init(void);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ 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.
|
||||
Start bit: can be long as 300-350us during start up and upto 2500us while key scanning
|
||||
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.
|
||||
|
|
@ -58,7 +58,7 @@ uint8_t ibm4704_send(uint8_t data)
|
|||
clock_lo();
|
||||
|
||||
/* wait for Start bit(Clock:lo/Data:hi) */
|
||||
WAIT(data_hi, 300, 0x30);
|
||||
WAIT(data_hi, 5000, 0x30);
|
||||
|
||||
/* Data bit */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
|
|
@ -89,7 +89,7 @@ uint8_t ibm4704_send(uint8_t data)
|
|||
return 0;
|
||||
ERROR:
|
||||
idle();
|
||||
if (ibm4704_error > 0x30) {
|
||||
if (ibm4704_error >= 0x30) {
|
||||
xprintf("S:%02X ", ibm4704_error);
|
||||
}
|
||||
IBM4704_INT_ON();
|
||||
|
|
|
|||
264
tmk_core/protocol/ibmpc.c
Normal file
264
tmk_core/protocol/ibmpc.c
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
Copyright 2010,2011,2012,2013,2019 Jun WAKO <wakojun@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* IBM PC keyboard protocol
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "ringbuf.h"
|
||||
#include "ibmpc.h"
|
||||
#include "debug.h"
|
||||
#include "timer.h"
|
||||
#include "wait.h"
|
||||
|
||||
|
||||
#define WAIT(stat, us, err) do { \
|
||||
if (!wait_##stat(us)) { \
|
||||
ibmpc_error = err; \
|
||||
goto ERROR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define BUF_SIZE 16
|
||||
static uint8_t buf[BUF_SIZE];
|
||||
static ringbuf_t rb = {
|
||||
.buffer = buf,
|
||||
.head = 0,
|
||||
.tail = 0,
|
||||
.size_mask = BUF_SIZE - 1
|
||||
};
|
||||
|
||||
volatile uint8_t ibmpc_protocol = IBMPC_PROTOCOL_AT;
|
||||
volatile uint8_t ibmpc_error = IBMPC_ERR_NONE;
|
||||
|
||||
void ibmpc_host_init(void)
|
||||
{
|
||||
clock_init();
|
||||
data_init();
|
||||
idle();
|
||||
IBMPC_INT_INIT();
|
||||
IBMPC_INT_ON();
|
||||
// POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
|
||||
//wait_ms(2500);
|
||||
}
|
||||
|
||||
int16_t ibmpc_host_send(uint8_t data)
|
||||
{
|
||||
bool parity = true;
|
||||
ibmpc_error = IBMPC_ERR_NONE;
|
||||
|
||||
if (ibmpc_protocol == IBMPC_PROTOCOL_XT) return -1;
|
||||
|
||||
dprintf("w%02X ", data);
|
||||
|
||||
IBMPC_INT_OFF();
|
||||
|
||||
/* terminate a transmission if we have */
|
||||
inhibit();
|
||||
wait_us(100); // 100us [4]p.13, [5]p.50
|
||||
|
||||
/* 'Request to Send' and Start bit */
|
||||
data_lo();
|
||||
clock_hi();
|
||||
WAIT(clock_lo, 10000, 1); // 10ms [5]p.50
|
||||
|
||||
/* Data bit[2-9] */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
wait_us(15);
|
||||
if (data&(1<<i)) {
|
||||
parity = !parity;
|
||||
data_hi();
|
||||
} else {
|
||||
data_lo();
|
||||
}
|
||||
WAIT(clock_hi, 50, 2);
|
||||
WAIT(clock_lo, 50, 3);
|
||||
}
|
||||
|
||||
/* Parity bit */
|
||||
wait_us(15);
|
||||
if (parity) { data_hi(); } else { data_lo(); }
|
||||
WAIT(clock_hi, 50, 4);
|
||||
WAIT(clock_lo, 50, 5);
|
||||
|
||||
/* Stop bit */
|
||||
wait_us(15);
|
||||
data_hi();
|
||||
|
||||
/* Ack */
|
||||
WAIT(data_lo, 50, 6);
|
||||
WAIT(clock_lo, 50, 7);
|
||||
|
||||
/* wait for idle state */
|
||||
WAIT(clock_hi, 50, 8);
|
||||
WAIT(data_hi, 50, 9);
|
||||
|
||||
idle();
|
||||
IBMPC_INT_ON();
|
||||
return ibmpc_host_recv_response();
|
||||
ERROR:
|
||||
ibmpc_error |= IBMPC_ERR_SEND;
|
||||
idle();
|
||||
IBMPC_INT_ON();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int16_t ibmpc_host_recv_response(void)
|
||||
{
|
||||
// Command may take 25ms/20ms at most([5]p.46, [3]p.21)
|
||||
uint8_t retry = 25;
|
||||
while (retry-- && ringbuf_is_empty(&rb)) {
|
||||
wait_ms(1);
|
||||
}
|
||||
int16_t data = ringbuf_get(&rb);
|
||||
if (data != -1) dprintf("r%02X ", data);
|
||||
return data;
|
||||
}
|
||||
|
||||
/* get data received by interrupt */
|
||||
int16_t ibmpc_host_recv(void)
|
||||
{
|
||||
int16_t data = ringbuf_get(&rb);
|
||||
if (data != -1) dprintf("r%02X ", data);
|
||||
return data;
|
||||
}
|
||||
|
||||
ISR(IBMPC_INT_VECT)
|
||||
{
|
||||
static uint16_t last_time = 0;
|
||||
static enum {
|
||||
START,
|
||||
BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7,
|
||||
PARITY,
|
||||
STOP,
|
||||
} state = START;
|
||||
static uint8_t data = 0;
|
||||
static uint8_t parity = 1;
|
||||
|
||||
// return unless falling edge
|
||||
if (clock_in()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset state when taking more than 1ms
|
||||
if (last_time && timer_elapsed(last_time) > 10) {
|
||||
ibmpc_error = IBMPC_ERR_TIMEOUT | IBMPC_ERR_RECV | state;
|
||||
state = START;
|
||||
data = 0;
|
||||
parity = 1;
|
||||
}
|
||||
last_time = timer_read();
|
||||
|
||||
switch (state) {
|
||||
case START:
|
||||
if (ibmpc_protocol == IBMPC_PROTOCOL_XT) {
|
||||
// ignore start(0) bit
|
||||
if (!data_in()) return;
|
||||
} else {
|
||||
if (data_in())
|
||||
goto ERROR;
|
||||
}
|
||||
case BIT0:
|
||||
case BIT1:
|
||||
case BIT2:
|
||||
case BIT3:
|
||||
case BIT4:
|
||||
case BIT5:
|
||||
case BIT6:
|
||||
case BIT7:
|
||||
data >>= 1;
|
||||
if (data_in()) {
|
||||
data |= 0x80;
|
||||
parity++;
|
||||
}
|
||||
if (state == BIT7 && ibmpc_protocol == IBMPC_PROTOCOL_XT) {
|
||||
if (!ringbuf_put(&rb, data)) {
|
||||
ibmpc_error = IBMPC_ERR_FULL;
|
||||
goto ERROR;
|
||||
}
|
||||
ibmpc_error = IBMPC_ERR_NONE;
|
||||
goto DONE;
|
||||
}
|
||||
break;
|
||||
case PARITY:
|
||||
if (data_in()) {
|
||||
if (!(parity & 0x01))
|
||||
goto ERROR;
|
||||
} else {
|
||||
if (parity & 0x01)
|
||||
goto ERROR;
|
||||
}
|
||||
break;
|
||||
case STOP:
|
||||
if (!data_in())
|
||||
goto ERROR;
|
||||
if (!ringbuf_put(&rb, data)) {
|
||||
ibmpc_error = IBMPC_ERR_FULL;
|
||||
goto ERROR;
|
||||
}
|
||||
ibmpc_error = IBMPC_ERR_NONE;
|
||||
goto DONE;
|
||||
break;
|
||||
default:
|
||||
goto ERROR;
|
||||
}
|
||||
goto NEXT;
|
||||
|
||||
ERROR:
|
||||
ibmpc_error |= state;
|
||||
ibmpc_error |= IBMPC_ERR_RECV;
|
||||
ringbuf_reset(&rb);
|
||||
DONE:
|
||||
last_time = 0;
|
||||
state = START;
|
||||
data = 0;
|
||||
parity = 1;
|
||||
return;
|
||||
NEXT:
|
||||
state++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* send LED state to keyboard */
|
||||
void ibmpc_host_set_led(uint8_t led)
|
||||
{
|
||||
ibmpc_host_send(0xED);
|
||||
ibmpc_host_send(led);
|
||||
}
|
||||
199
tmk_core/protocol/ibmpc.h
Normal file
199
tmk_core/protocol/ibmpc.h
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
Copyright 2010,2011,2012,2013,2019 Jun WAKO <wakojun@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IBMPC_H
|
||||
#define IBMPC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "wait.h"
|
||||
#include "print.h"
|
||||
|
||||
/*
|
||||
* IBM PC keyboard protocol
|
||||
*
|
||||
* PS/2 Resources
|
||||
* --------------
|
||||
* [1] The PS/2 Mouse/Keyboard Protocol
|
||||
* http://www.computer-engineering.org/ps2protocol/
|
||||
* Concise and thorough primer of PS/2 protocol.
|
||||
*
|
||||
* [2] Keyboard and Auxiliary Device Controller
|
||||
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
|
||||
* Signal Timing and Format
|
||||
*
|
||||
* [3] Keyboards(101- and 102-key)
|
||||
* http://www.mcamafia.de/pdf/ibm_hitrc11.pdf
|
||||
* Keyboard Layout, Scan Code Set, POR, and Commands.
|
||||
*
|
||||
* [4] PS/2 Reference Manuals
|
||||
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
|
||||
* Collection of IBM Personal System/2 documents.
|
||||
*
|
||||
* [5] TrackPoint Engineering Specifications for version 3E
|
||||
* https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
|
||||
*/
|
||||
#define IBMPC_ACK 0xFA
|
||||
#define IBMPC_RESEND 0xFE
|
||||
#define IBMPC_SET_LED 0xED
|
||||
|
||||
#define IBMPC_PROTOCOL_AT 0
|
||||
#define IBMPC_PROTOCOL_XT 1
|
||||
|
||||
// TODO: error numbers
|
||||
#define IBMPC_ERR_NONE 0
|
||||
#define IBMPC_ERR_RECV 0x00
|
||||
#define IBMPC_ERR_SEND 0x10
|
||||
#define IBMPC_ERR_TIMEOUT 0x20
|
||||
#define IBMPC_ERR_FULL 0x40
|
||||
|
||||
#define IBMPC_LED_SCROLL_LOCK 0
|
||||
#define IBMPC_LED_NUM_LOCK 1
|
||||
#define IBMPC_LED_CAPS_LOCK 2
|
||||
|
||||
|
||||
extern volatile uint8_t ibmpc_protocol;
|
||||
extern volatile uint8_t ibmpc_error;
|
||||
|
||||
void ibmpc_host_init(void);
|
||||
int16_t ibmpc_host_send(uint8_t data);
|
||||
int16_t ibmpc_host_recv_response(void);
|
||||
int16_t ibmpc_host_recv(void);
|
||||
void ibmpc_host_set_led(uint8_t usb_led);
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* static functions
|
||||
*------------------------------------------------------------------*/
|
||||
#if defined(__AVR__)
|
||||
/*
|
||||
* Clock
|
||||
*/
|
||||
static inline void clock_init(void)
|
||||
{
|
||||
IBMPC_CLOCK_PORT &= ~(1<<IBMPC_CLOCK_BIT);
|
||||
IBMPC_CLOCK_DDR |= (1<<IBMPC_CLOCK_BIT);
|
||||
}
|
||||
|
||||
static inline void clock_lo(void)
|
||||
{
|
||||
IBMPC_CLOCK_PORT &= ~(1<<IBMPC_CLOCK_BIT);
|
||||
IBMPC_CLOCK_DDR |= (1<<IBMPC_CLOCK_BIT);
|
||||
}
|
||||
|
||||
static inline void clock_hi(void)
|
||||
{
|
||||
/* input with pull up */
|
||||
IBMPC_CLOCK_DDR &= ~(1<<IBMPC_CLOCK_BIT);
|
||||
IBMPC_CLOCK_PORT |= (1<<IBMPC_CLOCK_BIT);
|
||||
}
|
||||
|
||||
static inline bool clock_in(void)
|
||||
{
|
||||
IBMPC_CLOCK_DDR &= ~(1<<IBMPC_CLOCK_BIT);
|
||||
IBMPC_CLOCK_PORT |= (1<<IBMPC_CLOCK_BIT);
|
||||
wait_us(1);
|
||||
return IBMPC_CLOCK_PIN&(1<<IBMPC_CLOCK_BIT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Data
|
||||
*/
|
||||
static inline void data_init(void)
|
||||
{
|
||||
IBMPC_DATA_DDR &= ~(1<<IBMPC_DATA_BIT);
|
||||
IBMPC_DATA_PORT |= (1<<IBMPC_DATA_BIT);
|
||||
}
|
||||
|
||||
static inline void data_lo(void)
|
||||
{
|
||||
IBMPC_DATA_PORT &= ~(1<<IBMPC_DATA_BIT);
|
||||
IBMPC_DATA_DDR |= (1<<IBMPC_DATA_BIT);
|
||||
}
|
||||
|
||||
static inline void data_hi(void)
|
||||
{
|
||||
/* input with pull up */
|
||||
IBMPC_DATA_DDR &= ~(1<<IBMPC_DATA_BIT);
|
||||
IBMPC_DATA_PORT |= (1<<IBMPC_DATA_BIT);
|
||||
}
|
||||
|
||||
static inline bool data_in(void)
|
||||
{
|
||||
IBMPC_DATA_DDR &= ~(1<<IBMPC_DATA_BIT);
|
||||
IBMPC_DATA_PORT |= (1<<IBMPC_DATA_BIT);
|
||||
wait_us(1);
|
||||
return IBMPC_DATA_PIN&(1<<IBMPC_DATA_BIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static inline uint16_t wait_clock_lo(uint16_t us)
|
||||
{
|
||||
while (clock_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_clock_hi(uint16_t us)
|
||||
{
|
||||
while (!clock_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_data_lo(uint16_t us)
|
||||
{
|
||||
while (data_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_data_hi(uint16_t us)
|
||||
{
|
||||
while (!data_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
|
||||
/* idle state that device can send */
|
||||
static inline void idle(void)
|
||||
{
|
||||
clock_hi();
|
||||
data_hi();
|
||||
}
|
||||
|
||||
/* inhibit device to send */
|
||||
static inline void inhibit(void)
|
||||
{
|
||||
clock_lo();
|
||||
data_hi();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -49,7 +49,20 @@ OPT_DEFS += $(LUFA_OPTS)
|
|||
# This indicates using LUFA stack
|
||||
OPT_DEFS += -DPROTOCOL_LUFA
|
||||
|
||||
ifeq (yes,$(strip $(LUFA_DEBUG)))
|
||||
LUFA_OPTS += -DLUFA_DEBUG
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(LUFA_DEBUG_SUART)))
|
||||
SRC += common/avr/suart.S
|
||||
LUFA_OPTS += -DLUFA_DEBUG_SUART
|
||||
# Keep print/debug lines when disabling HID console. See common.mk.
|
||||
DEBUG_PRINT_AVAILABLE = yes
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(LUFA_DEBUG_UART)))
|
||||
SRC += common/avr/uart.c
|
||||
LUFA_OPTS += -DLUFA_DEBUG_UART
|
||||
# Keep print/debug lines when disabling HID console. See common.mk.
|
||||
DEBUG_PRINT_AVAILABLE = yes
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@
|
|||
#include "avr/suart.h"
|
||||
#endif
|
||||
|
||||
#ifdef LUFA_DEBUG_UART
|
||||
#include "uart.h"
|
||||
#endif
|
||||
|
||||
#include "matrix.h"
|
||||
#include "descriptor.h"
|
||||
#include "lufa.h"
|
||||
|
|
@ -218,7 +222,9 @@ static void console_task(void)
|
|||
*/
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[C]");
|
||||
#endif
|
||||
/* For battery powered device */
|
||||
if (!USB_IsInitialized) {
|
||||
USB_Disable();
|
||||
|
|
@ -229,7 +235,9 @@ void EVENT_USB_Device_Connect(void)
|
|||
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[D]");
|
||||
#endif
|
||||
/* For battery powered device */
|
||||
USB_IsInitialized = false;
|
||||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
|
||||
|
|
@ -575,25 +583,22 @@ static void send_consumer(uint16_t data)
|
|||
/*******************************************************************************
|
||||
* sendchar
|
||||
******************************************************************************/
|
||||
#ifdef CONSOLE_ENABLE
|
||||
int8_t sendchar(uint8_t c)
|
||||
{
|
||||
#ifdef LUFA_DEBUG_SUART
|
||||
xmit(c);
|
||||
#endif
|
||||
|
||||
bool r = console_putc(c);
|
||||
return (r ? 0 : -1);
|
||||
}
|
||||
#else
|
||||
int8_t sendchar(uint8_t c)
|
||||
{
|
||||
#ifdef LUFA_DEBUG_SUART
|
||||
xmit(c);
|
||||
#ifdef LUFA_DEBUG_UART
|
||||
uart_putchar(c);
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
console_putc(c);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
@ -629,11 +634,15 @@ int main(void)
|
|||
SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
|
||||
#endif
|
||||
|
||||
#ifdef LUFA_DEBUG_UART
|
||||
uart_init(115200);
|
||||
#endif
|
||||
|
||||
// setup sendchar: DO NOT USE print functions before this line
|
||||
print_set_sendchar(sendchar);
|
||||
host_set_driver(&lufa_driver);
|
||||
|
||||
print("Keyboard init.\n");
|
||||
print("\n\nTMK:" STR(TMK_VERSION) "/LUFA\n\n");
|
||||
hook_early_init();
|
||||
keyboard_setup();
|
||||
setup_usb();
|
||||
|
|
@ -645,6 +654,7 @@ int main(void)
|
|||
|
||||
keyboard_init();
|
||||
|
||||
#ifndef NO_USB_STARTUP_WAIT_LOOP
|
||||
/* wait for USB startup */
|
||||
while (USB_DeviceState != DEVICE_STATE_Configured) {
|
||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
|
|
@ -652,19 +662,20 @@ int main(void)
|
|||
#else
|
||||
USB_USBTask();
|
||||
#endif
|
||||
matrix_scan();
|
||||
hook_usb_startup_wait_loop();
|
||||
}
|
||||
print("\nUSB configured.\n");
|
||||
#endif
|
||||
|
||||
hook_late_init();
|
||||
|
||||
print("\nKeyboard start.\n");
|
||||
while (1) {
|
||||
#ifndef NO_USB_SUSPEND_LOOP
|
||||
while (USB_DeviceState == DEVICE_STATE_Suspended) {
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[s]");
|
||||
#endif
|
||||
hook_usb_suspend_loop();
|
||||
}
|
||||
#endif
|
||||
|
||||
keyboard_task();
|
||||
|
||||
|
|
@ -690,12 +701,12 @@ static uint8_t _led_stats = 0;
|
|||
__attribute__((weak))
|
||||
void hook_usb_suspend_entry(void)
|
||||
{
|
||||
// Turn LED off to save power
|
||||
// Set 0 with putting aside status before suspend and restore
|
||||
// it after wakeup, then LED is updated at keyboard_task() in main loop
|
||||
// Turn off LED to save power and keep its status to resotre it later.
|
||||
// LED status will be updated by keyboard_task() in main loop hopefully.
|
||||
_led_stats = keyboard_led_stats;
|
||||
keyboard_led_stats = 0;
|
||||
led_set(keyboard_led_stats);
|
||||
|
||||
// Calling long task here can prevent USB state transition
|
||||
|
||||
matrix_clear();
|
||||
clear_keyboard();
|
||||
|
|
@ -707,7 +718,10 @@ void hook_usb_suspend_entry(void)
|
|||
__attribute__((weak))
|
||||
void hook_usb_suspend_loop(void)
|
||||
{
|
||||
#ifndef LUFA_DEBUG_UART
|
||||
// This corrupts debug print when suspend
|
||||
suspend_power_down();
|
||||
#endif
|
||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
|
||||
USB_Device_SendRemoteWakeup();
|
||||
}
|
||||
|
|
@ -721,10 +735,11 @@ void hook_usb_wakeup(void)
|
|||
sleep_led_disable();
|
||||
#endif
|
||||
|
||||
// Restore LED status
|
||||
// BIOS/grub won't recognize/enumerate if led_set() takes long(around 40ms?)
|
||||
// Converters fall into the case and miss wakeup event(timeout to reply?) in the end.
|
||||
//led_set(host_keyboard_leds());
|
||||
// Instead, restore stats and update at keyboard_task() in main loop
|
||||
// Restore LED status and update at keyboard_task() in main loop
|
||||
keyboard_led_stats = _led_stats;
|
||||
|
||||
// Calling long task here can prevent USB state transition
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
void hook_usb_startup_wait_loop(void) {}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ USB_HID_DIR = protocol/usb_hid
|
|||
#
|
||||
# USB Host Shield
|
||||
#
|
||||
USB_HOST_SHIELD_DIR = $(USB_HID_DIR)/USB_Host_Shield_2.0-git
|
||||
USB_HOST_SHIELD_DIR = $(USB_HID_DIR)/USB_Host_Shield_2.0-tmk
|
||||
USB_HOST_SHIELD_SRC = \
|
||||
$(USB_HOST_SHIELD_DIR)/Usb.cpp \
|
||||
$(USB_HOST_SHIELD_DIR)/usbhid.cpp \
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit ed08df7e68af06a5612d938b1bbf55cc4458518a
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 48b2a0950496c7b8ba1bb6ddb937b6f00a6de781
|
||||
|
|
@ -1,21 +1,24 @@
|
|||
#include "parser.h"
|
||||
#include "usb_hid.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "print.h"
|
||||
|
||||
|
||||
void KBDReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
|
||||
{
|
||||
dprintf("input %d:", hid->GetAddress());
|
||||
xprintf("input %d:", hid->GetAddress());
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
dprintf(" %02X", buf[i]);
|
||||
xprintf(" %02X", buf[i]);
|
||||
}
|
||||
dprint("\r\n");
|
||||
xprintf("\r\n");
|
||||
|
||||
// ignore Cherry 0101010101010101 bug report
|
||||
// Rollover error
|
||||
// Cherry: 0101010101010101
|
||||
// https://geekhack.org/index.php?topic=69169.msg2638223#msg2638223
|
||||
if (buf[1] == 0x01) {
|
||||
dprint("Cherry bug: ignored\r\n");
|
||||
// Apple: 0000010101010101
|
||||
// https://geekhack.org/index.php?topic=69169.msg2760969#msg2760969
|
||||
if (buf[2] == 0x01) {
|
||||
xprintf("Rollover error: ignored\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue