/**************************************************************************** Module BallSortingService.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 "BallSortingService.h" // Hardware #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "inc/hw_sysctl.h" // Event & Services Framework #include "ES_Configure.h" #include "ES_Framework.h" #include "ES_DeferRecall.h" #include "ES_ShortTimer.h" #include "ES_Port.h" //Other Stuff #include "I2CService.h" #include "ServoModule.h" #include "CompassService.h" #include "GameplayHSM.h" #include "GameControlService.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 ENTER_POST ((MyPriority << 3) | 0) #define ENTER_RUN ((MyPriority << 3) | 1) #define ENTER_TIMEOUT ((MyPriority << 3) | 2) //Define Servo positions #define SERVO_CENTER #define SERVO_RECYCLE #define SERVO_LANDFILL //Define max storage #define MAX_RECYCLE 5 #define MAX_LANDFILL 6 // #define ALL_BITS (0xff<<2) Moved to ES_Port.h /*---------------------------- Module Functions ---------------------------*/ /* prototypes for private functions for this service.They should be functions relevant to the behavior of this service */ static uint8_t CategorizeColor(void); /*---------------------------- Module Variables ---------------------------*/ // with the introduction of Gen2, we need a module level Priority variable static uint8_t MyPriority; // add a deferral queue for up to 3 pending deferrals +1 to allow for ovehead static ES_Event_t DeferralQueue[3 + 1]; static BSState_t CurrentState; //Define counter values static uint8_t RecycleCount; static uint8_t LandfillCount; //Define color static uint8_t CurrentColor = 0; //Define game inactive or active flag static bool GameActive = false; //Define boolean variable for ball storing static bool HoldBallRecycle; //Set boolean variable for identifying if recycling center is full static bool FullRecycle = false; static bool FullLandfill = false; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function InitBallSortingService 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 J. Edward Carryer, 01/16/12, 10:00 ****************************************************************************/ bool InitBallSortingService(uint8_t Priority) { ES_Event_t ThisEvent; MyPriority = Priority; /******************************************** in here you write your initialization code *******************************************/ // initialize deferral queue for testing Deferal function ES_InitDeferralQueueWith(DeferralQueue, ARRAY_SIZE(DeferralQueue)); SetupAllServoFrequencies(); SetServoStartingPositions(); //Reset ball counters LandfillCount = 0; RecycleCount = 0; //Set servo to neutral position //PWMSERVO(8,SERVO_CENTER); //PLACEHOLDER// //Set next state to Initial pseudostate CurrentState = InitBSState; // post the initial transition event ThisEvent.EventType = ES_INIT; printf("Sorter"); if (ES_PostToService(MyPriority, ThisEvent) == true) { return true; } else { return false; } } /**************************************************************************** Function PostBallSortingService 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 PostBallSortingService(ES_Event_t ThisEvent) { return ES_PostToService(MyPriority, ThisEvent); } /**************************************************************************** Function RunBallSortingService Parameters ES_Event : the event to process Returns ES_Event, ES_NO_EVENT if no error ES_ERROR otherwise Description add your description here Notes Author J. Edward Carryer, 01/15/12, 15:23 ****************************************************************************/ ES_Event_t RunBallSortingService(ES_Event_t ThisEvent) { ES_Event_t ReturnEvent; ReturnEvent.EventType = ES_NO_EVENT; // assume no errors ES_Event_t NextEvent; // we will force the ball sorting service to always sort, no matter if // the game has started or not GameActive = true; switch (CurrentState) { case InitBSState: { //Initial State if (ThisEvent.EventType == ES_INIT) { //Reset ball counters LandfillCount = 0; RecycleCount = 0; printf("Setting values to 0\n\r"); //Set servo to neutral position ResetSorter(); //Set for No Ball CurrentState = NoBall; } } break; case NoBall: { puts("No ball\n\r"); if ((ThisEvent.EventType == BALL_AT_COLOR_SENSOR) && (GameActive == false)) { //Ball detected, but game is idle, keep waiting printf("Game Stopped\n\r"); CurrentState = NoBall; } else if ((ThisEvent.EventType == BALL_AT_COLOR_SENSOR) && (GameActive == true) && (ThisEvent.EventParam == 1) && (FullRecycle == false)) { //Ball is recycling, store in bin 1 //Set Servo to recycling direction //PLACEHOLDER for final integration SortRecycle(); //Increase Recycle count RecycleCount++; printf("Recycle recieved %d ball collected\n\r", RecycleCount); //Check if Recycle Count has gotten to the max value if (RecycleCount == MAX_RECYCLE) { printf("RECYCLE FULL, PLEASE EMPTY"); FullRecycle = true; //PLACEHOLDER for gameplay NextEvent.EventType = RECYCLE_FULL; PostBallSortingService(NextEvent); } //Start Timer for 500ms ES_Timer_InitTimer(ColorServoTimer, 500); //Set next state to Emptying CurrentState = Emptying; } else if ((ThisEvent.EventType == BALL_AT_COLOR_SENSOR) && (GameActive == true) && (ThisEvent.EventParam == 0) && (FullLandfill == false)) { //Ball is trash, store in bin 2 //Set Servo to landfill direction SortTrash(); //Increase Landfill count LandfillCount++; printf("Landfill recieved %d ball collected\n\r", LandfillCount); //Check if Landfill Count has gotten to the max value if (LandfillCount == MAX_LANDFILL) { //Set Max recycle flag active printf("LANDFILL FULL, PLEASE EMPTY"); FullLandfill = true; //PLACEHOLDER for gameplay post NextEvent.EventType = TRASH_FULL; PostBallSortingService(NextEvent); } //Start Timer for 500ms ES_Timer_InitTimer(ColorServoTimer, 500); //Set next state to Emptying CurrentState = Emptying; } else if ((ThisEvent.EventType == BALL_AT_COLOR_SENSOR) && (GameActive == true) && (ThisEvent.EventParam == 1) && (FullRecycle == true)) { printf("Recycle Full\n\r"); //Recycling is full,store ball type HoldBallRecycle = true; CurrentState = WaitingForBall; } else if ((ThisEvent.EventType == BALL_AT_COLOR_SENSOR) && (GameActive == true) && (ThisEvent.EventParam == 0) && (FullLandfill == true)) { printf("Trash Full\n\r"); //Landfill is full,store ball type HoldBallRecycle = false; CurrentState = WaitingForBall; } else if (ThisEvent.EventType == GAME_OVER) { printf("Game over, emptying\n\r"); //Return Servo to normal position ResetSorter(); //Reset ball counters LandfillCount = 0; FullLandfill = false; RecycleCount = 0; FullRecycle = false; //Return to no ball state CurrentState = NoBall; } else if ((ThisEvent.EventType == RECYCLE_EMPTY) && (GameActive == true)) { //Reset recycling ball counter puts("Emptying recycle"); RecycleCount = 0; FullRecycle = false; } else if ((ThisEvent.EventType == TRASH_EMPTY) && (GameActive == true)) { //Reset recycling ball counter puts("Emptying trash"); LandfillCount = 0; FullLandfill = false; } } break; case WaitingForBall: { puts("Wait 4 ball\n\r"); if (ThisEvent.EventType == GAME_OVER) { //Return Servo to normal position ResetSorter(); //Reset ball counters LandfillCount = 0; RecycleCount = 0; //Return to no ball state CurrentState = NoBall; } else if ((ThisEvent.EventType == RECYCLE_EMPTY) && (HoldBallRecycle == false)) { //Reset ball Counter RecycleCount = 0; FullRecycle = false; } else if ((ThisEvent.EventType == RECYCLE_EMPTY) && (HoldBallRecycle == true)) { //Reset ball Counter RecycleCount = 0; //Reset FullRecycle flag FullRecycle = false; //Ball is recycling, store in bin 1 SortRecycle(); //Add 1 to counter RecycleCount++; //Start 500 ms timer ES_Timer_InitTimer(ColorServoTimer, 500); //Set next state to Emptying CurrentState = Emptying; } else if ((ThisEvent.EventType == TRASH_EMPTY) && (HoldBallRecycle == true)) { //Reset ball Counter LandfillCount = 0; FullLandfill = false; } else if ((ThisEvent.EventType == TRASH_EMPTY) && (HoldBallRecycle == false)) { //Reset ball Counter LandfillCount = 0; //Reset FullLandfill flag FullLandfill = false; //Ball is Landfill, store in bin 0 SortTrash(); //Add 1 to counter LandfillCount++; //Start 500 ms timer ES_Timer_InitTimer(ColorServoTimer, 500); //Set next state to Emptying CurrentState = Emptying; } } break; case Emptying: { puts("Emptying\n\r"); //Timeout for servo if ((ThisEvent.EventType == ES_TIMEOUT) && (ThisEvent.EventParam == ColorServoTimer)) { printf("Servo returns\n\r"); //Return Servo to normal position ResetSorter(); //Return to no ball state CurrentState = NoBall; } else if (ThisEvent.EventType == TRASH_EMPTY) { //Reset ball Counter LandfillCount = 0; FullLandfill = false; } else if (ThisEvent.EventType == RECYCLE_EMPTY) { //Reset ball Counter RecycleCount = 0; FullRecycle = false; } else if (ThisEvent.EventType == GAME_OVER) { printf("Servo returns\n\r"); //Return Servo to normal position ResetSorter(); //Reset ball counters LandfillCount = 0; RecycleCount = 0; FullRecycle = false; FullLandfill = false; //Return to no ball state CurrentState = NoBall; } } break; default: {} break; } return ReturnEvent; } bool QueryNoBall(void) { if (CurrentState == NoBall) { return true; } else { return false; } } /*************************************************************************** private functions ***************************************************************************/ /*------------------------------- Footnotes -------------------------------*/ /*------------------------------ End of file ------------------------------*/