Merge remote-tracking branch 'tmk/master'

This commit is contained in:
Mark Sikora 2020-06-08 15:52:01 -04:00
commit 574fc5e2e8
35 changed files with 3971 additions and 3851 deletions

View file

@ -53,9 +53,6 @@ ARCH ?= AVR8
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB ?= $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512

View file

@ -70,7 +70,8 @@ ARCH ?= AVR8
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB ?= $(F_CPU)
# Interrupt driven control endpoint task(+60)
# TODO: This can prevent converter ISR from handling signal instantly, better remove it.
# Without this option debug prints from enable_break() won't be displayed comopletely.
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT

View file

@ -50,9 +50,6 @@ ARCH ?= AVR8
# 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. Do not enable this.
# This blocks long for capslock and etc. and can prevent signal handling.
#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# This improves response of keyboard when wakeup
OPT_DEFS += -DSUSPEND_MODE_STANDBY
@ -78,8 +75,8 @@ 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
KEYMAP_SECTION_ENABLE ?= yes
UNIMAP_ENABLE ?= yes
# Optimize size but this may cause error "relocation truncated to fit"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -33,9 +33,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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 int8_t process_cs1(uint8_t code);
static int8_t process_cs2(uint8_t code);
static int8_t process_cs3(uint8_t code);
static uint8_t matrix[MATRIX_ROWS];
@ -105,6 +105,7 @@ void matrix_init(void)
* d. ID is BF BF: Terminal keyboard CodeSet3
* e. error on recv: maybe broken PS/2
*/
uint8_t current_protocol = 0;
uint16_t keyboard_id = 0x0000;
keyboard_kind_t keyboard_kind = NONE;
uint8_t matrix_scan(void)
@ -112,6 +113,8 @@ uint8_t matrix_scan(void)
// scan code reading states
static enum {
INIT,
WAIT_SETTLE,
AT_RESET,
XT_RESET,
XT_RESET_WAIT,
XT_RESET_DONE,
@ -126,23 +129,45 @@ uint8_t matrix_scan(void)
if (ibmpc_error) {
xprintf("\nERR:%02X\n", ibmpc_error);
xprintf("\nERR:%02X ISR:%04X ", ibmpc_error, ibmpc_isr_debug);
// 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");
xprintf("[RST] ");
state = INIT;
}
}
// clear or process error
ibmpc_error = IBMPC_ERR_NONE;
ibmpc_isr_debug = 0;
}
// check protocol change AT/XT
if (ibmpc_protocol && ibmpc_protocol != current_protocol) {
xprintf("\nPRT:%02X ISR:%04X ", ibmpc_protocol, ibmpc_isr_debug);
// protocol change between AT and XT indicates that
// keyboard is hotswapped or something goes wrong.
// This requires initializing keyboard again probably.
if (((current_protocol&IBMPC_PROTOCOL_XT) && (ibmpc_protocol&IBMPC_PROTOCOL_AT)) ||
((current_protocol&IBMPC_PROTOCOL_AT) && (ibmpc_protocol&IBMPC_PROTOCOL_XT))) {
if (state == LOOP) {
xprintf("[CHG] ");
state = INIT;
}
}
current_protocol = ibmpc_protocol;
ibmpc_isr_debug = 0;
}
switch (state) {
case INIT:
ibmpc_host_disable();
xprintf("I%u ", timer_read());
keyboard_kind = NONE;
keyboard_id = 0x0000;
@ -150,7 +175,31 @@ uint8_t matrix_scan(void)
matrix_clear();
clear_keyboard();
state = XT_RESET;
init_time = timer_read();
state = WAIT_SETTLE;
break;
case WAIT_SETTLE:
// wait for keyboard to settle after plugin
if (timer_elapsed(init_time) > 1000) {
state = AT_RESET;
}
break;
case AT_RESET:
ibmpc_host_isr_clear();
ibmpc_host_enable();
wait_ms(1); // keyboard can't respond to command without this
// SKIDATA-2-DE(and some other keyboards?) stores 'Code Set' setting in nonvlatile memory
// and keeps it until receiving reset. Sending reset here may be useful to clear it, perhaps.
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#select-alternate-scan-codesf0
// reset command
if (0xFA == ibmpc_host_send(0xFF)) {
state = WAIT_AA;
} else {
state = XT_RESET;
}
xprintf("A%u ", timer_read());
break;
case XT_RESET:
// Reset XT-initialize keyboard
@ -217,19 +266,8 @@ uint8_t matrix_scan(void)
}
break;
case READ_ID:
xprintf("R%u ", timer_read());
// SKIDATA-2-DE(and some other keyboards?) stores 'Code Set' setting in nonvlatile memory
// and keeps it until receiving reset. Sending reset here may be useful to clear it, perhaps.
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#select-alternate-scan-codesf0
//ibmpc_host_send(0xFF); // reset command
//read_wait(500); // BAT takes 600-900ms(84-key) or 300-500ms(101/102-key) [8] 4-7, 4-39
keyboard_id = read_keyboard_id();
if (ibmpc_error) {
xprintf("\nERR:%02X\n", ibmpc_error);
ibmpc_error = IBMPC_ERR_NONE;
}
xprintf("R%u ", timer_read());
if (0x0000 == keyboard_id) { // CodeSet2 AT(IBM PC AT 84-key)
keyboard_kind = PC_AT;
@ -241,9 +279,11 @@ uint8_t matrix_scan(void)
xprintf("Mouse: not supported\n");
keyboard_kind = NONE;
#ifdef G80_2551_SUPPORT
} else if (0xAB86 == keyboard_id) { // CodeSet2 PS/2 Terminal
// For G80-2551 and other 122-key terminal keyboards
} else if (0xAB86 == keyboard_id ||
0xAB85 == keyboard_id) { // For G80-2551 and other 122-key terminal
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#ab86
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#ab85
if ((0xFA == ibmpc_host_send(0xF0)) &&
(0xFA == ibmpc_host_send(0x03))) {
// switch to code set 3
@ -252,6 +292,11 @@ uint8_t matrix_scan(void)
keyboard_kind = PC_AT;
}
#endif
} else if (0xBFB0 == keyboard_id) { // IBM RT Keyboard
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#bfb0
// TODO: LED indicator fix
//keyboard_kind = PC_TERMINAL_IBM_RT;
keyboard_kind = PC_TERMINAL;
} else if (0xAB00 == (keyboard_id & 0xFF00)) { // CodeSet2 PS/2
keyboard_kind = PC_AT;
} else if (0xBF00 == (keyboard_id & 0xFF00)) { // CodeSet3 Terminal
@ -260,7 +305,7 @@ uint8_t matrix_scan(void)
keyboard_kind = PC_AT;
}
xprintf("ID:%04X(%d)\n", keyboard_id, keyboard_kind);
xprintf("\nID:%04X(%d) ", keyboard_id, keyboard_kind);
state = SETUP;
break;
@ -275,6 +320,8 @@ uint8_t matrix_scan(void)
case PC_TERMINAL:
// Set all keys to make/break type
ibmpc_host_send(0xF8);
// This should not be harmful
led_set(host_keyboard_leds());
break;
default:
break;
@ -282,18 +329,39 @@ uint8_t matrix_scan(void)
state = LOOP;
xprintf("L%u ", timer_read());
case LOOP:
switch (keyboard_kind) {
case PC_XT:
if (process_cs1() == -1) state = INIT;
{
uint16_t code = ibmpc_host_recv();
if (code == -1) {
// no code
break;
case PC_AT:
if (process_cs2() == -1) state = INIT;
break;
case PC_TERMINAL:
if (process_cs3() == -1) state = INIT;
break;
default:
}
// Keyboard Error/Overrun([3]p.26) or Buffer full
// Scan Code Set 1: 0xFF
// Scan Code Set 2 and 3: 0x00
// Buffer full(IBMPC_ERR_FULL): 0xFF
if (code == 0x00 || code == 0xFF) {
// clear stuck keys
matrix_clear();
clear_keyboard();
xprintf("\n[OVR] ");
break;
}
switch (keyboard_kind) {
case PC_XT:
if (process_cs1(code) == -1) state = INIT;
break;
case PC_AT:
if (process_cs2(code) == -1) state = INIT;
break;
case PC_TERMINAL:
if (process_cs3(code) == -1) state = INIT;
break;
default:
break;
}
}
break;
default:
@ -347,8 +415,19 @@ void matrix_clear(void)
void led_set(uint8_t usb_led)
{
//if (keyboard_kind != PC_AT) return;
// Sending before keyboard recognition may be harmful for XT keyboard
if (keyboard_kind == NONE) return;
// XT keyobard doesn't support any command and it is harmful perhaps
// https://github.com/tmk/tmk_keyboard/issues/635#issuecomment-626993437
if (keyboard_kind == PC_XT) return;
// It should be safe to send the command to keyboards with AT protocol
// - IBM Terminal doesn't support the command and response with 0xFE but it is not harmful.
// - Some other Terminals like G80-2551 supports the command.
// https://geekhack.org/index.php?topic=103648.msg2894921#msg2894921
// TODO: PC_TERMINAL_IBM_RT support
uint8_t ibmpc_led = 0;
if (usb_led & (1<<USB_LED_SCROLL_LOCK))
ibmpc_led |= (1<<IBMPC_LED_SCROLL_LOCK);
@ -437,7 +516,7 @@ static uint8_t cs1_e0code(uint8_t code) {
return 0x00;
}
static int8_t process_cs1(void)
static int8_t process_cs1(uint8_t code)
{
static enum {
INIT,
@ -448,27 +527,9 @@ static int8_t process_cs1(void)
E1_9D,
} state = INIT;
uint16_t code = ibmpc_host_recv();
if (code == -1) {
return 0;
}
// Check invalid codes; 0x59-7F won't be used in real XT keyboards probably
// 0x62 is used to handle escape code E0 and E1
if ((code & 0x7F) >= 0x62) {
xprintf("!CS1_INV!\n");
state = INIT;
return -1;
}
switch (state) {
case INIT:
switch (code) {
case 0x00:
case 0xFF: // Error/Overrun [3]p.26
xprintf("!CS1_ERR!\n");
return -1;
break;
case 0xE0:
state = E0;
break;
@ -625,12 +686,12 @@ static uint8_t cs2_e0code(uint8_t code) {
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 0x7C: return 0x7F; // 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 0x23: return 0x6F; // mute
case 0x10: return 0x08; // (WWW search) -> F13
case 0x18: return 0x10; // (WWW favourites) -> F14
case 0x20: return 0x18; // (WWW refresh) -> F15
@ -662,7 +723,7 @@ static uint8_t cs2_e0code(uint8_t code) {
}
}
static int8_t process_cs2(void)
static int8_t process_cs2(uint8_t code)
{
// scan code reading states
static enum {
@ -678,25 +739,9 @@ static int8_t process_cs2(void)
E1_F0_14_F0,
} state = INIT;
uint16_t code = ibmpc_host_recv();
if (code == -1) {
return 0;
}
switch (state) {
case INIT:
switch (code) {
case 0x00: // Error/Overrun [3]p.26
xprintf("!CS2_OVR!\n");
matrix_clear();
clear_keyboard();
break;
case 0xFF:
matrix_clear();
xprintf("!CS2_ERR!\n");
state = INIT;
return -1;
break;
case 0xE0:
state = E0;
break;
@ -711,15 +756,12 @@ static int8_t process_cs2(void)
state = INIT;
break;
case 0x84: // Alt'd PrintScreen
matrix_make(0x6F);
matrix_make(0x7F);
state = INIT;
break;
case 0xAA: // Self-test passed
case 0xFC: // Self-test failed
// reset or plugin-in new keyboard
state = INIT;
return -1;
break;
// replug or unstable connection probably
default: // normal key make
state = INIT;
if (code < 0x80) {
@ -758,7 +800,7 @@ static int8_t process_cs2(void)
state = INIT;
break;
case 0x84: // Alt'd PrintScreen
matrix_break(0x6F);
matrix_break(0x7F);
state = INIT;
break;
default:
@ -850,11 +892,10 @@ static int8_t process_cs2(void)
/*
* Terminal: Scan Code Set 3
*
* See [3], [7]
*
* Scan code 0x83 and 0x84 are handled exceptioanally to fit into 1-byte range index.
* See [3], [7] and
* https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#scan-code-set-3
*/
static int8_t process_cs3(void)
static int8_t process_cs3(uint8_t code)
{
static enum {
READY,
@ -866,23 +907,9 @@ static int8_t process_cs3(void)
#endif
} state = READY;
uint16_t code = ibmpc_host_recv();
if (code == -1) {
return 0;
}
switch (state) {
case READY:
switch (code) {
case 0x00: // Error/Overrun [3]p.26
xprintf("!CS3_OVR!\n");
matrix_clear();
clear_keyboard();
break;
case 0xFF:
xprintf("!CS3_ERR!\n");
return -1;
break;
case 0xF0:
state = F0;
break;
@ -920,23 +947,12 @@ static int8_t process_cs3(void)
matrix_make(code);
} else {
xprintf("!CS3_READY!\n");
//return -1;
return -1;
}
}
break;
case F0: // Break code
switch (code) {
case 0x00:
xprintf("!CS3_F0_OVR!\n");
matrix_clear();
clear_keyboard();
state = READY;
break;
case 0xFF:
xprintf("!CS3_F0_ERR!\n");
state = READY;
return -1;
break;
case 0x83: // PrintScreen
matrix_break(0x02);
state = READY;
@ -975,7 +991,7 @@ static int8_t process_cs3(void)
matrix_break(code);
} else {
xprintf("!CS3_F0!\n");
//return -1;
return -1;
}
}
break;

View file

@ -149,9 +149,9 @@ const uint8_t PROGMEM unimap_cs2[MATRIX_ROWS][MATRIX_COLS] = {
{ 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_NUHS, UNIMAP_P1, UNIMAP_JYEN, UNIMAP_P4, UNIMAP_P7, UNIMAP_PCMM, UNIMAP_VOLU, UNIMAP_MUTE }, /* 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 */
{ UNIMAP_F11, UNIMAP_PPLS, UNIMAP_P3, UNIMAP_PMNS, UNIMAP_PAST, UNIMAP_P9, UNIMAP_SLCK, UNIMAP_PSCR }, /* 78-7F */
};

View file

@ -65,9 +65,6 @@ ARCH ?= AVR8
# 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
# Boot Section Size in bytes
# Teensy halfKay 512

View file

@ -58,9 +58,6 @@ ARCH = AVR8
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512

View file

@ -68,9 +68,6 @@ ARCH ?= AVR8
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB ?= $(F_CPU)
# Interrupt driven control endpoint task(+60)
#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512

View file

@ -10,7 +10,6 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
# LUFA specific
ARCH ?= AVR8
F_USB ?= $(F_CPU)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Build Options

View file

@ -49,9 +49,6 @@ ARCH ?= AVR8
# 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.

View file

@ -49,9 +49,6 @@ ARCH ?= AVR8
# 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.

View file

@ -49,9 +49,6 @@ ARCH ?= AVR8
# 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.

View file

@ -68,9 +68,6 @@ ARCH ?= AVR8
# 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

View file

@ -52,9 +52,6 @@ ARCH ?= AVR8
# 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.

View file

@ -50,9 +50,6 @@ ARCH = AVR8
# 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
# Boot Section Size in bytes
# Teensy halfKay 512

View file

@ -82,9 +82,6 @@ ARCH ?= AVR8
# 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

View file

@ -226,13 +226,6 @@ void led_set(uint8_t 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.

View file

@ -54,9 +54,6 @@ ARCH ?= AVR8
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB ?= $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512

View file

@ -69,9 +69,6 @@ ARCH ?= AVR8
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB ?= $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512

View file

@ -37,6 +37,10 @@ enum macro_id {
#define AC_FRWD ACTION_MODS_KEY(MOD_LALT, KC_RIGHT)
#define AC_ENT_ ACTION_MODS_TAP_KEY(MOD_RCTL, KC_ENT)
// Display Brightness Control
// https://github.com/tmk/tmk_keyboard/issues/370#issuecomment-279113313
// BRTI(increment) and BRTD(decrement) are defined in actionmap.h
// Function: LShift with tap '('
#define AC_LPRN ACTION_FUNCTION_TAP(LSHIFT_LPAREN)
// Macro: say hello
@ -59,7 +63,7 @@ const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
PWR, 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, TRNS,
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT, PENT,
TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN, TRNS,TRNS,
TRNS, BRTD,BRTI,SLEP,WAKE,TRNS,PPLS,PMNS,END, PGDN,DOWN, TRNS,TRNS,
TRNS,TRNS, TRNS, TRNS,TRNS),
[2] = UNIMAP_HHKB(

View file

@ -1,5 +1,5 @@
/*
Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
Copyright 2012,2013,2020 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

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 Jun Wako <wakojun@gmail.com>
Copyright 2015,2020 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
@ -283,6 +283,8 @@ 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)
#define AC_BRIGHTNESS_INC ACTION_USAGE_CONSUMER(BRIGHTNESS_INCREMENT)
#define AC_BRIGHTNESS_DEC ACTION_USAGE_CONSUMER(BRIGHTNESS_DECREMENT)
/* Mousekey */
#define AC_MS_UP ACTION_MOUSEKEY(KC_MS_UP)
@ -417,6 +419,8 @@ 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)
#define AC_BRTI ACTION_USAGE_CONSUMER(BRIGHTNESS_INCREMENT)
#define AC_BRTD ACTION_USAGE_CONSUMER(BRIGHTNESS_DECREMENT)
/* Transparent */
#define AC_TRNS ACTION_KEY(KC_TRANSPARENT)

View file

@ -115,7 +115,7 @@ uint32_t timer_elapsed32(uint32_t last)
}
// excecuted once per 1ms.(excess for just timer count?)
ISR(TIMER0_COMPA_vect)
ISR(TIMER0_COMPA_vect, ISR_NOBLOCK)
{
timer_count++;
}

View file

@ -182,3 +182,6 @@ void keyboard_set_leds(uint8_t leds)
{
led_set(leds);
}
__attribute__ ((weak))
void led_set(uint8_t usb_led) {}

View file

@ -1,5 +1,5 @@
/*
Copyright 2011,2012 Jun Wako <wakojun@gmail.com>
Copyright 2011,2012,2020 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
@ -38,7 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE)
#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_WFAV)
#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRIGHTNESS_DEC)
#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31)
#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
@ -174,6 +174,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KC_WSTP KC_WWW_STOP
#define KC_WREF KC_WWW_REFRESH
#define KC_WFAV KC_WWW_FAVORITES
#define KC_BRTI KC_BRIGHTNESS_INC
#define KC_BRTD KC_BRIGHTNESS_DEC
/* Jump to bootloader */
#define KC_BTLD KC_BOOTLOADER
/* Transparent */
@ -438,7 +440,9 @@ enum internal_special_keycodes {
KC_WWW_FORWARD,
KC_WWW_STOP,
KC_WWW_REFRESH,
KC_WWW_FAVORITES, /* 0xBC */
KC_WWW_FAVORITES,
KC_BRIGHTNESS_INC,
KC_BRIGHTNESS_DEC, /* 0xBE */
/* Jump to bootloader */
KC_BOOTLOADER = 0xBF,

View file

@ -1,5 +1,5 @@
/*
Copyright 2013,2016 Jun Wako <wakojun@gmail.com>
Copyright 2013,2016,2020 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
@ -145,7 +145,7 @@ static action_t keycode_to_action(uint8_t keycode)
case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
return (action_t)ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
break;
case KC_AUDIO_MUTE ... KC_WWW_FAVORITES:
case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DEC:
return (action_t)ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
break;
case KC_MS_UP ... KC_MS_ACCEL2:

View file

@ -48,21 +48,21 @@ __attribute__ ((weak))
void matrix_print(void)
{
#if (MATRIX_COLS <= 8)
print("r/c 01234567\n");
print("\n 01234567\n");
#elif (MATRIX_COLS <= 16)
print("r/c 0123456789ABCDEF\n");
print("\n 0123456789ABCDEF\n");
#elif (MATRIX_COLS <= 32)
print("r/c 0123456789ABCDEF0123456789ABCDEF\n");
print("\n 0123456789ABCDEF0123456789ABCDEF\n");
#endif
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
#if (MATRIX_COLS <= 8)
xprintf("%02X: %08b%s\n", row, bitrev(matrix_get_row(row)),
xprintf("%X:%08b%s\n", row&0xF, bitrev(matrix_get_row(row)),
#elif (MATRIX_COLS <= 16)
xprintf("%02X: %016b%s\n", row, bitrev16(matrix_get_row(row)),
xprintf("%X:%016b%s\n", row&0xF, bitrev16(matrix_get_row(row)),
#elif (MATRIX_COLS <= 32)
xprintf("%02X: %032b%s\n", row, bitrev32(matrix_get_row(row)),
xprintf("%X:%032b%s\n", row&0xF, bitrev32(matrix_get_row(row)),
#endif
#ifdef MATRIX_HAS_GHOST
matrix_has_ghost_in_row(row) ? " <ghost" : ""

View file

@ -1,5 +1,5 @@
/*
Copyright 2011,2012 Jun Wako <wakojun@gmail.com>
Copyright 2011,2012,2020 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
@ -37,8 +37,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#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
/*
* USB HID Specifications
* https://www.usb.org/hid#approved-usage-table-review-requests
*/
/*
* Consumer Page(0x0C)
* https://github.com/tmk/tmk_keyboard/issues/370
*/
#define AUDIO_MUTE 0x00E2
#define AUDIO_VOL_UP 0x00E9
@ -68,8 +75,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define TRANSPORT_REWIND 0x00B4
#define TRANSPORT_EJECT 0x00B8
#define APPCONTROL_MINIMIZE 0x0206
/* Display Brightness Controls https://www.usb.org/sites/default/files/hutrr41_0.pdf */
#define BRIGHTNESS_INCREMENT 0x006F
#define BRIGHTNESS_DECREMENT 0x0070
/* Generic Desktop Page(0x01) - system power control */
/*
* Generic Desktop Page(0x01) - system power control
*/
#define SYSTEM_POWER_DOWN 0x0081
#define SYSTEM_SLEEP 0x0082
#define SYSTEM_WAKE_UP 0x0083
@ -182,7 +194,9 @@ typedef struct {
(key == KC_WWW_FORWARD ? APPCONTROL_FORWARD : \
(key == KC_WWW_STOP ? APPCONTROL_STOP : \
(key == KC_WWW_REFRESH ? APPCONTROL_REFRESH : \
(key == KC_WWW_FAVORITES ? APPCONTROL_BOOKMARKS : 0)))))))))))))))))))))
(key == KC_WWW_FAVORITES ? APPCONTROL_BOOKMARKS : \
(key == KC_BRIGHTNESS_INC ? BRIGHTNESS_INCREMENT : \
(key == KC_BRIGHTNESS_DEC ? BRIGHTNESS_DECREMENT : 0)))))))))))))))))))))))
#ifdef __cplusplus
}

