Merge remote-tracking branch 'tmk/master'
This commit is contained in:
commit
9c3121e122
18 changed files with 5738 additions and 5126 deletions
|
|
@ -82,10 +82,26 @@ KEYMAP_SECTION_ENABLE ?= yes # fixed address keymap for keymap editor
|
|||
ADB_MOUSE_MAXACC ?= 8
|
||||
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"
|
||||
#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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -39,6 +39,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
/* Locking resynchronize hack */
|
||||
#define LOCKING_RESYNC_ENABLE
|
||||
|
||||
// Mouse Extended Report
|
||||
#define MOUSE_EXT_REPORT
|
||||
|
||||
|
||||
/* ADB port setting */
|
||||
#define ADB_PORT PORTD
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ void matrix_init(void)
|
|||
DDRD |= (1<<6); PORTD |= (1<<6);
|
||||
|
||||
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
|
||||
// it would fail to recognize layout and enable Extended protocol.
|
||||
|
|
@ -228,16 +230,51 @@ detect_again:
|
|||
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 };
|
||||
/* byte0: speed
|
||||
* 0xa0, 0xa5, 0xb0 and 0xb5 seem to work
|
||||
* uppper nibble:
|
||||
* 0x00-70, 0xc0-f0 no movement and button event
|
||||
* 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_listen_buf(addr, ADB_REG_2, cmd1, sizeof(cmd1));
|
||||
adb_host_flush(addr);
|
||||
adb_host_listen_buf(addr, ADB_REG_2, cmd2, sizeof(cmd2));
|
||||
adb_host_listen_buf(addr, ADB_REG_2, cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -255,12 +292,10 @@ detect_again:
|
|||
goto again;
|
||||
}
|
||||
|
||||
#ifdef MAX
|
||||
#undef MAX
|
||||
#endif
|
||||
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -332,6 +367,12 @@ void adb_mouse_task(void)
|
|||
if (!(buf[2] & 0x80)) buttons |= MOUSE_BTN3;
|
||||
if (!(buf[1] & 0x80)) buttons |= MOUSE_BTN2;
|
||||
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;
|
||||
|
||||
int16_t xx, yy;
|
||||
|
|
@ -342,14 +383,27 @@ void adb_mouse_task(void)
|
|||
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)
|
||||
mouse_report.x = -MAX(-MAX(x, -127), -127);
|
||||
mouse_report.y = -MAX(-MAX(y, -127), -127);
|
||||
#ifndef MOUSE_EXT_REPORT
|
||||
x = (x > 127) ? 127 : ((x < -127) ? -127 : x);
|
||||
y = (y > 127) ? 127 : ((y < -127) ? -127 : y);
|
||||
#endif
|
||||
|
||||
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.
|
||||
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
|
|
@ -42,6 +42,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
// G80-2551 terminal keyboard support
|
||||
#define G80_2551_SUPPORT
|
||||
|
||||
// PS/2 Mouse support
|
||||
//#define IBMPC_MOUSE_ENABLE
|
||||
|
||||
// Mouse Extended Report
|
||||
//#define MOUSE_EXT_REPORT
|
||||
|
||||
|
||||
/*
|
||||
* Pin and interrupt configuration
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@ static int16_t read_wait(uint16_t wait_ms)
|
|||
return code;
|
||||
}
|
||||
|
||||
#define ID_STR(id) (id == 0xFFFE ? "_????" : \
|
||||
(id == 0xFFFD ? "_Z150" : \
|
||||
(id == 0x0000 ? "_AT84" : \
|
||||
"")))
|
||||
|
||||
static uint16_t read_keyboard_id(void)
|
||||
{
|
||||
uint16_t id = 0;
|
||||
|
|
@ -85,7 +90,6 @@ DONE:
|
|||
void hook_early_init(void)
|
||||
{
|
||||
ibmpc_host_init();
|
||||
ibmpc_host_enable();
|
||||
}
|
||||
|
||||
void matrix_init(void)
|
||||
|
|
@ -130,9 +134,18 @@ uint8_t matrix_scan(void)
|
|||
} state = INIT;
|
||||
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) {
|
||||
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
|
||||
if (!(ibmpc_error & (IBMPC_ERR_SEND | IBMPC_ERR_FULL))) {
|
||||
|
|
@ -150,7 +163,7 @@ uint8_t matrix_scan(void)
|
|||
|
||||
// check protocol change AT/XT
|
||||
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
|
||||
// keyboard is hotswapped or something goes wrong.
|
||||
|
|
@ -169,8 +182,6 @@ uint8_t matrix_scan(void)
|
|||
|
||||
switch (state) {
|
||||
case INIT:
|
||||
ibmpc_host_disable();
|
||||
|
||||
xprintf("I%u ", timer_read());
|
||||
keyboard_kind = NONE;
|
||||
keyboard_id = 0x0000;
|
||||
|
|
@ -181,19 +192,20 @@ uint8_t matrix_scan(void)
|
|||
|
||||
init_time = timer_read();
|
||||
state = WAIT_SETTLE;
|
||||
ibmpc_host_enable();
|
||||
break;
|
||||
case WAIT_SETTLE:
|
||||
while (ibmpc_host_recv() != -1) ; // read data
|
||||
|
||||
// wait for keyboard to settle after plugin
|
||||
if (timer_elapsed(init_time) > 1000) {
|
||||
if (timer_elapsed(init_time) > 3000) {
|
||||
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
|
||||
xprintf("A%u ", timer_read());
|
||||
|
||||
// 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.
|
||||
// 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 {
|
||||
state = XT_RESET;
|
||||
}
|
||||
xprintf("A%u ", timer_read());
|
||||
break;
|
||||
case XT_RESET:
|
||||
// Reset XT-initialize keyboard
|
||||
|
|
@ -281,15 +292,15 @@ uint8_t matrix_scan(void)
|
|||
} else if (0xFFFE == keyboard_id) { // CodeSet2 PS/2 fails to response?
|
||||
keyboard_kind = PC_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
|
||||
xprintf("Mouse: not supported\n");
|
||||
keyboard_kind = NONE;
|
||||
#ifdef G80_2551_SUPPORT
|
||||
} 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
|
||||
keyboard_kind = PC_MOUSE;
|
||||
} else if (0xAB85 == keyboard_id || // IBM 122-key Model M, NCD N-97
|
||||
0xAB86 == keyboard_id || // Cherry G80-2551, IBM 1397000
|
||||
0xAB92 == keyboard_id) { // IBM 5576-001
|
||||
// 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)) &&
|
||||
(0xFA == ibmpc_host_send(0x03))) {
|
||||
|
|
@ -298,7 +309,21 @@ uint8_t matrix_scan(void)
|
|||
} else {
|
||||
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
|
||||
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#bfb0
|
||||
// TODO: LED indicator fix
|
||||
|
|
@ -308,11 +333,24 @@ uint8_t matrix_scan(void)
|
|||
keyboard_kind = PC_AT;
|
||||
} else if (0xBF00 == (keyboard_id & 0xFF00)) { // CodeSet3 Terminal
|
||||
keyboard_kind = PC_TERMINAL;
|
||||
} else if (0x7F00 == (keyboard_id & 0xFF00)) { // CodeSet3 Terminal 1394204
|
||||
keyboard_kind = PC_TERMINAL;
|
||||
} 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;
|
||||
break;
|
||||
|
|
@ -324,15 +362,89 @@ uint8_t matrix_scan(void)
|
|||
case PC_AT:
|
||||
led_set(host_keyboard_leds());
|
||||
break;
|
||||
case PC_AT_Z150:
|
||||
// TODO: do not set indicators temporarily for debug
|
||||
break;
|
||||
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;
|
||||
#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:
|
||||
break;
|
||||
}
|
||||
|
|
@ -350,12 +462,12 @@ uint8_t matrix_scan(void)
|
|||
// Scan Code Set 1: 0xFF
|
||||
// Scan Code Set 2 and 3: 0x00
|
||||
// Buffer full(IBMPC_ERR_FULL): 0xFF
|
||||
if (code == 0x00 || code == 0xFF) {
|
||||
if (keyboard_kind != PC_MOUSE && (code == 0x00 || code == 0xFF)) {
|
||||
// clear stuck keys
|
||||
matrix_clear();
|
||||
clear_keyboard();
|
||||
|
||||
xprintf("\n[OVR] ");
|
||||
xprintf("\n[CLR] ");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -364,12 +476,118 @@ uint8_t matrix_scan(void)
|
|||
if (process_cs1(code) == -1) state = INIT;
|
||||
break;
|
||||
case PC_AT:
|
||||
case PC_AT_Z150:
|
||||
if (process_cs2(code) == -1) state = INIT;
|
||||
break;
|
||||
case PC_TERMINAL:
|
||||
if (process_cs3(code) == -1) state = INIT;
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
|
@ -432,6 +650,7 @@ void led_set(uint8_t usb_led)
|
|||
// 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;
|
||||
if (keyboard_kind == PC_MOUSE) 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.
|
||||
|
|
@ -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)
|
||||
{
|
||||
// scan code reading states
|
||||
|
|
@ -754,6 +997,9 @@ static int8_t process_cs2(uint8_t code)
|
|||
|
||||
switch (state) {
|
||||
case INIT:
|
||||
if (0xAB90 == keyboard_id || 0xAB91 == keyboard_id) {
|
||||
code = translate_5576_cs2(code);
|
||||
}
|
||||
switch (code) {
|
||||
case 0xE0:
|
||||
state = E0;
|
||||
|
|
@ -787,6 +1033,9 @@ static int8_t process_cs2(uint8_t code)
|
|||
}
|
||||
break;
|
||||
case E0: // E0-Prefixed
|
||||
if (0xAB90 == keyboard_id || 0xAB91 == keyboard_id) {
|
||||
code = translate_5576_cs2_e0(code);
|
||||
}
|
||||
switch (code) {
|
||||
case 0x12: // to be ignored
|
||||
case 0x59: // to be ignored
|
||||
|
|
@ -807,6 +1056,9 @@ static int8_t process_cs2(uint8_t code)
|
|||
}
|
||||
break;
|
||||
case F0: // Break code
|
||||
if (0xAB90 == keyboard_id || 0xAB91 == keyboard_id) {
|
||||
code = translate_5576_cs2(code);
|
||||
}
|
||||
switch (code) {
|
||||
case 0x83: // F7
|
||||
matrix_break(0x02);
|
||||
|
|
@ -828,6 +1080,9 @@ static int8_t process_cs2(uint8_t code)
|
|||
}
|
||||
break;
|
||||
case E0_F0: // Break code of E0-prefixed
|
||||
if (0xAB90 == keyboard_id || 0xAB91 == keyboard_id) {
|
||||
code = translate_5576_cs2_e0(code);
|
||||
}
|
||||
switch (code) {
|
||||
case 0x12: // to be ignored
|
||||
case 0x59: // to be ignored
|
||||
|
|
@ -902,12 +1157,26 @@ static int8_t process_cs2(uint8_t code)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Terminal: Scan Code Set 3
|
||||
*
|
||||
* See [3], [7] and
|
||||
* 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 enum {
|
||||
|
|
@ -920,8 +1189,21 @@ static int8_t process_cs3(uint8_t code)
|
|||
#endif
|
||||
} 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) {
|
||||
case READY:
|
||||
if (0xAB92 == keyboard_id) {
|
||||
code = translate_5576_cs3(code);
|
||||
}
|
||||
switch (code) {
|
||||
case 0xF0:
|
||||
state = F0;
|
||||
|
|
@ -933,10 +1215,10 @@ static int8_t process_cs3(uint8_t code)
|
|||
matrix_make(0x7F);
|
||||
break;
|
||||
case 0x85: // Muhenkan
|
||||
matrix_make(0x0B);
|
||||
matrix_make(0x68);
|
||||
break;
|
||||
case 0x86: // Henkan
|
||||
matrix_make(0x06);
|
||||
matrix_make(0x78);
|
||||
break;
|
||||
case 0x87: // Hiragana
|
||||
matrix_make(0x00);
|
||||
|
|
@ -960,51 +1242,44 @@ static int8_t process_cs3(uint8_t code)
|
|||
matrix_make(code);
|
||||
} else {
|
||||
xprintf("!CS3_READY!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case F0: // Break code
|
||||
state = READY;
|
||||
if (0xAB92 == keyboard_id) {
|
||||
code = translate_5576_cs3(code);
|
||||
}
|
||||
switch (code) {
|
||||
case 0x83: // PrintScreen
|
||||
matrix_break(0x02);
|
||||
state = READY;
|
||||
break;
|
||||
case 0x84: // Keypad *
|
||||
matrix_break(0x7F);
|
||||
state = READY;
|
||||
break;
|
||||
case 0x85: // Muhenkan
|
||||
matrix_break(0x0B);
|
||||
state = READY;
|
||||
matrix_break(0x68);
|
||||
break;
|
||||
case 0x86: // Henkan
|
||||
matrix_break(0x06);
|
||||
state = READY;
|
||||
matrix_break(0x78);
|
||||
break;
|
||||
case 0x87: // Hiragana
|
||||
matrix_break(0x00);
|
||||
state = READY;
|
||||
break;
|
||||
case 0x8B: // Left GUI
|
||||
matrix_break(0x01);
|
||||
state = READY;
|
||||
break;
|
||||
case 0x8C: // Right GUI
|
||||
matrix_break(0x09);
|
||||
state = READY;
|
||||
break;
|
||||
case 0x8D: // Application
|
||||
matrix_break(0x0A);
|
||||
state = READY;
|
||||
break;
|
||||
default:
|
||||
state = READY;
|
||||
if (code < 0x80) {
|
||||
matrix_break(code);
|
||||
} else {
|
||||
xprintf("!CS3_F0!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef 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) \
|
||||
(kind == PC_XT ? "XT" : \
|
||||
kind == PC_AT ? "AT" : \
|
||||
kind == PC_TERMINAL ? "TERMINAL" : \
|
||||
kind == PC_AT_Z150 ? "AT_Z150" : \
|
||||
kind == PC_MOUSE ? "MOUSE" : \
|
||||
"NONE")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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_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_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 */
|
||||
#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)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ void host_keyboard_send(report_keyboard_t *report)
|
|||
void host_mouse_send(report_mouse_t *report)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -159,8 +159,15 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint8_t buttons;
|
||||
#ifndef MOUSE_EXT_REPORT
|
||||
int8_t x;
|
||||
int8_t y;
|
||||
#else
|
||||
int8_t boot_x;
|
||||
int8_t boot_y;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
#endif
|
||||
int8_t v;
|
||||
int8_t h;
|
||||
} __attribute__ ((packed)) report_mouse_t;
|
||||
|
|
|
|||
|
|
@ -254,6 +254,23 @@ void adb_host_flush(uint8_t addr)
|
|||
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
|
||||
void adb_host_kbd_led(uint8_t addr, uint8_t led)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
|
||||
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_mouse_task(void);
|
||||
void adb_mouse_init(void);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "debug.h"
|
||||
#include "timer.h"
|
||||
#include "wait.h"
|
||||
#include "ringbuf.h"
|
||||
|
||||
|
||||
#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_error = IBMPC_ERR_NONE;
|
||||
|
||||
/* 2-byte buffer for data received from keyboard
|
||||
* buffer states:
|
||||
* FFFF: empty
|
||||
* FFss: one 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;
|
||||
/* buffer for data received from device */
|
||||
#define RINGBUF_SIZE 16
|
||||
static uint8_t rbuf[RINGBUF_SIZE];
|
||||
static ringbuf_t rb = {};
|
||||
|
||||
/* internal state of receiving data */
|
||||
static volatile uint16_t isr_state = 0x8000;
|
||||
static uint8_t timer_start = 0;
|
||||
|
|
@ -80,6 +77,7 @@ void ibmpc_host_init(void)
|
|||
inhibit();
|
||||
IBMPC_INT_INIT();
|
||||
IBMPC_INT_OFF();
|
||||
ringbuf_init(&rb, rbuf, RINGBUF_SIZE);
|
||||
}
|
||||
|
||||
void ibmpc_host_enable(void)
|
||||
|
|
@ -98,18 +96,30 @@ int16_t ibmpc_host_send(uint8_t data)
|
|||
{
|
||||
bool parity = true;
|
||||
ibmpc_error = IBMPC_ERR_NONE;
|
||||
uint8_t retry = 0;
|
||||
|
||||
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();
|
||||
|
||||
RETRY:
|
||||
/* terminate a transmission if we have */
|
||||
inhibit();
|
||||
wait_us(100); // [5]p.54
|
||||
wait_us(200); // [5]p.54
|
||||
|
||||
/* 'Request to Send' and Start bit */
|
||||
data_lo();
|
||||
wait_us(100);
|
||||
wait_us(200);
|
||||
clock_hi(); // [5]p.54 [clock low]>100us [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 */
|
||||
wait_us(15);
|
||||
data_hi();
|
||||
WAIT(clock_hi, 50, 6);
|
||||
if (ibmpc_protocol == IBMPC_PROTOCOL_AT_Z150) { goto RECV; }
|
||||
WAIT(clock_lo, 50, 7);
|
||||
|
||||
/* 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
|
||||
recv_data = 0xFFFF;
|
||||
ibmpc_host_isr_clear();
|
||||
|
||||
idle();
|
||||
IBMPC_INT_ON();
|
||||
return ibmpc_host_recv_response();
|
||||
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;
|
||||
inhibit();
|
||||
wait_ms(2);
|
||||
idle();
|
||||
IBMPC_INT_ON();
|
||||
return -1;
|
||||
|
|
@ -166,54 +178,19 @@ ERROR:
|
|||
*/
|
||||
int16_t ibmpc_host_recv(void)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
uint8_t ret = 0xFF;
|
||||
int16_t ret = -1;
|
||||
|
||||
// Enable ISR if buffer was full
|
||||
if (ringbuf_is_full(&rb)) {
|
||||
ibmpc_host_isr_clear();
|
||||
IBMPC_INT_ON();
|
||||
idle();
|
||||
}
|
||||
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
data = recv_data;
|
||||
|
||||
// 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);
|
||||
ret = ringbuf_get(&rb);
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret != -1) dprintf("r%02X ", ret&0xFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -234,7 +211,7 @@ void ibmpc_host_isr_clear(void)
|
|||
ibmpc_protocol = 0;
|
||||
ibmpc_error = 0;
|
||||
isr_state = 0x8000;
|
||||
recv_data = 0xFFFF;
|
||||
ringbuf_reset(&rb);
|
||||
}
|
||||
|
||||
#define LO8(w) (*((uint8_t *)&(w)))
|
||||
|
|
@ -387,25 +364,19 @@ ISR(IBMPC_INT_VECT)
|
|||
break;
|
||||
}
|
||||
|
||||
ERROR:
|
||||
// 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 (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;
|
||||
CLEAR:
|
||||
if (!ringbuf_put(&rb, isr_state & 0xFF)) {
|
||||
// buffer overflow
|
||||
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
|
||||
isr_state = 0x8000;
|
||||
NEXT:
|
||||
|
|
|
|||
|
|
@ -94,16 +94,14 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
|
|||
|
||||
HID_RI_USAGE_PAGE(8, 0x09), /* Button */
|
||||
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_MAXIMUM(8, 0x01),
|
||||
HID_RI_REPORT_COUNT(8, 0x05),
|
||||
HID_RI_REPORT_COUNT(8, 0x08),
|
||||
HID_RI_REPORT_SIZE(8, 0x01),
|
||||
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(8, 0x30), /* Usage X */
|
||||
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_SIZE(8, 0x08),
|
||||
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_LOGICAL_MINIMUM(8, -127),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue