1 /* 2 * GenSM.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 GenSM.c 35 * \brief Generic state machine implementation 36 * 37 * \see GenSM.h 38 */ 39 40 41 #define __FILE_ID__ FILE_ID_128 42 #include "tidef.h" 43 #include "osApi.h" 44 #include "report.h" 45 #include "GenSM.h" 46 47 48 /** 49 * \fn genSM_Create 50 * \brief Cerates a generic state machine object 51 * 52 * Cerates a generic state machine object. Allocates system resources. 53 * 54 * \note event/action matrix and debug descriptions are used by reference, and are not copied! 55 * \param hOS - handle to the OS object 56 * \return Handle to the generic state machine object 57 * \sa GenSM_Unload, GenSM_Init, genSM_SetDefaults 58 */ 59 TI_HANDLE genSM_Create (TI_HANDLE hOS) 60 { 61 TGenSM *pGenSM = NULL; 62 63 /* Allocate object storage */ 64 pGenSM = os_memoryAlloc (hOS, sizeof(TGenSM)); 65 if (NULL != pGenSM) 66 { 67 /* Store OS handle */ 68 pGenSM->hOS = hOS; 69 } 70 71 return (TI_HANDLE)pGenSM; 72 } 73 74 /** 75 * \fn genSM_Unload 76 * \brief Unloads a generic state machine object 77 * 78 * Unloads a generic state machine object. Frees system resources consumed by the object. 79 * 80 * \param hGenSM - hanlde to the generic state machine object 81 * \return None 82 * \sa GenSM_Create 83 */ 84 void genSM_Unload (TI_HANDLE hGenSM) 85 { 86 TGenSM *pGenSM = (TGenSM*)hGenSM; 87 88 /* free the generic state machine object storage */ 89 os_memoryFree (pGenSM->hOS, hGenSM, sizeof (TGenSM)); 90 } 91 92 /** 93 * \fn genSM_Init 94 * \brief Initializes the generic state machine object 95 * 96 * Initializes the generic state machine object. Store handles to other modules. 97 * 98 * \param hGenSM - hanlde to the generic state machine object 99 * \param hReport - handle to the report module 100 * \return None 101 * \sa GenSM_Create, genSM_SetDefaults 102 */ 103 void genSM_Init (TI_HANDLE hGenSM, TI_HANDLE hReport) 104 { 105 TGenSM *pGenSM = (TGenSM*)hGenSM; 106 107 /* store report handle */ 108 pGenSM->hReport = hReport; 109 } 110 111 /** 112 * \fn genSM_SetDefaults 113 * \brief Set default values to the generic state machine 114 * 115 * Set default values to the generic state machine 116 * 117 * \note event/action matrix and debug descriptions are used by reference, and are not copied! 118 * \param hGenSM - hanlde to the generic state machine object 119 * \param uStateNum - number of states 120 * \param uEventNum - number of events 121 * \param pMatrix - pointer to the event/actions matrix 122 * \param uInitialState - the initial state 123 * \param pGenSMName - a string describing the state machine, for debug prints 124 * \param pStateDesc - strings describing the state machine states, for debug prints 125 * \param pEventDesc - strings describing the state machine events, for debug prints 126 * \param uModuleLogIndex - Log index used by the module using the state machine 127 * \return None 128 * \sa genSM_Create, genSM_Init 129 */ 130 void genSM_SetDefaults (TI_HANDLE hGenSM, TI_UINT32 uStateNum, TI_UINT32 uEventNum, 131 TGenSM_matrix pMatrix, TI_UINT32 uInitialState, TI_INT8 *pGenSMName, 132 TI_INT8 **pStateDesc, TI_INT8 **pEventDesc, TI_UINT32 uModuleLogIndex) 133 { 134 TGenSM *pGenSM = (TGenSM*)hGenSM; 135 136 /* set values */ 137 pGenSM->uStateNum = uStateNum; 138 pGenSM->uEventNum = uEventNum; 139 pGenSM->tMatrix = pMatrix; 140 pGenSM->uCurrentState = uInitialState; 141 pGenSM->pGenSMName = pGenSMName; 142 pGenSM->pStateDesc = pStateDesc; 143 pGenSM->pEventDesc = pEventDesc; 144 pGenSM->uModuleLogIndex = uModuleLogIndex; 145 pGenSM->bEventPending = TI_FALSE; 146 pGenSM->bInAction = TI_FALSE; 147 } 148 149 void genSM_Event (TI_HANDLE hGenSM, TI_UINT32 uEvent, void *pData) 150 { 151 TGenSM *pGenSM = (TGenSM*)hGenSM; 152 TI_UINT32 uCurrentState; 153 TGenSM_actionCell *pCell; 154 155 #ifdef TI_DBG 156 /* sanity check */ 157 if (uEvent >= pGenSM->uEventNum) 158 { 159 TRACE3(pGenSM->hReport, REPORT_SEVERITY_ERROR , ": module: %d received event %d, which is out of events boundry %d\n", pGenSM->uModuleLogIndex, uEvent, pGenSM->uEventNum); 160 } 161 if (TI_TRUE == pGenSM->bEventPending) 162 { 163 TRACE3(pGenSM->hReport, REPORT_SEVERITY_ERROR , ": module: %d received event %d, when event %d is pending execution!\n", pGenSM->uModuleLogIndex, uEvent, pGenSM->uEvent); 164 } 165 #endif 166 167 /* mark that an event is pending */ 168 pGenSM->bEventPending = TI_TRUE; 169 170 /* save event and data */ 171 pGenSM->uEvent = uEvent; 172 pGenSM->pData = pData; 173 174 /* if an event is currently executing, return (new event will be handled when current event is done) */ 175 if (TI_TRUE == pGenSM->bInAction) 176 { 177 TRACE1(pGenSM->hReport, REPORT_SEVERITY_INFORMATION , ": module: %d delaying execution of event \n", pGenSM->uModuleLogIndex); 178 return; 179 } 180 181 /* execute events, until none is pending */ 182 while (TI_TRUE == pGenSM->bEventPending) 183 { 184 /* get the cell pointer for the current state and event */ 185 pCell = &(pGenSM->tMatrix[ (pGenSM->uCurrentState * pGenSM->uEventNum) + pGenSM->uEvent ]); 186 187 188 /* print state transition information */ 189 TRACE4(pGenSM->hReport, REPORT_SEVERITY_INFORMATION, "genSM_Event: module %d <currentState = %d, event = %d> --> nextState = %d\n", pGenSM->uModuleLogIndex, pGenSM->uCurrentState, uEvent, pCell->uNextState); 190 191 /* mark that event execution is in place */ 192 pGenSM->bInAction = TI_TRUE; 193 194 /* mark that pending event is being handled */ 195 pGenSM->bEventPending = TI_FALSE; 196 197 /* keep current state */ 198 uCurrentState = pGenSM->uCurrentState; 199 200 /* update current state */ 201 pGenSM->uCurrentState = pCell->uNextState; 202 203 /* run transition function */ 204 (*(pCell->fAction)) (pGenSM->pData); 205 206 /* mark that event execution is complete */ 207 pGenSM->bInAction = TI_FALSE; 208 } 209 } 210 211 /** 212 * \fn genSM_GetCurrentState 213 * \brief retrieves the state machine current state 214 * 215 * retrieves the state machine current state 216 * 217 * \param hGenSM - hanlde to the generic state machine object 218 * \return state machine current state 219 */ 220 TI_UINT32 genSM_GetCurrentState (TI_HANDLE hGenSM) 221 { 222 TGenSM *pGenSM = (TGenSM*)hGenSM; 223 224 return pGenSM->uCurrentState; 225 } 226