rgbyteclock-code/ringbuffer.c

99 lines
2.0 KiB
C

/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <struppi@struppi.name> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* (c) 2008-2014 Stefan Rupp
* ----------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <inttypes.h>
#include <util/atomic.h>
#include "ringbuffer.h"
void ringbuf_init(void *ringbuffer, uint8_t rb_size, void (*idle_func)(void))
{
ringbuffer_t *rb = (ringbuffer_t *) ringbuffer;
rb->size = rb_size;
rb->free = rb_size;
rb->write_idx = 0;
rb->read_idx = 0;
rb->idle_func = idle_func;
return;
}
int8_t ringbuf_get_nb(void *ringbuffer, uint8_t *ch)
{
ringbuffer_t *rb = (ringbuffer_t *) ringbuffer;
if ( rb->size - rb->free == 0) {
*ch = 0xff;
return 0;
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
rb->free++;
*ch = rb->buffer[rb->read_idx++];
if ( rb->read_idx >= rb->size ) {
rb->read_idx = 0;
}
}
return 1;
}
int8_t ringbuf_get(void *ringbuffer, uint8_t *ch)
{
ringbuffer_t *rb = (ringbuffer_t *) ringbuffer;
while ( rb->size - rb->free == 0) {
if (rb->idle_func != NULL) {
rb->idle_func();
}
}
rb->free++;
*ch = rb->buffer[rb->read_idx++];
if ( rb->read_idx >= rb->size ) {
rb->read_idx = 0;
}
return 1;
}
int8_t ringbuf_put_nb(void * ringbuffer, uint8_t ch)
{
ringbuffer_t *rb = (ringbuffer_t *) ringbuffer;
if (rb->free > 0) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
rb->free--;
rb->buffer[rb->write_idx++] = ch;
if (rb->write_idx >= rb->size) {
rb->write_idx = 0;
}
}
return 1;
}
return 0;
}
int8_t ringbuf_get_num_waiting( void * ringbuffer)
{
ringbuffer_t *rb = (ringbuffer_t *) ringbuffer;
uint8_t waiting;
waiting = rb->size - rb->free;
return waiting;
}