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