/* * fsm.c * * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name Texas Instruments nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** \file fsm.c * \brief finite state machine source code * * \see fsm.h */ /***************************************************************************/ /* */ /* MODULE: fsm.c */ /* PURPOSE: Finite State Machine source code */ /* */ /***************************************************************************/ #define __FILE_ID__ FILE_ID_127 #include "tidef.h" #include "osApi.h" #include "report.h" #include "fsm.h" /* Constants */ /* Enumerations */ /* Typedefs */ /* Structures */ /* External data definitions */ /* External functions definitions */ /* Function prototypes */ /** * * fsm_Init - Initialize the FSM structure * * \b Description: * * Init The FSM structure. If matrix argument is NULL, allocate memory for * new matrix. * * \b ARGS: * * O - pFsm - the generated FSM module \n * I - noOfStates - Number of states in the module \n * I - noOfStates - Number of events in the module \n * I/O - matrix - the state event matrix * I - transFunc - Transition finction for the state machine \n * * \b RETURNS: * * TI_OK on success, TI_NOK on failure * * \sa fsm_Event */ TI_STATUS fsm_Create(TI_HANDLE hOs, fsm_stateMachine_t **pFsm, TI_UINT8 MaxNoOfStates, TI_UINT8 MaxNoOfEvents) { /* check for perliminary conditions */ if ((pFsm == NULL) || (MaxNoOfStates == 0) || (MaxNoOfEvents == 0)) { return TI_NOK; } /* allocate memory for FSM context */ *pFsm = (fsm_stateMachine_t *)os_memoryAlloc(hOs, sizeof(fsm_stateMachine_t)); if (*pFsm == NULL) { return TI_NOK; } os_memoryZero(hOs, (*pFsm), sizeof(fsm_stateMachine_t)); /* allocate memory for FSM matrix */ (*pFsm)->stateEventMatrix = (fsm_Matrix_t)os_memoryAlloc(hOs, MaxNoOfStates * MaxNoOfEvents * sizeof(fsm_actionCell_t)); if ((*pFsm)->stateEventMatrix == NULL) { os_memoryFree(hOs, *pFsm, sizeof(fsm_stateMachine_t)); return TI_NOK; } os_memoryZero(hOs, (*pFsm)->stateEventMatrix, (MaxNoOfStates * MaxNoOfEvents * sizeof(fsm_actionCell_t))); /* update pFsm structure with parameters */ (*pFsm)->MaxNoOfStates = MaxNoOfStates; (*pFsm)->MaxNoOfEvents = MaxNoOfEvents; return(TI_OK); } /** * * fsm_Unload - free all memory allocated to FSM structure * * \b Description: * * Unload the FSM structure. * * \b ARGS: * * O - pFsm - the generated FSM module \n * I - noOfStates - Number of states in the module \n * I - noOfStates - Number of events in the module \n * I/O - matrix - the state event matrix * I - transFunc - Transition finction for the state machine \n * * \b RETURNS: * * TI_OK on success, TI_NOK on failure * * \sa fsm_Event */ TI_STATUS fsm_Unload(TI_HANDLE hOs, fsm_stateMachine_t *pFsm) { /* check for perliminary conditions */ if (pFsm == NULL) { return TI_NOK; } /* free memory of FSM matrix */ if (pFsm->stateEventMatrix != NULL) { os_memoryFree(hOs, pFsm->stateEventMatrix, pFsm->MaxNoOfStates * pFsm->MaxNoOfEvents * sizeof(fsm_actionCell_t)); } /* free memory for FSM context (no need to check for null) */ os_memoryFree(hOs, pFsm, sizeof(fsm_stateMachine_t)); return(TI_OK); } /** * * fsm_Init - Initialize the FSM structure * * \b Description: * * Init The FSM structure. If matrix argument is NULL, allocate memory for * new matrix. * * \b ARGS: * * O - pFsm - the generated FSM module \n * I - noOfStates - Number of states in the module \n * I - noOfStates - Number of events in the module \n * I/O - matrix - the state event matrix * I - transFunc - Transition finction for the state machine \n * * \b RETURNS: * * TI_OK on success, TI_NOK on failure * * \sa fsm_Event */ TI_STATUS fsm_Config(fsm_stateMachine_t *pFsm, fsm_Matrix_t pMatrix, TI_UINT8 ActiveNoOfStates, TI_UINT8 ActiveNoOfEvents, fsm_eventActivation_t transFunc, TI_HANDLE hOs) { /* check for perliminary conditions */ if ((pFsm == NULL) || (pMatrix == NULL)) { return TI_NOK; } if ((ActiveNoOfStates > pFsm->MaxNoOfStates) || (ActiveNoOfEvents > pFsm->MaxNoOfEvents)) { return TI_NOK; } /* copy matrix to FSM context */ os_memoryCopy(hOs, (void *)pFsm->stateEventMatrix, (void *)pMatrix, ActiveNoOfStates * ActiveNoOfEvents * sizeof(fsm_actionCell_t)); /* update pFsm structure with parameters */ pFsm->ActiveNoOfStates = ActiveNoOfStates; pFsm->ActiveNoOfEvents = ActiveNoOfEvents; pFsm->transitionFunc = transFunc; return(TI_OK); } /** * * fsm_Event - perform event transition in the matrix * * \b Description: * * Perform event transition in the matrix * * \b ARGS: * * I - pFsm - the generated FSM module \n * I/O - currentState - current state of the SM \n * I - event - event causing transition \n * I - pData - data for activation function \n * * \b RETURNS: * * TI_OK on success, TI_NOK on failure * * \sa fsm_Init */ TI_STATUS fsm_Event(fsm_stateMachine_t *pFsm, TI_UINT8 *currentState, TI_UINT8 event, void *pData) { TI_UINT8 oldState; TI_STATUS status; /* check for FSM existance */ if (pFsm == NULL) { return(TI_NOK); } /* boundary check */ if ((*currentState >= pFsm->ActiveNoOfStates) || (event >= pFsm->ActiveNoOfEvents)) { return(TI_NOK); } oldState = *currentState; /* update current state */ *currentState = pFsm->stateEventMatrix[(*currentState * pFsm->ActiveNoOfEvents) + event].nextState; /* activate transition function */ if( !(*pFsm->stateEventMatrix[(oldState * pFsm->ActiveNoOfEvents) + event].actionFunc) ) { return(TI_NOK); } status = (*pFsm->stateEventMatrix[(oldState * pFsm->ActiveNoOfEvents) + event].actionFunc)(pData); return status; } /** * * fsm_GetNextState - Retrun the next state for a given current state and an event. * * \b Description: * * Retrun the next state for a given current state and an event. * * \b ARGS: * * I - pFsm - the generated FSM module \n * I - currentState - current state of the SM \n * I - event - event causing transition \n * O - nextState - returned next state \n * * \b RETURNS: * * TI_OK on success, TI_NOK on failure * * \sa */ TI_STATUS fsm_GetNextState(fsm_stateMachine_t *pFsm, TI_UINT8 currentState, TI_UINT8 event, TI_UINT8 *nextState) { if (pFsm != NULL) { if ((currentState < pFsm->ActiveNoOfStates) && (event < pFsm->ActiveNoOfEvents)) { *nextState = pFsm->stateEventMatrix[(currentState * pFsm->ActiveNoOfEvents) + event].nextState; return(TI_OK); } } return(TI_NOK); } TI_STATUS action_nop(void *pData) { return TI_OK; }