diff --git a/tmk_core/common/ringbuf.h b/tmk_core/common/ringbuf.h index 23bb41e0..d9eec238 100644 --- a/tmk_core/common/ringbuf.h +++ b/tmk_core/common/ringbuf.h @@ -19,6 +19,7 @@ static inline void ringbuf_write(ringbuf_t *buf, uint8_t data); static inline bool ringbuf_is_empty(ringbuf_t *buf); static inline bool ringbuf_is_full(ringbuf_t *buf); static inline void ringbuf_reset(ringbuf_t *buf); +static inline void ringbuf_push(ringbuf_t *buf, uint8_t data); static inline void ringbuf_init(ringbuf_t *buf, uint8_t *array, uint8_t size) { @@ -70,4 +71,10 @@ static inline void ringbuf_reset(ringbuf_t *buf) buf->head = 0; buf->tail = 0; } +static inline void ringbuf_push(ringbuf_t *buf, uint8_t data) +{ + buf->buffer[buf->head] = data; + buf->head++; + buf->head &= buf->size_mask; +} #endif diff --git a/tmk_core/protocol/ibmpc.c b/tmk_core/protocol/ibmpc.c index ff4f54ca..4fd0f508 100644 --- a/tmk_core/protocol/ibmpc.c +++ b/tmk_core/protocol/ibmpc.c @@ -214,11 +214,10 @@ void ibmpc_host_isr_clear(void) ringbuf_reset(&rb); } -#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? + +// NOTE: With this ISR data line should be read within 5us after clock falling edge. +// Confirmed that ATmega32u4 can read data line in 2.5us from interrupt after +// ISR prologue pushs r18, r19, r20, r21, r24, r25 r30 and r31 with GCC 5.4.0 ISR(IBMPC_INT_VECT) { uint8_t dbit; @@ -366,16 +365,19 @@ ISR(IBMPC_INT_VECT) DONE: // store data - if (!ringbuf_put(&rb, isr_state & 0xFF)) { - // buffer overflow - ibmpc_error = IBMPC_ERR_FULL; - + ringbuf_push(&rb, isr_state & 0xFF); + if (ringbuf_is_full(&rb)) { + // just became full // Disable ISR if buffer is full IBMPC_INT_OFF(); // inhibit: clock_lo IBMPC_CLOCK_PORT &= ~(1<