#include <stdint.h>
#include "FIFO.h"

#define FIFO_SUCCESS    1
#define FIFO_FAIL       0
#define SIZE         1024

static uint8_t RX_buffer[SIZE];
static uint8_t *RX_head, *RX_tail;
static uint8_t TX_buffer[SIZE];
static uint8_t *TX_head, *TX_tail;

void FIFO_init(void)
{
	RX_head = RX_tail = &RX_buffer[0];	
	TX_head = TX_tail = &TX_buffer[0];
}

int RX_FIFO_empty(void)
{
	return RX_head == RX_tail;	
}

int RX_FIFO_full(void)
{
	uint8_t *ptr = RX_tail + 1;
	if (ptr == &RX_buffer[SIZE])
		ptr = &RX_buffer[0];
	return ptr == RX_head;
}

int RX_FIFO_count(void)
{
	return RX_tail >= RX_head ? RX_tail - RX_head : SIZE - (RX_head - RX_tail);
}

int RX_FIFO_put(uint8_t data)
{
	if (RX_FIFO_full())
		return FIFO_FAIL;
	*RX_tail++ = data;
	if (RX_tail == &RX_buffer[SIZE])
		RX_tail = &RX_buffer[0];
	return FIFO_SUCCESS;
}

int RX_FIFO_get(uint8_t *data)
{
	if (RX_FIFO_empty())
		return FIFO_FAIL;
	*data = *RX_head++;
	if (RX_head == &RX_buffer[SIZE])
		RX_head = &RX_buffer[0];
	return FIFO_SUCCESS;
}


int TX_FIFO_empty(void)
{
	return TX_head == TX_tail;	
}

int TX_FIFO_full(void)
{
	uint8_t *ptr = TX_tail + 1;
	if (ptr == &TX_buffer[SIZE])
		ptr = &TX_buffer[0];
	return ptr == TX_head;
}

int TX_FIFO_put(uint8_t data)
{
	if (TX_FIFO_full())
		return FIFO_FAIL;
	*TX_tail++ = data;
	if (TX_tail == &TX_buffer[SIZE])
		TX_tail = &TX_buffer[0];
	return FIFO_SUCCESS;
}

int TX_FIFO_get(uint8_t *data)
{
	if (TX_FIFO_empty())
		return FIFO_FAIL;
	*data = *TX_head++;
	if (TX_head == &TX_buffer[SIZE])
		TX_head = &TX_buffer[0];
	return FIFO_SUCCESS;
}