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