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