/**************************************************************************** Module Recess2SM.c Revision 2.0.1 Description This is a template file for implementing state machines. Notes ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ // Basic includes for a program using the Events and Services Framework #include "ES_Configure.h" #include "ES_Framework.h" /* include header files for this state machine as well as any machines at the next lower level in the hierarchy that are sub-machines to this machine */ #include "Recess2SM.h" #include "SimpleDriveToASM.h" #include "ReloadControl.h" #include "JSR.h" /*----------------------------- Module Defines ----------------------------*/ // define constants for the states for this machine // and any other local defines /*---------------------------- Module Functions ---------------------------*/ /* prototypes for private functions for this machine, things like during functions, entry & exit functions.They should be functions relevant to the behavior of this state machine */ static ES_Event DuringWaitToReload( ES_Event Event); static ES_Event DuringDrivingToA( ES_Event Event); static ES_Event DuringRequestingBall( ES_Event Event); static ES_Event DuringWaitingForBall( ES_Event Event); /*---------------------------- Module Variables ---------------------------*/ // everybody needs a state variable, you may need others as well static Recess2State_t CurrentState; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function RunRound2DriveSM Parameters ES_Event: the event to process Returns ES_Event: an event to return Description add your description here Notes uses nested switch/case to implement the machine. Author J. Edward Carryer, 2/11/05, 10:45AM ****************************************************************************/ ES_Event RunRecess2SM( ES_Event CurrentEvent ) { unsigned char MakeTransition = false;/* are we making a state transition? */ Recess2State_t NextState = CurrentState; ES_Event EntryEventKind = { ES_ENTRY, 0 };// default to normal entry to new state ES_Event ReturnEvent = CurrentEvent; // assume we are not consuming event switch ( CurrentState ) { case ST_DrivingToA: // If current state is state one // Execute During function for state one. ES_ENTRY & ES_EXIT are // processed here allow the lowere level state machines to re-map // or consume the event CurrentEvent = DuringDrivingToA(CurrentEvent); //process any events if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active { switch (CurrentEvent.EventType) { case EV_BACK_WALL_REACHED: //If event is event one NextState = ST_WaitToReload;//Decide what the next state will be // for internal transitions, skip changing MakeTransition MakeTransition = true; //mark that we are taking a transition // level state machine ReturnEvent = CurrentEvent; break; } } break; case ST_WaitToReload : // If current state is state one // Execute During function for state one. ES_ENTRY & ES_EXIT are // processed here allow the lowere level state machines to re-map // or consume the event CurrentEvent = DuringWaitToReload(CurrentEvent); //process any events if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active { switch(CurrentEvent.EventType){ case ES_TIMEOUT: if(CurrentEvent.EventParam == RELOAD_TIMER){ NextState = ST_RequestingBall;//Decide what the next state will be // for internal transitions, skip changing MakeTransition MakeTransition = true; //mark that we are taking a transition // level state machine ReturnEvent = CurrentEvent; } break; } } break; case ST_RequestingBall : // If current state is state one // Execute During function for state one. ES_ENTRY & ES_EXIT are // processed here allow the lowere level state machines to re-map // or consume the event CurrentEvent = DuringRequestingBall(CurrentEvent); //process any events if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active { switch(CurrentEvent.EventType){ case ES_TIMEOUT: if(CurrentEvent.EventParam == RELOAD_TIMER){ NextState = ST_WaitingForBall;//Decide what the next state will be // for internal transitions, skip changing MakeTransition MakeTransition = true; //mark that we are taking a transition // level state machine ReturnEvent = CurrentEvent; } break; } } break; case ST_WaitingForBall: // If current state is state one // Execute During function for state one. ES_ENTRY & ES_EXIT are // processed here allow the lowere level state machines to re-map // or consume the event CurrentEvent = DuringWaitingForBall(CurrentEvent); //process any events if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active { switch(CurrentEvent.EventType){ case ES_TIMEOUT: if(CurrentEvent.EventParam == RELOAD_TIMER){ NextState = ST_RequestingBall;//Decide what the next state will be // for internal transitions, skip changing MakeTransition MakeTransition = true; //mark that we are taking a transition // level state machine ReturnEvent = CurrentEvent; } break; } } break; }// end switch CurrentState // If we are making a state transition if (MakeTransition == true) { // Execute exit function for current state CurrentEvent.EventType = ES_EXIT; RunRecess2SM(CurrentEvent); CurrentState = NextState; //Modify state variable // Execute entry function for new state // this defaults to ES_ENTRY RunRecess2SM(EntryEventKind); } return(ReturnEvent); } /**************************************************************************** Function StartRound2DriveSM Parameters None Returns None Description Does any required initialization for this state machine Notes Author J. Edward Carryer, 2/18/99, 10:38AM ****************************************************************************/ void StartRecess2SM ( ES_Event CurrentEvent ) { // local variable to get debugger to display the value of CurrentEvent ES_Event LocalEvent = CurrentEvent; // to implement entry to a history state or directly to a substate // you can modify the initialization of the CurrentState variable // otherwise just start in the entry state every time the state machine // is started if ( ES_ENTRY_HISTORY != CurrentEvent.EventType ) { SimpleDriveToAState_t simpleToAState = QuerySimpleDriveToASM(); if(simpleToAState == ST_DriveToA){ CurrentState = ST_DrivingToA; }else{ CurrentState = ST_WaitToReload; } } // call the entry function (if any) for the ENTRY_STATE RunRecess2SM(CurrentEvent); } /**************************************************************************** Function QueryRound2DriveSM Parameters None Returns TemplateState_t The current state of the Template state machine Description returns the current state of the Template state machine Notes Author J. Edward Carryer, 2/11/05, 10:38AM ****************************************************************************/ Recess2State_t QueryRecess2SM ( void ) { return(CurrentState); } /*************************************************************************** private functions ***************************************************************************/ static ES_Event DuringDrivingToA( ES_Event Event) { ES_Event ReturnEvent = Event; // assmes no re-mapping or comsumption // process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events if (Event.EventType == ES_ENTRY) { StartSimpleDriveToASM(Event); } else if ( Event.EventType == ES_EXIT ) { Event = RunSimpleDriveToASM(Event); }else // do the 'during' function for this state { Event = RunSimpleDriveToASM(Event); } // return either Event, if you don't want to allow the lower level machine // to remap the current event, or ReturnEvent if you do want to allow it. return(ReturnEvent); } static ES_Event DuringWaitToReload( ES_Event Event) { ES_Event ReturnEvent = Event; // assmes no re-mapping or comsumption // process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events if (Event.EventType == ES_ENTRY) { ES_Timer_InitTimer(RELOAD_TIMER, RELOAD_WAIT_INTERVAL); } else if ( Event.EventType == ES_EXIT ) { }else // do the 'during' function for this state { } // return either Event, if you don't want to allow the lower level machine // to remap the current event, or ReturnEvent if you do want to allow it. return(ReturnEvent); } static ES_Event DuringRequestingBall( ES_Event Event) { ES_Event ReturnEvent = Event; // assmes no re-mapping or comsumption // process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events if (Event.EventType == ES_ENTRY) { //Start Requesting a Ball (450 ms) if allowed if(QueryReload()){ printf("Turn on Reload IR \n\r"); TurnOnReloadIR(); } ES_Timer_InitTimer(RELOAD_TIMER, RELOADING_IR_INTERVAL); } else if ( Event.EventType == ES_EXIT ) { //Stop Requesting a Ball TurnOffReloadIR(); }else // do the 'during' function for this state { } // return either Event, if you don't want to allow the lower level machine // to remap the current event, or ReturnEvent if you do want to allow it. return(ReturnEvent); } static ES_Event DuringWaitingForBall( ES_Event Event) { ES_Event ReturnEvent = Event; // assmes no re-mapping or comsumption // process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events if (Event.EventType == ES_ENTRY) { //Wait 3 Seconds for the ball ES_Timer_InitTimer(RELOAD_TIMER, WAIT_FOR_BALL_INTERVAL); } else if ( Event.EventType == ES_EXIT ) { }else // do the 'during' function for this state { } // return either Event, if you don't want to allow the lower level machine // to remap the current event, or ReturnEvent if you do want to allow it. return(ReturnEvent); }