} while (0)
-volatile uint8_t ibmpc_protocol = IBMPC_PROTOCOL_AT;
+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
bool parity = true;
ibmpc_error = IBMPC_ERR_NONE;
- if (ibmpc_protocol == IBMPC_PROTOCOL_XT) return -1;
-
dprintf("w%02X ", data);
IBMPC_INT_OFF();
}
}
+ if ((data | 0x00FF) != 0xFFFF) dprintf("b%04X ", data);
if (ret != 0xFF) dprintf("r%02X ", ret);
- if (recv_data != 0xFFFF) dprintf("b%04X ", recv_data);
return ((ret != 0xFF) ? ret : -1);
}
// 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
// midway
goto NEXT;
break;
- case 0b11000000:
- // XT_Clone-done
- recv_data = recv_data<<8;
- recv_data |= (isr_state>>8) & 0xFF;
+ 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
+ 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_ERROR;
goto DONE;
break;
case 0b10100000: // ^2
goto NEXT;
} else {
// no stop bit: XT_IBM-done
- recv_data = recv_data<<8;
- recv_data |= (isr_state>>8) & 0xFF;
+ isr_state = isr_state>>8;
+ ibmpc_protocol = IBMPC_PROTOCOL_XT_IBM;
goto DONE;
}
}
case 0b10010000:
case 0b01010000:
case 0b11010000:
- // TODO: parity check?
// AT-done
- recv_data = recv_data<<8;
- recv_data |= (isr_state>>6) & 0xFF;
+ // DO NOT check stop bit. Zenith Z-150(AT) asserts stop bit as low for no reason.
+ // https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#zenith-z-150-beige
+ // TODO: parity check?
+ 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:
+ ibmpc_isr_debug = isr_state;
isr_state = 0x8000;
recv_data = 0xFF00; // clear data and scancode of error 0x00
return;
DONE:
- // TODO: process error code: 0x00(AT), 0xFF(XT) in particular
+ if ((isr_state & 0x00FF) == 0x00FF) {
+ // receive error code 0xFF
+ ibmpc_error = IBMPC_ERR_FF;
+ }
+ if ((recv_data & 0xFF00) != 0xFF00) {
+ // buffer full and overwritten
+ ibmpc_error = IBMPC_ERR_FULL;
+ }
+ recv_data = recv_data<<8;
+ recv_data |= isr_state & 0xFF;
isr_state = 0x8000; // clear to next data
NEXT:
return;
/* 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);
+ }
}