1 /** \file nrfsm.c
2 * \brief non-recursive finite state machine source code
3 *
4 * \see nrfsm.h
5 */
6
7 /****************************************************************************
8 **+-----------------------------------------------------------------------+**
9 **| |**
10 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
11 **| All rights reserved. |**
12 **| |**
13 **| Redistribution and use in source and binary forms, with or without |**
14 **| modification, are permitted provided that the following conditions |**
15 **| are met: |**
16 **| |**
17 **| * Redistributions of source code must retain the above copyright |**
18 **| notice, this list of conditions and the following disclaimer. |**
19 **| * Redistributions in binary form must reproduce the above copyright |**
20 **| notice, this list of conditions and the following disclaimer in |**
21 **| the documentation and/or other materials provided with the |**
22 **| distribution. |**
23 **| * Neither the name Texas Instruments nor the names of its |**
24 **| contributors may be used to endorse or promote products derived |**
25 **| from this software without specific prior written permission. |**
26 **| |**
27 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
28 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
29 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
30 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
31 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
32 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
33 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
34 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
35 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
36 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
37 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
38 **| |**
39 **+-----------------------------------------------------------------------+**
40 ****************************************************************************/
41
42 /***************************************************************************/
43 /* */
44 /* MODULE: fsm.c */
45 /* PURPOSE: Finite State Machine source code */
46 /* */
47 /***************************************************************************/
48
49 #include "osTIType.h"
50 #include "osApi.h"
51 #include "utils.h"
52 #include "nrfsm.h"
53
54 /* Constants */
55
56 /* Enumerations */
57
58 /* Typedefs */
59
60 /* Structures */
61
62 /** General NR-FSM structure */
63 typedef struct
64 {
65 TI_HANDLE hOs; /**< OS handle */
66 nrfsm_matrix_t matrix; /**< State\event matrix */
67 UINT32 uMaxNoOfStates; /**< Max number of states in the matrix */
68 UINT32 uMaxNoOfEvents; /**< Max number of events in the matrix */
69 UINT32 uActNoOfStates; /**< Actual number of states in the matrix */
70 UINT32 uActNoOfEvents; /**< Actual number of events in the matrix */
71 UINT32 uInAction; /**< Number of handled events */
72 UINT32 state; /**< Current state */
73 UINT32 event; /**< Last event sent */
74 void *pData; /**< Last event data */
75 BOOL bEventPending; /**< Event pending indicator */
76
77 } nrfsm_t;
78
79
80 /* External data definitions */
81
82 /* External functions definitions */
83
84 /* Function prototypes */
85
86 /**
87 *
88 * nrfsm_Init - Initialize the FSM structure
89 *
90 * \b Description:
91 *
92 * Init The FSM structure. If matrix argument is NULL, allocate memory for
93 * new matrix.
94 *
95 * \b ARGS:
96 *
97 * I - hOs - OS handler
98 * O - hFsm - the generated FSM module \n
99 * I - uMaxNoOfStates - Number of states in the module \n
100 * I - uMaxNoOfEvents - Number of events in the module \n
101 *
102 * \b RETURNS:
103 *
104 * OK on success, NOK on failure
105 *
106 * \sa fsm_Event
107 */
nrfsm_Create(TI_HANDLE hOs,TI_HANDLE * hFsm,UINT32 uMaxNoOfStates,UINT32 uMaxNoOfEvents)108 TI_STATUS nrfsm_Create (TI_HANDLE hOs,
109 TI_HANDLE *hFsm,
110 UINT32 uMaxNoOfStates,
111 UINT32 uMaxNoOfEvents)
112 {
113 nrfsm_t *pFsm;
114
115 /* Check for preliminary conditions */
116 if (hFsm == NULL || uMaxNoOfStates == 0 || uMaxNoOfEvents == 0)
117 {
118 return NOK;
119 }
120
121 /* Allocate memory for FSM context */
122 pFsm = (nrfsm_t *)os_memoryAlloc (hOs, sizeof(nrfsm_t));
123 if (pFsm == NULL)
124 {
125 return NOK;
126 }
127
128 /* Allocate memory for FSM matrix */
129 pFsm->matrix = (nrfsm_matrix_t)os_memoryAlloc (hOs, uMaxNoOfStates * uMaxNoOfEvents * sizeof(nrfsm_action_cell_t));
130 if (pFsm->matrix == NULL)
131 {
132 os_memoryFree (hOs, pFsm, sizeof(nrfsm_t));
133 return NOK;
134 }
135
136 /* Update pFsm structure with parameters */
137 pFsm->uMaxNoOfStates = uMaxNoOfStates;
138 pFsm->uMaxNoOfEvents = uMaxNoOfEvents;
139 pFsm->hOs = hOs;
140
141 *hFsm = (TI_HANDLE)pFsm;
142
143 return OK;
144 }
145
146
147 /**
148 *
149 * nrfsm_Unload - free all memory allocated to FSM structure
150 *
151 * \b Description:
152 *
153 * Unload the FSM structure.
154 *
155 * \b ARGS:
156 *
157 * I - hFsm - the generated FSM module handle \n
158 *
159 * \b RETURNS:
160 *
161 * OK on success, NOK on failure
162 *
163 * \sa fsm_Event
164 */
nrfsm_Unload(TI_HANDLE hFsm)165 TI_STATUS nrfsm_Unload (TI_HANDLE hFsm)
166 {
167 nrfsm_t *pFsm = (nrfsm_t *)hFsm;
168
169 /* Check for preliminary conditions */
170 if (pFsm == NULL)
171 {
172 return NOK;
173 }
174
175 /* Free memory of FSM matrix */
176 if (pFsm->matrix != NULL)
177 {
178 os_memoryFree (pFsm->hOs,
179 pFsm->matrix,
180 pFsm->uMaxNoOfStates * pFsm->uMaxNoOfEvents * sizeof(nrfsm_action_cell_t));
181 }
182
183 /* Free memory for FSM context (no need to check for null) */
184 os_memoryFree (pFsm->hOs, pFsm, sizeof(nrfsm_t));
185
186 return OK;
187 }
188
189
190 /**
191 *
192 * fsm_Init - Initialize the FSM structure
193 *
194 * \b Description:
195 *
196 * Init The FSM structure. If matrix argument is NULL, allocate memory for
197 * new matrix.
198 *
199 * \b ARGS:
200 *
201 * O - hFsm - the generated FSM module handle \n
202 * I - uActNoOfStates - Actual number of states in the module \n
203 * I - uActNoOfEvents - Actual number of events in the module \n
204 * I/O - pMatrix - the state event matrix pointer
205 *
206 * \b RETURNS:
207 *
208 * OK on success, NOK on failure
209 *
210 * \sa fsm_Event
211 */
nrfsm_Config(TI_HANDLE hFsm,nrfsm_matrix_t pMatrix,UINT32 uActNoOfStates,UINT32 uActNoOfEvents)212 TI_STATUS nrfsm_Config (TI_HANDLE hFsm,
213 nrfsm_matrix_t pMatrix,
214 UINT32 uActNoOfStates,
215 UINT32 uActNoOfEvents)
216 {
217 nrfsm_t *pFsm = (nrfsm_t *)hFsm;
218
219 /* Check for preliminary conditions */
220 if (pFsm == NULL || pMatrix == NULL)
221 {
222 return NOK;
223 }
224
225 if (uActNoOfStates > pFsm->uMaxNoOfStates ||
226 uActNoOfEvents > pFsm->uMaxNoOfEvents)
227 {
228 return NOK;
229 }
230
231 /* Copy matrix to FSM context */
232 os_memoryCopy (pFsm->hOs,
233 pFsm->matrix,
234 pMatrix,
235 uActNoOfStates * uActNoOfEvents * sizeof(nrfsm_action_cell_t));
236
237 /* Update pFsm structure with parameters */
238 pFsm->uActNoOfStates = uActNoOfStates;
239 pFsm->uActNoOfEvents = uActNoOfEvents;
240 pFsm->uInAction = 0;
241 pFsm->state = 0;
242
243 return OK;
244 }
245
246
247 /**
248 *
249 * nrfsm_Event - perform event transition in the matrix
250 *
251 * \b Description:
252 *
253 * Perform event transition in the matrix
254 *
255 * \b ARGS:
256 *
257 * I - hFsm - the generated FSM module handle handle \n
258 * I - event - event causing transition \n
259 * I - pData - data for activation function \n
260 *
261 * \b RETURNS:
262 *
263 * OK on success, NOK on failure, 1 on pending in queue
264 *
265 * \sa fsm_Init
266 */
nrfsm_Event(TI_HANDLE hFsm,UINT32 event,void * pData)267 TI_STATUS nrfsm_Event (TI_HANDLE hFsm, UINT32 event, void *pData)
268 {
269 nrfsm_t *pFsm = (nrfsm_t *)hFsm;
270 UINT32 uIndex;
271
272 /* Check for FSM existance */
273 if (pFsm == NULL)
274 {
275 return NOK;
276 }
277
278 /* Boundary check */
279 if (pFsm->state >= pFsm->uActNoOfStates || event >= pFsm->uActNoOfEvents)
280 {
281 return NOK;
282 }
283
284 /* Store request action */
285 pFsm->event = event;
286 pFsm->pData = pData;
287 pFsm->bEventPending = TRUE;
288 /*pFsm->uInAction ++;*/
289
290 /* If currently performing an action, return (requested event will be handled when current action is finished) */
291 if (pFsm->uInAction > 0)
292 {
293 if (pFsm->uInAction > 1)
294 return NOK;
295 return (TI_STATUS)1;
296 }
297
298 /* Perform requested events (avoid recursion when an action sends another event to any SM) */
299 while (pFsm->bEventPending/*pFsm->uInAction*/)
300 {
301 pFsm->uInAction ++;
302 pFsm->bEventPending = FALSE;
303
304 /* Calculate action cell index */
305 uIndex = pFsm->state * pFsm->uActNoOfEvents + pFsm->event;
306
307 /* Update current state */
308 pFsm->state = pFsm->matrix[uIndex].nState;
309
310 /* Activate transition function */
311 (*pFsm->matrix[uIndex].fAction) (pFsm->pData);
312
313 pFsm->uInAction --;
314 }
315
316 return OK;
317 }
318
319
320 /**
321 *
322 * nrfsm_SetState - Set the initial state.
323 *
324 * \b Description:
325 *
326 * Set the initial state.
327 *
328 * \b ARGS:
329 *
330 * I - hFsm - the generated FSM module handle \n
331 * I - state - current state of the SM \n
332 *
333 * \b RETURNS:
334 *
335 * OK on success, NOK on failure
336 *
337 * \sa
338 */
nrfsm_SetState(TI_HANDLE hFsm,UINT32 state)339 TI_STATUS nrfsm_SetState (TI_HANDLE hFsm, UINT32 state)
340 {
341 nrfsm_t *pFsm = (nrfsm_t *)hFsm;
342
343 /* Boundary check */
344 if (pFsm->state >= pFsm->uActNoOfStates)
345 {
346 return NOK;
347 }
348 else
349 {
350 pFsm->state = state;
351 return OK;
352 }
353 }
354
355
356 /**
357 *
358 * nrfsm_GetNextState - Return the current state.
359 *
360 * \b Description:
361 *
362 * Return the current state.
363 *
364 * \b ARGS:
365 *
366 * I - hFsm - the generated FSM module handle \n
367 * O - state - current state of the SM \n
368 *
369 * \b RETURNS:
370 *
371 * OK on success, NOK on failure
372 *
373 * \sa
374 */
nrfsm_GetState(TI_HANDLE hFsm,UINT32 * state)375 TI_STATUS nrfsm_GetState (TI_HANDLE hFsm, UINT32 *state)
376 {
377 nrfsm_t *pFsm = (nrfsm_t *)hFsm;
378
379 *state = pFsm->state;
380
381 return OK;
382 }
383
384
385 /**
386 *
387 * nrfsm_GetNextState - Return the next state for a given current state and an event.
388 *
389 * \b Description:
390 *
391 * Return the next state for a given current state and an event.
392 *
393 * \b ARGS:
394 *
395 * I - pFsm - the generated FSM module \n
396 * I - event - event causing transition \n
397 * O - state - returned next state \n
398 *
399 * \b RETURNS:
400 *
401 * OK on success, NOK on failure
402 *
403 * \sa
404 */
nrfsm_GetNextState(TI_HANDLE hFsm,UINT32 event,UINT32 * state)405 TI_STATUS nrfsm_GetNextState (TI_HANDLE hFsm, UINT32 event, UINT32 *state)
406 {
407 nrfsm_t *pFsm = (nrfsm_t *)hFsm;
408
409 if (pFsm != NULL)
410 {
411 if (pFsm->state < pFsm->uActNoOfStates && event < pFsm->uActNoOfEvents)
412 {
413 *state = pFsm->matrix[pFsm->state * pFsm->uActNoOfEvents + event].nState;
414 return OK;
415 }
416 }
417
418 return NOK;
419 }
420
421
422 /*TI_STATUS action_nop(void *pData)
423 {
424 return OK;
425 }*/
426
427