Merge remote-tracking branch 'tmk/master'

This commit is contained in:
Mark Sikora 2021-08-05 10:54:33 -04:00
commit 9c3121e122
18 changed files with 5738 additions and 5126 deletions

View file

@ -82,10 +82,26 @@ KEYMAP_SECTION_ENABLE ?= yes # fixed address keymap for keymap editor
ADB_MOUSE_MAXACC ?= 8 ADB_MOUSE_MAXACC ?= 8
OPT_DEFS += -DADB_MOUSE_MAXACC=$(ADB_MOUSE_MAXACC) OPT_DEFS += -DADB_MOUSE_MAXACC=$(ADB_MOUSE_MAXACC)
# Enable scroll wheel functionality using the y-axis of the mouse
# Hold the assigned button down to scroll using the mouse
#
# Example:
# Kensington Turbo Mouse 5
# ________
# middle click -> |3 __ 4| <- scroll toggle (browser back when disabled)
# | / \ |
# | \__/ |
# left click -> |1 2| <- right click
# |________|
#
ADB_MOUSE_SCROLL_BUTTON ?= 4 # Assign the button (1-8) (0 to disable)
ADB_MOUSE_SCROLL_SPEED ?= 10 # 1 (fastest) to 127 (slowest)
# Optimize size but this may cause error "relocation truncated to fit" # Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax #EXTRALDFLAGS = -Wl,--relax
OPT_DEFS += -DADB_MOUSE_SCROLL_BUTTON=$(ADB_MOUSE_SCROLL_BUTTON)
OPT_DEFS += -DADB_MOUSE_SCROLL_SPEED=$(ADB_MOUSE_SCROLL_SPEED)
# #
# Keymap file # Keymap file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Locking resynchronize hack */ /* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE #define LOCKING_RESYNC_ENABLE
// Mouse Extended Report
#define MOUSE_EXT_REPORT
/* ADB port setting */ /* ADB port setting */
#define ADB_PORT PORTD #define ADB_PORT PORTD

View file

