You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.4 KiB

#include "ringbuf_small.h"
#include <util/atomic.h>
/* Very generic implementation of an interrupt-safe ringbuffer
*
* Contention handling:
* - writing of pointers only with interrupt lock
* - reading of pointers allowed at any time
* - volatile not really necessary, unless you really need the functions to
* react to freespace/newdata while they're running
*
* PUT AND GET ARE NOT REENTRANT!
*/
void ringbuf_init(ringbuf_t *rb, uint16_t *buf, uint8_t size){
rb->startptr = buf;
rb->size = size;
rb->readpos = 0;
rb->writepos = 0;
}
/* pushes a value onto the ringbuffer
* returns 0 on success, 1 on buffer full
*/
uint8_t ringbuf_put(ringbuf_t *rb, uint16_t value){
// calculate next ptr pos
uint8_t next = rb->writepos + 1;
if(next >= rb->size){
next = 0;
}
// check for space
if(next == rb->readpos){
return(1); // give up
}
*(rb->startptr + rb->writepos) = value;
// do we need a barrier here?
rb->writepos = next;
return(0);
}
/* gets a value from the ringbuffer
* returns 0 on success, 1 on buffer empty
*/
uint8_t ringbuf_get(ringbuf_t *rb, uint16_t *data){
//uint16_t value;
uint8_t next;
// calculate next ptr pos
next = rb->readpos + 1;
if(next >= rb->size){
next = 0;
}
//check for empty
if(rb->readpos == rb->writepos){
return(1);
}
*data = *(rb->startptr + rb->readpos);
rb->readpos = next;
return(0);
}