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