189 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			189 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_ */
 |