1/** \file fsm.c
2 *  \brief finite state machine source code
3 *
4 *  \see fsm.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 "report.h"
53#include "fsm.h"
54
55/* Constants */
56
57/* Enumerations */
58
59/* Typedefs */
60
61/* Structures */
62
63/* External data definitions */
64
65/* External functions definitions */
66
67/* Function prototypes */
68
69/**
70*
71* fsm_Init  - Initialize the FSM structure
72*
73* \b Description:
74*
75* Init The FSM structure. If matrix argument is NULL, allocate memory for
76* new matrix.
77*
78* \b ARGS:
79*
80*  O   - pFsm - the generated FSM module  \n
81*  I   - noOfStates - Number of states in the module \n
82*  I   - noOfStates - Number of events in the module \n
83*  I/O - matrix - the state event matrix
84*  I   - transFunc - Transition finction for the state machine \n
85*
86* \b RETURNS:
87*
88*  OK on success, NOK on failure
89*
90* \sa fsm_Event
91*/
92TI_STATUS fsm_Create(TI_HANDLE				hOs,
93				fsm_stateMachine_t		**pFsm,
94				UINT8					MaxNoOfStates,
95				UINT8					MaxNoOfEvents)
96{
97	/* check for perliminary conditions */
98	if ((pFsm == NULL) || (MaxNoOfStates == 0) || (MaxNoOfEvents == 0))
99	{
100		return NOK;
101	}
102
103	/* allocate memory for FSM context */
104	*pFsm = (fsm_stateMachine_t *)os_memoryAlloc(hOs, sizeof(fsm_stateMachine_t));
105	if (*pFsm == NULL)
106	{
107		return NOK;
108	}
109	os_memoryZero(hOs, (*pFsm), sizeof(fsm_stateMachine_t)); /* Dm: Fix */
110
111	/* allocate memory for FSM matrix */
112	(*pFsm)->stateEventMatrix = (fsm_Matrix_t)os_memoryAlloc(hOs, MaxNoOfStates * MaxNoOfEvents * sizeof(fsm_actionCell_t));
113	if ((*pFsm)->stateEventMatrix == NULL)
114	{
115		os_memoryFree(hOs, *pFsm, sizeof(fsm_stateMachine_t));
116		return NOK;
117	}
118	os_memoryZero(hOs, (*pFsm)->stateEventMatrix,
119		(MaxNoOfStates * MaxNoOfEvents * sizeof(fsm_actionCell_t)));
120	/* update pFsm structure with parameters */
121	(*pFsm)->MaxNoOfStates = MaxNoOfStates;
122	(*pFsm)->MaxNoOfEvents = MaxNoOfEvents;
123
124	return(OK);
125}
126
127/**
128*
129* fsm_Unload  - free all memory allocated to FSM structure
130*
131* \b Description:
132*
133* Unload the FSM structure.
134*
135* \b ARGS:
136*
137*  O   - pFsm - the generated FSM module  \n
138*  I   - noOfStates - Number of states in the module \n
139*  I   - noOfStates - Number of events in the module \n
140*  I/O - matrix - the state event matrix
141*  I   - transFunc - Transition finction for the state machine \n
142*
143* \b RETURNS:
144*
145*  OK on success, NOK on failure
146*
147* \sa fsm_Event
148*/
149TI_STATUS fsm_Unload(TI_HANDLE				hOs,
150				fsm_stateMachine_t		*pFsm)
151{
152	/* check for perliminary conditions */
153	if (pFsm == NULL)
154	{
155		return NOK;
156	}
157
158	/* free memory of FSM matrix */
159	if (pFsm->stateEventMatrix != NULL)
160	{
161		os_memoryFree(hOs, pFsm->stateEventMatrix,
162					  pFsm->MaxNoOfStates * pFsm->MaxNoOfEvents * sizeof(fsm_actionCell_t));
163	}
164
165	/* free memory for FSM context (no need to check for null) */
166	os_memoryFree(hOs, pFsm, sizeof(fsm_stateMachine_t));
167
168	return(OK);
169}
170
171/**
172*
173* fsm_Init  - Initialize the FSM structure
174*
175* \b Description:
176*
177* Init The FSM structure. If matrix argument is NULL, allocate memory for
178* new matrix.
179*
180* \b ARGS:
181*
182*  O   - pFsm - the generated FSM module  \n
183*  I   - noOfStates - Number of states in the module \n
184*  I   - noOfStates - Number of events in the module \n
185*  I/O - matrix - the state event matrix
186*  I   - transFunc - Transition finction for the state machine \n
187*
188* \b RETURNS:
189*
190*  OK on success, NOK on failure
191*
192* \sa fsm_Event
193*/
194TI_STATUS fsm_Config(fsm_stateMachine_t	*pFsm,
195				  fsm_Matrix_t			pMatrix,
196				  UINT8					ActiveNoOfStates,
197				  UINT8					ActiveNoOfEvents,
198				  fsm_eventActivation_t	transFunc,
199				  TI_HANDLE				hOs)
200{
201	/* check for perliminary conditions */
202	if ((pFsm == NULL) ||
203		(pMatrix == NULL))
204	{
205		return NOK;
206	}
207
208	if ((ActiveNoOfStates > pFsm->MaxNoOfStates) ||
209		(ActiveNoOfEvents > pFsm->MaxNoOfEvents))
210	{
211		return NOK;
212	}
213
214	/* copy matrix to FSM context */
215	os_memoryCopy(hOs, (void *)pFsm->stateEventMatrix, (void *)pMatrix,
216				  ActiveNoOfStates * ActiveNoOfEvents * sizeof(fsm_actionCell_t));
217
218	/* update pFsm structure with parameters */
219	pFsm->ActiveNoOfStates = ActiveNoOfStates;
220	pFsm->ActiveNoOfEvents = ActiveNoOfEvents;
221	pFsm->transitionFunc = transFunc;
222	return(OK);
223}
224
225/**
226*
227* fsm_Event  - perform event transition in the matrix
228*
229* \b Description:
230*
231* Perform event transition in the matrix
232*
233* \b ARGS:
234*
235*  I   - pFsm - the generated FSM module  \n
236*  I/O - currentState - current state of the SM \n
237*  I   - event - event causing transition \n
238*  I   - pData - data for activation function \n
239*
240* \b RETURNS:
241*
242*  OK on success, NOK on failure
243*
244* \sa fsm_Init
245*/
246TI_STATUS fsm_Event(fsm_stateMachine_t		*pFsm,
247				 UINT8					*currentState,
248				 UINT8					event,
249				 void					*pData)
250{
251	UINT8		oldState;
252	TI_STATUS		status;
253
254	/* check for FSM existance */
255	if (pFsm == NULL)
256	{
257		return(NOK);
258	}
259
260	/* boundary check */
261	if ((*currentState >= pFsm->ActiveNoOfStates) || (event >= pFsm->ActiveNoOfEvents))
262	{
263		return(NOK);
264	}
265
266	oldState = *currentState;
267	/* update current state */
268	*currentState = pFsm->stateEventMatrix[(*currentState * pFsm->ActiveNoOfEvents) + event].nextState;
269
270	/* activate transition function */
271	if( !(*pFsm->stateEventMatrix[(oldState * pFsm->ActiveNoOfEvents) + event].actionFunc) ) {
272	    return(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*  OK on success, NOK on failure
298*
299* \sa
300*/
301TI_STATUS fsm_GetNextState(fsm_stateMachine_t		*pFsm,
302						UINT8					currentState,
303						UINT8					event,
304						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(OK);
312		}
313	}
314
315	return(NOK);
316}
317
318TI_STATUS action_nop(void *pData)
319{
320	return OK;
321}
322