View file

@ -56,15 +56,17 @@ POSSIBILITY OF SUCH DAMAGE.
} while (0)
volatile uint16_t ibmpc_isr_debug = 0;
volatile uint8_t ibmpc_protocol = IBMPC_PROTOCOL_NO;
volatile uint8_t ibmpc_error = IBMPC_ERR_NONE;
/* 2-byte buffer for data received from keyhboard
/* 2-byte buffer for data received from keyboard
* buffer states:
* FFFF: empty
* FFss: one data
* sstt: two data(full)
* 0xFF can not be stored as data in buffer because it means empty or no data.
* sstt: two data
* eeFF: error
* where ss, tt and ee are 0x00-0xFE. 0xFF means empty or no data in buffer.
*/
static volatile uint16_t recv_data = 0xFFFF;
/* internal state of receiving data */
@ -103,12 +105,13 @@ int16_t ibmpc_host_send(uint8_t data)
/* terminate a transmission if we have */
inhibit();
wait_us(100); // 100us [4]p.13, [5]p.50
wait_us(100); // [5]p.54
/* 'Request to Send' and Start bit */
data_lo();
clock_hi();
WAIT(clock_lo, 10000, 1); // 10ms [5]p.50
wait_us(100);
clock_hi(); // [5]p.54 [clock low]>100us [5]p.50
WAIT(clock_lo, 10000, 1); // [5]p.53, -10ms [5]p.50
/* Data bit[2-9] */
for (uint8_t i = 0; i < 8; i++) {
@ -132,14 +135,15 @@ int16_t ibmpc_host_send(uint8_t data)
/* Stop bit */
wait_us(15);
data_hi();
/* Ack */
WAIT(data_lo, 50, 6);
WAIT(clock_hi, 50, 6);
WAIT(clock_lo, 50, 7);
/* Ack */
WAIT(data_lo, 50, 8);
/* wait for idle state */
WAIT(clock_hi, 50, 8);
WAIT(data_hi, 50, 9);
WAIT(clock_hi, 50, 9);
WAIT(data_hi, 50, 10);
// clear buffer to get response correctly
recv_data = 0xFFFF;
@ -165,19 +169,50 @@ int16_t ibmpc_host_recv(void)
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
data = recv_data;
if ((data&0xFF00) != 0xFF00) { // recv_data:sstt -> recv_data:FFtt, ret:ss
ret = (data>>8)&0x00FF;
recv_data = data | 0xFF00;
} else if (data != 0xFFFF) { // recv_data:FFss -> recv_data:FFFF, ret:ss
ret = data&0x00FF;
recv_data = data | 0x00FF;
// remove data from buffer:
// FFFF(empty) -> FFFF
// FFss(one data) -> FFFF
// sstt(two data) -> FFtt
// eeFF(errror) -> FFFF
recv_data = data | (((data&0xFF00) == 0xFF00) ? 0x00FF : 0xFF00);
}
if ((data&0x00FF) == 0x00FF) {
// error: eeFF
switch (data>>8) {
case IBMPC_ERR_FF:
// 0xFF(Overrun/Error) from keyboard
dprintf("!FF! ");
ret = 0xFF;
break;
case IBMPC_ERR_FULL:
// buffer full
dprintf("!FULL! ");
ret = 0xFF;
break;
case 0xFF:
// empty: FFFF
return -1;
default:
// other errors
dprintf("e%02X ", data>>8);
return -1;
}
} else {
if ((data | 0x00FF) != 0xFFFF) {
// two data: sstt
dprintf("b:%04X ", data);
ret = (data>>8);
} else {
// one data: FFss
ret = (data&0x00FF);
}
}
if ((data | 0x00FF) != 0xFFFF) dprintf("b%04X ", data);
if (ret != 0xFF) dprintf("r%02X ", ret);
return ((ret != 0xFF) ? ret : -1);
//dprintf("i%04X ", ibmpc_isr_debug); ibmpc_isr_debug = 0;
dprintf("r%02X ", ret);
return ret;
}
int16_t ibmpc_host_recv_response(void)
@ -193,10 +228,15 @@ int16_t ibmpc_host_recv_response(void)
void ibmpc_host_isr_clear(void)
{
ibmpc_isr_debug = 0;
ibmpc_protocol = 0;
ibmpc_error = 0;
isr_state = 0x8000;
recv_data = 0xFFFF;
}
#define LO8(w) (*((uint8_t *)&(w)))
#define HI8(w) (*(((uint8_t *)&(w))+1))
// NOTE: With this ISR data line can be read within 2us after clock falling edge.
// To read data line early as possible:
// write naked ISR with asembly code to read the line and call C func to do other job?
@ -215,11 +255,14 @@ ISR(IBMPC_INT_VECT)
} else {
// should not take more than 1ms
if (timer_start != t && (uint8_t)(timer_start + 1) != t) {
ibmpc_isr_debug = isr_state;
ibmpc_error = IBMPC_ERR_TIMEOUT;
//goto ERROR;
// timeout error recovery by clearing isr_state?
timer_start = t;
isr_state = 0x8000;
goto ERROR;
// timeout error recovery - start receiving new data
// it seems to work somehow but may not under unstable situation
//timer_start = t;
//isr_state = 0x8000;
}
}
@ -244,10 +287,12 @@ ISR(IBMPC_INT_VECT)
// x x x x x x x x | *1 0 0 0 0 0 0 0 midway(8 bits received)
// b6 b5 b4 b3 b2 b1 b0 1 | 0 *1 0 0 0 0 0 0 XT_IBM-midway ^1
// b7 b6 b5 b4 b3 b2 b1 b0 | 0 *1 0 0 0 0 0 0 AT-midway ^1
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 *1 0 0 0 0 0 0 XT_Clone-done
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 *1 0 0 0 0 0 0 XT_Clone-done ^3
// b6 b5 b4 b3 b2 b1 b0 1 | 1 *1 0 0 0 0 0 0 XT_IBM-error ^3
// pr b7 b6 b5 b4 b3 b2 b1 | 0 0 *1 0 0 0 0 0 AT-midway[b0=0]
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 0 *1 0 0 0 0 0 XT_IBM-done ^2
// pr b7 b6 b5 b4 b3 b2 b1 | 1 0 *1 0 0 0 0 0 AT-midway[b0=1] ^2
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 1 *1 0 0 0 0 0 XT_IBM-error-done
// x x x x x x x x | x 1 1 0 0 0 0 0 illegal
// st pr b7 b6 b5 b4 b3 b2 | b1 b0 0 *1 0 0 0 0 AT-done
// x x x x x x x x | x x 1 *1 0 0 0 0 illegal
@ -264,10 +309,30 @@ ISR(IBMPC_INT_VECT)
// midway
goto NEXT;
break;
case 0b11000000:
// XT_Clone-done
case 0b11000000: // ^3
{
uint8_t us = 100;
// wait for rising and falling edge of b7 of XT_IBM
while (!(IBMPC_CLOCK_PIN&(1<<IBMPC_CLOCK_BIT)) && us) { wait_us(1); us--; }
while ( IBMPC_CLOCK_PIN&(1<<IBMPC_CLOCK_BIT) && us) { wait_us(1); us--; }
if (us) {
// XT_IBM-error: read start(0) as 1
goto NEXT;
} else {
// XT_Clone-done
ibmpc_isr_debug = isr_state;
isr_state = isr_state>>8;
ibmpc_protocol = IBMPC_PROTOCOL_XT_CLONE;
goto DONE;
}
}
break;
case 0b11100000:
// XT_IBM-error-done
ibmpc_isr_debug = isr_state;
isr_state = isr_state>>8;
ibmpc_protocol = IBMPC_PROTOCOL_XT_CLONE;
ibmpc_protocol = IBMPC_PROTOCOL_XT_ERROR;
goto DONE;
break;
case 0b10100000: // ^2
@ -282,6 +347,7 @@ ISR(IBMPC_INT_VECT)
goto NEXT;
} else {
// no stop bit: XT_IBM-done
ibmpc_isr_debug = isr_state;
isr_state = isr_state>>8;
ibmpc_protocol = IBMPC_PROTOCOL_XT_IBM;
goto DONE;
@ -294,39 +360,52 @@ ISR(IBMPC_INT_VECT)
case 0b11010000:
// AT-done
// TODO: parity check?
ibmpc_isr_debug = isr_state;
// stop bit check
if (isr_state & 0x8000) {
ibmpc_protocol = IBMPC_PROTOCOL_AT;
} else {
// Zenith Z-150 AT(beige/white lable) asserts stop bit as low
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#zenith-z-150-beige
ibmpc_protocol = IBMPC_PROTOCOL_AT_Z150;
}
isr_state = isr_state>>6;
ibmpc_protocol = IBMPC_PROTOCOL_AT;
goto DONE;
break;
case 0b01100000:
case 0b11100000:
case 0b00110000:
case 0b10110000:
case 0b01110000:
case 0b11110000:
default: // xxxx_oooo(any 1 in low nibble)
// Illegal
ibmpc_isr_debug = isr_state;
ibmpc_error = IBMPC_ERR_ILLEGAL;
goto ERROR;
break;
}
ERROR:
isr_state = 0x8000;
recv_data = 0xFF00; // clear data and scancode of error 0x00
return;
// error: eeFF
recv_data = (ibmpc_error<<8) | 0x00FF;
goto CLEAR;
DONE:
if ((isr_state & 0x00FF) == 0x00FF) {
// receive error code 0xFF
ibmpc_error = IBMPC_ERR_FF;
goto ERROR;
}
if ((recv_data & 0xFF00) != 0xFF00) {
// buffer full and overwritten
if (HI8(recv_data) != 0xFF && LO8(recv_data) != 0xFF) {
// buffer full
ibmpc_error = IBMPC_ERR_FULL;
goto ERROR;
}
// store data
recv_data = recv_data<<8;
recv_data |= isr_state & 0xFF;
isr_state = 0x8000; // clear to next data
CLEAR:
// clear for next data
isr_state = 0x8000;
NEXT:
return;
}
@ -334,6 +413,7 @@ NEXT:
/* send LED state to keyboard */
void ibmpc_host_set_led(uint8_t led)
{
ibmpc_host_send(0xED);
ibmpc_host_send(led);
if (0xFA == ibmpc_host_send(0xED)) {
ibmpc_host_send(led);
}
}

