Files
E32_433_dev/Core/Src/fifo.c
2026-04-10 20:26:51 +08:00

169 lines
3.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 )
{
/* 参数检查 */
if( (fifo == 0) || (buffer == 0) || (size == 0) )
{
return FIFO_ERROR_NULL;
}
/* 长度检查 (必须是2^n) */
if( size & (size - 1) )
{
return FIFO_ERROR_LENGTH;
}
/* 默认 */
fifo->size = size;
fifo->buffer = buffer;
fifo->in = 0;
fifo->out = 0;
return FIFO_OK;
}
fifo_error_t fifo_clear( fifo_t *fifo )
{
/* 参数检查 */
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;
/* 记录原始用户写入长度 */
org_length = length;
/* 计算FIFO剩余容量 */
length = MIN( length, fifo->size - fifo->in + fifo->out );
/* 计算FIFO缓存区末尾是否还有足够位置 */
end_length = MIN( length, fifo->size - ( fifo->in & ( fifo->size - 1 ) ) );
/* 找到FIFO可写入区域的起始地址 */
fifo_buffer = fifo->buffer + ( fifo->in & ( fifo->size - 1 ) );
/* 如果FIFO末尾有容量则将用户数据复制到FIFO缓存区末尾 */
for( i = 0; i < end_length; i++ )
{
*( fifo_buffer++ ) = *( buffer++ );
}
/* 计算用户数据是否已全部复制 */
j = length - end_length;
/* 如果用户数据有剩余则需要从FIFO缓存区头部开始复制*/
if ( j > 0 )
{
fifo_buffer = fifo->buffer;
for( i = 0; i < j; i++ )
{
*( fifo_buffer++ ) = *( buffer++ );
}
}
/* 记录已进入FIFO的长度 */
fifo->in += length;
/* 如果进入FIFO数据的长度小于用户实际写入数据的长度那就是FIFO满了装不下了 */
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;
/* 记录原始用户读取长度 */
org_length = length;
/* 计算FIFO已入队数据长度 */
length = MIN( length, fifo->in - fifo->out );
/* 计算FIFO末尾出队长度 */
end_length = MIN( length, fifo->size - ( fifo->out & ( fifo->size - 1 ) ) );
/* 找到FIFO末尾出队区域的起始地址 */
fifo_buffer = fifo->buffer + ( fifo->out & ( fifo->size - 1 ) );
/* 如果FIFO末尾有数据出队则从FIFO内复制给用户数据缓存 */
for( i = 0; i < end_length; i++ )
{
*( buffer++ ) = *( fifo_buffer++ );
}
/* 计算用户数据是否已全部复制 */
j = length - end_length;
/* 如果用户数据有剩余则需要从FIFO缓存区头部开始复制*/
if ( j > 0 )
{
fifo_buffer = fifo->buffer;
for( i = 0; i < j; i++ )
{
*( buffer++ ) = *( fifo_buffer++ ) ;
}
}
/* 记录已出队的长度 */
fifo->out += length;
/* 如果FIFO出队数据长度小于用户实际需要数据的长度那就是FIFO空了数量不够 */
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;
}