RunSPISM { Initialize unsigned char SPIResponse Initialize an index i for commands Initialize an array of FSR SPI commands Initialize events: ReturnEvent, PostEvent, StartEvent Set starting flag to FALSE switch ( CurrentState ) { case InitSPIState : // If current state is initial Psedudo State Start current state in initial pseudo state IF Event is ES_Init Initialize SPI IF SPI Transmit Empty Flag is set send 0xFD to check for number of balls in play move on to waiting state ENDIF ENDIF case PreGameFirstResponseSPI : // If current state is state one IF new SPI input detected (SPI Interrupt Flag is set) Read in the SPI from EventParameter Go to waiting for byte timeout ENDIF case PreGameWaitByteSPI : // If current state is state one IF 2 ms has passed IF SPI Transmit Empty Flag is set send 0x00 move on to waiting state ENDIF ENDIF case PreGameSecondResponseSPI : // If current state is state one IF new SPI input detected (SPI Interrupt Flag is set) Read in the SPI from EventParameter Check to see if the game has started IF the SPI input is not out of sync or bad command IF number of balls is 0 set starting flag to TRUE, we are ready to start once the number changes ENDIF ENDIF IF the number of balls in play is greater than zero and the starting flag is set send starting command to GameTimerService and GamePlayHSM - we are starting the game move state from pregame to game ELSE go back to pregame command state and send out command to check for number of balls again ENDIF ENDIF case PreGameCommandSPI : // If current state is state one IF SPI Transmit Empty Flag is set send 0xFD to check for number of balls in play move on to waiting state ENDIF case CommandSPI: IF SPI Transmit Empty Flag is set loop through the index i and send next SPI query move on to waiting state ENDIF case FirstResponseSPI : IF new SPI input detected (SPI Interrupt Flag is set) Read in the SPI from EventParameter Go to waiting for byte timeout ENDIF case WaitByteSPI : IF 2 ms has passed IF SPI Transmit Empty Flag is set send 0x00 move on to waiting state ENDIF ENDIF case SecondResponseSPI : // If current state is state one IF new SPI input detected (SPI Interrupt Flag is set) Read in the SPI from EventParameter IF the SPI input is not out of sync or bad command\ update parameters based on query index update query index assign data to data structure BinData - determine how many balls we own vs. how many balls opponents own get score and determine winning or losing check for wall movement check for score updates update GamePlayHSM move state to send next command ENDIF ENDIF } SPIState_t QuerySPISM ( void ) { Return the current state of the SPI state machine; } Public Functions: /**************************************************************************** Function CheckForMovingWall Parameters None Returns signed char If the wall has moved since last check, +1 for increasing angle -1 for decreasing angle, and 0 for unchanged Notes Author B. Garcia, 3/2/12 ****************************************************************************/ signed char CheckForMovingWall(void) { Local variables: Boolean returnVal Static unsigned int lastAngle Set returnVal to false If lastAngle is less than angle) Set returnVal to 1 else if lastAngle is greater than angle Set ReturnVal to -1 Update lastAngle to angle return returnVal; } /**************************************************************************** Function CheckForUpdatedScore Parameters None Returns boolean If the score has updated since last check Notes Author B. Garcia, 3/2/12 ****************************************************************************/ boolean CheckForUpdatedScore(void) { Function level variables: boolean returnVal = False; static unsigned int lastbin1 static unsigned int lastbin2 static unsigned int lastbin3 static unsigned int lastbin4 if one or more bins changed since last time { Set returnval to true } return returnVal; } /**************************************************************************** Function NumBinsToWin Parameters None Returns uchar How many bins are needed to win. Answer will be 1 or 2. Notes Author B. Garcia, 3/2/12 ****************************************************************************/ unsigned char NumBinsToWin(void) { Local Variables: unsigned char i; unsigned char NumOfWinningBins = 2; if any one bin contains greater than or equal to half the balls in play set NumOfWinningBins to 1 end if return NumOfWinningBins /**************************************************************************** Function FirstQuadrantToWin Parameters None Returns uchar Which quadrant has the most balls. "1" Corresponds to Quadrant I, etc. Notes Author B. Garcia, 3/2/12 ****************************************************************************/ unsigned char FirstQuadrantToWin(void) { Function level variables: unsigned char QuadrantWithMostBalls = 0; unsigned char i; unsigned char mostBalls = 0; Search Bin_Data for the bin with most balls Update QuadrantWithMostBalls and mostBalls correspondingly return QuadrantWithMostBalls; } /**************************************************************************** Function FirstQuadrantToWin Parameters None Returns uchar Which quadrant has the most balls. "1" Corresponds to Quadrant I, etc. Notes Author B. Garcia, 3/2/12 ****************************************************************************/ uchar FindNearestWall(uchar currentQuad) { Function level variables: unsigned char desiredDirection; unsigned char CW_Quad_of_Current; unsigned char CCW_Quad_of_Current; Update CW_Quad_of_Current to currentQuad + 1 If CW_Quad_of_Current equals 5 set CW_Quad_of_Current to 1 Update CCW_Quad_of_Current to currentQuad - 1 If CCW_Quad_of_Current equals 0 Set CCW_Quad_of_Current to 4 If they own the CW bin Set desiredDirection to CW Else if they own the CCW bin Set desiredDirection to CCW End if Return desiredDirection /**************************************************************************** Function SecondQuadrantToWin Parameters None Returns uchar Which quadrant has the 2nd most balls. Returns 0 if both neighboring quadrants have the same amount of balls. Notes Author B. Garcia, 3/2/12 ****************************************************************************/ unsigned char SecondQuadrantToWin(void) { Function level variables: unsigned char QuadrantWithMostBalls; unsigned char QuadrantWith2ndMostBalls; unsigned char CW_of_QuadWithMostBalls; unsigned char CCW_of_QuadWithMostBalls; Set QuadrantWithMostBalls to FirstQuadrantToWin(); Define CW_of_QuadWithMostBalls as QuadrantWithMostBalls + 1; If CW_of_QuadWithMostBalls equals 5 Set CW_of_QuadWithMostBalls to 1 Define CCW_of_QuadWithMostBalls as QuadrantWithMostBalls - 1; If CCW_of_QuadWithMostBalls equals 0 Set CCW_of_QuadWithMostBalls to 4; If CW_of_QuadWithMostBalls has more balls than CCW_of_QuadWithMostBalls QuadrantWith2ndMostBalls is CW_of_QuadWithMostBalls else if CW_of_QuadWithMostBalls has less balls than CCW_of_QuadWithMostBalls QuadrantWith2ndMostBalls is CCW_of_QuadWithMostBalls; Else set QuadrantWith2ndMostBalls to 0; Call getBinNumberAtQuadrant(QuadrantWith2ndMostBalls)) to find the corresponding bin number return QuadrantWith2ndMostBalls; /**************************************************************************** Function OwnedQuadrantWithMostBalls Parameters None Returns uchar Which quadrant has the most balls on our side of the wall. Notes Author B. Garcia, 3/2/12 ****************************************************************************/ unsigned char OwnedQuadrantWithMostBalls(void) Function level variables: unsigned char i; unsigned char firstOwnedQuadrant = 0; unsigned char secondOwnedQuadrant = 0; boolean jump = False; unsigned char Quadrant; unsigned char mostBalls = 0; Loop through the bins to find which are owned If firstOwnedQuadrant has more balls than SecondOwnedQuadrant Return firstOwnedQuadrant; else Return secondOwnedQuadrant; /**************************************************************************** Function AreWallAnglesTolerable Parameters None Returns uchar Which bin has the most balls. "1" Corresponds to Quadrant I, etc. Notes Author B. Garcia, 3/2/12 ****************************************************************************/ boolean AreWallAnglesTolerable(void) return weAreWinning; /**************************************************************************** Function IsMostFullQuadrantOwned Parameters None Returns uchar Which bin has the most balls. "1" Corresponds to Quadrant I, etc. Notes Author B. Garcia, 3/2/12 ****************************************************************************/ boolean IsMostFullQuadrantOwned(void) Function level variables: boolean returnVal = Fals unsigned char QuadrantWithMostBalls Call FirstQuadrantToWin() to find QuadrantWithMostBalls If we own QuadrantWithMostBalls returnVal is True return the returnVal /**************************************************************************** Function getBinNumberAtQuadrant Parameters None Returns uchar The identity of the bin at the selected quadrant. Notes Author B. Garcia, 3/2/12 ****************************************************************************/ unsigned char getBinNumberAtQuadrant(unsigned char Quad) return the identity of the bin at the selected quadrant. Private functions: void SPITimerInitTEST(void) Initialize the timer to 1ms rate Set the baud rate Set clock setting to mode 3 void BinUpdate(unsigned char index) { If index is 0 If the saved color is RED Assign bin1 score to Q4 Else assign bin1 score to Q2 break; if index is 1 if the saved color is RED Assign bin2 score to Q3, Else assign bin2 score to Q1 break; if index is 2 if the saved color is RED assign bin3 score to Q2 else assign bin3 score to Q4 break; if index is 3: if the saved color is RED assign bin 4 score to Q1 else assign bin3 score to Q3 break; if index is 4 call ClassifyAngle() break; void SetUpBinStructure(unsigned char color) { If the team color is Red Store saved_color as RED; Initialize the bin structure to define which quadrants correspond to the different bins else if team color is Blue Store saved_color as RED; Initialize the bin structure to define which quadrants correspond to the different bins static void ClassifyAngle(void) { If the current angle is less than WALL_ANGLE_A Update Bin_Data structure to reflect who owns the different bins Else if the current angle is less than WALL_ANGLE_B Update Bin_Data structure to reflect who owns the different bins Else if the current angle is less than WALL_ANGLE_C Update Bin_Data structure to reflect who owns the different bins Else if the current angle is less than WALL_ANGLE_D Update Bin_Data structure to reflect who owns the different bins Else if the current angle is less than WALL_ANGLE_E Update Bin_Data structure to reflect who owns the different bins Else if the current angle is less than WALL_ANGLE_F Update Bin_Data structure to reflect who owns the different bins Else if the current angle is less than WALL_ANGLE_G Update Bin_Data structure to reflect who owns the different bins Else if the current angle is less than WALL_ANGLE_H Update Bin_Data structure to reflect who owns the different bins Else Update Bin_Data structure to reflect who owns the different bins