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