/**************************************************************************** Module GameControlService.c Revision 1.0.1 Description This is the first service for the Test Harness under the Gen2 Events and Services Framework. Notes History When Who What/Why -------------- --- -------- 10/26/17 18:26 jec moves definition of ALL_BITS to ES_Port.h 10/19/17 21:28 jec meaningless change to test updating 10/19/17 18:42 jec removed referennces to driverlib and programmed the ports directly 08/21/17 21:44 jec modified LED blink routine to only modify bit 3 so that I can test the new new framework debugging lines on PF1-2 08/16/17 14:13 jec corrected ONE_SEC constant to match Tiva tick rate 11/02/13 17:21 jec added exercise of the event deferral/recall module 08/05/13 20:33 jec converted to test harness service 01/16/12 09:58 jec began conversion from TemplateFSM.c ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ // This module #include "GameControlService.h" // Hardware #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "inc/hw_sysctl.h" #include "driverlib/pwm.h" #include "inc/hw_pwm.h" // Event & Services Framework #include "ES_Configure.h" #include "ES_Framework.h" #include "ES_DeferRecall.h" #include "ES_ShortTimer.h" #include "ES_Port.h" //Include other files #include "CompassService.h" #include "GameplayHSM.h" #include "HardwareInitialize.h" #include "CollisionModule.h" #include "BeaconSense.h" #include "ServoModule.h" #include "MotorSM.h" #include "PWM_Module.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) //Time to dump #define DUMPTIME 100 //Hardware bits #define TEAMSWITCH /*---------------------------- Module Functions ---------------------------*/ /* prototypes for private functions for this service.They should be functions relevant to the behavior of this service */ void SaveColorFreq(uint8_t SPI); static void TurnOnPWMEmitters(void); /*---------------------------- Module Variables ---------------------------*/ // with the introduction of Gen2, we need a module level Priority variable static uint8_t MyPriority; static GameControlState_t CurrentState; // add a deferral queue for up to 3 pending deferrals +1 to allow for ovehead //static ES_Event_t DeferralQueue[3 + 1]; static uint16_t GameTime = 0; // Compass query variables static uint8_t AssignedTeam; static uint8_t ColorAssigned; static uint16_t FreqAssigned; static uint8_t EastRecycleColor; static uint8_t WestRecycleColor; // Adding history for recycling center static uint8_t LastEastRecycleColor; static uint8_t LastWestRecycleColor; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function InitGameControlService Parameters uint8_t : the priority of this service Returns bool, false if error in initialization, true otherwise Description Calls initialization for all non-framework modules in 218B project: - HardwareInitialize - BeaconSense - CollisionModule - Servos Saves away the priority, and does any other required initialization for this service. Notes Author J. Edward Carryer, 01/16/12, 10:00 ****************************************************************************/ bool InitGameControlService(uint8_t Priority) { ES_Event_t ThisEvent; MyPriority = Priority; // initialize all hardware InitializeHardware(); // initialize collision module InitializeCollisionDetection(); // initialize beacon sensors InitializeBeaconSense(); // set up servos SetupAllServoFrequencies(); SetServoStartingPositions(); // turn on recycling emitter TurnOnPWMEmitters(); // post the initial transition event ThisEvent.EventType = ES_INIT; CurrentState = InitGState; if (ES_PostToService(MyPriority, ThisEvent) == true) { return true; } else { return false; } } /**************************************************************************** Function PostGameControlService 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 J. Edward Carryer, 10/23/11, 19:25 ****************************************************************************/ bool PostGameControlService(ES_Event_t ThisEvent) { return ES_PostToService(MyPriority, ThisEvent); } /**************************************************************************** Function RunGameControlService Parameters ES_Event_t : the event to process Returns ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise Description Notes Author J. Edward Carryer, 01/15/12, 15:23 ****************************************************************************/ ES_Event_t RunGameControlService(ES_Event_t ThisEvent) { ES_Event_t ReturnEvent; ES_Event_t NextEvent; static uint16_t TeamByte = 0; static uint8_t RemainingTime; ReturnEvent.EventType = ES_NO_EVENT; // assume no errors //Pass NextState to CurrentState switch (CurrentState) { case InitGState: { if (ThisEvent.EventType == ES_INIT) { //Read team designation switch TeamByte = (HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + ALL_BITS)) >> 5); //Post to Compass Service the byte if (TeamByte == 0) { //printf("Team North! \n\r"); //Register as Team North NextEvent.EventType = TEAM_SELECT; NextEvent.EventParam = 0x10; //Set team servo to correct position RaiseUSA(); } else if (TeamByte == 1) { //printf("Team South! Viva Mexico! \n\r"); //Register as Team South NextEvent.EventType = TEAM_SELECT; NextEvent.EventParam = 0x01; //Set team servo to correct position RaiseMexcio(); } //Post event to Compass Service PostCompassService(NextEvent); //Transition for next State CurrentState = WaitingforREG; } } break; case WaitingforREG: { //Waiting for Team registration success from Compass service if (ThisEvent.EventType == REG_COMPLETE) { //printf("Registration complete!\n\r"); //Call getter functions from Compass Service AssignedTeam = GetTeamAssignment(); ColorAssigned = GetColorAssignment(); FreqAssigned = GetFreqAssignment(); EastRecycleColor = GetEastRecycleColor(); WestRecycleColor = GetWestRecycleColor(); //Start 100ms timer ES_Timer_InitTimer(GameControlTimer, 100); //Turn off Game indicator LED HWREG(GPIO_PORTF_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT1HI; //Set transition for GameOff State CurrentState = GameOff; } } break; case GameOff: { //Waiting for events switch (ThisEvent.EventType) { case ES_TIMEOUT: { //printf("Game inactive...\n\r"); //Call getter functions from Compass Service AssignedTeam = GetTeamAssignment(); ColorAssigned = GetColorAssignment(); FreqAssigned = GetFreqAssignment(); EastRecycleColor = GetEastRecycleColor(); WestRecycleColor = GetWestRecycleColor(); //Start 1s timer ES_Timer_InitTimer(GameControlTimer, 1000); //Set transition to next state CurrentState = GameOff; } break; case GAME_STARTED: { //Turn on game indicator LED HWREG(GPIO_PORTF_BASE + (GPIO_O_DATA + ALL_BITS)) &= BIT1LO; //Set transition to next state CurrentState = GameOn; } } } break; case GameOn: { if (ThisEvent.EventType == ES_TIMEOUT) { //printf("\r\nGame Active"); //Call getter functions from Compass Service AssignedTeam = GetTeamAssignment(); ColorAssigned = GetColorAssignment(); FreqAssigned = GetFreqAssignment(); EastRecycleColor = GetEastRecycleColor(); WestRecycleColor = GetWestRecycleColor(); //Check if frequency has changed or not if ((WestRecycleColor != LastWestRecycleColor) || (EastRecycleColor != LastEastRecycleColor)) { //POST CHANGE FREQUENCY EVENT HERE NextEvent.EventType = RECYCLING_CHANGE; PostGameplayMasterSM(NextEvent); } //set GameTime += 1 GameTime++; //printf("\r\nGameTime: %d\r\n", GameTime); RemainingTime = 138 - GameTime; //if(138 - GameTime) < TimeToDump: post START_DUMPING if (RemainingTime < DUMPTIME) { NextEvent.EventType = START_DUMPING; PostGameControlService(NextEvent); PostGameplayMasterSM(NextEvent); } //Start timer for 1000ms ES_Timer_InitTimer(GameControlTimer, 1000); //Set transition to next state CurrentState = GameOn; } else if (ThisEvent.EventType == START_DUMPING) { //Set transition to next state CurrentState = TimeToDump; } else if (ThisEvent.EventType == GAME_OVER) { //printf("Game Over %d", GameTime); //Set GameTime = 0 GameTime = 0; //post MOTOR_COMMAND (EventParam = STOP) NextEvent.EventType = MOTOR_COMMAND; NextEvent.EventParam = STOP; PostMotorSM(NextEvent); //Turn off game indicator LED HWREG(GPIO_PORTF_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT1HI; //Post transition for next event CurrentState = GameOff; } //Save history of last state LastEastRecycleColor = EastRecycleColor; LastWestRecycleColor = WestRecycleColor; } break; case TimeToDump: { switch (ThisEvent.EventType) { case ES_TIMEOUT: { //printf("Clutch time, Time: %d\n\r",GameTime); GameTime++; if (GameTime == 0) { // it is game over NextEvent.EventType = GAME_OVER; PostGameControlService(NextEvent); PostGameplayMasterSM(NextEvent); PostCompassService(NextEvent); } //Call getter functions from Compass Service AssignedTeam = GetTeamAssignment(); ColorAssigned = GetColorAssignment(); FreqAssigned = GetFreqAssignment(); EastRecycleColor = GetEastRecycleColor(); WestRecycleColor = GetWestRecycleColor(); if ((WestRecycleColor != LastWestRecycleColor) || (EastRecycleColor != LastEastRecycleColor)) { //POST CHANGE FREQUENCY EVENT HERE NextEvent.EventType = RECYCLING_CHANGE; PostGameplayMasterSM(NextEvent); } //Start timer for 1000ms ES_Timer_InitTimer(GameControlTimer, 1000); //Set transition to next state CurrentState = TimeToDump; } break; case GAME_OVER: { printf("Game Over %d", GameTime); //Set GameTime = 0 GameTime = 0; //post MOTOR_COMMAND (EventParam = STOP) NextEvent.EventType = MOTOR_COMMAND; NextEvent.EventParam = STOP; PostMotorSM(NextEvent); //Turn off game indicator LED HWREG(GPIO_PORTF_BASE + (GPIO_O_DATA + ALL_BITS)) |= BIT1HI; //Post transition for next event CurrentState = GameOff; } break; } LastEastRecycleColor = EastRecycleColor; LastWestRecycleColor = WestRecycleColor; } break; } return ReturnEvent; } /**************************************************************************** Function QueryGameControl Parameters None Returns GameControlState_t The current state of the state machine Description returns the current state of the GameControl state machine Notes Author Bibit Bianchini, 2/21/2019 ****************************************************************************/ GameControlState_t QueryGameControl(void) { return CurrentState; } /**************************************************************************** Collection of Functions GetOurLandfillFreq GetOurRecycleBeaconFreq Parameters None Returns uint16_t : the frequencies Description Returns the frequencies of our current landfill and recyling center beacons. Notes Author Bibit Bianchini, 2/25/2019 ****************************************************************************/ uint16_t GetOurLandfillFreq(void) { // based on what team we are on if (GetTeamAssignment() == NORTH) { return NorthLandfillFreq; } else { return SouthLandfillFreq; } } uint16_t GetOurRecycleBeaconFreq(void) { // based on which recycling center is accepting our color uint8_t OurColor = GetColorAssignment(); if (GetEastRecycleColor() == OurColor) { return EastRecyclingFreq; } else { return WestRecyclingFreq; } } /*************************************************************************** private functions ***************************************************************************/ static void TurnOnPWMEmitters(void) { uint16_t RecycleOpenFreq; RecycleOpenFreq = GetOurRecycleBeaconFreq(); //Set Initial PWM Frequency PWM_SetFrequency(RecycleOpenFreq, RecycleEmitter); //Turn off PWM frequency PWM_SetDuty(50, RecycleEmitter); //Enable PWM line HWREG(PWM1_BASE + PWM_O_ENABLE) |= PWM_ENABLE_PWM0EN; } /*------------------------------- Footnotes -------------------------------*/ /*------------------------------ End of file ------------------------------*/