SingingCat 0
application
ringbuffer.c
1#include "ringbuffer.h"
2#include "mculibrary.h"
3#include "string.h"
4// dummy - may be dynamic in future
5static uint16_t bufsize(struct ringbuffer *r) {
6 return 1023;
7}
8
9void ringbuffer_add_byte(struct ringbuffer *r, uint8_t b) {
10 uint16_t size = bufsize(r);
11
12 if (r->writeptr >= size) {
13 r->writeptr = 0;
14 }
15 r->buf[r->writeptr] = b;
16 r->writeptr++;
17 r->bytes++;
18}
19uint16_t ringbuffer_get_byte(struct ringbuffer *r) {
20 uint16_t size = bufsize(r);
21
22 if (r->readptr >= size) {
23 r->readptr = 0;
24 }
25 if (r->bytes == 0) {
26 return 500;
27 }
28 uint8_t res = r->buf[r->readptr];
29
30 r->readptr++;
31 uint16_t foo = (uint16_t)res;
32
33 mculib_disable_irq(2);
34 r->bytes--;
35 mculib_enable_irq(2);
36 return foo & 0xFF;
37}
38
39
40void ringbuffer_init(struct ringbuffer *r) {
41 memset(r, 0, sizeof(struct ringbuffer));
42}
43
44// return number of characters (-2 == delimiter not found, -1 buf too small
45// TODO: it seems to consume more bytes than available and leave the readptr somewhat borken
46int ringbuffer_get_to_delimiter(struct ringbuffer *r, char delimiter, char *outbuf, int outbufsize) {
47 uint16_t size = bufsize(r);
48 uint16_t readptr = r->readptr;
49 uint32_t bytes = r->bytes;
50 uint16_t linelen = 0;
51
52repeat:
53 if (readptr >= size) {
54 readptr = 0;
55 }
56
57 if (bytes == 0) {
58 return -2;
59 }
60 uint8_t res = r->buf[readptr];
61
62 // a "line" is somewhat ill defined. can be \n, \r, or \r\n
63 if ((res == delimiter) || (delimiter == '\r' && res == '\n') || (delimiter == '\n' && res == '\r')) {
64 readptr++; // consume the delimeter
65 if (readptr >= size) {
66 readptr = 0;
67 }
68 bytes--;
69 // also "consume" the bytes!
70 mculib_disable_irq(2);
71 r->bytes = r->bytes - linelen;
72 r->readptr = readptr;
73 mculib_enable_irq(2);
74
75 return linelen;
76 }
77 readptr++;
78 bytes--;
79 outbuf[linelen++] = res;
80 outbuf[linelen] = 0;
81 if (linelen >= outbufsize) {
82 return -1;
83 }
84 goto repeat;
85}