/**************************************************************************** Module Cannon_SM.c Revision 1.0.1 Description This is the first service for cannon state machine under the Gen2 Events and Services Framework. Notes ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ /* include header files for this service */ #include "Cannon_SM.h" #include <string.h> #include <stdlib.h> #include "Cannon.h" #include "Servo.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) uint16_t DELTA = 3*(COUNT_UPPER_LIM-COUNT_LOWER_LIM)/100.0; /*---------------------------- Module Functions ---------------------------*/ /* prototypes for private functions for this service.They should be functions relevant to the behavior of this service */ bool PotChecker(void); /*---------------------------- Module Variables ---------------------------*/ // with the introduction of Gen2, we need a module level Priority variable static uint8_t MyPriority; static Cannon_SMState_t CurrentSMState; static uint16_t CurrentCannonADCount; // 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 InitCannon_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 InitCannon_SM ( uint8_t Priority ) { ES_Event_t ThisEvent; MyPriority = Priority; //Init cannon hardware Cannon_HWInit(); //Initialize cannon position CurrentCannonADCount = Cannon_GetPotValue(); Cannon_UserPosition(CurrentCannonADCount); //Set SM currentstate CurrentSMState = IdleNotPlaying; //Intialzie Deferral Queue ES_InitDeferralQueueWith(DeferralQueue, ARRAY_SIZE(DeferralQueue)); // post the initial transition event ThisEvent.EventType = ES_INIT; if (ES_PostToService(MyPriority, ThisEvent) == true) { return true; } else { return false; } } /**************************************************************************** Function PostCannon_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 PostCannon_SM( ES_Event_t ThisEvent ) { return ES_PostToService( MyPriority, ThisEvent); } /**************************************************************************** Function RunCannon_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 RunCannon_SM( ES_Event_t ThisEvent ) { //ES_Event_t NewEvent; ES_Event_t ReturnEvent; ReturnEvent.EventType = ES_NO_EVENT; UI_State_t CannonState; switch (CurrentSMState) { case IdleNotPlaying: //If power has been regenerated if (ThisEvent.EventType == Power_Complete) { //Update SM State CurrentSMState = IdlePlaying; } break; case IdlePlaying: //If RST or end of game event if (ThisEvent.EventType == RST || ThisEvent.EventType == End_Of_Game) { //Update SM state CurrentSMState = IdleNotPlaying; } //else if meteor is destroyed else if (ThisEvent.EventType == Meteor_Destroyed) { //Start timer ES_Timer_InitTimer(CANNON_TIMER, 1500); //Start vibratory motor CannonState = On; Cannon_Vibrate(CannonState); //Update current state CurrentSMState = KnobVibrating; } //else if cannon button is pressed else if (ThisEvent.EventType == Cannon_Button_Down) { //Start timer ES_Timer_InitTimer(CANNON_TIMER, 500); //Turn on LED CannonState = On; Cannon_LED(CannonState); //Update SM state CurrentSMState = LEDLit; } //Else if we receive a new pot value else if(ThisEvent.EventType == New_Pot_Value) { //Position cannon Cannon_UserPosition(ThisEvent.EventParam); } break; case LEDLit: //If RST or end of game event if (ThisEvent.EventType == RST || ThisEvent.EventType == End_Of_Game) { //Update SM state CurrentSMState = IdleNotPlaying; //Turn off LED CannonState = Off; Cannon_LED(CannonState); } //else if we get a timeout else if (ThisEvent.EventType == ES_TIMEOUT) { //Update SM state CurrentSMState = IdlePlaying; //Turn off LED CannonState = Off; Cannon_LED(CannonState); ES_RecallEvents(MyPriority, DeferralQueue); } else if (ThisEvent.EventType == Meteor_Destroyed) { ES_DeferEvent(DeferralQueue, ThisEvent); } break; case KnobVibrating: if (ThisEvent.EventType == RST || ThisEvent.EventType == End_Of_Game) { //Update SM state CurrentSMState = IdleNotPlaying; //Turn off vibratory motor CannonState = Off; Cannon_Vibrate(CannonState); } //else if we get a timeout else if (ThisEvent.EventType == ES_TIMEOUT) { //Update SM state CurrentSMState = IdlePlaying; //Turn off vibratory motor CannonState = Off; Cannon_Vibrate(CannonState); } break; } return ReturnEvent; } /*************************************************************************** private functions ***************************************************************************/ /*** PotChecker Function Description Arguments: none Returns: bool. True if there is a new event This function check for the change in knob position Author: Trey Weber ***/ bool PotChecker(void) { ES_Event_t NewEvent; bool ReturnVal = false; //Get AD Pot value uint16_t ADPotVal = Cannon_GetPotValue(); //If pot has been turned more than 1% if (abs(ADPotVal-CurrentCannonADCount) > DELTA) { //Post to service NewEvent.EventType = New_Pot_Value; NewEvent.EventParam = ADPotVal; PostCannon_SM(NewEvent); ReturnVal = true; //Update AD value CurrentCannonADCount = ADPotVal; } return ReturnVal; } /*------------------------------- Footnotes -------------------------------*/ /*------------------------------ End of file ------------------------------*/