• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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