/* * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD * All rights reserved. * * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use * exclusively with CVA's microcontroller products. This file can be freely * distributed within development tools that are supporting such microcontroller * products. * * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. */ #ifndef _RINGBUFFER_H_ #define _RINGBUFFER_H_ /*! \brief Contains public interface to various functions related * to the ring buffer template */ /******************************************************************************* * the includes ******************************************************************************/ #include #ifdef __cplusplus extern "C" { #endif /******************************************************************************* * the defines ******************************************************************************/ /******************************************************************************* * the typedefs ******************************************************************************/ /*! \brief RingBuffer prototype definition */ typedef struct _RingBufferType_ { void *pBuffer; /*!< The actual buffer holder */ int32_t readIndex; /*!< The current index for the read */ int32_t writeIndex; /*!< The current index for the write */ int32_t usedNum; /*!< The number of used elements */ int32_t totalNum; /*!< The number of total elements */ } RingBufferType; /******************************************************************************* * the globals ******************************************************************************/ /******************************************************************************* * the function prototypes ******************************************************************************/ /*! \brief Initializes the ringbuffer instance * * This function initializes a ringbuffer instance * * \param[in] obj : pointer to RingBuffer instance * \param[in] pBuffer : the actual buffer holder * \param[in] size : the size of actual buffer holder */ static inline void RingBuffer_Init(RingBufferType *obj, void *pBuffer, uint32_t size) { obj->pBuffer = pBuffer; obj->readIndex = 0; obj->writeIndex = 0; obj->usedNum = 0; obj->totalNum = size; } /*! \brief Puts an element to the ringbuffer. * * This function puts an element to the ringbuffer. * * \param[in] obj : pointer to RingBuffer instance * \param[in] pElem : pointer to the element to push into the buffer * \param[in] size : the size of the element in bytes * \return the result of the put operation * true : success * false : failed because the buffer is full */ static inline bool RingBuffer_Put(RingBufferType *obj, const void *pElem, uint32_t size) { uint32_t i = 0; unsigned char *src; unsigned char *dest; /* Check if the buffer is full */ if(obj->usedNum >= obj->totalNum) { return false; } /* Copy the element */ src = (unsigned char *)pElem; dest = (unsigned char *)obj->pBuffer + (obj->writeIndex * size); for(i = 0; i < size; i++) { *dest++ = *src++; } /* Move the index */ obj->writeIndex++; if(obj->writeIndex >= obj->totalNum) { obj->writeIndex = 0; } obj->usedNum++; return true; } /*! \brief Gets an element from the ringbuffer. * * This function gets an element from the ringbuffer. * * \param[in] obj : pointer to RingBuffer instance * \param[in] pElem : pointer to the element to get from the buffer * \param[in] size : the size of the element in bytes * \return the result of the put operation * true : success * false : failed because the buffer is empty */ static inline bool RingBuffer_Get(RingBufferType *obj, void *pElem, uint32_t size) { uint32_t i = 0; unsigned char *src; unsigned char *dest; /* Check if the buffer is empty */ if(obj->usedNum <= 0) { return false; } /* Copy the element */ dest = (unsigned char *)pElem; src = (unsigned char *)obj->pBuffer + (obj->readIndex * size); for(i = 0; i < size; i++) { *dest++ = *src++; } /* Move the index */ obj->readIndex++; if(obj->readIndex >= obj->totalNum) { obj->readIndex = 0; } obj->usedNum--; return true; } /*! \brief See if the ringbuffer is full. * * This function gets if the ringbuffer is full * * \param[in] obj : pointer to RingBuffer instance * \return whether the buffer is full * true : the buffer is full * false : the buffer is not full */ static inline bool RingBuffer_IsFull(const RingBufferType *obj) { return (obj->usedNum >= obj->totalNum); } /*! \brief See if the ringbuffer is empty. * * This function gets if the ringbuffer is empty * * \param[in] obj : pointer to RingBuffer instance * \return whether the buffer is empty * true : the buffer is empty * false : the buffer is not empty */ static inline bool RingBuffer_IsEmpty(const RingBufferType *obj) { return (obj->usedNum <= 0); } #ifdef __cplusplus } #endif /* extern "C" */ #endif /* _RINGBUFFER_H_ */