From: tmk Date: Wed, 25 Jul 2018 09:53:38 +0000 (+0900) Subject: core: Add ring buffer file X-Git-Url: https://git.friedersdorff.com/?a=commitdiff_plain;h=6632802c7903b4aed1f91dd0b25f7227523f110a;p=max%2Ftmk_keyboard.git core: Add ring buffer file --- 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