373 lines
11 KiB
C
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);
|
|
}
|
|
|
|
|