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_ */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |