ibm4704_usb: Fix protocol handling

example_keyboards
tmk 10 years ago
parent 6b588eb7f7
commit 80fd3b0b24

@ -8,6 +8,7 @@ Keyboard initialization process takes a few seconds at start up. During that you
Update Update
------ ------
2015/05/05 Added keymaps for 107-key, 77-key and 50-key. Thanks, orihalcon @ geekhack! 2015/05/05 Added keymaps for 107-key, 77-key and 50-key. Thanks, orihalcon @ geekhack!
2015/05/19 Fixed a protocol handling bug.

@ -53,7 +53,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Pin interrupt on rising edge of clock */ /* Pin interrupt on rising edge of clock */
#define IBM4704_INT_INIT() do { EICRA |= ((1<<ISC11)|(1<<ISC10)); } while (0) #define IBM4704_INT_INIT() do { EICRA |= ((1<<ISC11)|(1<<ISC10)); } while (0)
#define IBM4704_INT_ON() do { EIMSK |= (1<<INT1); } while (0) #define IBM4704_INT_ON() do { EIFR |= (1<<INTF1); EIMSK |= (1<<INT1); } while (0)
#define IBM4704_INT_OFF() do { EIMSK &= ~(1<<INT1); } while (0) #define IBM4704_INT_OFF() do { EIMSK &= ~(1<<INT1); } while (0)
#define IBM4704_INT_VECT INT1_vect #define IBM4704_INT_VECT INT1_vect

@ -166,13 +166,14 @@ Data sent from host:
| `-----`--- scan code | `-----`--- scan code
`------------- enable bit(0: enable repeat, 1: enable break) `------------- enable bit(0: enable repeat, 1: enable break)
00-77 Enable repeat(78-7F: invalid scancode) 00-79 Enable repeat
80-F7 Enable break(F8-FF: invalid scancode) 80-F9 Enable break(FA-FF are used as other commands, see above.)
FE Resend(011ah) no need to use FE Resend(011ah) no need to use
FF End(0114h) exits FC command mode. FF End(0114h) exits FC command mode.
Response from keyboard: Response from keyboard:
FD Out of bound - Invalid scancode FD Out of bound - Invalid scancode
-- OK - No response means that command is accepted.
Examples: Examples:
To enable break code of all keys. To enable break code of all keys.

@ -67,35 +67,31 @@ uint8_t matrix_cols(void)
static void enable_break(void) static void enable_break(void)
{ {
uint8_t ret;
print("Enable break: "); print("Enable break: ");
// valid scancode: 00-79h // valid scancode: 00-79h
for (uint8_t code = 0; code < 0x7A; code++) { for (uint8_t code = 0; code < 0x7A; code++) {
while (ibm4704_send(0x80|code)) _delay_ms(1); while (ibm4704_send(0x80|code)) _delay_ms(10);
// get none when ok, get FD when out of bound _delay_ms(5); // wait for response
_delay_ms(5); // No response(FF) when ok, FD when out of bound
if ((ret = ibm4704_recv()) != 0xff) { xprintf("s%02X:r%02X ", code, ibm4704_recv());
xprintf("c%02X:r%02X ", code, ret);
}
_delay_ms(1);
} }
_delay_us(1000); while (ibm4704_send(0xFF)) { _delay_ms(10); } // End
while (ibm4704_send(0xFF)) { _delay_ms(1); } // End
print("End\n"); print("End\n");
} }
void matrix_init(void)
{
debug_enable = true;
void matrix_setup(void)
{
ibm4704_init(); ibm4704_init();
matrix_clear(); }
_delay_ms(2000); // wait for starting up debug console void matrix_init(void)
{
debug_enable = true;
print("IBM 4704 converter\n"); print("IBM 4704 converter\n");
while (ibm4704_send(0xFE)) _delay_ms(1); // resend matrix_clear();
_delay_ms(5); _delay_ms(2000); // wait for keyboard starting up
xprintf("Keyboard ID: %02X\n", ibm4704_recv()); xprintf("Keyboard ID: %02X\n", ibm4704_recv());
enable_break(); enable_break();
} }

@ -21,9 +21,10 @@ uint8_t ibm4704_error = 0;
void ibm4704_init(void) void ibm4704_init(void)
{ {
inhibit(); // keep keyboard from sending
IBM4704_INT_INIT(); IBM4704_INT_INIT();
IBM4704_INT_ON(); IBM4704_INT_ON();
idle(); idle(); // allow keyboard sending
} }
/* /*
@ -132,8 +133,8 @@ Stop bit: Keyboard pulls down Data line to lo after 9th clock.
ISR(IBM4704_INT_VECT) ISR(IBM4704_INT_VECT)
{ {
static enum { static enum {
STOP, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY, STOP
} state = STOP; } state = BIT0;
// LSB first // LSB first
static uint8_t data = 0; static uint8_t data = 0;
// Odd parity // Odd parity
@ -141,11 +142,7 @@ ISR(IBM4704_INT_VECT)
ibm4704_error = 0; ibm4704_error = 0;
switch (state++) { switch (state) {
case STOP:
// Data:Low
WAIT(data_lo, 10, state);
break;
case BIT0: case BIT0:
case BIT1: case BIT1:
case BIT2: case BIT2:
@ -166,6 +163,10 @@ ISR(IBM4704_INT_VECT)
} }
if (!parity) if (!parity)
goto ERROR; goto ERROR;
break;
case STOP:
// Data:Low
WAIT(data_lo, 100, state);
rbuf_enqueue(data); rbuf_enqueue(data);
ibm4704_error = IBM4704_ERR_NONE; ibm4704_error = IBM4704_ERR_NONE;
goto DONE; goto DONE;
@ -173,13 +174,14 @@ ISR(IBM4704_INT_VECT)
default: default:
goto ERROR; goto ERROR;
} }
state++;
goto RETURN; goto RETURN;
ERROR: ERROR:
ibm4704_error = state; ibm4704_error = state;
while (ibm4704_send(0xFE)) _delay_ms(1); // resend while (ibm4704_send(0xFE)) _delay_ms(1); // resend
xprintf("R:%02X%02X\n", state, data); xprintf("R:%02X%02X\n", state, data);
DONE: DONE:
state = STOP; state = BIT0;
data = 0; data = 0;
parity = false; parity = false;
RETURN: RETURN:

Loading…
Cancel
Save