@ -71,6 +71,8 @@ void matrix_init(void)
DDRD |= (1<<6); PORTD |= (1<<6); DDRD |= (1<<6); PORTD |= (1<<6);
adb_host_init(); adb_host_init();
adb_host_reset_hard();
//adb_host_reset(); // some of devices done't recognize
// AEK/AEKII(ANSI/ISO) startup is slower. Without proper delay // AEK/AEKII(ANSI/ISO) startup is slower. Without proper delay
// it would fail to recognize layout and enable Extended protocol. // it would fail to recognize layout and enable Extended protocol.
@ -228,16 +230,51 @@ detect_again:
if (mouse_handler == ADB_HANDLER_TURBO_MOUSE) { if (mouse_handler == ADB_HANDLER_TURBO_MOUSE) {
xprintf("TM5: ext\n"); xprintf("TM5: ext\n");
// Kensington Turbo Mouse 5 command sequence to enable four buttons /* byte0: speed
// https://elixir.bootlin.com/linux/v4.4/source/drivers/macintosh/adbhid.c#L1176 * 0xa0, 0xa5, 0xb0 and 0xb5 seem to work
// https://github.com/NetBSD/src/blob/64b8a48e1288eb3902ed73113d157af50b2ec596/sys/arch/macppc/dev/ams.c#L261 * uppper nibble:
static uint8_t cmd1[] = { 0xE7, 0x8C, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x94 }; * 0x00-70, 0xc0-f0 no movement and button event
static uint8_t cmd2[] = { 0xA5, 0x14, 0x00, 0x00, 0x69, 0xFF, 0xFF, 0x27 }; * 0x80 enables mouse output speed slow
* 0x90 enables mouse output
* 0xa0 enables mouse output
* 0xb0 enables mouse output speed fast -126 to 126
* lower nibble:
* 0x08 makes cursor not smooth, bit4 should be 0
* 0x02 disables button4, bit1 should be 0
* how other bits work is not clear.
* byte1: button mapping - upper nibble for button1 and lower for button2
* 0x14 button1 and button2 mapped as themselves
* 0x0 disabled
* 0x1 button1
* 0x2 button1 toggle
* 0x3 no effect key event FFFF
* 0x4 button2
* 0x5 button2 toggle
* 0x6 button3
* 0x7 button3 toggle
* 0x8 ?toggle weirdly?
* 0x9 button4
* 0xa button4 toggle
* 0xb ?disabled?
* 0xc Left
* 0xd Right
* 0xe Alt+Left
* 0xf Alt+Right
* byte2: 0x00 - 0x40 on powerup, seems to do nothing
* byte3: 0x00 - 0x01 on powerup, seems to do nothing
* byte4: button mapping - upper nibble for button3 and lower for button4
* 0x69 button3 and button4 mapped as themselves(see byte1)
* byte5: 0xff unknown
* byte6: 0xff unknown
* byte7: 0xff checksum - must be 0xff before calculating
* https://github.com/NetBSD/src/blob/8966d5b1cf335756dd9bba3331e84c659bf917e1/sys/dev/adb/adb_ktm.c#L181
*/
//static uint8_t cmd[] = { 0xA5, 0x14, 0x00, 0x00, 0x69, 0xFF, 0xFF, 0xFF };
static uint8_t cmd[] = { 0xB5, 0x14, 0x00, 0x00, 0x69, 0xFF, 0xFF, 0xFF };
cmd[7] = cmd[0] ^ cmd[1] ^ cmd[2] ^ cmd[3] ^ cmd[4] ^ cmd[5] ^ cmd[6] ^ cmd[7];
adb_host_flush(addr); adb_host_flush(addr);
adb_host_listen_buf(addr, ADB_REG_2, cmd1, sizeof(cmd1)); adb_host_listen_buf(addr, ADB_REG_2, cmd, sizeof(cmd));
adb_host_flush(addr);
adb_host_listen_buf(addr, ADB_REG_2, cmd2, sizeof(cmd2));
} }
@ -255,12 +292,10 @@ detect_again:
goto again; goto again;
} }
#ifdef MAX
#undef MAX
#endif
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
static report_mouse_t mouse_report = {}; static report_mouse_t mouse_report = {};
static int32_t scroll_state = 0;
static uint8_t scroll_speed = ADB_MOUSE_SCROLL_SPEED;
static uint8_t scroll_button_mask = (1 << ADB_MOUSE_SCROLL_BUTTON) >> 1;
void adb_mouse_task(void) void adb_mouse_task(void)
{ {
@ -332,6 +367,12 @@ void adb_mouse_task(void)
if (!(buf[2] & 0x80)) buttons |= MOUSE_BTN3; if (!(buf[2] & 0x80)) buttons |= MOUSE_BTN3;
if (!(buf[1] & 0x80)) buttons |= MOUSE_BTN2; if (!(buf[1] & 0x80)) buttons |= MOUSE_BTN2;
if (!(buf[0] & 0x80)) buttons |= MOUSE_BTN1; if (!(buf[0] & 0x80)) buttons |= MOUSE_BTN1;
// check if the scroll enable button is pressed
bool scroll_enable = (bool)(buttons & scroll_button_mask);
// mask out the scroll button so it isn't reported
buttons &= ~scroll_button_mask;
mouse_report.buttons = buttons; mouse_report.buttons = buttons;
int16_t xx, yy; int16_t xx, yy;
@ -342,14 +383,27 @@ void adb_mouse_task(void)
x = xx * mouseacc; x = xx * mouseacc;
y = yy * mouseacc; y = yy * mouseacc;
// TODO: Fix HID report descriptor for mouse to support finer resolution #ifndef MOUSE_EXT_REPORT
// Cap our two bytes per axis to one byte. x = (x > 127) ? 127 : ((x < -127) ? -127 : x);
// Easier with a MIN-function, but since -MAX(-a,-b) = MIN(a,b)... y = (y > 127) ? 127 : ((y < -127) ? -127 : y);
// I.E. MIN(MAX(x,-127),127) = -MAX(-MAX(x, -127), -127) = MIN(-MIN(-x,127),127) #endif
mouse_report.x = -MAX(-MAX(x, -127), -127);
mouse_report.y = -MAX(-MAX(y, -127), -127);
dmprintf("[B:%02X X:%d(%d) Y:%d(%d) A:%d]\n", mouse_report.buttons, mouse_report.x, xx, mouse_report.y, yy, mouseacc); if (scroll_enable) {
scroll_state -= y;
mouse_report.v = scroll_state / scroll_speed;
scroll_state %= scroll_speed;
mouse_report.x = 0;
mouse_report.y = 0;
} else {
scroll_state = 0;
mouse_report.v = 0;
mouse_report.x = x;
mouse_report.y = y;
}
dmprintf("[B:%02X X:%d(%d) Y:%d(%d) V:%d A:%d]\n", mouse_report.buttons, mouse_report.x, xx, mouse_report.y, yy, mouse_report.v, mouseacc);
// Send result by usb. // Send result by usb.
host_mouse_send(&mouse_report); host_mouse_send(&mouse_report);

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

@ -42,6 +42,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// G80-2551 terminal keyboard support // G80-2551 terminal keyboard support
#define G80_2551_SUPPORT #define G80_2551_SUPPORT
// PS/2 Mouse support
//#define IBMPC_MOUSE_ENABLE
// Mouse Extended Report
//#define MOUSE_EXT_REPORT
/* /*
* Pin and interrupt configuration * Pin and interrupt configuration

View file

@ -50,6 +50,11 @@ static int16_t read_wait(uint16_t wait_ms)
return code; return code;
} }
#define ID_STR(id) (id == 0xFFFE ? "_????" : \
(id == 0xFFFD ? "_Z150" : \
(id == 0x0000 ? "_AT84" : \
"")))
static uint16_t read_keyboard_id(void) static uint16_t read_keyboard_id(void)
{ {
uint16_t id = 0; uint16_t id = 0;
@ -85,7 +90,6 @@ DONE:
void hook_early_init(void) void hook_early_init(void)
{ {
ibmpc_host_init(); ibmpc_host_init();
ibmpc_host_enable();
} }
void matrix_init(void) void matrix_init(void)
@ -130,9 +134,18 @@ uint8_t matrix_scan(void)
} state = INIT; } state = INIT;
static uint16_t init_time; static uint16_t init_time;
#ifdef IBMPC_MOUSE_ENABLE
static enum {
MOUSE_DEFAULT = 0, // Default three-button
MOUSE_INTELLI = 3, // Intellimouse Explorer 3-button & wheel
MOUSE_EXPLORER = 4, // Intellimouse Explorer 5-button & wheel
MOUSE_LOGITECH = 9 // Logitech PS/2++
} mouse_id = MOUSE_DEFAULT;
static uint8_t mouse_btn = 0;
#endif
if (ibmpc_error) { if (ibmpc_error) {
xprintf("\nERR:%02X ISR:%04X ", ibmpc_error, ibmpc_isr_debug); xprintf("\n%u ERR:%02X ISR:%04X ", timer_read(), ibmpc_error, ibmpc_isr_debug);
// when recv error, neither send error nor buffer full // when recv error, neither send error nor buffer full
if (!(ibmpc_error & (IBMPC_ERR_SEND | IBMPC_ERR_FULL))) { if (!(ibmpc_error & (IBMPC_ERR_SEND | IBMPC_ERR_FULL))) {
@ -150,7 +163,7 @@ uint8_t matrix_scan(void)
// check protocol change AT/XT // check protocol change AT/XT
if (ibmpc_protocol && ibmpc_protocol != current_protocol) { if (ibmpc_protocol && ibmpc_protocol != current_protocol) {
xprintf("\nPRT:%02X ISR:%04X ", ibmpc_protocol, ibmpc_isr_debug); xprintf("\n%u PRT:%02X ISR:%04X ", timer_read(), ibmpc_protocol, ibmpc_isr_debug);
// protocol change between AT and XT indicates that // protocol change between AT and XT indicates that
// keyboard is hotswapped or something goes wrong. // keyboard is hotswapped or something goes wrong.
@ -169,8 +182,6 @@ uint8_t matrix_scan(void)
switch (state) { switch (state) {
case INIT: case INIT:
ibmpc_host_disable();
xprintf("I%u ", timer_read()); xprintf("I%u ", timer_read());
keyboard_kind = NONE; keyboard_kind = NONE;
keyboard_id = 0x0000; keyboard_id = 0x0000;
@ -181,19 +192,20 @@ uint8_t matrix_scan(void)
init_time = timer_read(); init_time = timer_read();
state = WAIT_SETTLE; state = WAIT_SETTLE;
ibmpc_host_enable();
break; break;
case WAIT_SETTLE: case WAIT_SETTLE:
while (ibmpc_host_recv() != -1) ; // read data
// wait for keyboard to settle after plugin // wait for keyboard to settle after plugin
if (timer_elapsed(init_time) > 1000) { if (timer_elapsed(init_time) > 3000) {
state = AT_RESET; state = AT_RESET;
} }
break; break;
case AT_RESET: case AT_RESET:
ibmpc_host_isr_clear(); xprintf("A%u ", timer_read());
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 // SKIDATA-2-DE(and some other keyboards?) stores 'Code Set' setting in nonvolatile memory
// and keeps it until receiving reset. Sending reset here may be useful to clear it, perhaps. // 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 // https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#select-alternate-scan-codesf0
@ -203,7 +215,6 @@ uint8_t matrix_scan(void)
} else { } else {
state = XT_RESET; state = XT_RESET;
} }
xprintf("A%u ", timer_read());
break; break;
case XT_RESET: case XT_RESET:
// Reset XT-initialize keyboard // Reset XT-initialize keyboard
@ -281,15 +292,15 @@ uint8_t matrix_scan(void)
} else if (0xFFFE == keyboard_id) { // CodeSet2 PS/2 fails to response? } else if (0xFFFE == keyboard_id) { // CodeSet2 PS/2 fails to response?
keyboard_kind = PC_AT; keyboard_kind = PC_AT;
} else if (0xFFFD == keyboard_id) { // Zenith Z-150 AT } else if (0xFFFD == keyboard_id) { // Zenith Z-150 AT
keyboard_kind = PC_AT_Z150; keyboard_kind = PC_AT;
} else if (0x00FF == keyboard_id) { // Mouse is not supported } else if (0x00FF == keyboard_id) { // Mouse is not supported
xprintf("Mouse: not supported\n"); keyboard_kind = PC_MOUSE;
keyboard_kind = NONE; } else if (0xAB85 == keyboard_id || // IBM 122-key Model M, NCD N-97
#ifdef G80_2551_SUPPORT 0xAB86 == keyboard_id || // Cherry G80-2551, IBM 1397000
} else if (0xAB86 == keyboard_id || 0xAB92 == keyboard_id) { // IBM 5576-001
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 // https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#ab85
// 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#ab92
if ((0xFA == ibmpc_host_send(0xF0)) && if ((0xFA == ibmpc_host_send(0xF0)) &&
(0xFA == ibmpc_host_send(0x03))) { (0xFA == ibmpc_host_send(0x03))) {
@ -298,7 +309,21 @@ uint8_t matrix_scan(void)
} else { } else {
keyboard_kind = PC_AT; keyboard_kind = PC_AT;
} }
#endif } else if (0xAB90 == keyboard_id || // IBM 5576-002
0xAB91 == keyboard_id) { // IBM 5576-003
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#ab90
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#ab91
xprintf("\n5576_CS82h:");
if ((0xFA == ibmpc_host_send(0xF0)) &&
(0xFA == ibmpc_host_send(0x82))) {
// switch to code set 82h
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#ibm-5576-scan-codes-set
xprintf("OK ");
} else {
xprintf("NG ");
}
keyboard_kind = PC_AT;
} else if (0xBFB0 == keyboard_id) { // IBM RT Keyboard } else if (0xBFB0 == keyboard_id) { // IBM RT Keyboard
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#bfb0 // https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#bfb0
// TODO: LED indicator fix // TODO: LED indicator fix
@ -308,11 +333,24 @@ uint8_t matrix_scan(void)
keyboard_kind = PC_AT; keyboard_kind = PC_AT;
} else if (0xBF00 == (keyboard_id & 0xFF00)) { // CodeSet3 Terminal } else if (0xBF00 == (keyboard_id & 0xFF00)) { // CodeSet3 Terminal
keyboard_kind = PC_TERMINAL; keyboard_kind = PC_TERMINAL;
} else if (0x7F00 == (keyboard_id & 0xFF00)) { // CodeSet3 Terminal 1394204
keyboard_kind = PC_TERMINAL;
} else { } else {
keyboard_kind = PC_AT; xprintf("\nUnknown ID: Report to TMK ");
if ((0xFA == ibmpc_host_send(0xF0)) &&
(0xFA == ibmpc_host_send(0x02))) {
// switch to code set 2
keyboard_kind = PC_AT;
} else if ((0xFA == ibmpc_host_send(0xF0)) &&
(0xFA == ibmpc_host_send(0x03))) {
// switch to code set 3
keyboard_kind = PC_TERMINAL;
} else {
keyboard_kind = PC_AT;
}
} }
xprintf("\nID:%04X(%s) ", keyboard_id, KEYBOARD_KIND_STR(keyboard_kind)); xprintf("\nID:%04X(%s%s) ", keyboard_id, KEYBOARD_KIND_STR(keyboard_kind), ID_STR(keyboard_id));
state = SETUP; state = SETUP;
break; break;
@ -324,15 +362,89 @@ uint8_t matrix_scan(void)
case PC_AT: case PC_AT:
led_set(host_keyboard_leds()); led_set(host_keyboard_leds());
break; break;
case PC_AT_Z150:
// TODO: do not set indicators temporarily for debug
break;
case PC_TERMINAL: case PC_TERMINAL:
// Set all keys to make/break type // Set all keys to make/break type
ibmpc_host_send(0xF8); ibmpc_host_send(0xF8);
// This should not be harmful // This should not be harmful
led_set(host_keyboard_leds()); led_set(host_keyboard_leds());
break; break;
#ifdef IBMPC_MOUSE_ENABLE
case PC_MOUSE: {
uint8_t s[3];
void read_status(void) {
ibmpc_host_send(0xE9);
s[0] = ibmpc_host_recv_response();
s[1] = ibmpc_host_recv_response();
s[2] = ibmpc_host_recv_response();
xprintf("S[%02X %02X %02X] ", s[0], s[1], s[2]);
}
ibmpc_host_send(0xF5); // Disable
ibmpc_host_send(0xEA); // Set Stream Mode
read_status();
// Logitech Magic Status
// https://github.com/torvalds/linux/blob/master/drivers/input/mouse/logips2pp.c#L352
xprintf("\nLMS: ");
ibmpc_host_send(0xE8); ibmpc_host_send(0x00);
ibmpc_host_send(0xE6); ibmpc_host_send(0xE6); ibmpc_host_send(0xE6);
read_status();
if (s[0] == 0 || s[1] == 0) {
// Not Logitech
goto MOUSE_INTELLI;
}
// Logitech Magic Knock
// https://www.win.tue.nl/~aeb/linux/kbd/scancodes-13.html
// https://web.archive.org/web/20030714000535/www.dqcs.com/logitech/ps2ppspec.htm
// https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/drivers/input/serio/libps2.c#L347
xprintf("\nLOG: ");
// sliced magic byte: 0x39
ibmpc_host_send(0xE6);
ibmpc_host_send(0xE8); ibmpc_host_send(0x00);
ibmpc_host_send(0xE8); ibmpc_host_send(0x03);
ibmpc_host_send(0xE8); ibmpc_host_send(0x02);
ibmpc_host_send(0xE8); ibmpc_host_send(0x01);
// sliced magic byte: 0xDB
ibmpc_host_send(0xE6);
ibmpc_host_send(0xE8); ibmpc_host_send(0x03);
ibmpc_host_send(0xE8); ibmpc_host_send(0x01);
ibmpc_host_send(0xE8); ibmpc_host_send(0x02);
ibmpc_host_send(0xE8); ibmpc_host_send(0x03);
mouse_id = MOUSE_LOGITECH; // 9
goto MOUSE_DONE;
MOUSE_INTELLI:
// Intellimouse protocol: 3
xprintf("\nINT: ");
ibmpc_host_send(0xF3); ibmpc_host_send(0xC8);
ibmpc_host_send(0xF3); ibmpc_host_send(0x64);
ibmpc_host_send(0xF3); ibmpc_host_send(0x50);
mouse_id = read_keyboard_id() >> 8;
// Intellimouse Explorer protocol: 4
xprintf("\nEXP: ");
ibmpc_host_send(0xF3); ibmpc_host_send(0xC8);
ibmpc_host_send(0xF3); ibmpc_host_send(0xC8);
ibmpc_host_send(0xF3); ibmpc_host_send(0x50);
mouse_id = read_keyboard_id() >> 8;
// Not Intellimouse
if (mouse_id == 0) {
xprintf("\nDEF: ");
ibmpc_host_send(0xF6); // Set Default
}
MOUSE_DONE:
//ibmpc_host_send(0xEA); // Set Stream Mode
ibmpc_host_send(0xF4); // Enable
read_status();
xprintf("\nMouse: %s\n", ((mouse_id == MOUSE_LOGITECH) ? "LOGITECH" :
((mouse_id == MOUSE_INTELLI) ? "INTELLI" :
((mouse_id == MOUSE_EXPLORER) ? "EXPLORER" :
((mouse_id == MOUSE_DEFAULT) ? "DEFAULT" : "???")))));
break; }
#endif
default: default:
break; break;
} }
@ -350,12 +462,12 @@ uint8_t matrix_scan(void)
// Scan Code Set 1: 0xFF // Scan Code Set 1: 0xFF
// Scan Code Set 2 and 3: 0x00 // Scan Code Set 2 and 3: 0x00
// Buffer full(IBMPC_ERR_FULL): 0xFF // Buffer full(IBMPC_ERR_FULL): 0xFF
if (code == 0x00 || code == 0xFF) { if (keyboard_kind != PC_MOUSE && (code == 0x00 || code == 0xFF)) {
// clear stuck keys // clear stuck keys
matrix_clear(); matrix_clear();
clear_keyboard(); clear_keyboard();
xprintf("\n[OVR] "); xprintf("\n[CLR] ");
break; break;
} }
@ -364,12 +476,118 @@ uint8_t matrix_scan(void)
if (process_cs1(code) == -1) state = INIT; if (process_cs1(code) == -1) state = INIT;
break; break;
case PC_AT: case PC_AT:
case PC_AT_Z150:
if (process_cs2(code) == -1) state = INIT; if (process_cs2(code) == -1) state = INIT;
break; break;
case PC_TERMINAL: case PC_TERMINAL:
if (process_cs3(code) == -1) state = INIT; if (process_cs3(code) == -1) state = INIT;
break; break;
#ifdef IBMPC_MOUSE_ENABLE
case PC_MOUSE: {
// Logitec Mouse Data:
// https://github.com/torvalds/linux/blob/d2912cb15bdda8ba4a5dd73396ad62641af2f520/drivers/input/mouse/logips2pp.c#L41
// Intellimouse Data:
// https://www.win.tue.nl/~aeb/linux/kbd/scancodes-13.html
int16_t b0, b1, b2, b3;
int16_t x = 0, y = 0;
int8_t v = 0, h = 0;
b0 = code;
b1 = ibmpc_host_recv_response();
if (b1 == -1) break;
b2 = ibmpc_host_recv_response();
if (b2 == -1) break;
switch (mouse_id) {
case MOUSE_DEFAULT:
case MOUSE_INTELLI:
case MOUSE_EXPLORER:
mouse_btn = (mouse_btn & 0xF8) | (b0 & 0x07);
x = (b0 & 0x10) ? (b1 | 0xFF00) : b1;
y = (b0 & 0x20) ? (b2 | 0xFF00) : b2;
break;
case MOUSE_LOGITECH:
if ((b0 & 0x48) == 0x48 && (b1 & 0x02) == 0x02) {
switch (((b0 & 0x30) >> 2) | ((b1 & 0x30) >> 4)) {
case 1: // C8 Dx xx
// Ignored while Scroll-Up/Down is pressed
if (!(b2 & 0x40)) {
if (b2 & 0x80)
h = ((b2 & 0x08) ? 0xF0 : 0x00) | (b2 & 0x0F);
else
v = ((b2 & 0x08) ? 0xF0 : 0x00) | (b2 & 0x0F);
}
// Back
if (b2 & 0x10) mouse_btn |= (1 << 3); else mouse_btn &= ~(1 << 3);
// Forward
if (b2 & 0x20) mouse_btn |= (1 << 4); else mouse_btn &= ~(1 << 4);
break;
case 2: // C8 Ex xx
if (b2 & 0x01) mouse_btn |= (1 << 6); else mouse_btn &= ~(1 << 6);
if (b2 & 0x02) mouse_btn |= (1 << 7); else mouse_btn &= ~(1 << 7);
// Task
if (b2 & 0x04) mouse_btn |= (1 << 5); else mouse_btn &= ~(1 << 5);
// Scroll-Up
if (b2 & 0x08) mouse_btn |= (1 << 6); else mouse_btn &= ~(1 << 6);
// Scroll-Down
if (b2 & 0x10) mouse_btn |= (1 << 7); else mouse_btn &= ~(1 << 7);
break;
case 3: // TouchPad?
if (b2 & 0x80)
h = ((b2 & 0x80) ? 0xF0 : 0x00) | ((b2 >> 4) & 0x0F);
else
v = ((b2 & 0x80) ? 0xF0 : 0x00) | ((b2 >> 4) & 0x0F);
mouse_btn = (mouse_btn & 0xF8) | (b2 & 0x07);
break;
}
} else {
mouse_btn = (mouse_btn & 0xF8) | (b0 & 0x07);
x = (b0 & 0x10) ? (b1 | 0xFF00) : b1;
y = (b0 & 0x20) ? (b2 | 0xFF00) : b2;
}
break;
}
// Extra byte
switch (mouse_id) {
case MOUSE_INTELLI:
b3 = ibmpc_host_recv_response();
if (b3 == -1) break;
v = b3 & 0xFF;
break;
case MOUSE_EXPLORER:
b3 = ibmpc_host_recv_response();
if (b3 == -1) break;
// sign extension
v = ((b3 & 0x08) ? 0xF0 : 0x00) | (b3 & 0x0F);
// Back/Forward
if (b3 & 0x10) mouse_btn |= (1 << 3); else mouse_btn &= ~(1 << 3);
if (b3 & 0x20) mouse_btn |= (1 << 4); else mouse_btn &= ~(1 << 4);
break;
default:
break;
}
// chop to 8-bit
#define CHOP8(a) (((a) > 127) ? 127 : (((a) < -127) ? -127 : (a)))
report_mouse_t mouse_report = {};
mouse_report.buttons = mouse_btn;
#ifdef MOUSE_EXT_REPORT
mouse_report.x = x;
mouse_report.y = -y;
#else
mouse_report.x = CHOP8(x);
mouse_report.y = -CHOP8(y);
#endif
mouse_report.v = -CHOP8(v);
mouse_report.h = CHOP8(h);
host_mouse_send(&mouse_report);
xprintf("M[x:%d y:%d v:%d h:%d b:%02X]\n", mouse_report.x, mouse_report.y,
mouse_report.v, mouse_report.h, mouse_report.buttons);
break; }
#endif
default: default:
break; break;
} }
@ -432,6 +650,7 @@ void led_set(uint8_t usb_led)
// XT keyobard doesn't support any command and it is harmful perhaps // XT keyobard doesn't support any command and it is harmful perhaps
// https://github.com/tmk/tmk_keyboard/issues/635#issuecomment-626993437 // https://github.com/tmk/tmk_keyboard/issues/635#issuecomment-626993437
if (keyboard_kind == PC_XT) return; if (keyboard_kind == PC_XT) return;
if (keyboard_kind == PC_MOUSE) return;
// It should be safe to send the command to keyboards with AT protocol // 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. // - IBM Terminal doesn't support the command and response with 0xFE but it is not harmful.
@ -736,6 +955,30 @@ static uint8_t cs2_e0code(uint8_t code) {
} }
} }
// IBM 5576-002/003 Scan code translation
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#ibm-5576-code-set-82h
static uint8_t translate_5576_cs2(uint8_t code) {
switch (code) {
case 0x11: return 0x0F; // Zenmen -> RALT
case 0x13: return 0x11; // Kanji -> LALT
case 0x0E: return 0x54; // @
case 0x54: return 0x5B; // [
case 0x5B: return 0x5D; // ]
case 0x5C: return 0x6A; // JYEN
case 0x5D: return 0x6A; // JYEN
case 0x62: return 0x0E; // Han/Zen -> `~
case 0x7C: return 0x77; // Keypad *
}
return code;
}
static uint8_t translate_5576_cs2_e0(uint8_t code) {
switch (code) {
case 0x11: return 0x13; // Hiragana -> KANA
case 0x41: return 0x7C; // Keypad '
}
return code;
}
static int8_t process_cs2(uint8_t code) static int8_t process_cs2(uint8_t code)
{ {
// scan code reading states // scan code reading states
@ -754,6 +997,9 @@ static int8_t process_cs2(uint8_t code)
switch (state) { switch (state) {
case INIT: case INIT:
if (0xAB90 == keyboard_id || 0xAB91 == keyboard_id) {
code = translate_5576_cs2(code);
}
switch (code) { switch (code) {
case 0xE0: case 0xE0:
state = E0; state = E0;
@ -787,6 +1033,9 @@ static int8_t process_cs2(uint8_t code)
} }
break; break;
case E0: // E0-Prefixed case E0: // E0-Prefixed
if (0xAB90 == keyboard_id || 0xAB91 == keyboard_id) {
code = translate_5576_cs2_e0(code);
}
switch (code) { switch (code) {
case 0x12: // to be ignored case 0x12: // to be ignored
case 0x59: // to be ignored case 0x59: // to be ignored
@ -807,6 +1056,9 @@ static int8_t process_cs2(uint8_t code)
} }
break; break;
case F0: // Break code case F0: // Break code
if (0xAB90 == keyboard_id || 0xAB91 == keyboard_id) {
code = translate_5576_cs2(code);
}
switch (code) { switch (code) {
case 0x83: // F7 case 0x83: // F7
matrix_break(0x02); matrix_break(0x02);
@ -828,6 +1080,9 @@ static int8_t process_cs2(uint8_t code)
} }
break; break;
case E0_F0: // Break code of E0-prefixed case E0_F0: // Break code of E0-prefixed
if (0xAB90 == keyboard_id || 0xAB91 == keyboard_id) {
code = translate_5576_cs2_e0(code);
}
switch (code) { switch (code) {
case 0x12: // to be ignored case 0x12: // to be ignored
case 0x59: // to be ignored case 0x59: // to be ignored
@ -902,12 +1157,26 @@ static int8_t process_cs2(uint8_t code)
return 0; return 0;
} }
/* /*
* Terminal: Scan Code Set 3 * Terminal: Scan Code Set 3
* *
* See [3], [7] and * See [3], [7] and
* https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#scan-code-set-3 * https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#scan-code-set-3
*/ */
// IBM 5576-001 Scan code translation
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#ibm-5576-code-set-3
static uint8_t translate_5576_cs3(uint8_t code) {
switch (code) {
// Fix positon of keys to fit 122-key layout
case 0x13: return 0x5D; // JYEN
case 0x5C: return 0x51; // RO
case 0x76: return 0x7E; // Keypad '
case 0x7E: return 0x76; // Keypad Dup
}
return code;
}
static int8_t process_cs3(uint8_t code) static int8_t process_cs3(uint8_t code)
{ {
static enum { static enum {
@ -920,8 +1189,21 @@ static int8_t process_cs3(uint8_t code)
#endif #endif
} state = READY; } state = READY;
switch (code) {
case 0xAA: // BAT code
case 0xFC: // BAT code
case 0xBF: // Part of keyboard ID
case 0xAB: // Part keyboard ID
state = READY;
xprintf("!CS3_RESET!\n");
return -1;
}
switch (state) { switch (state) {
case READY: case READY:
if (0xAB92 == keyboard_id) {
code = translate_5576_cs3(code);
}
switch (code) { switch (code) {
case 0xF0: case 0xF0:
state = F0; state = F0;
@ -933,10 +1215,10 @@ static int8_t process_cs3(uint8_t code)
matrix_make(0x7F); matrix_make(0x7F);
break; break;
case 0x85: // Muhenkan case 0x85: // Muhenkan
matrix_make(0x0B); matrix_make(0x68);
break; break;
case 0x86: // Henkan case 0x86: // Henkan
matrix_make(0x06); matrix_make(0x78);
break; break;
case 0x87: // Hiragana case 0x87: // Hiragana
matrix_make(0x00); matrix_make(0x00);
@ -960,51 +1242,44 @@ static int8_t process_cs3(uint8_t code)
matrix_make(code); matrix_make(code);
} else { } else {
xprintf("!CS3_READY!\n"); xprintf("!CS3_READY!\n");
return -1;
} }
} }
break; break;
case F0: // Break code case F0: // Break code
state = READY;
if (0xAB92 == keyboard_id) {
code = translate_5576_cs3(code);
}
switch (code) { switch (code) {
case 0x83: // PrintScreen case 0x83: // PrintScreen
matrix_break(0x02); matrix_break(0x02);
state = READY;
break; break;
case 0x84: // Keypad * case 0x84: // Keypad *
matrix_break(0x7F); matrix_break(0x7F);
state = READY;
break; break;
case 0x85: // Muhenkan case 0x85: // Muhenkan
matrix_break(0x0B); matrix_break(0x68);
state = READY;
break; break;
case 0x86: // Henkan case 0x86: // Henkan
matrix_break(0x06); matrix_break(0x78);
state = READY;
break; break;
case 0x87: // Hiragana case 0x87: // Hiragana
matrix_break(0x00); matrix_break(0x00);
state = READY;
break; break;
case 0x8B: // Left GUI case 0x8B: // Left GUI
matrix_break(0x01); matrix_break(0x01);
state = READY;
break; break;
case 0x8C: // Right GUI case 0x8C: // Right GUI
matrix_break(0x09); matrix_break(0x09);
state = READY;
break; break;
case 0x8D: // Application case 0x8D: // Application
matrix_break(0x0A); matrix_break(0x0A);
state = READY;
break; break;
default: default:
state = READY;
if (code < 0x80) { if (code < 0x80) {
matrix_break(code); matrix_break(code);
} else { } else {
xprintf("!CS3_F0!\n"); xprintf("!CS3_F0!\n");
return -1;
} }
} }
break; break;

View file

@ -1,12 +1,12 @@
#ifndef IBMPC_USB_H #ifndef IBMPC_USB_H
#define IBMPC_USB_H #define IBMPC_USB_H
typedef enum { NONE, PC_XT, PC_AT, PC_TERMINAL, PC_AT_Z150 } keyboard_kind_t; typedef enum { NONE, PC_XT, PC_AT, PC_TERMINAL, PC_MOUSE } keyboard_kind_t;
#define KEYBOARD_KIND_STR(kind) \ #define KEYBOARD_KIND_STR(kind) \
(kind == PC_XT ? "XT" : \ (kind == PC_XT ? "XT" : \
kind == PC_AT ? "AT" : \ kind == PC_AT ? "AT" : \
kind == PC_TERMINAL ? "TERMINAL" : \ kind == PC_TERMINAL ? "TERMINAL" : \
kind == PC_AT_Z150 ? "AT_Z150" : \ kind == PC_MOUSE ? "MOUSE" : \
"NONE") "NONE")

View file

@ -269,7 +269,7 @@ enum layer_pram_tap_op {
#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF) #define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON) #define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR) #define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
#define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xc0 | ((mods>>8)&0x1f)) #define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xc0 | (((mods)>>8)&0x1f))
/* With Tapping */ /* With Tapping */
#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key)) #define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE) #define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)

View file

@ -65,6 +65,11 @@ void host_keyboard_send(report_keyboard_t *report)
void host_mouse_send(report_mouse_t *report) void host_mouse_send(report_mouse_t *report)
{ {
if (!driver) return; if (!driver) return;
#ifdef MOUSE_EXT_REPORT
// clip and copy to Boot protocol XY
report->boot_x = (report->x > 127) ? 127 : ((report->x < -127) ? -127 : report->x);
report->boot_y = (report->y > 127) ? 127 : ((report->y < -127) ? -127 : report->y);
#endif
(*driver->send_mouse)(report); (*driver->send_mouse)(report);
} }

View file

@ -159,8 +159,15 @@ typedef struct {
typedef struct { typedef struct {
uint8_t buttons; uint8_t buttons;
#ifndef MOUSE_EXT_REPORT
int8_t x; int8_t x;
int8_t y; int8_t y;
#else
int8_t boot_x;
int8_t boot_y;
int16_t x;
int16_t y;
#endif
int8_t v; int8_t v;
int8_t h; int8_t h;
} __attribute__ ((packed)) report_mouse_t; } __attribute__ ((packed)) report_mouse_t;

View file

@ -254,6 +254,23 @@ void adb_host_flush(uint8_t addr)
sei(); sei();
} }
void adb_host_reset(void)
{
cli();
attention();
send_byte(ADB_CMD_RESET);
place_bit0(); // Stopbit(0)
_delay_us(200); // Tlt/Stop to Start
sei();
}
void adb_host_reset_hard(void)
{
data_lo();
_delay_us(3000);
data_hi();
}
// send state of LEDs // send state of LEDs
void adb_host_kbd_led(uint8_t addr, uint8_t led) void adb_host_kbd_led(uint8_t addr, uint8_t led)
{ {

View file

@ -104,6 +104,8 @@ 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(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_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
void adb_host_flush(uint8_t addr); void adb_host_flush(uint8_t addr);
void adb_host_reset(void);
void adb_host_reset_hard(void);
void adb_host_kbd_led(uint8_t addr, uint8_t led); void adb_host_kbd_led(uint8_t addr, uint8_t led);
void adb_mouse_task(void); void adb_mouse_task(void);
void adb_mouse_init(void); void adb_mouse_init(void);

View file

@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "debug.h" #include "debug.h"
#include "timer.h" #include "timer.h"
#include "wait.h" #include "wait.h"
#include "ringbuf.h"
#define WAIT(stat, us, err) do { \ #define WAIT(stat, us, err) do { \
@ -60,15 +61,11 @@ volatile uint16_t ibmpc_isr_debug = 0;
volatile uint8_t ibmpc_protocol = IBMPC_PROTOCOL_NO; volatile uint8_t ibmpc_protocol = IBMPC_PROTOCOL_NO;
volatile uint8_t ibmpc_error = IBMPC_ERR_NONE; volatile uint8_t ibmpc_error = IBMPC_ERR_NONE;
/* 2-byte buffer for data received from keyboard /* buffer for data received from device */
* buffer states: #define RINGBUF_SIZE 16
* FFFF: empty static uint8_t rbuf[RINGBUF_SIZE];
* FFss: one data static ringbuf_t rb = {};
* 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 */ /* internal state of receiving data */
static volatile uint16_t isr_state = 0x8000; static volatile uint16_t isr_state = 0x8000;
static uint8_t timer_start = 0; static uint8_t timer_start = 0;
@ -80,6 +77,7 @@ void ibmpc_host_init(void)
inhibit(); inhibit();
IBMPC_INT_INIT(); IBMPC_INT_INIT();
IBMPC_INT_OFF(); IBMPC_INT_OFF();
ringbuf_init(&rb, rbuf, RINGBUF_SIZE);
} }
void ibmpc_host_enable(void) void ibmpc_host_enable(void)
@ -98,18 +96,30 @@ int16_t ibmpc_host_send(uint8_t data)
{ {
bool parity = true; bool parity = true;
ibmpc_error = IBMPC_ERR_NONE; ibmpc_error = IBMPC_ERR_NONE;
uint8_t retry = 0;
dprintf("w%02X ", data); dprintf("w%02X ", data);
// Not receiving data
if (isr_state != 0x8000) dprintf("isr:%04X ", isr_state);
while (isr_state != 0x8000) ;
// Not clock Lo
if (!clock_in()) dprintf("c:%u ", wait_clock_hi(1000));
// Not data Lo
if (!data_in()) dprintf("d:%u ", wait_data_hi(1000));
IBMPC_INT_OFF(); IBMPC_INT_OFF();
RETRY:
/* terminate a transmission if we have */ /* terminate a transmission if we have */
inhibit(); inhibit();
wait_us(100); // [5]p.54 wait_us(200); // [5]p.54
/* 'Request to Send' and Start bit */ /* 'Request to Send' and Start bit */
data_lo(); data_lo();
wait_us(100); wait_us(200);
clock_hi(); // [5]p.54 [clock low]>100us [5]p.50 clock_hi(); // [5]p.54 [clock low]>100us [5]p.50
WAIT(clock_lo, 10000, 1); // [5]p.53, -10ms [5]p.50 WAIT(clock_lo, 10000, 1); // [5]p.53, -10ms [5]p.50
@ -135,27 +145,29 @@ int16_t ibmpc_host_send(uint8_t data)
/* Stop bit */ /* Stop bit */
wait_us(15); wait_us(15);
data_hi(); data_hi();
WAIT(clock_hi, 50, 6);
if (ibmpc_protocol == IBMPC_PROTOCOL_AT_Z150) { goto RECV; }
WAIT(clock_lo, 50, 7);
/* Ack */ /* Ack */
WAIT(data_lo, 50, 8); WAIT(data_lo, 300, 6);
WAIT(data_hi, 300, 7);
WAIT(clock_hi, 300, 8);
/* wait for idle state */
WAIT(clock_hi, 50, 9);
WAIT(data_hi, 50, 10);
RECV:
// clear buffer to get response correctly // clear buffer to get response correctly
recv_data = 0xFFFF;
ibmpc_host_isr_clear(); ibmpc_host_isr_clear();
idle(); idle();
IBMPC_INT_ON(); IBMPC_INT_ON();
return ibmpc_host_recv_response(); return ibmpc_host_recv_response();
ERROR: ERROR:
// Retry for Z-150 AT start bit error
if (ibmpc_error == 1 && retry++ < 10) {
ibmpc_error = IBMPC_ERR_NONE;
dprintf("R ");
goto RETRY;
}
ibmpc_error |= IBMPC_ERR_SEND; ibmpc_error |= IBMPC_ERR_SEND;
inhibit();
wait_ms(2);
idle(); idle();
IBMPC_INT_ON(); IBMPC_INT_ON();
return -1; return -1;
@ -166,54 +178,19 @@ ERROR:
*/ */
int16_t ibmpc_host_recv(void) int16_t ibmpc_host_recv(void)
{ {
uint16_t data = 0; int16_t ret = -1;
uint8_t ret = 0xFF;
// Enable ISR if buffer was full
if (ringbuf_is_full(&rb)) {
ibmpc_host_isr_clear();
IBMPC_INT_ON();
idle();
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
data = recv_data; ret = ringbuf_get(&rb);
// 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 (ret != -1) dprintf("r%02X ", ret&0xFF);
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);
}
}
//dprintf("i%04X ", ibmpc_isr_debug); ibmpc_isr_debug = 0;
dprintf("r%02X ", ret);
return ret; return ret;
} }
@ -234,7 +211,7 @@ void ibmpc_host_isr_clear(void)
ibmpc_protocol = 0; ibmpc_protocol = 0;
ibmpc_error = 0; ibmpc_error = 0;
isr_state = 0x8000; isr_state = 0x8000;
recv_data = 0xFFFF; ringbuf_reset(&rb);
} }
#define LO8(w) (*((uint8_t *)&(w))) #define LO8(w) (*((uint8_t *)&(w)))
@ -387,25 +364,19 @@ ISR(IBMPC_INT_VECT)
break; break;
} }
ERROR:
// error: eeFF
recv_data = (ibmpc_error<<8) | 0x00FF;
goto CLEAR;
DONE: DONE:
if ((isr_state & 0x00FF) == 0x00FF) {
// receive error code 0xFF
ibmpc_error = IBMPC_ERR_FF;
goto ERROR;
}
if (HI8(recv_data) != 0xFF && LO8(recv_data) != 0xFF) {
// buffer full
ibmpc_error = IBMPC_ERR_FULL;
goto ERROR;
}
// store data // store data
recv_data = recv_data<<8; if (!ringbuf_put(&rb, isr_state & 0xFF)) {
recv_data |= isr_state & 0xFF; // buffer overflow
CLEAR: ibmpc_error = IBMPC_ERR_FULL;
// Disable ISR if buffer is full
IBMPC_INT_OFF();
// inhibit: clock_lo
IBMPC_CLOCK_PORT &= ~(1<<IBMPC_CLOCK_BIT);
IBMPC_CLOCK_DDR |= (1<<IBMPC_CLOCK_BIT);
}
ERROR:
// clear for next data // clear for next data
isr_state = 0x8000; isr_state = 0x8000;
NEXT: NEXT:

View file

@ -94,16 +94,14 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
HID_RI_USAGE_PAGE(8, 0x09), /* Button */ HID_RI_USAGE_PAGE(8, 0x09), /* Button */
HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */ HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */ HID_RI_USAGE_MAXIMUM(8, 0x08), /* Button 8 */
HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, 0x05), HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x03),
HID_RI_INPUT(8, HID_IOF_CONSTANT),
#ifndef MOUSE_EXT_REPORT
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x30), /* Usage X */ HID_RI_USAGE(8, 0x30), /* Usage X */
HID_RI_USAGE(8, 0x31), /* Usage Y */ HID_RI_USAGE(8, 0x31), /* Usage Y */
@ -112,6 +110,25 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
HID_RI_REPORT_COUNT(8, 0x02), HID_RI_REPORT_COUNT(8, 0x02),
HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
#else
/* Boot protocol XY ignored in Report protocol */
HID_RI_USAGE_PAGE(8, 0xff), /* Vendor */
HID_RI_USAGE(8, 0xff), /* Vendor */
HID_RI_LOGICAL_MINIMUM(8, -127),
HID_RI_LOGICAL_MAXIMUM(8, 127),
HID_RI_REPORT_COUNT(8, 0x02),
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x30), /* Usage X */
HID_RI_USAGE(8, 0x31), /* Usage Y */
HID_RI_LOGICAL_MINIMUM(16, -32767),
HID_RI_LOGICAL_MAXIMUM(16, 32767),
HID_RI_REPORT_COUNT(8, 0x02),
HID_RI_REPORT_SIZE(8, 16),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
#endif
HID_RI_USAGE(8, 0x38), /* Wheel */ HID_RI_USAGE(8, 0x38), /* Wheel */
HID_RI_LOGICAL_MINIMUM(8, -127), HID_RI_LOGICAL_MINIMUM(8, -127),