diff --git a/converter/xt_usb/matrix.c b/converter/xt_usb/matrix.c index fe4eebf3..f6784573 100644 --- a/converter/xt_usb/matrix.c +++ b/converter/xt_usb/matrix.c @@ -92,7 +92,7 @@ uint8_t matrix_scan(void) uint8_t code = xt_host_recv(); if (!code) return 0; - xprintf("%02X ", code); + dprintf("%02X ", code); switch (state) { case INIT: switch (code) { diff --git a/tmk_core/common/ringbuf.h b/tmk_core/common/ringbuf.h new file mode 100644 index 00000000..23bb41e0 --- /dev/null +++ b/tmk_core/common/ringbuf.h @@ -0,0 +1,73 @@ +#ifndef RINGBUF_H +#define RINGBUF_H + +#include +#include + +// NOTE: buffer size must be 2^n and up to 255. size_mask should be 2^n - 1 due to using &(AND) instead of %(modulo) +typedef struct { + uint8_t *buffer; + uint8_t head; + uint8_t tail; + uint8_t size_mask; +} ringbuf_t; + +static inline void ringbuf_init(ringbuf_t *buf, uint8_t *array, uint8_t size); +static inline int16_t ringbuf_get(ringbuf_t *buf); +static inline bool ringbuf_put(ringbuf_t *buf, uint8_t data); +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_init(ringbuf_t *buf, uint8_t *array, uint8_t size) +{ + buf->buffer = array; + buf->head = 0; + buf->tail = 0; + buf->size_mask = size - 1; +} +static inline int16_t ringbuf_get(ringbuf_t *buf) +{ + if (ringbuf_is_empty(buf)) return -1; + uint8_t data = buf->buffer[buf->tail]; + buf->tail++; + buf->tail &= buf->size_mask; + return data; +} +static inline bool ringbuf_put(ringbuf_t *buf, uint8_t data) +{ + if (ringbuf_is_full(buf)) { + return false; + } + buf->buffer[buf->head] = data; + buf->head++; + buf->head &= buf->size_mask; + return true; +} +// this overrides data in buffer when it is full +static inline void ringbuf_write(ringbuf_t *buf, uint8_t data) +{ + buf->buffer[buf->head] = data; + buf->head++; + buf->head &= buf->size_mask; + // eat tail: override data yet to be consumed + if (buf->head == buf->tail) { + buf->tail++; + buf->tail &= buf->size_mask; + } +} +static inline bool ringbuf_is_empty(ringbuf_t *buf) +{ + return (buf->head == buf->tail); +} +static inline bool ringbuf_is_full(ringbuf_t *buf) +{ + return (((buf->head + 1) & buf->size_mask) == buf->tail); +} +static inline void ringbuf_reset(ringbuf_t *buf) +{ + buf->head = 0; + buf->tail = 0; +} +#endif diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 60849aea..b1567fa9 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -43,6 +43,7 @@ #include "action.h" #include "led.h" #include "sendchar.h" +#include "ringbuf.h" #include "debug.h" #ifdef SLEEP_LED_ENABLE #include "sleep_led.h" @@ -89,60 +90,97 @@ host_driver_t lufa_driver = { * Console ******************************************************************************/ #ifdef CONSOLE_ENABLE -static void Console_Task(void) +#define SENDBUF_SIZE 256 +static uint8_t sbuf[SENDBUF_SIZE]; +static ringbuf_t sendbuf = { + .buffer = sbuf, + .head = 0, + .tail = 0, + .size_mask = SENDBUF_SIZE - 1 +}; + +static bool console_putc(uint8_t c) +{ + // return immediately if called while interrupt + if (!(SREG & (1< #include #include -#include "pbuff.h" #include "xt.h" #include "wait.h" #include "print.h" +#include "ringbuf.h" + + +#define BUF_SIZE 16 +static uint8_t buf[BUF_SIZE]; +static ringbuf_t rb = { + .buffer = buf, + .head = 0, + .tail = 0, + .size_mask = BUF_SIZE - 1 +}; void xt_host_init(void) { @@ -69,10 +79,12 @@ void xt_host_init(void) /* get data received by interrupt */ uint8_t xt_host_recv(void) { - if (pbuf_has_data()) { - return pbuf_dequeue(); - } else { + if (ringbuf_is_empty(&rb)) { return 0; + } else { + int16_t d = ringbuf_get(&rb); + XT_DATA_IN(); // ready to receive from keyboard + return d; } } @@ -111,7 +123,11 @@ ISR(XT_INT_VECT) break; } if (state++ == BIT7) { - pbuf_enqueue(data); + ringbuf_put(&rb, data); + if (ringbuf_is_full(&rb)) { + XT_DATA_LO(); // inhibit keyboard sending + print("Full"); + } state = START; data = 0; }