1 /*
2  * @brief Common ring buffer support functions
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products.  This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #ifndef __RING_BUFFER_H_
33 #define __RING_BUFFER_H_
34 
35 #include "lpc_types.h"
36 
37 /** @defgroup Ring_Buffer CHIP: Simple ring buffer implementation
38  * @ingroup CHIP_Common
39  * @{
40  */
41 
42 /**
43  * @brief Ring buffer structure
44  */
45 typedef struct {
46 	void *data;
47 	int count;
48 	int itemSz;
49 	uint32_t head;
50 	uint32_t tail;
51 } RINGBUFF_T;
52 
53 /**
54  * @def		RB_VHEAD(rb)
55  * volatile typecasted head index
56  */
57 #define RB_VHEAD(rb)              (*(volatile uint32_t *) &(rb)->head)
58 
59 /**
60  * @def		RB_VTAIL(rb)
61  * volatile typecasted tail index
62  */
63 #define RB_VTAIL(rb)              (*(volatile uint32_t *) &(rb)->tail)
64 
65 /**
66  * @brief	Initialize ring buffer
67  * @param	RingBuff	: Pointer to ring buffer to initialize
68  * @param	buffer		: Pointer to buffer to associate with RingBuff
69  * @param	itemSize	: Size of each buffer item size
70  * @param	count		: Size of ring buffer
71  * @note	Memory pointed by @a buffer must have correct alignment of
72  * 			@a itemSize, and @a count must be a power of 2 and must at
73  * 			least be 2 or greater.
74  * @return	Nothing
75  */
76 int RingBuffer_Init(RINGBUFF_T *RingBuff, void *buffer, int itemSize, int count);
77 
78 /**
79  * @brief	Resets the ring buffer to empty
80  * @param	RingBuff	: Pointer to ring buffer
81  * @return	Nothing
82  */
RingBuffer_Flush(RINGBUFF_T * RingBuff)83 STATIC INLINE void RingBuffer_Flush(RINGBUFF_T *RingBuff)
84 {
85 	RingBuff->head = RingBuff->tail = 0;
86 }
87 
88 /**
89  * @brief	Return size the ring buffer
90  * @param	RingBuff	: Pointer to ring buffer
91  * @return	Size of the ring buffer in bytes
92  */
RingBuffer_GetSize(RINGBUFF_T * RingBuff)93 STATIC INLINE int RingBuffer_GetSize(RINGBUFF_T *RingBuff)
94 {
95 	return RingBuff->count;
96 }
97 
98 /**
99  * @brief	Return number of items in the ring buffer
100  * @param	RingBuff	: Pointer to ring buffer
101  * @return	Number of items in the ring buffer
102  */
RingBuffer_GetCount(RINGBUFF_T * RingBuff)103 STATIC INLINE int RingBuffer_GetCount(RINGBUFF_T *RingBuff)
104 {
105 	return RB_VHEAD(RingBuff) - RB_VTAIL(RingBuff);
106 }
107 
108 /**
109  * @brief	Return number of free items in the ring buffer
110  * @param	RingBuff	: Pointer to ring buffer
111  * @return	Number of free items in the ring buffer
112  */
RingBuffer_GetFree(RINGBUFF_T * RingBuff)113 STATIC INLINE int RingBuffer_GetFree(RINGBUFF_T *RingBuff)
114 {
115 	return RingBuff->count - RingBuffer_GetCount(RingBuff);
116 }
117 
118 /**
119  * @brief	Return number of items in the ring buffer
120  * @param	RingBuff	: Pointer to ring buffer
121  * @return	1 if the ring buffer is full, otherwise 0
122  */
RingBuffer_IsFull(RINGBUFF_T * RingBuff)123 STATIC INLINE int RingBuffer_IsFull(RINGBUFF_T *RingBuff)
124 {
125 	return (RingBuffer_GetCount(RingBuff) >= RingBuff->count);
126 }
127 
128 /**
129  * @brief	Return empty status of ring buffer
130  * @param	RingBuff	: Pointer to ring buffer
131  * @return	1 if the ring buffer is empty, otherwise 0
132  */
RingBuffer_IsEmpty(RINGBUFF_T * RingBuff)133 STATIC INLINE int RingBuffer_IsEmpty(RINGBUFF_T *RingBuff)
134 {
135 	return RB_VHEAD(RingBuff) == RB_VTAIL(RingBuff);
136 }
137 
138 /**
139  * @brief	Insert a single item into ring buffer
140  * @param	RingBuff	: Pointer to ring buffer
141  * @param	data		: pointer to item
142  * @return	1 when successfully inserted,
143  *			0 on error (Buffer not initialized using
144  *			RingBuffer_Init() or attempted to insert
145  *			when buffer is full)
146  */
147 int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data);
148 
149 /**
150  * @brief	Insert an array of items into ring buffer
151  * @param	RingBuff	: Pointer to ring buffer
152  * @param	data		: Pointer to first element of the item array
153  * @param	num			: Number of items in the array
154  * @return	number of items successfully inserted,
155  *			0 on error (Buffer not initialized using
156  *			RingBuffer_Init() or attempted to insert
157  *			when buffer is full)
158  */
159 int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num);
160 
161 /**
162  * @brief	Pop an item from the ring buffer
163  * @param	RingBuff	: Pointer to ring buffer
164  * @param	data		: Pointer to memory where popped item be stored
165  * @return	1 when item popped successfuly onto @a data,
166  * 			0 When error (Buffer not initialized using
167  * 			RingBuffer_Init() or attempted to pop item when
168  * 			the buffer is empty)
169  */
170 int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data);
171 
172 /**
173  * @brief	Pop an array of items from the ring buffer
174  * @param	RingBuff	: Pointer to ring buffer
175  * @param	data		: Pointer to memory where popped items be stored
176  * @param	num			: Max number of items array @a data can hold
177  * @return	Number of items popped onto @a data,
178  * 			0 on error (Buffer not initialized using RingBuffer_Init()
179  * 			or attempted to pop when the buffer is empty)
180  */
181 int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num);
182 
183 
184 /**
185  * @}
186  */
187 
188 #endif /* __RING_BUFFER_H_ */
189