Home | History | Annotate | Download | only in utils
      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 */
     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 */
    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 */
    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 */
    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 */
    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 
    318 TI_STATUS action_nop(void *pData)
    319 {
    320 	return TI_OK;
    321 }
    322