ISF  2.2 rev 5
Intelligent Sensing Framework for Kinetis with Processor Expert
isf_fifo.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2015, Freescale Semiconductor, Inc.
4  *
5 */
6 /*
7  * isf_fifo.c
8  *
9  * Created on: Oct 1, 2013,
10  * Author: B37804
11  */
12 
13 #include "isf.h"
14 #include "isf_fifo.h"
15 #include "isf_util.h"
16 
17 #define ALLOCATED_BUFFER_BIT ((uint8)(1<<0))
18 #define FIFO_FULL_BIT ((uint8)(1<<7))
19 #define FIFO_FULL_CLR_MASK ((uint8)~FIFO_FULL_BIT)
20 
21 /*!
22  * @brief Initializes a new fifo structure with a provided buffer.
23  */
24 isf_fifo_status_t isf_fifo_init ( isf_fifo_t *pFifo, void *pData, uint16 sampleSize, uint16 bufferCapacity )
25 {
27 
28  if (pFifo == NULL) return ISF_FIFO_ERR_INVALID_PTR;
29  st = OSA_SemaCreate(&pFifo->bufferLock, 0);
30  if (st != ISF_SUCCESS) return ISF_FIFO_ERR_NO_INIT;
31 
32  pFifo->fifoState = 0;
33 
34  if (pData == NULL)
35  {
37 
38  if ( bufferCapacity != 0 )
39  {
40  pData = OSA_MemAllocZero(bufferCapacity * sampleSize);
41  if (pData == NULL) {
43  }
44  }
45  // else leave pData null- they plan to allocate it later with fifo_resize
46  }
47 
48  if (pData)
49  {
50  pFifo->pDataBuffer = (uint8 *)pData;
51  pFifo->pInsertPtr = pFifo->pDataBuffer;
52  pFifo->pLastEntry = pFifo->pDataBuffer + ((bufferCapacity-1) * sampleSize);
53  pFifo->pInsertPtr = (uint8 *)pData;
54  }
55  else
56  {
57  pFifo->pDataBuffer = 0;
58  pFifo->pInsertPtr = 0;
59  pFifo->pLastEntry = 0;
60  pFifo->pInsertPtr = 0;
61  }
62 
63  pFifo->sampleSize = sampleSize;
64  OSA_SemaPost(&pFifo->bufferLock);
65  return st;
66 }
67 
68 /*!
69  * @brief Convenience function to initialize a fifo structure and allocate a new fifo buffer.
70  */
71 isf_fifo_status_t isf_fifo_alloc ( isf_fifo_t *pFifo, uint16 sampleSize, uint16 bufferCapacity )
72 {
73  return isf_fifo_init ( pFifo, NULL, sampleSize, bufferCapacity );
74 }
75 
76 /*!
77  * @brief free a fifo's sample buffer.
78  */
80 {
82  st = OSA_SemaWait(&pFifo->bufferLock, OSA_WAIT_FOREVER);
83  if (st != ISF_SUCCESS) return ISF_FIFO_ERR_NO_INIT;
84 
85  if (pFifo->fifoState & ALLOCATED_BUFFER_BIT && (pFifo->pDataBuffer != NULL)) {
86  OSA_MemFree(pFifo->pDataBuffer);
87  pFifo->pDataBuffer = NULL;
88  pFifo->pInsertPtr = NULL;
89  pFifo->pLastEntry = NULL;
90  }
91  OSA_SemaPost(&pFifo->bufferLock);
92  return ISF_SUCCESS;
93 }
94 
95 /*!
96  * @brief Routine to change the supported fifo depth
97  *
98  * Warning: When the fifo is resized all sample data in the buffer is lost.
99  * It is suggested to resize only when empty
100  */
102 {
104  uint16 newSizeInBytes = newCapacity * pFifo->sampleSize;
105  st = OSA_SemaWait(&pFifo->bufferLock, OSA_WAIT_FOREVER);
106  if ((st != ISF_SUCCESS) || (pFifo->sampleSize == 0)) return ISF_FIFO_ERR_NO_INIT;
107 
108  if (!(pFifo->fifoState & ALLOCATED_BUFFER_BIT) ) return ISF_FIFO_ERR_USER_BUF;
109 
110  //check to see if they are asking for the same size as it is now
111 
112  {
113  uint16 currentSize = isf_fifo_get_buffer_size(pFifo);
114  //IF they want the same size, don't do anything and tell them it worked
115  if ( currentSize == newSizeInBytes) return ISF_SUCCESS;
116  }
117 
118  // Need to reallocate the buffer- remember the old one so we can free it later
119  uint8 *old = pFifo->pDataBuffer;
120  pFifo->pDataBuffer = OSA_MemAllocZero(newSizeInBytes);
121 
122  if (NULL != old)
123  {
124  OSA_MemFree(old);
125  }
126  OSA_SemaPost(&pFifo->bufferLock);
127  return ISF_SUCCESS;
128 }
129 
130 /*!
131  * @brief Routine to query the current fifo buffer size (bytes)
132  */
134 {
135  uint16 capacity;
136 
137  if ((pFifo->pLastEntry == NULL) ||(pFifo->pDataBuffer == NULL) || (pFifo->sampleSize == 0))
138  {
139  capacity = 0;
140  }
141  else
142  {
143  capacity = (pFifo->pLastEntry - pFifo->pDataBuffer + pFifo->sampleSize);
144  }
145 
146  return capacity;
147 }
148 
149 
150 
151 /*!
152  * @brief Routine to copy the whole sample buffer
153  */
155 {
157  st = OSA_SemaWait(&pFifo->bufferLock, OSA_WAIT_FOREVER);
158  if (st != ISF_SUCCESS) return ISF_FIFO_ERR_NO_INIT;
159 
160  isf_mem_copy(pFifo->pDataBuffer, samplePtr, ((uint8*)pFifo->pLastEntry)-((uint8 *)pFifo->pDataBuffer));
161 
162  OSA_SemaPost(&pFifo->bufferLock);
163 
164  return ISF_SUCCESS;
165 }
166 
167 /*!
168  * @brief Lock a sample buffer for exclusive access.
169  */
171 {
173 
174  st = OSA_SemaWait(&pFifo->bufferLock, OSA_WAIT_FOREVER);
175  if (st != ISF_SUCCESS) return ISF_FIFO_ERR_NO_INIT;
176 
177  return ISF_SUCCESS;
178 }
179 
180 /*!
181  * @brief Attempt to lock a sample buffer for exclusive access.
182  */
184 {
186  st = OSA_SemaWait(&pFifo->bufferLock, 0);
187  if (st == kStatus_OSA_Success) {
188  return ISF_SUCCESS;
189  }
190  else {
191  return ISF_FIFO_ERR_BUSY;
192  }
193  return ISF_SUCCESS;
194 }
195 
196 /*!
197  * @brief Release the exclusive access lock on a sample buffer.
198  */
200 {
202 
203  st = OSA_SemaPost(&pFifo->bufferLock);
204  if (st != ISF_SUCCESS) return ISF_FIFO_ERR_NO_INIT;
205 
206  return ISF_SUCCESS;
207 }
208 
209 /*
210  * The following functions require explicit lock calls to be made
211  * and are denoted by _el (explicit lock)
212  */
213 
214 /*!
215  * @brief Routine to clear the fifo
216  */
218 {
219  pFifo->pInsertPtr = pFifo->pDataBuffer;
220  pFifo->fifoState &= FIFO_FULL_CLR_MASK;
221 
222  return ISF_SUCCESS;
223 }
224 
225 
226 /*!
227  * @brief Routine returns the insert pointer for direct access
228  */
230 {
231  return pFifo->pInsertPtr;
232 }
233 
234 /*!
235  * @brief Routine increments the insert pointer after direct access
236  */
238 {
239  if (pFifo->pInsertPtr < pFifo->pLastEntry) {
240  pFifo->pInsertPtr += pFifo->sampleSize;
241  return ISF_SUCCESS;
242  }
243  else {
244  pFifo->fifoState |= FIFO_FULL_BIT;
245  return ISF_FIFO_FULL;
246 
247  }
248 }
249 
250 
251 /*!
252  * @brief Routine to traverse a fifo
253  * To initiate the traversal set pSamplePtr to NULL.
254  * The function will set the pointer to the first available sample and returns ISF_SUCCESS.
255  * Subsequent calls will increment the pointer to each available sample and return ISF_SUCCESS.
256  * When ISF_SUCCESS is returned, pSamplePtr may be dereferenced to obtain a fifo entry.
257  * When no more samples are available, the function returns ISF_FIFO_NO_MORE_ENTRIES.
258  */
259 isf_fifo_status_t isf_fifo_el_traverse ( isf_fifo_t *pFifo, void **pSamplePtr )
260 {
261  uint8 **p = (uint8 **)pSamplePtr;
262  uint8 *pnext;
263 
264  // Is this a new traversal?
265  if (*p == NULL )
266  {
267  // Set the pointer to the start of the data buffer
268  *p = (uint8 *)pFifo->pDataBuffer;
269  pnext = *p;
270  }
271  else
272  {
273  pnext = *p + pFifo->sampleSize;
274  }
275 
276  if (pnext >= pFifo->pInsertPtr)
277  {
278  if (pFifo->fifoState & FIFO_FULL_BIT)
279  {
280  // The full flag means there is a sample in the last spot
281  *p = pnext;
282  }
283 
284  // No full flag means we are traversing "early" and there is no sample at the insert pointer
286  }
287  else //Not at the end, just keep going.
288  {
289  // Just increment to the next sample
290  *p = pnext;
291  }
292 
293  return ISF_SUCCESS;
294 }
295 
296 
297 
298 
299 
300 
301 
302 
303 
unsigned char uint8
Definition: isf_types.h:76
#define ALLOCATED_BUFFER_BIT
Definition: isf_fifo.c:17
isf_fifo_status_t isf_fifo_resize(isf_fifo_t *pFifo, uint16 newCapacity)
Routine to change the supported fifo depth.
Definition: isf_fifo.c:101
#define ISF_FIFO_ERR_NO_MEM
Definition: isf_fifo.h:28
#define ISF_FIFO_ERR_USER_BUF
Definition: isf_fifo.h:29
uint16 isf_fifo_get_buffer_size(isf_fifo_t *pFifo)
Routine to query the current fifo buffer size (bytes)
Definition: isf_fifo.c:133
#define FIFO_FULL_BIT
Definition: isf_fifo.c:18
isf_fifo_status_t isf_fifo_data_copy(isf_fifo_t *pFifo, void *samplePtr)
Routine to copy the whole sample buffer.
Definition: isf_fifo.c:154
isf_fifo_status_t isf_fifo_init(isf_fifo_t *pFifo, void *pData, uint16 sampleSize, uint16 bufferCapacity)
Initializes a new fifo structure with a provided buffer.
Definition: isf_fifo.c:24
isf_fifo_status_t isf_fifo_lock(isf_fifo_t *pFifo)
Lock a sample buffer for exclusive access.
Definition: isf_fifo.c:170
#define FIFO_FULL_CLR_MASK
Definition: isf_fifo.c:19
isf_fifo_status_t isf_fifo_free(isf_fifo_t *pFifo)
free a fifo's sample buffer.
Definition: isf_fifo.c:79
isf_fifo_status_t isf_fifo_try_lock(isf_fifo_t *pFifo)
Attempt to lock a sample buffer for exclusive access.
Definition: isf_fifo.c:183
isf_fifo_status_t isf_fifo_el_clear(isf_fifo_t *pFifo)
Routine to clear the fifo.
Definition: isf_fifo.c:217
void * isf_fifo_el_get_insert_pointer(isf_fifo_t *pFifo)
Routine returns the insert pointer for direct access.
Definition: isf_fifo.c:229
uint32 isf_fifo_status_t
Definition: isf_fifo.h:16
The isf_util.h file contains the utility method declarations and macros.
void isf_mem_copy(void *src, void *dest, uint32 size)
memory copy
Definition: isf_util.c:128
uint8 * pDataBuffer
Definition: isf_fifo.h:20
#define ISF_FIFO_ERR_NO_INIT
Definition: isf_fifo.h:32
#define ISF_FIFO_ERR_BUSY
Definition: isf_fifo.h:30
uint16 sampleSize
Definition: isf_fifo.h:23
Main ISF header file. Contains code common to all ISF components.
unsigned short int uint16
Definition: isf_types.h:77
isf_fifo_status_t isf_fifo_unlock(isf_fifo_t *pFifo)
Release the exclusive access lock on a sample buffer.
Definition: isf_fifo.c:199
isf_fifo_status_t isf_fifo_el_traverse(isf_fifo_t *pFifo, void **pSamplePtr)
Routine to traverse a fifo To initiate the traversal set pSamplePtr to NULL. The function will set th...
Definition: isf_fifo.c:259
semaphore_t bufferLock
Definition: isf_fifo.h:24
#define ISF_FIFO_ERR_INVALID_PTR
Definition: isf_fifo.h:31
uint8 * pLastEntry
Definition: isf_fifo.h:22
isf_fifo_status_t isf_fifo_alloc(isf_fifo_t *pFifo, uint16 sampleSize, uint16 bufferCapacity)
Convenience function to initialize a fifo structure and allocate a new fifo buffer.
Definition: isf_fifo.c:71
#define ISF_FIFO_NO_MORE_ENTRIES
Definition: isf_fifo.h:34
uint8 fifoState
Definition: isf_fifo.h:25
isf_fifo_status_t isf_fifo_el_increment(isf_fifo_t *pFifo)
Routine increments the insert pointer after direct access.
Definition: isf_fifo.c:237
uint8 * pInsertPtr
Definition: isf_fifo.h:21
#define ISF_FIFO_FULL
Definition: isf_fifo.h:33