1 /** \file nrfsm.c 2 * \brief non-recursive finite state machine source code 3 * 4 * \see nrfsm.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 "nrfsm.h" 53 54 /* Constants */ 55 56 /* Enumerations */ 57 58 /* Typedefs */ 59 60 /* Structures */ 61 62 /** General NR-FSM structure */ 63 typedef struct 64 { 65 TI_HANDLE hOs; /**< OS handle */ 66 nrfsm_matrix_t matrix; /**< State\event matrix */ 67 UINT32 uMaxNoOfStates; /**< Max number of states in the matrix */ 68 UINT32 uMaxNoOfEvents; /**< Max number of events in the matrix */ 69 UINT32 uActNoOfStates; /**< Actual number of states in the matrix */ 70 UINT32 uActNoOfEvents; /**< Actual number of events in the matrix */ 71 UINT32 uInAction; /**< Number of handled events */ 72 UINT32 state; /**< Current state */ 73 UINT32 event; /**< Last event sent */ 74 void *pData; /**< Last event data */ 75 BOOL bEventPending; /**< Event pending indicator */ 76 77 } nrfsm_t; 78 79 80 /* External data definitions */ 81 82 /* External functions definitions */ 83 84 /* Function prototypes */ 85 86 /** 87 * 88 * nrfsm_Init - Initialize the FSM structure 89 * 90 * \b Description: 91 * 92 * Init The FSM structure. If matrix argument is NULL, allocate memory for 93 * new matrix. 94 * 95 * \b ARGS: 96 * 97 * I - hOs - OS handler 98 * O - hFsm - the generated FSM module \n 99 * I - uMaxNoOfStates - Number of states in the module \n 100 * I - uMaxNoOfEvents - Number of events in the module \n 101 * 102 * \b RETURNS: 103 * 104 * OK on success, NOK on failure 105 * 106 * \sa fsm_Event 107 */ 108 TI_STATUS nrfsm_Create (TI_HANDLE hOs, 109 TI_HANDLE *hFsm, 110 UINT32 uMaxNoOfStates, 111 UINT32 uMaxNoOfEvents) 112 { 113 nrfsm_t *pFsm; 114 115 /* Check for preliminary conditions */ 116 if (hFsm == NULL || uMaxNoOfStates == 0 || uMaxNoOfEvents == 0) 117 { 118 return NOK; 119 } 120 121 /* Allocate memory for FSM context */ 122 pFsm = (nrfsm_t *)os_memoryAlloc (hOs, sizeof(nrfsm_t)); 123 if (pFsm == NULL) 124 { 125 return NOK; 126 } 127 128 /* Allocate memory for FSM matrix */ 129 pFsm->matrix = (nrfsm_matrix_t)os_memoryAlloc (hOs, uMaxNoOfStates * uMaxNoOfEvents * sizeof(nrfsm_action_cell_t)); 130 if (pFsm->matrix == NULL) 131 { 132 os_memoryFree (hOs, pFsm, sizeof(nrfsm_t)); 133 return NOK; 134 } 135 136 /* Update pFsm structure with parameters */ 137 pFsm->uMaxNoOfStates = uMaxNoOfStates; 138 pFsm->uMaxNoOfEvents = uMaxNoOfEvents; 139 pFsm->hOs = hOs; 140 141 *hFsm = (TI_HANDLE)pFsm; 142 143 return OK; 144 } 145 146 147 /** 148 * 149 * nrfsm_Unload - free all memory allocated to FSM structure 150 * 151 * \b Description: 152 * 153 * Unload the FSM structure. 154 * 155 * \b ARGS: 156 * 157 * I - hFsm - the generated FSM module handle \n 158 * 159 * \b RETURNS: 160 * 161 * OK on success, NOK on failure 162 * 163 * \sa fsm_Event 164 */ 165 TI_STATUS nrfsm_Unload (TI_HANDLE hFsm) 166 { 167 nrfsm_t *pFsm = (nrfsm_t *)hFsm; 168 169 /* Check for preliminary conditions */ 170 if (pFsm == NULL) 171 { 172 return NOK; 173 } 174 175 /* Free memory of FSM matrix */ 176 if (pFsm->matrix != NULL) 177 { 178 os_memoryFree (pFsm->hOs, 179 pFsm->matrix, 180 pFsm->uMaxNoOfStates * pFsm->uMaxNoOfEvents * sizeof(nrfsm_action_cell_t)); 181 } 182 183 /* Free memory for FSM context (no need to check for null) */ 184 os_memoryFree (pFsm->hOs, pFsm, sizeof(nrfsm_t)); 185 186 return OK; 187 } 188 189 190 /** 191 * 192 * fsm_Init - Initialize the FSM structure 193 * 194 * \b Description: 195 * 196 * Init The FSM structure. If matrix argument is NULL, allocate memory for 197 * new matrix. 198 * 199 * \b ARGS: 200 * 201 * O - hFsm - the generated FSM module handle \n 202 * I - uActNoOfStates - Actual number of states in the module \n 203 * I - uActNoOfEvents - Actual number of events in the module \n 204 * I/O - pMatrix - the state event matrix pointer 205 * 206 * \b RETURNS: 207 * 208 * OK on success, NOK on failure 209 * 210 * \sa fsm_Event 211 */ 212 TI_STATUS nrfsm_Config (TI_HANDLE hFsm, 213 nrfsm_matrix_t pMatrix, 214 UINT32 uActNoOfStates, 215 UINT32 uActNoOfEvents) 216 { 217 nrfsm_t *pFsm = (nrfsm_t *)hFsm; 218 219 /* Check for preliminary conditions */ 220 if (pFsm == NULL || pMatrix == NULL) 221 { 222 return NOK; 223 } 224 225 if (uActNoOfStates > pFsm->uMaxNoOfStates || 226 uActNoOfEvents > pFsm->uMaxNoOfEvents) 227 { 228 return NOK; 229 } 230 231 /* Copy matrix to FSM context */ 232 os_memoryCopy (pFsm->hOs, 233 pFsm->matrix, 234 pMatrix, 235 uActNoOfStates * uActNoOfEvents * sizeof(nrfsm_action_cell_t)); 236 237 /* Update pFsm structure with parameters */ 238 pFsm->uActNoOfStates = uActNoOfStates; 239 pFsm->uActNoOfEvents = uActNoOfEvents; 240 pFsm->uInAction = 0; 241 pFsm->state = 0; 242 243 return OK; 244 } 245 246 247 /** 248 * 249 * nrfsm_Event - perform event transition in the matrix 250 * 251 * \b Description: 252 * 253 * Perform event transition in the matrix 254 * 255 * \b ARGS: 256 * 257 * I - hFsm - the generated FSM module handle handle \n 258 * I - event - event causing transition \n 259 * I - pData - data for activation function \n 260 * 261 * \b RETURNS: 262 * 263 * OK on success, NOK on failure, 1 on pending in queue 264 * 265 * \sa fsm_Init 266 */ 267 TI_STATUS nrfsm_Event (TI_HANDLE hFsm, UINT32 event, void *pData) 268 { 269 nrfsm_t *pFsm = (nrfsm_t *)hFsm; 270 UINT32 uIndex; 271 272 /* Check for FSM existance */ 273 if (pFsm == NULL) 274 { 275 return NOK; 276 } 277 278 /* Boundary check */ 279 if (pFsm->state >= pFsm->uActNoOfStates || event >= pFsm->uActNoOfEvents) 280 { 281 return NOK; 282 } 283 284 /* Store request action */ 285 pFsm->event = event; 286 pFsm->pData = pData; 287 pFsm->bEventPending = TRUE; 288 /*pFsm->uInAction ++;*/ 289 290 /* If currently performing an action, return (requested event will be handled when current action is finished) */ 291 if (pFsm->uInAction > 0) 292 { 293 if (pFsm->uInAction > 1) 294 return NOK; 295 return (TI_STATUS)1; 296 } 297 298 /* Perform requested events (avoid recursion when an action sends another event to any SM) */ 299 while (pFsm->bEventPending/*pFsm->uInAction*/) 300 { 301 pFsm->uInAction ++; 302 pFsm->bEventPending = FALSE; 303 304 /* Calculate action cell index */ 305 uIndex = pFsm->state * pFsm->uActNoOfEvents + pFsm->event; 306 307 /* Update current state */ 308 pFsm->state = pFsm->matrix[uIndex].nState; 309 310 /* Activate transition function */ 311 (*pFsm->matrix[uIndex].fAction) (pFsm->pData); 312 313 pFsm->uInAction --; 314 } 315 316 return OK; 317 } 318 319 320 /** 321 * 322 * nrfsm_SetState - Set the initial state. 323 * 324 * \b Description: 325 * 326 * Set the initial state. 327 * 328 * \b ARGS: 329 * 330 * I - hFsm - the generated FSM module handle \n 331 * I - state - current state of the SM \n 332 * 333 * \b RETURNS: 334 * 335 * OK on success, NOK on failure 336 * 337 * \sa 338 */ 339 TI_STATUS nrfsm_SetState (TI_HANDLE hFsm, UINT32 state) 340 { 341 nrfsm_t *pFsm = (nrfsm_t *)hFsm; 342 343 /* Boundary check */ 344 if (pFsm->state >= pFsm->uActNoOfStates) 345 { 346 return NOK; 347 } 348 else 349 { 350 pFsm->state = state; 351 return OK; 352 } 353 } 354 355 356 /** 357 * 358 * nrfsm_GetNextState - Return the current state. 359 * 360 * \b Description: 361 * 362 * Return the current state. 363 * 364 * \b ARGS: 365 * 366 * I - hFsm - the generated FSM module handle \n 367 * O - state - current state of the SM \n 368 * 369 * \b RETURNS: 370 * 371 * OK on success, NOK on failure 372 * 373 * \sa 374 */ 375 TI_STATUS nrfsm_GetState (TI_HANDLE hFsm, UINT32 *state) 376 { 377 nrfsm_t *pFsm = (nrfsm_t *)hFsm; 378 379 *state = pFsm->state; 380 381 return OK; 382 } 383 384 385 /** 386 * 387 * nrfsm_GetNextState - Return the next state for a given current state and an event. 388 * 389 * \b Description: 390 * 391 * Return the next state for a given current state and an event. 392 * 393 * \b ARGS: 394 * 395 * I - pFsm - the generated FSM module \n 396 * I - event - event causing transition \n 397 * O - state - returned next state \n 398 * 399 * \b RETURNS: 400 * 401 * OK on success, NOK on failure 402 * 403 * \sa 404 */ 405 TI_STATUS nrfsm_GetNextState (TI_HANDLE hFsm, UINT32 event, UINT32 *state) 406 { 407 nrfsm_t *pFsm = (nrfsm_t *)hFsm; 408 409 if (pFsm != NULL) 410 { 411 if (pFsm->state < pFsm->uActNoOfStates && event < pFsm->uActNoOfEvents) 412 { 413 *state = pFsm->matrix[pFsm->state * pFsm->uActNoOfEvents + event].nState; 414 return OK; 415 } 416 } 417 418 return NOK; 419 } 420 421 422 /*TI_STATUS action_nop(void *pData) 423 { 424 return OK; 425 }*/ 426 427