195 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * @brief Common ring buffer support functions
 | |
|  *
 | |
|  * @note
 | |
|  * Copyright(C) NXP Semiconductors, 2012
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * @par
 | |
|  * Software that is described herein is for illustrative purposes only
 | |
|  * which provides customers with programming information regarding the
 | |
|  * LPC products.  This software is supplied "AS IS" without any warranties of
 | |
|  * any kind, and NXP Semiconductors and its licensor disclaim any and
 | |
|  * all warranties, express or implied, including all implied warranties of
 | |
|  * merchantability, fitness for a particular purpose and non-infringement of
 | |
|  * intellectual property rights.  NXP Semiconductors assumes no responsibility
 | |
|  * or liability for the use of the software, conveys no license or rights under any
 | |
|  * patent, copyright, mask work right, or any other intellectual property rights in
 | |
|  * or to any products. NXP Semiconductors reserves the right to make changes
 | |
|  * in the software without notification. NXP Semiconductors also makes no
 | |
|  * representation or warranty that such application will be suitable for the
 | |
|  * specified use without further testing or modification.
 | |
|  *
 | |
|  * @par
 | |
|  * Permission to use, copy, modify, and distribute this software and its
 | |
|  * documentation is hereby granted, under NXP Semiconductors' and its
 | |
|  * licensor's relevant copyrights in the software, without fee, provided that it
 | |
|  * is used in conjunction with NXP Semiconductors microcontrollers.  This
 | |
|  * copyright, permission, and disclaimer notice must appear in all copies of
 | |
|  * this code.
 | |
|  */
 | |
| 
 | |
| #ifndef __RING_BUFFER_H_
 | |
| #define __RING_BUFFER_H_
 | |
| 
 | |
| #include "lpc_types.h"
 | |
| 
 | |
| /** @defgroup Ring_Buffer CHIP: Simple ring buffer implementation
 | |
|  * @ingroup CHIP_Common
 | |
|  * @{
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * @brief Ring buffer structure
 | |
|  */
 | |
| typedef struct {
 | |
| 	void *data;
 | |
| 	int count;
 | |
| 	int itemSz;
 | |
| 	uint32_t head;
 | |
| 	uint32_t tail;
 | |
| } RINGBUFF_T;
 | |
| 
 | |
| /**
 | |
|  * @def		RB_VHEAD(rb)
 | |
|  * volatile typecasted head index
 | |
|  */
 | |
| #define RB_VHEAD(rb)              (*(volatile uint32_t *) &(rb)->head)
 | |
| 
 | |
| /**
 | |
|  * @def		RB_VTAIL(rb)
 | |
|  * volatile typecasted tail index
 | |
|  */
 | |
| #define RB_VTAIL(rb)              (*(volatile uint32_t *) &(rb)->tail)
 | |
| 
 | |
| /**
 | |
|  * @brief	Initialize ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer to initialize
 | |
|  * @param	buffer		: Pointer to buffer to associate with RingBuff
 | |
|  * @param	itemSize	: Size of each buffer item size
 | |
|  * @param	count		: Size of ring buffer
 | |
|  * @note	Memory pointed by @a buffer must have correct alignment of
 | |
|  * 			@a itemSize, and @a count must be a power of 2 and must at
 | |
|  * 			least be 2 or greater.
 | |
|  * @return	Nothing
 | |
|  */
 | |
| int RingBuffer_Init(RINGBUFF_T *RingBuff, void *buffer, int itemSize, int count);
 | |
| 
 | |
| /**
 | |
|  * @brief	Resets the ring buffer to empty
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @return	Nothing
 | |
|  */
 | |
| STATIC INLINE void RingBuffer_Flush(RINGBUFF_T *RingBuff)
 | |
| {
 | |
| 	RingBuff->head = RingBuff->tail = 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief	Return size the ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @return	Size of the ring buffer in bytes
 | |
|  */
 | |
| STATIC INLINE int RingBuffer_GetSize(RINGBUFF_T *RingBuff)
 | |
| {
 | |
| 	return RingBuff->count;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief	Return number of items in the ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @return	Number of items in the ring buffer
 | |
|  */
 | |
| STATIC INLINE int RingBuffer_GetCount(RINGBUFF_T *RingBuff)
 | |
| {
 | |
| 	return RB_VHEAD(RingBuff) - RB_VTAIL(RingBuff);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief	Return number of free items in the ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @return	Number of free items in the ring buffer
 | |
|  */
 | |
| STATIC INLINE int RingBuffer_GetFree(RINGBUFF_T *RingBuff)
 | |
| {
 | |
| 	return RingBuff->count - RingBuffer_GetCount(RingBuff);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief	Return number of items in the ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @return	1 if the ring buffer is full, otherwise 0
 | |
|  */
 | |
| STATIC INLINE int RingBuffer_IsFull(RINGBUFF_T *RingBuff)
 | |
| {
 | |
| 	return (RingBuffer_GetCount(RingBuff) >= RingBuff->count);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief	Return empty status of ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @return	1 if the ring buffer is empty, otherwise 0
 | |
|  */
 | |
| STATIC INLINE int RingBuffer_IsEmpty(RINGBUFF_T *RingBuff)
 | |
| {
 | |
| 	return RB_VHEAD(RingBuff) == RB_VTAIL(RingBuff);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief	Insert a single item into ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @param	data		: pointer to item
 | |
|  * @return	1 when successfully inserted,
 | |
|  *			0 on error (Buffer not initialized using
 | |
|  *			RingBuffer_Init() or attempted to insert
 | |
|  *			when buffer is full)
 | |
|  */
 | |
| int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data);
 | |
| 
 | |
| /**
 | |
|  * @brief	Insert an array of items into ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @param	data		: Pointer to first element of the item array
 | |
|  * @param	num			: Number of items in the array
 | |
|  * @return	number of items successfully inserted,
 | |
|  *			0 on error (Buffer not initialized using
 | |
|  *			RingBuffer_Init() or attempted to insert
 | |
|  *			when buffer is full)
 | |
|  */
 | |
| int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num);
 | |
| 
 | |
| /**
 | |
|  * @brief	Pop an item from the ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @param	data		: Pointer to memory where popped item be stored
 | |
|  * @return	1 when item popped successfuly onto @a data,
 | |
|  * 			0 When error (Buffer not initialized using
 | |
|  * 			RingBuffer_Init() or attempted to pop item when
 | |
|  * 			the buffer is empty)
 | |
|  */
 | |
| int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data);
 | |
| 
 | |
| /**
 | |
|  * @brief	Pop an array of items from the ring buffer
 | |
|  * @param	RingBuff	: Pointer to ring buffer
 | |
|  * @param	data		: Pointer to memory where popped items be stored
 | |
|  * @param	num			: Max number of items array @a data can hold
 | |
|  * @return	Number of items popped onto @a data,
 | |
|  * 			0 on error (Buffer not initialized using RingBuffer_Init()
 | |
|  * 			or attempted to pop when the buffer is empty)
 | |
|  */
 | |
| int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num);
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * @}
 | |
|  */
 | |
| 
 | |
| #endif /* __RING_BUFFER_H_ */
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | 
