1*0561b2d8STREFOU Felix /**
2*0561b2d8STREFOU Felix ******************************************************************************
3*0561b2d8STREFOU Felix * @file stm_queue.c
4*0561b2d8STREFOU Felix * @author MCD Application Team
5*0561b2d8STREFOU Felix * @brief Queue management
6*0561b2d8STREFOU Felix ******************************************************************************
7*0561b2d8STREFOU Felix * @attention
8*0561b2d8STREFOU Felix *
9*0561b2d8STREFOU Felix * <h2><center>© Copyright (c) 2019 STMicroelectronics.
10*0561b2d8STREFOU Felix * All rights reserved.</center></h2>
11*0561b2d8STREFOU Felix *
12*0561b2d8STREFOU Felix * This software component is licensed by ST under BSD 3-Clause license,
13*0561b2d8STREFOU Felix * the "License"; You may not use this file except in compliance with the
14*0561b2d8STREFOU Felix * License. You may obtain a copy of the License at:
15*0561b2d8STREFOU Felix * opensource.org/licenses/BSD-3-Clause
16*0561b2d8STREFOU Felix *
17*0561b2d8STREFOU Felix ******************************************************************************
18*0561b2d8STREFOU Felix */
19*0561b2d8STREFOU Felix
20*0561b2d8STREFOU Felix /* Includes ------------------------------------------------------------------*/
21*0561b2d8STREFOU Felix
22*0561b2d8STREFOU Felix /* Includes ------------------------------------------------------------------*/
23*0561b2d8STREFOU Felix #include "utilities_common.h"
24*0561b2d8STREFOU Felix
25*0561b2d8STREFOU Felix #include "stm_queue.h"
26*0561b2d8STREFOU Felix
27*0561b2d8STREFOU Felix /* Private define ------------------------------------------------------------*/
28*0561b2d8STREFOU Felix /* Private typedef -------------------------------------------------------------*/
29*0561b2d8STREFOU Felix /* Private macro -------------------------------------------------------------*/
30*0561b2d8STREFOU Felix #define MOD(X,Y) (((X) >= (Y)) ? ((X)-(Y)) : (X))
31*0561b2d8STREFOU Felix
32*0561b2d8STREFOU Felix /* Private variables ---------------------------------------------------------*/
33*0561b2d8STREFOU Felix /* Global variables ----------------------------------------------------------*/
34*0561b2d8STREFOU Felix /* Extern variables ----------------------------------------------------------*/
35*0561b2d8STREFOU Felix /* Private function prototypes -----------------------------------------------*/
36*0561b2d8STREFOU Felix /* Private functions ---------------------------------------------------------*/
37*0561b2d8STREFOU Felix /* Public functions ----------------------------------------------------------*/
38*0561b2d8STREFOU Felix
39*0561b2d8STREFOU Felix /**
40*0561b2d8STREFOU Felix * @brief Initilaiilze queue strcuture .
41*0561b2d8STREFOU Felix * @note This function is used to initialize the global queue strcuture.
42*0561b2d8STREFOU Felix * @param q: pointer on queue strcture to be initialised
43*0561b2d8STREFOU Felix * @param queueBuffer: pointer on Queue Buffer
44*0561b2d8STREFOU Felix * @param queueSize: Size of Queue Buffer
45*0561b2d8STREFOU Felix * @param elementSize: Size of an element in the queue. if =0, the queue will manage variable sizze elements
46*0561b2d8STREFOU Felix * @retval always 0
47*0561b2d8STREFOU Felix */
CircularQueue_Init(queue_t * q,uint8_t * queueBuffer,uint32_t queueSize,uint16_t elementSize,uint8_t optionFlags)48*0561b2d8STREFOU Felix int CircularQueue_Init(queue_t *q, uint8_t* queueBuffer, uint32_t queueSize, uint16_t elementSize, uint8_t optionFlags)
49*0561b2d8STREFOU Felix {
50*0561b2d8STREFOU Felix q->qBuff = queueBuffer;
51*0561b2d8STREFOU Felix q->first = 0;
52*0561b2d8STREFOU Felix q->last = 0; /* queueSize-1; */
53*0561b2d8STREFOU Felix q->byteCount = 0;
54*0561b2d8STREFOU Felix q->elementCount = 0;
55*0561b2d8STREFOU Felix q->queueMaxSize = queueSize;
56*0561b2d8STREFOU Felix q->elementSize = elementSize;
57*0561b2d8STREFOU Felix q->optionFlags = optionFlags;
58*0561b2d8STREFOU Felix
59*0561b2d8STREFOU Felix if ((optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG) && q-> elementSize)
60*0561b2d8STREFOU Felix {
61*0561b2d8STREFOU Felix /* can not deal with splitting at the end of buffer with fixed size element */
62*0561b2d8STREFOU Felix return -1;
63*0561b2d8STREFOU Felix }
64*0561b2d8STREFOU Felix return 0;
65*0561b2d8STREFOU Felix }
66*0561b2d8STREFOU Felix
67*0561b2d8STREFOU Felix /**
68*0561b2d8STREFOU Felix * @brief Add element to the queue .
69*0561b2d8STREFOU Felix * @note This function is used to add one or more element(s) to the Circular Queue .
70*0561b2d8STREFOU Felix * @param q: pointer on queue structure to be handled
71*0561b2d8STREFOU Felix * @param X; pointer on element(s) to be added
72*0561b2d8STREFOU Felix * @param elementSize: Size of element to be added to the queue. Only used if the queue manage variable size elements
73*0561b2d8STREFOU Felix * @param nbElements: number of elements in the in buffer pointed by x
74*0561b2d8STREFOU Felix * @retval pointer on last element just added to the queue, NULL if the element to be added do not fit in the queue (too big)
75*0561b2d8STREFOU Felix */
CircularQueue_Add(queue_t * q,uint8_t * x,uint16_t elementSize,uint32_t nbElements)76*0561b2d8STREFOU Felix uint8_t* CircularQueue_Add(queue_t *q, uint8_t* x, uint16_t elementSize, uint32_t nbElements)
77*0561b2d8STREFOU Felix {
78*0561b2d8STREFOU Felix
79*0561b2d8STREFOU Felix uint8_t* ptr = NULL; /* fct return ptr to the element freshly added, if no room fct return NULL */
80*0561b2d8STREFOU Felix uint16_t curElementSize = 0; /* the size of the element currently stored at q->last position */
81*0561b2d8STREFOU Felix uint8_t elemSizeStorageRoom = 0 ; /* Indicate the header (which contain only size) of element in case of varaibale size elemenet (q->elementsize == 0) */
82*0561b2d8STREFOU Felix uint32_t curBuffPosition; /* the current position in the queue buffer */
83*0561b2d8STREFOU Felix uint32_t i; /* loop counter */
84*0561b2d8STREFOU Felix uint32_t NbBytesToCopy = 0, NbCopiedBytes = 0 ; /* Indicators for copying bytes in queue */
85*0561b2d8STREFOU Felix uint32_t eob_free_size; /* Eof End of Quque Buffer Free Size */
86*0561b2d8STREFOU Felix uint8_t wrap_will_occur = 0; /* indicate if a wrap around will occurs */
87*0561b2d8STREFOU Felix uint8_t wrapped_element_eob_size; /* In case of Wrap around, indicat size of parta of elemenet that fit at thened of the queuue buffer */
88*0561b2d8STREFOU Felix uint16_t overhead = 0; /* In case of CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG or CIRCULAR_QUEUE_NO_WRAP_FLAG options,
89*0561b2d8STREFOU Felix indcate the size overhead that will be generated by adding the element with wrap management (split or no wrap ) */
90*0561b2d8STREFOU Felix
91*0561b2d8STREFOU Felix
92*0561b2d8STREFOU Felix elemSizeStorageRoom = (q->elementSize == 0) ? 2 : 0;
93*0561b2d8STREFOU Felix /* retrieve the size of last element sored: the value stored at the beginning of the queue element if element size is variable otherwise take it from fixed element Size member */
94*0561b2d8STREFOU Felix if (q->byteCount)
95*0561b2d8STREFOU Felix {
96*0561b2d8STREFOU Felix curElementSize = (q->elementSize == 0) ? q->qBuff[q->last] + ((q->qBuff[MOD((q->last+1), q->queueMaxSize)])<<8) + 2 : q->elementSize;
97*0561b2d8STREFOU Felix }
98*0561b2d8STREFOU Felix /* if queue element have fixed size , reset the elementSize arg with fixed element size value */
99*0561b2d8STREFOU Felix if (q->elementSize > 0)
100*0561b2d8STREFOU Felix {
101*0561b2d8STREFOU Felix elementSize = q->elementSize;
102*0561b2d8STREFOU Felix }
103*0561b2d8STREFOU Felix
104*0561b2d8STREFOU Felix eob_free_size = (q->last >= q->first) ? q->queueMaxSize - (q->last + curElementSize) : 0;
105*0561b2d8STREFOU Felix
106*0561b2d8STREFOU Felix /* check how many bytes of wrapped element (if anay) are at end of buffer */
107*0561b2d8STREFOU Felix wrapped_element_eob_size = (((elementSize + elemSizeStorageRoom )*nbElements) < eob_free_size) ? 0 : (eob_free_size % (elementSize + elemSizeStorageRoom));
108*0561b2d8STREFOU Felix wrap_will_occur = wrapped_element_eob_size > elemSizeStorageRoom;
109*0561b2d8STREFOU Felix
110*0561b2d8STREFOU Felix overhead = (wrap_will_occur && (q->optionFlags & CIRCULAR_QUEUE_NO_WRAP_FLAG)) ? wrapped_element_eob_size : overhead;
111*0561b2d8STREFOU Felix overhead = (wrap_will_occur && (q->optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG)) ? elemSizeStorageRoom : overhead;
112*0561b2d8STREFOU Felix
113*0561b2d8STREFOU Felix
114*0561b2d8STREFOU Felix /* Store now the elements if ennough room for all elements */
115*0561b2d8STREFOU Felix if (elementSize && ((q->byteCount + ((elementSize + elemSizeStorageRoom )*nbElements) + overhead) <= q->queueMaxSize))
116*0561b2d8STREFOU Felix {
117*0561b2d8STREFOU Felix /* loop to add all elements */
118*0561b2d8STREFOU Felix for (i=0; i < nbElements; i++)
119*0561b2d8STREFOU Felix {
120*0561b2d8STREFOU Felix q->last = MOD ((q->last + curElementSize),q->queueMaxSize);
121*0561b2d8STREFOU Felix curBuffPosition = q->last;
122*0561b2d8STREFOU Felix
123*0561b2d8STREFOU Felix /* store the element */
124*0561b2d8STREFOU Felix /* store fisrt the element size if element size is varaible */
125*0561b2d8STREFOU Felix if (q->elementSize == 0)
126*0561b2d8STREFOU Felix {
127*0561b2d8STREFOU Felix q->qBuff[curBuffPosition++]= elementSize & 0xFF;
128*0561b2d8STREFOU Felix curBuffPosition = MOD(curBuffPosition, q->queueMaxSize);
129*0561b2d8STREFOU Felix q->qBuff[curBuffPosition++]= (elementSize & 0xFF00) >> 8 ;
130*0561b2d8STREFOU Felix curBuffPosition = MOD(curBuffPosition, q->queueMaxSize);
131*0561b2d8STREFOU Felix q->byteCount += 2;
132*0561b2d8STREFOU Felix }
133*0561b2d8STREFOU Felix
134*0561b2d8STREFOU Felix /* Identify number of bytes of copy takeing account possible wrap, in this case NbBytesToCopy will contains size that fit at end of the queue buffer */
135*0561b2d8STREFOU Felix NbBytesToCopy = MIN((q->queueMaxSize-curBuffPosition),elementSize);
136*0561b2d8STREFOU Felix /* check if no wrap (NbBytesToCopy == elementSize) or if Wrap and no spsicf option;
137*0561b2d8STREFOU Felix In thi case part of data will copied at the end of the buffer and the rest a the beggining */
138*0561b2d8STREFOU Felix if ((NbBytesToCopy == elementSize) || ((NbBytesToCopy < elementSize) && (q->optionFlags == CIRCULAR_QUEUE_NO_FLAG)))
139*0561b2d8STREFOU Felix {
140*0561b2d8STREFOU Felix /* Copy First part (or emtire buffer ) from current position up to the end of the buffer queue (or before if enough room) */
141*0561b2d8STREFOU Felix memcpy(&q->qBuff[curBuffPosition],&x[i*elementSize],NbBytesToCopy);
142*0561b2d8STREFOU Felix /* Adjust bytes count */
143*0561b2d8STREFOU Felix q->byteCount += NbBytesToCopy;
144*0561b2d8STREFOU Felix /* Wrap */
145*0561b2d8STREFOU Felix curBuffPosition = 0;
146*0561b2d8STREFOU Felix /* set NbCopiedBytes bytes with ampount copied */
147*0561b2d8STREFOU Felix NbCopiedBytes = NbBytesToCopy;
148*0561b2d8STREFOU Felix /* set the rest to copy if wrao , if no wrap will be 0 */
149*0561b2d8STREFOU Felix NbBytesToCopy = elementSize - NbBytesToCopy;
150*0561b2d8STREFOU Felix /* set the current element Size, will be used to calaculate next last position at beggining of loop */
151*0561b2d8STREFOU Felix curElementSize = (elementSize) + elemSizeStorageRoom ;
152*0561b2d8STREFOU Felix }
153*0561b2d8STREFOU Felix else if (NbBytesToCopy) /* We have a wrap to manage */
154*0561b2d8STREFOU Felix {
155*0561b2d8STREFOU Felix /* case of CIRCULAR_QUEUE_NO_WRAP_FLAG option */
156*0561b2d8STREFOU Felix if (q->optionFlags & CIRCULAR_QUEUE_NO_WRAP_FLAG)
157*0561b2d8STREFOU Felix {
158*0561b2d8STREFOU Felix /* if element size are variable and NO_WRAP option, Invalidate end of buffer setting 0xFFFF size*/
159*0561b2d8STREFOU Felix if (q->elementSize == 0)
160*0561b2d8STREFOU Felix {
161*0561b2d8STREFOU Felix q->qBuff[curBuffPosition-2] = 0xFF;
162*0561b2d8STREFOU Felix q->qBuff[curBuffPosition-1] = 0xFF;
163*0561b2d8STREFOU Felix }
164*0561b2d8STREFOU Felix q->byteCount += NbBytesToCopy; /* invalid data at the end of buffer are take into account in byteCount */
165*0561b2d8STREFOU Felix /* No bytes coped a the end of buffer */
166*0561b2d8STREFOU Felix NbCopiedBytes = 0;
167*0561b2d8STREFOU Felix /* all element to be copied at the begnning of buffer */
168*0561b2d8STREFOU Felix NbBytesToCopy = elementSize;
169*0561b2d8STREFOU Felix /* Wrap */
170*0561b2d8STREFOU Felix curBuffPosition = 0;
171*0561b2d8STREFOU Felix /* if variable size element, invalidate end of buffer setting OxFFFF in element header (size) */
172*0561b2d8STREFOU Felix if (q->elementSize == 0)
173*0561b2d8STREFOU Felix {
174*0561b2d8STREFOU Felix q->qBuff[curBuffPosition++] = NbBytesToCopy & 0xFF;
175*0561b2d8STREFOU Felix q->qBuff[curBuffPosition++] = (NbBytesToCopy & 0xFF00) >> 8 ;
176*0561b2d8STREFOU Felix q->byteCount += 2;
177*0561b2d8STREFOU Felix }
178*0561b2d8STREFOU Felix
179*0561b2d8STREFOU Felix }
180*0561b2d8STREFOU Felix /* case of CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG option */
181*0561b2d8STREFOU Felix else if (q->optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG)
182*0561b2d8STREFOU Felix {
183*0561b2d8STREFOU Felix if (q->elementSize == 0)
184*0561b2d8STREFOU Felix {
185*0561b2d8STREFOU Felix /* reset the size of current element to the nb bytes fitting at the end of buffer */
186*0561b2d8STREFOU Felix q->qBuff[curBuffPosition-2] = NbBytesToCopy & 0xFF;
187*0561b2d8STREFOU Felix q->qBuff[curBuffPosition-1] = (NbBytesToCopy & 0xFF00) >> 8 ;
188*0561b2d8STREFOU Felix /* copy the bytes */
189*0561b2d8STREFOU Felix memcpy(&q->qBuff[curBuffPosition],&x[i*elementSize],NbBytesToCopy);
190*0561b2d8STREFOU Felix q->byteCount += NbBytesToCopy;
191*0561b2d8STREFOU Felix /* set the number of copied bytes */
192*0561b2d8STREFOU Felix NbCopiedBytes = NbBytesToCopy;
193*0561b2d8STREFOU Felix /* set rest of data to be copied to begnning of buffer */
194*0561b2d8STREFOU Felix NbBytesToCopy = elementSize - NbBytesToCopy;
195*0561b2d8STREFOU Felix /* one element more dur to split in 2 elements */
196*0561b2d8STREFOU Felix q->elementCount++;
197*0561b2d8STREFOU Felix /* Wrap */
198*0561b2d8STREFOU Felix curBuffPosition = 0;
199*0561b2d8STREFOU Felix /* Set new size for rest of data */
200*0561b2d8STREFOU Felix q->qBuff[curBuffPosition++] = NbBytesToCopy & 0xFF;
201*0561b2d8STREFOU Felix q->qBuff[curBuffPosition++] = (NbBytesToCopy & 0xFF00) >> 8 ;
202*0561b2d8STREFOU Felix q->byteCount += 2;
203*0561b2d8STREFOU Felix }
204*0561b2d8STREFOU Felix else
205*0561b2d8STREFOU Felix {
206*0561b2d8STREFOU Felix /* Should not occur */
207*0561b2d8STREFOU Felix /* can not manage split Flag on Fixed size element */
208*0561b2d8STREFOU Felix /* Buffer is corrupted */
209*0561b2d8STREFOU Felix return NULL;
210*0561b2d8STREFOU Felix }
211*0561b2d8STREFOU Felix }
212*0561b2d8STREFOU Felix curElementSize = (NbBytesToCopy) + elemSizeStorageRoom ;
213*0561b2d8STREFOU Felix q->last = 0;
214*0561b2d8STREFOU Felix }
215*0561b2d8STREFOU Felix
216*0561b2d8STREFOU Felix /* some remaning byte to copy */
217*0561b2d8STREFOU Felix if (NbBytesToCopy)
218*0561b2d8STREFOU Felix {
219*0561b2d8STREFOU Felix memcpy(&q->qBuff[curBuffPosition],&x[(i*elementSize)+NbCopiedBytes],NbBytesToCopy);
220*0561b2d8STREFOU Felix q->byteCount += NbBytesToCopy;
221*0561b2d8STREFOU Felix }
222*0561b2d8STREFOU Felix
223*0561b2d8STREFOU Felix /* One more element */
224*0561b2d8STREFOU Felix q->elementCount++;
225*0561b2d8STREFOU Felix }
226*0561b2d8STREFOU Felix
227*0561b2d8STREFOU Felix ptr = q->qBuff + (MOD((q->last+elemSizeStorageRoom ),q->queueMaxSize));
228*0561b2d8STREFOU Felix }
229*0561b2d8STREFOU Felix /* for Breakpoint only...to remove */
230*0561b2d8STREFOU Felix else
231*0561b2d8STREFOU Felix {
232*0561b2d8STREFOU Felix return NULL;
233*0561b2d8STREFOU Felix }
234*0561b2d8STREFOU Felix return ptr;
235*0561b2d8STREFOU Felix }
236*0561b2d8STREFOU Felix
237*0561b2d8STREFOU Felix
238*0561b2d8STREFOU Felix /**
239*0561b2d8STREFOU Felix * @brief Remove element from the queue and copy it in provided buffer
240*0561b2d8STREFOU Felix * @note This function is used to remove and element from the Circular Queue .
241*0561b2d8STREFOU Felix * @param q: pointer on queue structure to be handled
242*0561b2d8STREFOU Felix * @param elementSize: Pointer to return Size of element to be removed
243*0561b2d8STREFOU Felix * @param buffer: destination buffer where to copy element
244*0561b2d8STREFOU Felix * @retval Pointer on removed element. NULL if queue was empty
245*0561b2d8STREFOU Felix */
CircularQueue_Remove_Copy(queue_t * q,uint16_t * elementSize,uint8_t * buffer)246*0561b2d8STREFOU Felix uint8_t* CircularQueue_Remove_Copy(queue_t *q, uint16_t* elementSize, uint8_t* buffer)
247*0561b2d8STREFOU Felix {
248*0561b2d8STREFOU Felix return NULL;
249*0561b2d8STREFOU Felix }
250*0561b2d8STREFOU Felix
251*0561b2d8STREFOU Felix
252*0561b2d8STREFOU Felix
253*0561b2d8STREFOU Felix /**
254*0561b2d8STREFOU Felix * @brief Remove element from the queue.
255*0561b2d8STREFOU Felix * @note This function is used to remove and element from the Circular Queue .
256*0561b2d8STREFOU Felix * @param q: pointer on queue structure to be handled
257*0561b2d8STREFOU Felix * @param elementSize: Pointer to return Size of element to be removed
258*0561b2d8STREFOU Felix * @retval Pointer on removed element. NULL if queue was empty
259*0561b2d8STREFOU Felix */
CircularQueue_Remove(queue_t * q,uint16_t * elementSize)260*0561b2d8STREFOU Felix uint8_t* CircularQueue_Remove(queue_t *q, uint16_t* elementSize)
261*0561b2d8STREFOU Felix {
262*0561b2d8STREFOU Felix uint8_t elemSizeStorageRoom = 0;
263*0561b2d8STREFOU Felix uint8_t* ptr= NULL;
264*0561b2d8STREFOU Felix elemSizeStorageRoom = (q->elementSize == 0) ? 2 : 0;
265*0561b2d8STREFOU Felix *elementSize = 0;
266*0561b2d8STREFOU Felix if (q->byteCount > 0)
267*0561b2d8STREFOU Felix {
268*0561b2d8STREFOU Felix /* retreive element Size */
269*0561b2d8STREFOU Felix *elementSize = (q->elementSize == 0) ? q->qBuff[q->first] + ((q->qBuff[MOD((q->first+1), q->queueMaxSize)])<<8) : q->elementSize;
270*0561b2d8STREFOU Felix
271*0561b2d8STREFOU Felix if ((q->optionFlags & CIRCULAR_QUEUE_NO_WRAP_FLAG) && !(q->optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG))
272*0561b2d8STREFOU Felix {
273*0561b2d8STREFOU Felix if (((*elementSize == 0xFFFF) && q->elementSize == 0 ) ||
274*0561b2d8STREFOU Felix ((q->first > q->last) && q->elementSize && ((q->queueMaxSize - q->first) < q->elementSize)))
275*0561b2d8STREFOU Felix {
276*0561b2d8STREFOU Felix /* all data from current position up to the end of buffer are invalid */
277*0561b2d8STREFOU Felix q->byteCount -= (q->queueMaxSize - q->first);
278*0561b2d8STREFOU Felix /* Adjust first element pos */
279*0561b2d8STREFOU Felix q->first = 0;
280*0561b2d8STREFOU Felix /* retrieve the rigth size after the wrap [if varaible size element] */
281*0561b2d8STREFOU Felix *elementSize = (q->elementSize == 0) ? q->qBuff[q->first] + ((q->qBuff[MOD((q->first+1), q->queueMaxSize)])<<8) : q->elementSize;
282*0561b2d8STREFOU Felix }
283*0561b2d8STREFOU Felix }
284*0561b2d8STREFOU Felix
285*0561b2d8STREFOU Felix /* retreive element */
286*0561b2d8STREFOU Felix ptr = q->qBuff + (MOD((q->first + elemSizeStorageRoom), q->queueMaxSize));
287*0561b2d8STREFOU Felix
288*0561b2d8STREFOU Felix /* adjust byte count */
289*0561b2d8STREFOU Felix q->byteCount -= (*elementSize + elemSizeStorageRoom) ;
290*0561b2d8STREFOU Felix
291*0561b2d8STREFOU Felix /* Adjust q->first */
292*0561b2d8STREFOU Felix if (q->byteCount > 0)
293*0561b2d8STREFOU Felix {
294*0561b2d8STREFOU Felix q->first = MOD((q->first+ *elementSize + elemSizeStorageRoom ), q->queueMaxSize);
295*0561b2d8STREFOU Felix }
296*0561b2d8STREFOU Felix /* adjust element count */
297*0561b2d8STREFOU Felix --q->elementCount;
298*0561b2d8STREFOU Felix }
299*0561b2d8STREFOU Felix return ptr;
300*0561b2d8STREFOU Felix }
301*0561b2d8STREFOU Felix
302*0561b2d8STREFOU Felix
303*0561b2d8STREFOU Felix /**
304*0561b2d8STREFOU Felix * @brief "Sense" first element of the queue, without removing it and copy it in provided buffer
305*0561b2d8STREFOU Felix * @note This function is used to return a pointer on the first element of the queue without removing it.
306*0561b2d8STREFOU Felix * @param q: pointer on queue structure to be handled
307*0561b2d8STREFOU Felix * @param elementSize: Pointer to return Size of element to be removed
308*0561b2d8STREFOU Felix * @param buffer: destination buffer where to copy element
309*0561b2d8STREFOU Felix * @retval Pointer on sensed element. NULL if queue was empty
310*0561b2d8STREFOU Felix */
311*0561b2d8STREFOU Felix
CircularQueue_Sense_Copy(queue_t * q,uint16_t * elementSize,uint8_t * buffer)312*0561b2d8STREFOU Felix uint8_t* CircularQueue_Sense_Copy(queue_t *q, uint16_t* elementSize, uint8_t* buffer)
313*0561b2d8STREFOU Felix {
314*0561b2d8STREFOU Felix return NULL;
315*0561b2d8STREFOU Felix }
316*0561b2d8STREFOU Felix
317*0561b2d8STREFOU Felix
318*0561b2d8STREFOU Felix /**
319*0561b2d8STREFOU Felix * @brief "Sense" first element of the queue, without removing it.
320*0561b2d8STREFOU Felix * @note This function is used to return a pointer on the first element of the queue without removing it.
321*0561b2d8STREFOU Felix * @param q: pointer on queue structure to be handled
322*0561b2d8STREFOU Felix * @param elementSize: Pointer to return Size of element to be removed
323*0561b2d8STREFOU Felix * @retval Pointer on sensed element. NULL if queue was empty
324*0561b2d8STREFOU Felix */
CircularQueue_Sense(queue_t * q,uint16_t * elementSize)325*0561b2d8STREFOU Felix uint8_t* CircularQueue_Sense(queue_t *q, uint16_t* elementSize)
326*0561b2d8STREFOU Felix {
327*0561b2d8STREFOU Felix uint8_t elemSizeStorageRoom = 0;
328*0561b2d8STREFOU Felix uint8_t* x= NULL;
329*0561b2d8STREFOU Felix elemSizeStorageRoom = (q->elementSize == 0) ? 2 : 0;
330*0561b2d8STREFOU Felix *elementSize = 0;
331*0561b2d8STREFOU Felix uint32_t FirstElemetPos = 0;
332*0561b2d8STREFOU Felix
333*0561b2d8STREFOU Felix if (q->byteCount > 0)
334*0561b2d8STREFOU Felix {
335*0561b2d8STREFOU Felix FirstElemetPos = q->first;
336*0561b2d8STREFOU Felix *elementSize = (q->elementSize == 0) ? q->qBuff[q->first] + ((q->qBuff[MOD((q->first+1), q->queueMaxSize)])<<8) : q->elementSize;
337*0561b2d8STREFOU Felix
338*0561b2d8STREFOU Felix if ((q->optionFlags & CIRCULAR_QUEUE_NO_WRAP_FLAG) && !(q->optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG))
339*0561b2d8STREFOU Felix {
340*0561b2d8STREFOU Felix if (((*elementSize == 0xFFFF) && q->elementSize == 0 ) ||
341*0561b2d8STREFOU Felix ((q->first > q->last) && q->elementSize && ((q->queueMaxSize - q->first) < q->elementSize)))
342*0561b2d8STREFOU Felix
343*0561b2d8STREFOU Felix {
344*0561b2d8STREFOU Felix /* all data from current position up to the end of buffer are invalid */
345*0561b2d8STREFOU Felix FirstElemetPos = 0; /* wrap to the begiining of buffer */
346*0561b2d8STREFOU Felix
347*0561b2d8STREFOU Felix /* retrieve the rigth size after the wrap [if varaible size element] */
348*0561b2d8STREFOU Felix *elementSize = (q->elementSize == 0) ? q->qBuff[FirstElemetPos]+ ((q->qBuff[MOD((FirstElemetPos+1), q->queueMaxSize)])<<8) : q->elementSize;
349*0561b2d8STREFOU Felix }
350*0561b2d8STREFOU Felix }
351*0561b2d8STREFOU Felix /* retrieve element */
352*0561b2d8STREFOU Felix x = q->qBuff + (MOD((FirstElemetPos + elemSizeStorageRoom), q->queueMaxSize));
353*0561b2d8STREFOU Felix }
354*0561b2d8STREFOU Felix return x;
355*0561b2d8STREFOU Felix }
356*0561b2d8STREFOU Felix
357*0561b2d8STREFOU Felix /**
358*0561b2d8STREFOU Felix * @brief Check if queue is empty.
359*0561b2d8STREFOU Felix * @note This function is used to to check if the queue is empty.
360*0561b2d8STREFOU Felix * @param q: pointer on queue structure to be handled
361*0561b2d8STREFOU Felix * @retval TRUE (!0) if the queue is empyu otherwise FALSE (0)
362*0561b2d8STREFOU Felix */
CircularQueue_Empty(queue_t * q)363*0561b2d8STREFOU Felix int CircularQueue_Empty(queue_t *q)
364*0561b2d8STREFOU Felix {
365*0561b2d8STREFOU Felix int ret=FALSE;
366*0561b2d8STREFOU Felix if (q->byteCount <= 0)
367*0561b2d8STREFOU Felix {
368*0561b2d8STREFOU Felix ret=TRUE;
369*0561b2d8STREFOU Felix }
370*0561b2d8STREFOU Felix return ret;
371*0561b2d8STREFOU Felix }
372*0561b2d8STREFOU Felix
CircularQueue_NbElement(queue_t * q)373*0561b2d8STREFOU Felix int CircularQueue_NbElement(queue_t *q)
374*0561b2d8STREFOU Felix {
375*0561b2d8STREFOU Felix return q->elementCount;
376*0561b2d8STREFOU Felix }
377