169 lines
3.4 KiB
C
169 lines
3.4 KiB
C
|
|
#include "fifo.h"
|
|||
|
|
|
|||
|
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|||
|
|
|
|||
|
|
|
|||
|
|
fifo_error_t fifo_create( fifo_t *fifo , uint8_t *buffer, uint32_t size )
|
|||
|
|
{
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
if( (fifo == 0) || (buffer == 0) || (size == 0) )
|
|||
|
|
{
|
|||
|
|
return FIFO_ERROR_NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2^n) */
|
|||
|
|
if( size & (size - 1) )
|
|||
|
|
{
|
|||
|
|
return FIFO_ERROR_LENGTH;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Ĭ<><C4AC> */
|
|||
|
|
fifo->size = size;
|
|||
|
|
fifo->buffer = buffer;
|
|||
|
|
fifo->in = 0;
|
|||
|
|
fifo->out = 0;
|
|||
|
|
|
|||
|
|
return FIFO_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fifo_error_t fifo_clear( fifo_t *fifo )
|
|||
|
|
{
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
if( fifo == 0 )
|
|||
|
|
{
|
|||
|
|
return FIFO_ERROR_NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fifo->in = 0;
|
|||
|
|
fifo->out = 0;
|
|||
|
|
|
|||
|
|
return FIFO_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
fifo_error_t fifo_write( fifo_t *fifo, uint8_t *buffer, uint32_t length )
|
|||
|
|
{
|
|||
|
|
uint32_t i, j;
|
|||
|
|
uint32_t end_length, org_length;
|
|||
|
|
uint8_t *fifo_buffer;
|
|||
|
|
|
|||
|
|
/* <20><>¼ԭʼ<D4AD>û<EFBFBD>д<EFBFBD>볤<EFBFBD><EBB3A4> */
|
|||
|
|
org_length = length;
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>FIFOʣ<4F><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
length = MIN( length, fifo->size - fifo->in + fifo->out );
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>FIFO<46><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĩβ<C4A9>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㹻λ<E3B9BB><CEBB> */
|
|||
|
|
end_length = MIN( length, fifo->size - ( fifo->in & ( fifo->size - 1 ) ) );
|
|||
|
|
|
|||
|
|
/* <20>ҵ<EFBFBD>FIFO<46><4F>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ */
|
|||
|
|
fifo_buffer = fifo->buffer + ( fifo->in & ( fifo->size - 1 ) );
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>FIFOĩβ<C4A9><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>ݸ<EFBFBD><DDB8>Ƶ<EFBFBD>FIFO<46><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĩβ */
|
|||
|
|
for( i = 0; i < end_length; i++ )
|
|||
|
|
{
|
|||
|
|
*( fifo_buffer++ ) = *( buffer++ );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
j = length - end_length;
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>࣬<EFBFBD><E0A3AC><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>FIFO<46><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>*/
|
|||
|
|
if ( j > 0 )
|
|||
|
|
{
|
|||
|
|
fifo_buffer = fifo->buffer;
|
|||
|
|
|
|||
|
|
for( i = 0; i < j; i++ )
|
|||
|
|
{
|
|||
|
|
*( fifo_buffer++ ) = *( buffer++ );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><>¼<EFBFBD>ѽ<EFBFBD><D1BD><EFBFBD>FIFO<46>ij<EFBFBD><C4B3><EFBFBD> */
|
|||
|
|
fifo->in += length;
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>FIFO<46><4F><EFBFBD>ݵij<DDB5><C4B3><EFBFBD>С<EFBFBD><D0A1><EFBFBD>û<EFBFBD>ʵ<EFBFBD><CAB5>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ݵij<DDB5><C4B3>ȣ<EFBFBD><C8A3>Ǿ<EFBFBD><C7BE><EFBFBD>FIFO<46><4F><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
if( length < org_length )
|
|||
|
|
{
|
|||
|
|
return FIFO_ERROR_FULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return FIFO_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fifo_error_t fifo_read( fifo_t *fifo, uint8_t *buffer, uint32_t length )
|
|||
|
|
{
|
|||
|
|
uint32_t i, j;
|
|||
|
|
uint32_t end_length, org_length;
|
|||
|
|
uint8_t *fifo_buffer;
|
|||
|
|
|
|||
|
|
/* <20><>¼ԭʼ<D4AD>û<EFBFBD><C3BB><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> */
|
|||
|
|
org_length = length;
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>FIFO<46><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> */
|
|||
|
|
length = MIN( length, fifo->in - fifo->out );
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>FIFOĩβ<C4A9><CEB2><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD> */
|
|||
|
|
end_length = MIN( length, fifo->size - ( fifo->out & ( fifo->size - 1 ) ) );
|
|||
|
|
|
|||
|
|
/* <20>ҵ<EFBFBD>FIFOĩβ<C4A9><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ */
|
|||
|
|
fifo_buffer = fifo->buffer + ( fifo->out & ( fifo->size - 1 ) );
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>FIFOĩβ<C4A9><CEB2><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>FIFO<46>ڸ<EFBFBD><DAB8>Ƹ<EFBFBD><C6B8>û<EFBFBD><C3BB><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD> */
|
|||
|
|
for( i = 0; i < end_length; i++ )
|
|||
|
|
{
|
|||
|
|
*( buffer++ ) = *( fifo_buffer++ );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
j = length - end_length;
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>࣬<EFBFBD><E0A3AC><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>FIFO<46><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>*/
|
|||
|
|
if ( j > 0 )
|
|||
|
|
{
|
|||
|
|
fifo_buffer = fifo->buffer;
|
|||
|
|
|
|||
|
|
for( i = 0; i < j; i++ )
|
|||
|
|
{
|
|||
|
|
*( buffer++ ) = *( fifo_buffer++ ) ;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><>¼<EFBFBD>ѳ<EFBFBD><D1B3>ӵij<D3B5><C4B3><EFBFBD> */
|
|||
|
|
fifo->out += length;
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>FIFO<46><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>С<EFBFBD><D0A1><EFBFBD>û<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ݵij<DDB5><C4B3>ȣ<EFBFBD><C8A3>Ǿ<EFBFBD><C7BE><EFBFBD>FIFO<46><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
if( length < org_length )
|
|||
|
|
{
|
|||
|
|
return FIFO_ERROR_EMPTY;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return FIFO_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fifo_error_t fifo_get_length( fifo_t *fifo , uint32_t *length)
|
|||
|
|
{
|
|||
|
|
if( (fifo==0) || (length==0) )
|
|||
|
|
{
|
|||
|
|
return FIFO_ERROR_NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
*length = fifo->in - fifo->out;
|
|||
|
|
|
|||
|
|
return FIFO_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fifo_error_t fifo_get_remain_length( fifo_t *fifo , uint32_t *length)
|
|||
|
|
{
|
|||
|
|
if( (fifo==0) || (length==0) )
|
|||
|
|
{
|
|||
|
|
return FIFO_ERROR_NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
*length = fifo->size - ( fifo->in - fifo->out );
|
|||
|
|
|
|||
|
|
return FIFO_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|