#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
 */
int8_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);
}







