]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/common/ringbuf.h
core: Update comments in keycode.h
[max/tmk_keyboard.git] / tmk_core / common / ringbuf.h
1 #ifndef RINGBUF_H
2 #define RINGBUF_H
3
4 #include <stdint.h>
5 #include <stdbool.h>
6
7 // 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)
8 typedef struct {
9     uint8_t *buffer;
10     uint8_t head;
11     uint8_t tail;
12     uint8_t size_mask;
13 } ringbuf_t;
14
15 static inline void ringbuf_init(ringbuf_t *buf, uint8_t *array, uint8_t size);
16 static inline int16_t ringbuf_get(ringbuf_t *buf);
17 static inline bool ringbuf_put(ringbuf_t *buf, uint8_t data);
18 static inline void ringbuf_write(ringbuf_t *buf, uint8_t data);
19 static inline bool ringbuf_is_empty(ringbuf_t *buf);
20 static inline bool ringbuf_is_full(ringbuf_t *buf);
21 static inline void ringbuf_reset(ringbuf_t *buf);
22
23 static inline void ringbuf_init(ringbuf_t *buf, uint8_t *array, uint8_t size)
24 {
25     buf->buffer = array;
26     buf->head = 0;
27     buf->tail = 0;
28     buf->size_mask = size - 1;
29 }
30 static inline int16_t ringbuf_get(ringbuf_t *buf)
31 {
32     if (ringbuf_is_empty(buf)) return -1;
33     uint8_t data = buf->buffer[buf->tail];
34     buf->tail++;
35     buf->tail &= buf->size_mask;
36     return  data;
37 }
38 static inline bool ringbuf_put(ringbuf_t *buf, uint8_t data)
39 {
40     if (ringbuf_is_full(buf)) {
41         return false;
42     }
43     buf->buffer[buf->head] = data;
44     buf->head++;
45     buf->head &= buf->size_mask;
46     return true;
47 }
48 // this overrides data in buffer when it is full
49 static inline void ringbuf_write(ringbuf_t *buf, uint8_t data)
50 {
51     buf->buffer[buf->head] = data;
52     buf->head++;
53     buf->head &= buf->size_mask;
54     // eat tail: override data yet to be consumed
55     if (buf->head == buf->tail) {
56         buf->tail++;
57         buf->tail &= buf->size_mask;
58     }
59 }
60 static inline bool ringbuf_is_empty(ringbuf_t *buf)
61 {
62     return (buf->head == buf->tail);
63 }
64 static inline bool ringbuf_is_full(ringbuf_t *buf)
65 {
66     return (((buf->head + 1) & buf->size_mask) == buf->tail);
67 }
68 static inline void ringbuf_reset(ringbuf_t *buf)
69 {
70     buf->head = 0;
71     buf->tail = 0;
72 }
73 #endif