/****************************************************************************** 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); }