Home | History | Annotate | Download | only in utils
      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