X-Git-Url: https://git.friedersdorff.com/?a=blobdiff_plain;f=tmk_core%2Fprotocol%2Fibmpc.c;h=5f2ca79b2fba9f1bd8067b46ed1d2ca8ca6044a1;hb=12e5a3a13eb86852ad58c131e28ba29c5f09bb2d;hp=546c2ac6c2ac675ff6b692975edc61c872167ebd;hpb=53d10fe2478300d8e35b0e1ea67cf184d78e9f06;p=max%2Ftmk_keyboard.git diff --git a/tmk_core/protocol/ibmpc.c b/tmk_core/protocol/ibmpc.c index 546c2ac6..5f2ca79b 100644 --- a/tmk_core/protocol/ibmpc.c +++ b/tmk_core/protocol/ibmpc.c @@ -105,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++) { @@ -134,14 +135,15 @@ int16_t ibmpc_host_send(uint8_t data) /* Stop bit */ wait_us(15); data_hi(); + WAIT(clock_hi, 50, 6); + WAIT(clock_lo, 50, 7); /* Ack */ - WAIT(data_lo, 50, 6); - WAIT(clock_lo, 50, 7); + 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; @@ -208,6 +210,7 @@ int16_t ibmpc_host_recv(void) } } + //dprintf("i%04X ", ibmpc_isr_debug); ibmpc_isr_debug = 0; dprintf("r%02X ", ret); return ret; } @@ -225,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? @@ -245,13 +253,16 @@ ISR(IBMPC_INT_VECT) if (isr_state == 0x8000) { timer_start = t; } else { - // should not take more than 1ms - if (timer_start != t && (uint8_t)(timer_start + 1) != t) { + // This gives 2.0ms at least before timeout + if ((uint8_t)(t - timer_start) >= 3) { + 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; } } @@ -310,6 +321,7 @@ ISR(IBMPC_INT_VECT) goto NEXT; } else { // XT_Clone-done + ibmpc_isr_debug = isr_state; isr_state = isr_state>>8; ibmpc_protocol = IBMPC_PROTOCOL_XT_CLONE; goto DONE; @@ -335,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; @@ -346,11 +359,17 @@ ISR(IBMPC_INT_VECT) case 0b01010000: case 0b11010000: // AT-done - // 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? + 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: @@ -376,7 +395,7 @@ DONE: ibmpc_error = IBMPC_ERR_FF; goto ERROR; } - if ((recv_data & 0xFF00) != 0xFF00) { + if (HI8(recv_data) != 0xFF && LO8(recv_data) != 0xFF) { // buffer full ibmpc_error = IBMPC_ERR_FULL; goto ERROR;