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