mirror of
https://github.com/ep00ch/lwip-contrib-mac.git
synced 2024-09-17 22:57:12 +00:00
132 lines
2.7 KiB
C
132 lines
2.7 KiB
C
|
/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */
|
||
|
|
||
|
/* ---------------------------------------------- */
|
||
|
/* --- fifo 4 unix ------------------------------ */
|
||
|
/* ---------------------------------------------- */
|
||
|
#include "netif/fifo.h"
|
||
|
#include "lwip/debug.h"
|
||
|
#include "lwip/def.h"
|
||
|
#include "lwip/sys.h"
|
||
|
#include "lwip/arch.h"
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#ifndef TRUE
|
||
|
#define TRUE 1
|
||
|
#endif
|
||
|
#ifndef FALSE
|
||
|
#define FALSE 0
|
||
|
#endif
|
||
|
|
||
|
|
||
|
u8_t fifoGet(fifo_t * fifo)
|
||
|
{
|
||
|
u8_t c;
|
||
|
|
||
|
sys_sem_wait(fifo->sem); // enter critical section
|
||
|
|
||
|
if (fifo->dataslot == fifo->emptyslot)
|
||
|
{
|
||
|
fifo->getWaiting = TRUE; // tell putFifo to signal us when data is available
|
||
|
sys_sem_signal(fifo->sem); // leave critical section (allow input from serial port..)
|
||
|
sys_sem_wait(fifo->getSem); // wait 4 data
|
||
|
sys_sem_wait(fifo->sem); // reenter critical section
|
||
|
}
|
||
|
|
||
|
c = fifo->data[fifo->dataslot++];
|
||
|
fifo->len--;
|
||
|
|
||
|
if (fifo->dataslot == FIFOSIZE)
|
||
|
{
|
||
|
fifo->dataslot = 0;
|
||
|
}
|
||
|
sys_sem_signal(fifo->sem); // leave critical section
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
|
||
|
s16_t fifoGetNonBlock(fifo_t * fifo)
|
||
|
{
|
||
|
u16_t c;
|
||
|
|
||
|
sys_sem_wait(fifo->sem); // enter critical section
|
||
|
|
||
|
if (fifo->dataslot == fifo->emptyslot)
|
||
|
{
|
||
|
// empty fifo
|
||
|
c = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
c = fifo->data[fifo->dataslot++];
|
||
|
fifo->len--;
|
||
|
|
||
|
if (fifo->dataslot == FIFOSIZE)
|
||
|
{
|
||
|
fifo->dataslot = 0;
|
||
|
}
|
||
|
}
|
||
|
sys_sem_signal(fifo->sem); // leave critical section
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
|
||
|
void fifoPut(fifo_t * fifo, int fd)
|
||
|
{
|
||
|
/* FIXME: mutex around struct data.. */
|
||
|
int cnt=0;
|
||
|
|
||
|
sys_sem_wait( fifo->sem ); // enter critical
|
||
|
|
||
|
DEBUGF( SIO_FIFO_DEBUG,("fifoput: len%d dat%d empt%d --> ", fifo->len, fifo->dataslot, fifo->emptyslot ) );
|
||
|
|
||
|
if ( fifo->emptyslot < fifo->dataslot )
|
||
|
{
|
||
|
cnt = read( fd, &fifo->data[fifo->emptyslot], fifo->dataslot - fifo->emptyslot );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cnt = read( fd, &fifo->data[fifo->emptyslot], FIFOSIZE-fifo->emptyslot );
|
||
|
}
|
||
|
fifo->emptyslot += cnt;
|
||
|
fifo->len += cnt;
|
||
|
|
||
|
DEBUGF( SIO_FIFO_DEBUG,("len%d dat%d empt%d\n", fifo->len, fifo->dataslot, fifo->emptyslot ) );
|
||
|
|
||
|
if ( fifo->len > FIFOSIZE )
|
||
|
{
|
||
|
printf( "ERROR: fifo overrun detected len=%d, flushing\n", fifo->len );
|
||
|
fifo->dataslot = 0;
|
||
|
fifo->emptyslot = 0;
|
||
|
fifo->len = 0;
|
||
|
}
|
||
|
|
||
|
if ( fifo->emptyslot == FIFOSIZE )
|
||
|
{
|
||
|
fifo->emptyslot = 0;
|
||
|
DEBUGF( SIO_FIFO_DEBUG, ("(WRAP) ") );
|
||
|
|
||
|
sys_sem_signal( fifo->sem ); // leave critical
|
||
|
fifoPut( fifo, fd );
|
||
|
return;
|
||
|
}
|
||
|
if ( fifo->getWaiting )
|
||
|
{
|
||
|
fifo->getWaiting = FALSE;
|
||
|
sys_sem_signal( fifo->getSem );
|
||
|
}
|
||
|
|
||
|
sys_sem_signal( fifo->sem ); // leave critical
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
void fifoInit(fifo_t * fifo)
|
||
|
{
|
||
|
fifo->dataslot = 0;
|
||
|
fifo->emptyslot = 0;
|
||
|
fifo->len = 0;
|
||
|
fifo->sem = sys_sem_new(1); // critical section 1=free to enter
|
||
|
fifo->getSem = sys_sem_new(0); // 0 = no one waiting
|
||
|
fifo->getWaiting = FALSE;
|
||
|
}
|