1 /*
2 * fsm.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /** \file fsm.c
35 * \brief finite state machine source code
36 *
37 * \see fsm.h
38 */
39
40
41 /***************************************************************************/
42 /* */
43 /* MODULE: fsm.c */
44 /* PURPOSE: Finite State Machine source code */
45 /* */
46 /***************************************************************************/
47
48 #define __FILE_ID__ FILE_ID_127
49 #include "tidef.h"
50 #include "osApi.h"
51 #include "report.h"
52 #include "fsm.h"
53
54 /* Constants */
55
56 /* Enumerations */
57
58 /* Typedefs */
59
60 /* Structures */
61
62 /* External data definitions */
63
64 /* External functions definitions */
65
66 /* Function prototypes */
67
68 /**
69 *
70 * fsm_Init - Initialize the FSM structure
71 *
72 * \b Description:
73 *
74 * Init The FSM structure. If matrix argument is NULL, allocate memory for
75 * new matrix.
76 *
77 * \b ARGS:
78 *
79 * O - pFsm - the generated FSM module \n
80 * I - noOfStates - Number of states in the module \n
81 * I - noOfStates - Number of events in the module \n
82 * I/O - matrix - the state event matrix
83 * I - transFunc - Transition finction for the state machine \n
84 *
85 * \b RETURNS:
86 *
87 * TI_OK on success, TI_NOK on failure
88 *
89 * \sa fsm_Event
90 */
fsm_Create(TI_HANDLE hOs,fsm_stateMachine_t ** pFsm,TI_UINT8 MaxNoOfStates,TI_UINT8 MaxNoOfEvents)91 TI_STATUS fsm_Create(TI_HANDLE hOs,
92 fsm_stateMachine_t **pFsm,
93 TI_UINT8 MaxNoOfStates,
94 TI_UINT8 MaxNoOfEvents)
95 {
96 /* check for perliminary conditions */
97 if ((pFsm == NULL) || (MaxNoOfStates == 0) || (MaxNoOfEvents == 0))
98 {
99 return TI_NOK;
100 }
101
102 /* allocate memory for FSM context */
103 *pFsm = (fsm_stateMachine_t *)os_memoryAlloc(hOs, sizeof(fsm_stateMachine_t));
104 if (*pFsm == NULL)
105 {
106 return TI_NOK;
107 }
108 os_memoryZero(hOs, (*pFsm), sizeof(fsm_stateMachine_t));
109
110 /* allocate memory for FSM matrix */
111 (*pFsm)->stateEventMatrix = (fsm_Matrix_t)os_memoryAlloc(hOs, MaxNoOfStates * MaxNoOfEvents * sizeof(fsm_actionCell_t));
112 if ((*pFsm)->stateEventMatrix == NULL)
113 {
114 os_memoryFree(hOs, *pFsm, sizeof(fsm_stateMachine_t));
115 return TI_NOK;
116 }
117 os_memoryZero(hOs, (*pFsm)->stateEventMatrix,
118 (MaxNoOfStates * MaxNoOfEvents * sizeof(fsm_actionCell_t)));
119 /* update pFsm structure with parameters */
120 (*pFsm)->MaxNoOfStates = MaxNoOfStates;
121 (*pFsm)->MaxNoOfEvents = MaxNoOfEvents;
122
123 return(TI_OK);
124 }
125
126 /**
127 *
128 * fsm_Unload - free all memory allocated to FSM structure
129 *
130 * \b Description:
131 *
132 * Unload the FSM structure.
133 *
134 * \b ARGS:
135 *
136 * O - pFsm - the generated FSM module \n
137 * I - noOfStates - Number of states in the module \n
138 * I - noOfStates - Number of events in the module \n
139 * I/O - matrix - the state event matrix
140 * I - transFunc - Transition finction for the state machine \n
141 *
142 * \b RETURNS:
143 *
144 * TI_OK on success, TI_NOK on failure
145 *
146 * \sa fsm_Event
147 */
fsm_Unload(TI_HANDLE hOs,fsm_stateMachine_t * pFsm)148 TI_STATUS fsm_Unload(TI_HANDLE hOs,
149 fsm_stateMachine_t *pFsm)
150 {
151 /* check for perliminary conditions */
152 if (pFsm == NULL)
153 {
154 return TI_NOK;
155 }
156
157 /* free memory of FSM matrix */
158 if (pFsm->stateEventMatrix != NULL)
159 {
160 os_memoryFree(hOs, pFsm->stateEventMatrix,
161 pFsm->MaxNoOfStates * pFsm->MaxNoOfEvents * sizeof(fsm_actionCell_t));
162 }
163
164 /* free memory for FSM context (no need to check for null) */
165 os_memoryFree(hOs, pFsm, sizeof(fsm_stateMachine_t));
166
167 return(TI_OK);
168 }
169
170 /**
171 *
172 * fsm_Init - Initialize the FSM structure
173 *
174 * \b Description:
175 *
176 * Init The FSM structure. If matrix argument is NULL, allocate memory for
177 * new matrix.
178 *
179 * \b ARGS:
180 *
181 * O - pFsm - the generated FSM module \n
182 * I - noOfStates - Number of states in the module \n
183 * I - noOfStates - Number of events in the module \n
184 * I/O - matrix - the state event matrix
185 * I - transFunc - Transition finction for the state machine \n
186 *
187 * \b RETURNS:
188 *
189 * TI_OK on success, TI_NOK on failure
190 *
191 * \sa fsm_Event
192 */
fsm_Config(fsm_stateMachine_t * pFsm,fsm_Matrix_t pMatrix,TI_UINT8 ActiveNoOfStates,TI_UINT8 ActiveNoOfEvents,fsm_eventActivation_t transFunc,TI_HANDLE hOs)193 TI_STATUS fsm_Config(fsm_stateMachine_t *pFsm,
194 fsm_Matrix_t pMatrix,
195 TI_UINT8 ActiveNoOfStates,
196 TI_UINT8 ActiveNoOfEvents,
197 fsm_eventActivation_t transFunc,
198 TI_HANDLE hOs)
199 {
200 /* check for perliminary conditions */
201 if ((pFsm == NULL) ||
202 (pMatrix == NULL))
203 {
204 return TI_NOK;
205 }
206
207 if ((ActiveNoOfStates > pFsm->MaxNoOfStates) ||
208 (ActiveNoOfEvents > pFsm->MaxNoOfEvents))
209 {
210 return TI_NOK;
211 }
212
213 /* copy matrix to FSM context */
214 os_memoryCopy(hOs, (void *)pFsm->stateEventMatrix, (void *)pMatrix,
215 ActiveNoOfStates * ActiveNoOfEvents * sizeof(fsm_actionCell_t));
216
217 /* update pFsm structure with parameters */
218 pFsm->ActiveNoOfStates = ActiveNoOfStates;
219 pFsm->ActiveNoOfEvents = ActiveNoOfEvents;
220 pFsm->transitionFunc = transFunc;
221 return(TI_OK);
222 }
223
224 /**
225 *
226 * fsm_Event - perform event transition in the matrix
227 *
228 * \b Description:
229 *
230 * Perform event transition in the matrix
231 *
232 * \b ARGS:
233 *
234 * I - pFsm - the generated FSM module \n
235 * I/O - currentState - current state of the SM \n
236 * I - event - event causing transition \n
237 * I - pData - data for activation function \n
238 *
239 * \b RETURNS:
240 *
241 * TI_OK on success, TI_NOK on failure
242 *
243 * \sa fsm_Init
244 */
fsm_Event(fsm_stateMachine_t * pFsm,TI_UINT8 * currentState,TI_UINT8 event,void * pData)245 TI_STATUS fsm_Event(fsm_stateMachine_t *pFsm,
246 TI_UINT8 *currentState,
247 TI_UINT8 event,
248 void *pData)
249 {
250 TI_UINT8 oldState;
251 TI_STATUS status;
252
253 /* check for FSM existance */
254 if (pFsm == NULL)
255 {
256 return TI_NOK;
257 }
258
259 /* boundary check */
260 if ((*currentState >= pFsm->ActiveNoOfStates) || (event >= pFsm->ActiveNoOfEvents))
261 {
262 return TI_NOK;
263 }
264
265 oldState = *currentState;
266 /* update current state */
267 *currentState = pFsm->stateEventMatrix[(*currentState * pFsm->ActiveNoOfEvents) + event].nextState;
268
269 /* activate transition function */
270 if ((*pFsm->stateEventMatrix[(oldState * pFsm->ActiveNoOfEvents) + event].actionFunc) == NULL)
271 {
272 return TI_NOK;
273 }
274 status = (*pFsm->stateEventMatrix[(oldState * pFsm->ActiveNoOfEvents) + event].actionFunc)(pData);
275
276 return status;
277 }
278
279
280 /**
281 *
282 * fsm_GetNextState - Retrun the next state for a given current state and an event.
283 *
284 * \b Description:
285 *
286 * Retrun the next state for a given current state and an event.
287 *
288 * \b ARGS:
289 *
290 * I - pFsm - the generated FSM module \n
291 * I - currentState - current state of the SM \n
292 * I - event - event causing transition \n
293 * O - nextState - returned next state \n
294 *
295 * \b RETURNS:
296 *
297 * TI_OK on success, TI_NOK on failure
298 *
299 * \sa
300 */
fsm_GetNextState(fsm_stateMachine_t * pFsm,TI_UINT8 currentState,TI_UINT8 event,TI_UINT8 * nextState)301 TI_STATUS fsm_GetNextState(fsm_stateMachine_t *pFsm,
302 TI_UINT8 currentState,
303 TI_UINT8 event,
304 TI_UINT8 *nextState)
305 {
306 if (pFsm != NULL)
307 {
308 if ((currentState < pFsm->ActiveNoOfStates) && (event < pFsm->ActiveNoOfEvents))
309 {
310 *nextState = pFsm->stateEventMatrix[(currentState * pFsm->ActiveNoOfEvents) + event].nextState;
311 return(TI_OK);
312 }
313 }
314
315 return(TI_NOK);
316 }
317
action_nop(void * pData)318 TI_STATUS action_nop(void *pData)
319 {
320 return TI_OK;
321 }
322