99 lines
2.0 KiB
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;
|
||
|
}
|
||
|
|