2025-05-21 11:31:07 +08:00

373 lines
11 KiB
C

/******************************************************************************
Copyright @2024 - 2044 Shenzhen dcenzix Technology Ltd.
******************************************************************************
@file cola_fifo.c
@brief
@author xiexiongwu
@version V1.0
@date 2024年5月29日
******************************************************************************/
/*----------------------------------------------*
* 包含头文件 *
*----------------------------------------------*/
#include "cola_fifo.h"
/*----------------------------------------------*
* 宏定义 *
*----------------------------------------------*/
/*----------------------------------------------*
* 枚举定义 *
*----------------------------------------------*/
/*----------------------------------------------*
* 结构体定义 *
*----------------------------------------------*/
/*----------------------------------------------*
* 全局变量 *
*----------------------------------------------*/
/*----------------------------------------------*
* 常量定义 *
*----------------------------------------------*/
/*----------------------------------------------*
* 函数原型说明 *
*----------------------------------------------*/
/**
*@brief 判断当前是否需要升级
*
*@param void
*@return uint8_t 1:需要升级
* 0:不需要升级
*
*/
static __inline uint32_t fifo_length(cola_fifo_t *p_fifo)
{
return (p_fifo->buf_size - p_fifo->read_pos + p_fifo->write_pos) % p_fifo->buf_size;
}
#define FIFO_LENGTH() fifo_length(p_fifo) /**< Macro for calculating the FIFO length. */
/**@brief Put one byte to the FIFO. */
static __inline void fifo_put(cola_fifo_t *p_fifo, uint8_t byte)
{
p_fifo->p_buf[p_fifo->write_pos] = byte;
p_fifo->write_pos = (p_fifo->write_pos + 1) % p_fifo->buf_size;
}
/**@brief Look at one byte in the FIFO. */
static __inline void fifo_peek(cola_fifo_t *p_fifo, uint16_t index, uint8_t *p_byte)
{
*p_byte = p_fifo->p_buf[(p_fifo->read_pos + index) % p_fifo->buf_size];
}
/**@brief Get one byte from the FIFO. */
static __inline void fifo_get(cola_fifo_t *p_fifo, uint8_t *p_byte)
{
fifo_peek(p_fifo, 0, p_byte);
p_fifo->read_pos = (p_fifo->read_pos + 1) % p_fifo->buf_size;
}
/**@brief Function for initializing the FIFO.
*
* @param[out] p_fifo FIFO object.
* @param[in] p_buf FIFO buffer for storing data. The buffer size must be a power of two.
* @param[in] buf_size Size of the FIFO buffer provided. This size must be a power of two.
*
* @return true If initialization was successful.
* @return false If a NULL pointer is provided as buffer.
* @return false If size of buffer provided is not a power of two.
*/
bool cola_fifo_init(cola_fifo_t *p_fifo, uint8_t *p_buf, uint16_t buf_size)
{
// Check buffer for null pointer.
if (p_buf == NULL)
{
return false;
}
p_fifo->p_buf = p_buf;
p_fifo->buf_size = buf_size;
p_fifo->read_pos = 0;
p_fifo->write_pos = 0;
return true;
}
/**@brief Function for adding an element to the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO.
* @param[in] byte Data byte to add to the FIFO.
*
* @return true If an element has been successfully added to the FIFO.
* @return false If the FIFO is full.
*/
bool cola_fifo_put(cola_fifo_t *p_fifo, uint8_t byte)
{
if (FIFO_LENGTH() < p_fifo->buf_size)
{
fifo_put(p_fifo, byte);
return true;
}
return false;
}
/**@brief Function for getting the next element from the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO.
* @param[out] p_byte Byte fetched from the FIFO.
*
* @return true If an element was returned.
* @return false If there are no more elements in the queue.
*/
bool cola_fifo_get(cola_fifo_t *p_fifo, uint8_t *p_byte)
{
if (FIFO_LENGTH() != 0)
{
fifo_get(p_fifo, p_byte);
return 1;
}
return 0;
}
bool __inline cola_fifo_is_full(cola_fifo_t *p_fifo)
{
if (!p_fifo)
{
return false;
}
return (((p_fifo->write_pos + 1) % p_fifo->buf_size) == p_fifo->read_pos) ? true : false;
}
bool __inline cola_fifo_is_empty(cola_fifo_t *p_fifo)
{
if (!p_fifo)
{
return false;
}
return (p_fifo->write_pos == p_fifo->read_pos) ? true : false;
}
/**@brief Function for looking at an element in the FIFO, without consuming it.
*
* @param[in] p_fifo Pointer to the FIFO.
* @param[out] p_byte_array Byte fetched from the FIFO.
* @param[in] p_size Bytes size fetched from the FIFO.
* @param[in] p_offset Bytes offset from start point.
*
* @return true If an element was returned.
* @return false If there are no more elements in the queue, or the index was
* too large.
*/
bool cola_fifo_peek(cola_fifo_t *p_fifo, uint8_t *p_byte_array, uint32_t p_size, uint32_t p_offset)
{
if (!p_fifo || (0 == p_size) || !p_byte_array)
{
return false;
}
const uint32_t byte_count = fifo_length(p_fifo);
// Check if the FIFO is empty.
if (0 == byte_count)
{
return false;
}
if (p_size + p_offset > byte_count)
{
return false;
}
uint32_t index = 0;
// Fetch bytes from the FIFO.
while (index < p_size)
{
fifo_peek(p_fifo, index + p_offset, &p_byte_array[index]);
index++;
}
return true;
}
/**@brief Function for flushing the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO.
*
* @return none
*/
void cola_fifo_flush(cola_fifo_t *p_fifo)
{
if (!p_fifo)
{
return;
}
uint32_t usLen = cola_fifo_length(p_fifo);
if (usLen > 0)
{
cola_fifo_remove(p_fifo, usLen);
}
}
/**@brief Function for remove bytes from the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO.
* @param[in] p_offset bytes removed from the FIFO.
*
* @return none
*/
void cola_fifo_remove(cola_fifo_t *p_fifo, uint32_t p_offset)
{
if (!p_fifo)
{
return;
}
const uint32_t byte_count = fifo_length(p_fifo);
// Check if the FIFO is empty.
if (0 == byte_count)
{
return;
}
if (p_offset > byte_count)
{
return;
}
p_fifo->read_pos = (p_fifo->read_pos + p_offset) % p_fifo->buf_size;
}
/**@brief Function for reading bytes from the FIFO.
*
* This function can also be used to get the number of bytes in the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
* @param[out] p_byte_array Memory pointer where the read bytes are fetched from the FIFO.
* Can be NULL. If NULL, the number of bytes that can be read in the FIFO
* are returned in the p_size parameter.
* @param[in] p_size Address to memory indicating the maximum number of bytes to be read.
* The provided memory is overwritten with the actual number of bytes
* read if the procedure was successful. This field must not be NULL.
* If p_byte_array is set to NULL by the application, this parameter
* returns the number of bytes in the FIFO.
*
* @return true If the procedure is successful. The actual number of bytes read might
* be less than the requested maximum, depending on how many elements exist
* in the FIFO. Even if less bytes are returned, the procedure is considered
* successful.
* @return false If a NULL parameter was passed for a parameter that must not
* be NULL.
* @return false If the FIFO is empty.
*/
bool cola_fifo_read(cola_fifo_t *p_fifo, uint8_t *p_byte_array, uint32_t p_size)
{
if (!p_fifo || (0 == p_size) || !p_byte_array)
{
return false;
}
if (cola_fifo_is_empty(p_fifo))
{
return false;
}
uint32_t index = 0;
// Fetch bytes from the FIFO.
while (index < p_size)
{
fifo_get(p_fifo, &p_byte_array[index++]);
}
return true;
}
/**@brief Function for writing bytes to the FIFO.
*
* This function can also be used to get the available size on the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
* @param[in] p_byte_array Memory pointer containing the bytes to be written to the FIFO.
* Can be NULL. If NULL, this function returns the number of bytes
* that can be written to the FIFO.
* @param[in] p_size Address to memory indicating the maximum number of bytes to be written.
* The provided memory is overwritten with the number of bytes that were actually
* written if the procedure is successful. This field must not be NULL.
* If p_byte_array is set to NULL by the application, this parameter
* returns the number of bytes available in the FIFO.
*
* @return true If the procedure is successful. The actual number of bytes written might
* be less than the requested maximum, depending on how much room there is in
* the FIFO. Even if less bytes are written, the procedure is considered
* successful. If the write was partial, the application should use
* subsequent calls to attempt writing the data again.
* @return false If a NULL parameter was passed for a parameter that must not
* be NULL.
* @return false If the FIFO is full.
*
*/
bool cola_fifo_write(cola_fifo_t *p_fifo, const uint8_t *p_byte_array, uint32_t p_size)
{
//VERIFY_PARAM_NOT_NULL(p_fifo);
//VERIFY_PARAM_NOT_NULL(p_size);
if (!p_fifo || (0 == p_size) || !p_byte_array)
{
return false;
}
if (cola_fifo_is_full(p_fifo))
{
return false;
}
uint32_t index = 0;
//Fetch bytes from the FIFO.
while (index < p_size)
{
fifo_put(p_fifo, p_byte_array[index++]);
}
return true;
}
/**@brief Function for the length of the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO.
*
* @return the length of the FIFO
*/
uint32_t cola_fifo_length(cola_fifo_t *p_fifo)
{
return fifo_length(p_fifo);
}