2024-05-13 08:14:17 +08:00

195 lines
5.5 KiB
C

/*
* 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 <stdint.h>
#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_ */