Security_ISR: Interrupt Response Routine, No Inputs, No Outputs If interrupt was due to the timer subsystem Call the timer interrupt response routine If interrupt was due to the SPI subsystem Call SPIReceive to process the message Turn off the SPI interrupt flag If interrupt was due to CCP3 Call the OutputCompareISR function InitSPI: No Input, No Output Configure SPI port No write collision detect No receive overflow indicator Enable serial port, SCK, SDO, SDI as serial pins Clock idles high SPI Slave, SS pin control enabled, Use Timer2/2 Set SPI status register to Data sampled in middle of output Data transmitted on falling edge of SCK Read only Turn On SPI interrupt Clear buffer SPIReceive: No Input, No Output If SPI buffer is full Store the buffer value into SSPArray at the appropriate index Increment the index by one If the index is greater than 6, we have received all 6 bytes If the Swiped Card is not one of the Team Color Cards Set the ColorSwipeFlag to Zero Check the 3rd byte of SSPArray, and see what it matches If Atoll #1, Card 1 Set RFIDScanned to ATOLL1_SWIPE If Atoll #1, Card 2 Set RFIDScanned to ATOLL1_SWIPE If Atoll #2, Card 1 Set RFIDScanned to ATOLL2_SWIPE If Atoll #2, Card 2 Set RFIDScanned to ATOLL2_SWIPE If Atoll #3, Card 1 Set RFIDScanned to ATOLL3_SWIPE If Atoll #3, Card 2 Set RFIDScanned to ATOLL3_SWIPE If Atoll #4, Card 1 Set RFIDScanned to ATOLL4_SWIPE If Atoll #4, Card 2 Set RFIDScanned to ATOLL4_SWIPE If Atoll #5, Card 1 Set RFIDScanned to ATOLL5_SWIPE If Atoll #5, Card 2 Set RFIDScanned to ATOLL5_SWIPE If State is GAME_IDLE or GAME_ON and Red Tag was Swiped Set RFIDScanned to RED_SWIPE Set TeamColor to RED and ColorSwipeFlag to 1 Turn on the RED debug LED Else if State is GAME_IDLE or GAME_ON and Green Tag was Swiped Set RFIDScanned to GREEN_SWIPE Set TeamColor to GREEN and ColorSwipeFlag to 1 Turn on the Green Debug LED Else if White Card was scanned Set RFIDScanned to WHITE_SWIPE Set Team Color to No Color Turn off all Team Color LEDs Set ColorSwipeFlag to 1 Reset Servos to the NO_FLAG position Else Set ColorSwipeFlag to 0 If RFIDcard scanned was not a color flag Send request atoll capture message to the Atoll Reset SPI byte counter to 0 GetReply: No Input, No Output If a new message has been completely received Get the length of the message by calling ReturnDataSize For each byte in the message Store the message into the ReceivedData array of the approrpriate index Set the CurrentMessage received to the output of ProcessMSG CalculateLeftSpeed: Takes unsigned char Speed and unsigned char Direction, Returns unsigned char returnSpeed If Heading is less than 90 and Speed greater than 0 tempSpeed = Speed - Speed*(90 - Heading)/90 If 90 - Heading is greater than the TURN_THRESHOLD Subtract TURN_OFFSET from tempSpeed If tempSpeed is negative Set returnSpeed to 0 Otherwise tempSeed is returnSpeed else if Heading is greater than 90 and Speed is greater than 0 returnSpeed = Speed + Speed*(Heading - 90)/90 If Heading - 90 is greater than TURN_THRESHOLD Subtract TURN_OFFSET from returnSpeed Otherwise returnSpeed is 0 If Direction is equal to 1, We are going Forward Set Direction Pin (RD4) HI If Direction is equal to 0, We are going Backward Set Direction Pin (RD4) LO Convert speeds 0-100 to PWM 20-100 CalculateRightSpeed: Takes unsigned char Speed and unsigned char Direction, Returns unsigned char returnSpeed If Heading is less than 90 and Speed greater than 0 returnSpeed = Speed + Speed*(90 - Heading)/90 If 90 - Heading is greater than the TURN_THRESHOLD Subtract TURN_OFFSET from returnSpeed else if Heading is greater than 90 and Speed is greater than 0 tempSpeed = Speed - Speed*(Heading - 90)/90 If Heading - 90 is greater than TURN_THRESHOLD Subtract TURN_OFFSET from tempSpeed If tempSpeed is negative returnSpeed is 0 Otherwise returnSpeed is tempSpeed Otherwise returnSpeed is 0 If Direction is equal to 1, We are going Forward Set Direction Pin (RD5) LO If Direction is equal to 0, We are going Backward Set Direction Pin (RD5) HI Convert speeds 0-100 to PWM 20-100 HandleReceivedmessage: Takes no inputs, Returns no outputs Call GetReply to see if a new message was received If TeamColor Flag is set to No_COLOR, we have been swiped by a white card Set GameState to GAME_IDLE Switching on CurrentMessage If it is a drive command Toggle Port B0 for debugging Set the Speed and RefDirection from the received message Save our reference speed for controller If Control is ON Call CalculateLeftSpeed with Speed/RefDirection/RefHeading to get Left Speed. Call CalculateRightSpeed with Speed/RefDirection/RefHeading to get Right Speed Call SetDuty with LeftSpeed and RightSpeed Reset the CurrentMessage to NoMesssage Switching on GameState If GameState is GAME_IDLE If SPI Message was a Color Swipe Set ColorSwipeFlag to 0 Start Teammmate Timer Set The next GameState to LISTEN_FOR_TEAMMATE If a White Card Was Swiped Set ColorSwipeFlag to 0 Send the Team Color Send the Atoll# 0 to indicate a clear atoll command Create the Packet as a B2C (Boat to Controller) Command Reset the current message to no message If GameState is LISTEN_FOR_TEAMMATE If current Message was a Color BroadCast from Team Mate if Teammate was your color Found a Teammate, Send A Directed Reply Team ACK until ACK Received Back Extract Address MSB Set Next GameState to WAITING_FOR_ACK Reset current message to NoMessage If CurrentMessage is NoMessage If Teammate Timer Times out, No Teammate Found Start Broadcasting Request For Teammate Initalize BroadcastCounter to 0 Set GameState to BROADCAST_TEAM_MESSAGE If any other message was received Ignore, and reset current message to NoMessage If GameState is WAITING_FOR_ACK If message received was ModemACK Reset BroadcastCounter to 0 If TeamColor is Red Call SetServo to Raise the Red Flag else if TeamColor is Green Call SetServo to Raise the Green Flag Set GameState to GAME_ON Reset CurrentMessage to No Message If NoMessage Received If BroadcastCounter is less than 10 If Message Was Broadcasted Send Another Message otherwise We've Exceeded max 10 Messages Return to GAME_IDLE State Set BroadcastCounter to 0 If any other message was received Ignore, and reset current message to NoMessage If GameState is BROADCAST_TEAM_MESSAGE If CurrentMessage is TeammateACK If ACK received, Teammate Found with same color Set GameState to GAME_ON Reset BroadcastCounter to 0 If TeamColor is Red Call SetServo to RED_FlAG If TeamColor is Green Call SetServo to GREEN_FLAG Reset CurrentMessage to No Message If BroadcastCounter is less than 255 If Message Was Broadcasted Send another Team Broadcast message Increment the BroadcastCounter Otherwise we've timed Out Call SetServo to place Flag in TIMEOUT_FLAG position Reset BroadcastCounter to 0 If any other message was received Ignore, and reset current message to NoMessage If GameState is GAME_ON If TeamColor is NO_COLOR, a White Card was Swiped Set GameState to GAME_IDLE Otherwise If Current Message was AtollSuccess Send Atoll Captured Broadcast Set Current Message to NoMessage If Current Message was AtollFailure Resend Atoll Capture Request If we fail, just send out who owns it Set Current Message to NoMessage If Current Message was AtollCaptured Do Nothing If Any other message was recieved And the message was not NoMessage Set the CurrentMessage to NoMessage Main: Takes No Inputs, Returns No Outputs Turn off analog inputs (PCFG = 1111) Set Debug LED ports as outputs (B0,D0,D2,D3,D4,D5) Initialize Ports (RB0 = ON/ RD0 = RD2 = RD3 = RD4 = RD5 = OFF) Initialize Servo Subsytem Initialize PWM Subsystem Initialize SPI Subsystem (Make sure to InitSPI After InitSPI) Initialize UART Subsystem Initialize A2D Subsystem Initialize TimerPIC Subsystem Initialize SendTimer to SENDTIMEOUT Value Initialize ControlTimer to CONTROLPERIOD value Initialize Counter to 0 Enable Interrupts Loop Forever: Run Transmit State Machine Run Reeceived Message State Machine Run Handle Recevied Message State Machine