diff --git a/tmk_core/protocol/ibmpc.c b/tmk_core/protocol/ibmpc.c index a60c31b1..ff4f54ca 100644 --- a/tmk_core/protocol/ibmpc.c +++ b/tmk_core/protocol/ibmpc.c @@ -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) @@ -180,60 +178,19 @@ ERROR: */ int16_t ibmpc_host_recv(void) { - uint16_t data = 0; - uint8_t ret = 0xFF; + int16_t ret = -1; - 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); - } - - 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 overflow - dprintf("!OVF! "); - 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); - } - } - - // Enable ISR if recv_data is not full - if ((recv_data | 0x00FF) == 0xFFFF) { + // Enable ISR if buffer was full + if (ringbuf_is_full(&rb)) { ibmpc_host_isr_clear(); IBMPC_INT_ON(); idle(); } - //dprintf("i%04X ", ibmpc_isr_debug); ibmpc_isr_debug = 0; - dprintf("r%02X ", ret); + + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + ret = ringbuf_get(&rb); + } + if (ret != -1) dprintf("r%02X ", ret&0xFF); return ret; } @@ -254,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))) @@ -407,32 +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) { + // store data + if (!ringbuf_put(&rb, isr_state & 0xFF)) { // buffer overflow ibmpc_error = IBMPC_ERR_FULL; - goto ERROR; - } - // store data - recv_data = recv_data<<8; - recv_data |= isr_state & 0xFF; -CLEAR: - // Disable ISR if recv_data is full - if ((recv_data | 0x00FF) != 0xFFFF) { + + // Disable ISR if buffer is full IBMPC_INT_OFF(); // inhibit: clock_lo IBMPC_CLOCK_PORT &= ~(1<