/**************************************************************************** Module PowerCrank_SM.c Revision 1.0.1 Description This is the first service for the Test Harness under the Gen2 Events and Services Framework. Notes ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ /* include header files for this service */ #include "PowerCrank_SM.h" #include <string.h> #include "Servo.h" #include "PowerLib.h" #include "ArcadeFSM.h" #include "Cannon_SM.h" #include "ResetService.h" /* include header files for hardware access */ #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "inc/hw_sysctl.h" /* include header files for the framework */ #include "ES_Configure.h" #include "ES_Framework.h" #include "ES_DeferRecall.h" #include "ES_ShortTimer.h" /*----------------------------- Module Defines ----------------------------*/ // these times assume a 1.000mS/tick timing #define ONE_SEC 1000 #define HALF_SEC (ONE_SEC/2) #define TWO_SEC (ONE_SEC*2) #define FIVE_SEC (ONE_SEC*5) #define MAX_COUNT 100 //Tune the following two values to span proper servo range #define BEGINNING_TIME 0 #define END_TIME 100 #define DeltaTime (END_TIME-BEGINNING_TIME)/100 /*---------------------------- Module Functions ---------------------------*/ /* prototypes for private functions for this service.They should be functions relevant to the behavior of this service */ bool CheckPowerCrankEvents(void); /*---------------------------- Module Variables ---------------------------*/ // with the introduction of Gen2, we need a module level Priority variable static uint8_t MyPriority; static PowerCrank_SMState_t CurrentSMState; static uint16_t counter = 0; static uint8_t LastInputState = 0; static uint8_t CurrentTimePercentage = 0; // add a deferral queue for up to 3 pending deferrals +1 to allow for overhead static ES_Event_t DeferralQueue[3+1]; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function InitPowerCrank_SM Parameters uint8_t : the priorty of this service Returns bool, false if error in initialization, true otherwise Description Saves away the priority, and does any other required initialization for this service Notes Author Trey Weber ****************************************************************************/ bool InitPowerCrank_SM ( uint8_t Priority ) { MyPriority = Priority; //Initialize hardware PowerLib_HWInit(); CurrentSMState = Idle_PC; return true; } /**************************************************************************** Function PostPowerCrank_SM Parameters EF_Event ThisEvent ,the event to post to the queue Returns bool false if the Enqueue operation failed, true otherwise Description Posts an event to this state machine's queue Notes Author Trey Weber ****************************************************************************/ bool PostPowerCrank_SM( ES_Event_t ThisEvent ) { return ES_PostToService( MyPriority, ThisEvent); } /**************************************************************************** Function RunPowerCrank_SM Parameters ES_Event_t : the event to process Returns ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise Description add your description here Notes Author Trey Weber ****************************************************************************/ ES_Event_t RunPowerCrank_SM( ES_Event_t ThisEvent ) { ES_Event_t NewEvent; ES_Event_t ReturnEvent; ReturnEvent.EventType = ES_NO_EVENT; switch (CurrentSMState) { case NotCranking: //Check for Falling edge if (ThisEvent.EventType == Falling_Edge) { //Initialize timer ES_Timer_InitTimer(CRANK_TIMER, 50); //Update current state CurrentSMState = Cranking; } else if (ThisEvent.EventType == RST || ThisEvent.EventType == End_Of_Game) { CurrentSMState = Idle_PC; counter = 0; CurrentTimePercentage = 0; } else if (ThisEvent.EventType == ES_TIMEOUT) { //Check if we are below max count if (counter < MAX_COUNT) { //Increment counter counter++; //Increment power gauge CurrentTimePercentage++; PowerLib_MoveGauge(counter); } //else we have reached maximum count else { //Post interaction complete to arcade SM NewEvent.EventType = Interaction_Completed; PostArcadeFSM(NewEvent); //Post Power complete to cannon SM NewEvent.EventType = Power_Complete; PostCannon_SM(NewEvent); //Reset counter counter = 0; //Reset state CurrentSMState = Idle_PC; //Reset servo position CurrentTimePercentage = 0; } } break; case Cranking: //Check for reset or end of game if (ThisEvent.EventType == RST || ThisEvent.EventType == End_Of_Game) { CurrentSMState = Idle_PC; counter = 0; CurrentTimePercentage = 0; } //else check for rising edge else if (ThisEvent.EventType == Rising_Edge) { //Update SM state CurrentSMState = NotCranking; } //else if we get a timeout else if (ThisEvent.EventType == ES_TIMEOUT) { //Check if we are below max count if (counter < (MAX_COUNT)) { //Increment counter counter++; //Increment power gauge CurrentTimePercentage++; PowerLib_MoveGauge(counter); //Init timer ES_Timer_InitTimer(CRANK_TIMER, 30); } //else we have reached maximum count else { //Post interaction complete to arcade SM NewEvent.EventType = Interaction_Completed; PostArcadeFSM(NewEvent); //Post Power complete to cannon SM NewEvent.EventType = Power_Complete; PostCannon_SM(NewEvent); //Reset counter counter = 0; //Reset state CurrentSMState = Idle_PC; //Reset servo position CurrentTimePercentage = 0; } } break; case Idle_PC: //Power regen interaction begin if (ThisEvent.EventType == Low_Power) { //Check if state is low uint8_t PinState = PowerLib_PinState(); if (PinState == 1) { //Update state CurrentSMState = NotCranking; } //Else it is high else { //Update state CurrentSMState = Cranking; //Init timer ES_Timer_InitTimer(CRANK_TIMER, 30); } } //Else check for TOT Inserted else if (ThisEvent.EventType == Tot_Inserted) { //Set gauge to min PowerLib_MoveGauge(BEGINNING_TIME); counter = 0; CurrentTimePercentage = 0; } break; } return ReturnEvent; } PowerCrank_SMState_t QueryPowerCrank_SM(void) { return CurrentSMState; } /*************************************************************************** private functions ***************************************************************************/ /*** CheckPowerCrankEvents Function Description Arguments: none Returns: bool. True if ther is a new event This function check for the rotation of the power crank Author: Trey Weber ***/ bool CheckPowerCrankEvents(void){ ES_Event_t NewEvent; bool ReturnVal = false; //Get current input state uint8_t CurrentInputState = PowerLib_PinState(); //Check if state has changed if (CurrentInputState != LastInputState) { if (CurrentInputState != 0) { //Found rising edge NewEvent.EventType = Rising_Edge; PostPowerCrank_SM(NewEvent); PostResetService(NewEvent); } else { //Found falling edge NewEvent.EventType = Falling_Edge; PostPowerCrank_SM(NewEvent); PostResetService(NewEvent); } ReturnVal = true; //Return successfully } //Set new state LastInputState = CurrentInputState; //Return return ReturnVal; } /*------------------------------- Footnotes -------------------------------*/ /*------------------------------ End of file ------------------------------*/