View file

@ -71,9 +71,12 @@ POSSIBILITY OF SUCH DAMAGE.
#define IBMPC_SET_LED 0xED
#define IBMPC_PROTOCOL_NO 0
#define IBMPC_PROTOCOL_AT 1
#define IBMPC_PROTOCOL_XT_IBM 2
#define IBMPC_PROTOCOL_XT_CLONE 3
#define IBMPC_PROTOCOL_AT 0x10
#define IBMPC_PROTOCOL_AT_Z150 0x11
#define IBMPC_PROTOCOL_XT 0x20
#define IBMPC_PROTOCOL_XT_IBM 0x21
#define IBMPC_PROTOCOL_XT_CLONE 0x22
#define IBMPC_PROTOCOL_XT_ERROR 0x23
// Error numbers
#define IBMPC_ERR_NONE 0
@ -82,13 +85,14 @@ POSSIBILITY OF SUCH DAMAGE.
#define IBMPC_ERR_TIMEOUT 0x20
#define IBMPC_ERR_FULL 0x40
#define IBMPC_ERR_ILLEGAL 0x80
#define IBMPC_ERR_FF 0xFF
#define IBMPC_ERR_FF 0xF0
#define IBMPC_LED_SCROLL_LOCK 0
#define IBMPC_LED_NUM_LOCK 1
#define IBMPC_LED_CAPS_LOCK 2
extern volatile uint16_t ibmpc_isr_debug;
extern volatile uint8_t ibmpc_protocol;
extern volatile uint8_t ibmpc_error;

View file

@ -41,7 +41,8 @@ VPATH += $(TMK_DIR)/$(TMK_LUFA_PATH)
TMK_LUFA_OPTS = -DUSB_DEVICE_ONLY
TMK_LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS
TMK_LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
# Do not enable this for converters in particular, it blocks other tasks long.
# Do not enable INTERRUPT_CONTROL_ENDPOINT for converters which requires ISR in particular,
# it can block other ISRs long like 500-1000us for HID keyboard LED report.
#TMK_LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
TMK_LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
TMK_LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1

View file

@ -411,6 +411,9 @@ gccversion :
program: $(TARGET).hex $(TARGET).eep
$(PROGRAM_CMD)
dude: $(TARGET).hex
avrdude -p$(MCU) -cavr109 -b57600 -Uflash:w:$(TARGET).hex -P$(DEV)
teensy: $(TARGET).hex
teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex