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*/
91TI_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*/
148TI_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*/
193TI_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*/
245TI_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) ) {
271		return(TI_NOK);
272	}
273	status = (*pFsm->stateEventMatrix[(oldState * pFsm->ActiveNoOfEvents) + event].actionFunc)(pData);
274
275	return status;
276}
277
278
279/**
280*
281* fsm_GetNextState  - Retrun the next state for a given current state and an event.
282*
283* \b Description:
284*
285* Retrun the next state for a given current state and an event.
286*
287* \b ARGS:
288*
289*  I   - pFsm - the generated FSM module  \n
290*  I   - currentState - current state of the SM \n
291*  I   - event - event causing transition \n
292*  O   - nextState - returned next state \n
293*
294* \b RETURNS:
295*
296*  TI_OK on success, TI_NOK on failure
297*
298* \sa
299*/
300TI_STATUS fsm_GetNextState(fsm_stateMachine_t		*pFsm,
301						TI_UINT8					currentState,
302						TI_UINT8					event,
303						TI_UINT8					*nextState)
304{
305	if (pFsm != NULL)
306	{
307		if ((currentState < pFsm->ActiveNoOfStates) && (event < pFsm->ActiveNoOfEvents))
308		{
309			*nextState = pFsm->stateEventMatrix[(currentState * pFsm->ActiveNoOfEvents) + event].nextState;
310			return(TI_OK);
311		}
312	}
313
314	return(TI_NOK);
315}
316
317TI_STATUS action_nop(void *pData)
318{
319	return TI_OK;
320}
321