Red October
     an ME218C Project

ME218C: Red October

Dept. of Mechanical Eng. | Stanford University



Meaningless graphic

C Code

File Menu
main.c    helm_input.c    helm_display.c    ibutton.c    xbee.c   
helm_input.h helm_display.h ibutton.h xbee.h
// MAIN.C
// in E128_Integrated Project

// Matthew Hill, Taylor Penn, Michael Wittenberg




#include <hidef.h>      /* common defines and macros */
#include <mc9s12e128.h>     /* derivative information */
#include <S12E128bits.h>

#include <stdio.h>
#include "S12eVec.h"
#include "XBee.h"
#include "iButton.h"
#include "helm_display.h"
#include "ADS12.H"
#include "helm_input.h"
 
#define REFRESH_PERIOD 37500 
#define YES 1
#define NO 0

#define WAITING_FOR_IBUTTON     17
#define SEND_IBUTTON_MESSAGE    18
#define LOOKING_FOR_WATERCRAFT  19
#define PAIRED                  20
#define PLAYING_GAME            21
#define ENGAGEMENT_OVER         22
#define STANDING_DOWN           23

#define IBUTTON 0x01

#define COMMAND 0x02

#define NO_ACTION_NAV 0x88
#define NO_ACTION_SPECIAL 0x00


// 
#define FULL_STAND_DOWN         50
//all of these are in the special byte, the navigation byte is zero
#define ADMIRAL 0x04
#define STAND_DOWN 0x01
#define START_GAME 0x02
#define END_GAME 0x04
#define BLUE_GOAL 0x08
#define RED_GOAL 0x10
#define HARD_RESET 0x40
#define PING 0x80
#define SOFT_RESET 0x20

#define PING_RESPONSE 0x10 

#define ADMIRAL_ADDRESS_MSB 0xBC
#define ADMIRAL_ADDRESS_LSB 0xFF
 


// incoming data HEADERS 
#define ADMIRAL_HEADER 0x04
#define CRAFT_HEADER   0x08
//no action for these, but to see what we are receiving
#define IBUTTON_HELM_HEADER 0x01
#define HELM_HEADER 0x02	   


// completely unecessary animation flags
#define CIRCLE  1
#define FLASH_PAIRED   2
#define DOUBLE_CIRCLE 3
 
void Main_Init(void);
void InitializePeriodTimer(void);


// message parsing functions, defines
void Message_Machine(void);
void Handle_Admiral(void);

void Handle_iButton(void);
void Handle_Craft(void);
void Import_Message_Machine(void);

void InitializeSecondTimer(void);


void Send_If_Needed(void);


// Message_In; */
static unsigned char Message_In[12];     //array of 12 chars
static char NeedToSend = 0;              //only used in returning array from a function



static unsigned char destination_MSB = 0x00;
static unsigned char destination_LSB = 0x00;

static unsigned char header_in = 0x00;
static unsigned char navigation_in = 0x00;

static unsigned char special_in = 0x00;                                                

static unsigned char keypress_throttle = 0x00;

static unsigned char keypress_direction = 0x00;

static unsigned char incoming_address_MSB = 0x00;

static unsigned char incoming_address_LSB = 0x00;

// pairing stuff
static unsigned char paired_Address_LSB = 0x00;

static unsigned char paired_Address_MSB = 0x00;
static unsigned char iButton_LSB = 0x00;

static unsigned char iButton_MSB = 0x00;    

static unsigned char game_state = WAITING_FOR_IBUTTON;


 // **********************************************************
 // test code #defines
 // **********************************************************


//#define _TRANSMIT_TEST
//#define _SEGMENT_DISPLAY_TEST 
//#define _INPUTS_TEST
//#define _LEDS_TEST

#define _GAME_CODE






// _GAME_CODE IS THE MAIN CODE
// IT PLAYS THE GAME

#ifdef _GAME_CODE
    //    static char game_state = WAITING_FOR_IBUTTON;		< -- now a module level variable

// initialize variables    

// Module variables

    static unsigned int next_time = 0;	 				
    static int counter_test = 0;

    static int i;
    static char key_press;
    static unsigned char iButton_last_msb;

    static unsigned char iButton_last_lsb;

    static long int stand_down_counter = FULL_STAND_DOWN;  // to time the standown

    static char animateFlag = 0;	  					   // to animate
    static int  animate_counter = 0;					   // " 

   
 
void main()
{
  
// Initializes the variables we need  
    int voice = 17;

    int roll = 17;
    int FSR = 17;

    int pitch = 17;
    unsigned char speedout = 17;

    unsigned char directionout = 17;
    unsigned char pumpspeedout = 17;

    unsigned char reverseout = 17;
    unsigned char special1 = 0;

    unsigned char special2 = 0;
    

// Initialize the timer that does our stand-down count
// and our animation:
    InitializeSecondTimer();                  
                        

// initialize the XBee module, the helm input ports, and the helm output ports

    XBee_Init();        
    InitDisplayPorts();
    InitInputPorts();
    
    PTT = 0xFF;  						// clear the display

	Set_XBee_Address(0x00, 0x00);       // set to an invalid address
										// so we can't spam by accident
    EnableInterrupts;


// do the following forever

    while(1)    // GAME LOOOOP
    {
      
      switch(game_state)	 		// based on the state we're in, we want to act differently

      				
      {
        case WAITING_FOR_IBUTTON:  	// if we don't have an ibutton

            printf("1 \r\n");

            animateFlag = DOUBLE_CIRCLE;// animate the "double circle   
            Message_Machine();  		// check for received messages
        
            printf("WAITING_FOR_IBUTTON state \r\n");

            InitiButtonModule(); //needs to be called each time, since it resets prescalers
            
            printf("2 \r\n");
           
            
            // see if there's an iButton present
            // this thing is blocking, but not very long at all
            // but we don't want to interrupt it...
            // we'll never get anywhere if we do
            //DisableInterrupts;
            if(PollForiButton()) { //returns true if ibutton found

            
       
      		   ReadiButton();
      		   iButton_last_msb = GetiButtonMSB();
               iButton_last_lsb = GetiButtonLSB();

               ReadiButton();
      		   if((GetiButtonMSB() == iButton_last_msb) 
      		       && (GetiButtonLSB() == iButton_last_lsb)
      		       && (iButton_last_msb != 0xFF) 
      		       && (iButton_last_msb != 0x00)) //two concurrent reads the same, and not 0x0000 or 0xFFFF

                { 
                   iButton_LSB = iButton_last_lsb;	  // store values 
                   iButton_MSB = iButton_last_msb; 
                } else printf("Second iButton read doesn't match \r\n");     
            }

            
            printf("3 \r\n");
  
            
            if ((iButton_LSB)&&(iButton_MSB)) 
            {
               	 // we're out of the iButton code, we can get interrupted

               	 
                 printf("iButton read as %x %x \r\n",iButton_MSB,iButton_LSB);
             // START THE SENDING EVER 200ms 
                Set_XBee_Address(0xFF, 0xFF);     	 
                InitializePeriodTimer();

                 game_state = SEND_IBUTTON_MESSAGE;  // only change state if we've found an iButton
                 break;  
            }
            
                printf("4 \r\n");

            
            break;
            
            
            
            
            
        case SEND_IBUTTON_MESSAGE:
        
            Message_Machine();
        
            puts("SEND_IBUTTON_MESSAGE state \r\n");

            
            // set which data we're going to send
            //header = IBUTTON;
            //navigation = GetiButtonMSB();
            //special = GetiButtonLSB();
            Set_XBee_Bytes(IBUTTON, GetiButtonMSB(), GetiButtonLSB());
            printf("iButton LSB: %x, iButton MSB: %x \r\n", GetiButtonLSB(),GetiButtonMSB());

            // enable interrupts, so we transmit every 200 ms
            EnableInterrupts;   
            // change our game state
            
            animateFlag = 0;
            PTT = middle;           // turn on only the middle dash
            					    // to show we have an ibutton, are searching

            
            game_state = LOOKING_FOR_WATERCRAFT;
            puts("changed state to LOOKING_FOR_WATERCRAFT \r\n"); 
                
            break;

            
        
        case LOOKING_FOR_WATERCRAFT:

            Message_Machine();
            break;
        
        case PAIRED:

        
            //printf("paired case");
            Set_XBee_Address(0xDD, 0xAA); // <-- junk address
        
            Message_Machine();

           // break;
           // game_state = PLAYING_GAME;
            break;
         
           
        case  PLAYING_GAME:
        
            Set_Standdown_LED(PLAYING_GAME);

        
            Set_XBee_Address(paired_Address_MSB, paired_Address_LSB);
            Message_Machine();
            
           
            
            // poll for inputs
            special1 = 0;

            special2 = 0;
 
            speedout =  Set_Speed();
            directionout =  Set_Direction();

            pumpspeedout =  Set_PumpSpeed();
            reverseout =  Check_Reverse();  
            if(Report_Special1()) 
            {

                special1 = BIT4HI;      
            }
            if(Report_Special2()) 
            {
                special2 = BIT5HI;      
            }

            // assemble the Xbee output byte
			printf("%x, %x, %x\r\n", COMMAND, ((directionout*16)+speedout), (pumpspeedout + special1 + special2));

            Set_XBee_Bytes(COMMAND, ((directionout*16)+speedout), (pumpspeedout + special1 + special2));  
            break;

            
        case STANDING_DOWN:
            Message_Machine();
            Set_XBee_Address(paired_Address_MSB, paired_Address_LSB);

            Set_XBee_Bytes(COMMAND,0x88,0x00);
        
        
        break;
        
        case ENGAGEMENT_OVER:

            Message_Machine();
             
            special1 = 0;
            special2 = 0;

 
            speedout =  Set_Speed();
            directionout =  Set_Direction();
            pumpspeedout =  Set_PumpSpeed();

            reverseout =  Check_Reverse();  
            if(Report_Special1()) 
            {
                special1 = BIT4HI;      
            }

            if(Report_Special2()) 
            {
                special2 = BIT5HI;      
            }
            
            
            // assemble the Xbee output byte
            
            printf("%x, %x, %x\r\n", COMMAND, ((directionout*16)+speedout), (pumpspeedout + special1 + special2));

            Set_XBee_Bytes(COMMAND, ((directionout*16)+speedout), (special1+special2 + 0x00));  
            break;

            
        break;
      }  
    }
}
//}//end main	
#endif








       








// **********************************************************************************
// ************************* INITIALIZATIONS
// **********************************************************************************


void Main_Init(void)

{
    TIM0_TSCR1 |= _S12_TEN;  //start timer0
    TIM0_TSCR2 |= (_S12_PR2 | _S12_PR1 | _S12_PR0); //set timer0 prescaler to 128

    DDRP |= BIT5HI; //set P5 as an output (used to test) 
    PTP = 0xFF; 
    
    
}


void InitializePeriodTimer(void) 
// initializes timer on channel 4
{
   TIM0_TSCR1   |=   _S12_TEN;            // turns timer on

   TIM0_TSCR2   |=  (_S12_PR2 | _S12_PR1 | _S12_PR0); //set timer0 prescaler to 128
   TIM0_TIOS    |= _S12_IOS4;	        //  OUTPUT CAPTURE

   TIM0_TIE     |= _S12_C4I;            // ENABLE THIS INTERRUPT!!!!!!
   TIM0_TCTL1   |= TIM0_TCTL1 & ~(_S12_OL4 | _S12_OM4);  // no pin associated with this one

   TIM0_TC4     = TIM0_TCNT + REFRESH_PERIOD; // schedule first event
   TIM0_TFLG1   |= _S12_C4F;           // clear OC4 flag;

   puts("Period Timer Initialized\r\n");
   
   DDRP |=  BIT5HI;  // P5 is now an output
   PTP  =   0xFF;    // initialize to HI

   
   printf("DEBUG: Pin P5 enabled as an output\r\n");
    
}

void InitializeSecondTimer(void) 
// initializes timer on channel 5
{

   TIM2_TSCR1   |=   _S12_TEN;            // turns timer on
   TIM2_TSCR2   |=  (_S12_PR2 | _S12_PR1 | _S12_PR0); //set timer0 prescaler to 128

   TIM2_TIOS    |= _S12_IOS7;	        //  OUTPUT CAPTURE
   TIM2_TIE     |= _S12_C7I;            // ENABLE THIS INTERRUPT!!!!!!

   TIM2_TCTL1   |= TIM2_TCTL1 & ~(_S12_OL7 | _S12_OM7);  // no pin associated with this one

   TIM2_TC7     = TIM0_TCNT + REFRESH_PERIOD; // schedule first event
   TIM2_TFLG1   |= _S12_C5F;           // clear OC4 flag;

   puts("Second Timer Initialized\r\n");
   
   //DDRP |=  BIT5HI;  // P5 is now an output
   //PTP  =   0xFF;    // initialize to HI
   
   //printf("DEBUG: Pin P5 enabled as an output\r\n");
    
}


// **********************************************************************************
// ************************* INTERRUPT SERVICE ROUTINES
// **********************************************************************************


void interrupt _Vec_tim0ch4 Periodic_ISR (void) 
{

    TIM0_TFLG1 = _S12_C4F;                  // clear dem flags  
    TIM0_TC4 += REFRESH_PERIOD;              // set next event

// TEST CODE:
    
// blip pin P5 (assuming P5 is already an output, configured above)
  // PTP ^= BIT5HI;  
   // printf("____________INTERRUPT!\r\n");       

   
    NeedToSend = YES;     // set send flag...this means we need to send
    // Set_Xbee_Out based on whatever the helm says
    //DisableInterrupts;
    //Send_XBee_Data(header,navigation,special);	 // sets module level variables needed to send
    //EnableInterrupts;
    //this next code is blocking.  We did this so that other parts of our main 
    //loop won't cause us to transmit slower (i.e. 5 printfs between calls to
    //SendingFSM would put ~5ms between bytes sent to the XBee . We weren't
    //sure how long we would have between bytes sent before the XBee would reset.  
    //if(header_out&BIT0HI | header_out&BIT1HI)   //only send 0x02 or 0x01 (message or ibutton)
    //{
        
        while(1)					  // end of Autosend

        {
             if(SendingFSM() ) break;  
        }  
}


// this is our Second Timer
// it does the stand down
// and the animation
void interrupt _Vec_tim2ch7 Periodic_ISR_copy (void) 
{

    TIM2_TFLG2 = _S12_C7F;                  // clear dem flags 
    TIM2_TFLG1 = _S12_C7F;         
    TIM2_TC7 += REFRESH_PERIOD;              // set next event
//    printf("Second interrupt machine \r\n");

        
    if (game_state == STANDING_DOWN)   // if we're standing down
    {
       stand_down_counter--;     
       if(stand_down_counter==0) 
       {

            stand_down_counter = FULL_STAND_DOWN;
            Set_Standdown_LED(PLAYING_GAME);
            animateFlag = 0;

            DisplayBoatNumber(paired_Address_LSB); 
            game_state = PLAYING_GAME;   
       }
       
       
    }


// the following segment controls the 7-segment display animation
// based on which animation flag is set


    if (animateFlag)   // if we're supposed to animate
    {
    /* Figure 8
       switch(animate_counter%8) 
       {
            case 0:
                 PTT = bottom_center;
            break;
            case 1:
                 PTT = bottom_right;
            break;
            case 2:
                 PTT = middle;
            break;
            case 3:
                 PTT = top_left;
            break;
            case 4:
                 PTT = top_center;
            break;
            case 5:
                 PTT = top_right;
            break;
            case 6:
                 PTT = middle;
            break;
            case 7:
                 PTT = bottom_left;
            break;
       }
       */
        /*  circle
        switch(animate_counter%6) 
       {
            case 0:
                 PTT = bottom_center;
            break;
            case 1:
                 PTT = bottom_right;
            break;
            case 2:
                 PTT = top_right;
            break;
            case 3:
                 PTT = top_center;
            break;
            case 4:
                 PTT = top_left;
            break;
            case 5:
                 PTT = bottom_left;
      
       }
       */
       		 // double circle
       if(animateFlag == DOUBLE_CIRCLE) 
       {

        
             switch(animate_counter%3) 
           {
                case 0:
                     PTT = (bottom_center&top_center);

                break;
                case 1:
                     PTT = (bottom_right&top_left);

                break;
                case 2:
                     PTT = (top_right&bottom_left);

                break;
            
           }
           animate_counter++;
       }
           
       if(animateFlag == CIRCLE) 
       {

        
       // build / debuild a circle     
          switch(animate_counter%11) 
           {
               case 0:
                     PTT = bottom_center;

                break;
                case 1:
                     PTT = (bottom_center&bottom_right);

                break;
                case 2:
                     PTT = (bottom_center&bottom_right&top_right);

                break;
                case 3:
                     PTT = (bottom_center&bottom_right&top_right&top_center);

                break;
                case 4:
                     PTT = (bottom_center&bottom_right&top_right&top_center&top_left);

                break;
                case 5:
                     PTT = (bottom_center&bottom_right&top_right&top_center&top_left&bottom_left);

                break;
                case 6:
                     PTT = (bottom_right&top_right&top_center&top_left&bottom_left);

                break;
                case 7:
                     PTT = (top_right&top_center&top_left&bottom_left);

                break;
                case 8:
                     PTT = (top_center&top_left&bottom_left);

                break;
                case 9:
                     PTT = (top_left&bottom_left);

                break;
                case 10:
                     PTT = (bottom_left);
          
           }  
            animate_counter++;  
       }

       
       if (animateFlag == FLASH_PAIRED) 
       {
        
          switch(animate_counter%2) 
           {

               case 0:
                     PTT = 0xFF;
                break;

                case 1:
                    DisplayBoatNumber(paired_Address_LSB); 
                break; 
           }      
        animate_counter++;  
       }
    }   
}




void interrupt _Vec_sci1 SCI_Interrupt_Machine(void)

{
   // static char dummy = 0;
    DisableInterrupts;  //disable global interrupts.  We don't want
                        //to be interrupted while receiving data.

   
   
    ReceivingFSM(); 
    
     
   /* while(ReceivingFSM())
    {
        dummy++;  
        
    } */
    //printf("In SCI interrupt \r\n");
    EnableInterrupts; //re-enable interrupts 
}


// **********************************************************************************
//  ******************************** MESSAGE_MACHINE *******************************
//  ********************************                 *******************************
// **********************************************************************************

// message machine checks if we've received a new message
// if so, it reads in all the values (Import_Message_Machine)
// and deals with them appropriately
// based on incoming message header
void Message_Machine(void) {

    if(Check_Message_Flag())
    {
        Clear_Message_Flag();

        Import_Message_Machine();
      //  puts("Message received.....");
        	    switch(header_in)
        	    {
        	        case  ADMIRAL_HEADER:

        	           Handle_Admiral();
        	           break;

        	        case  CRAFT_HEADER:   
        	            Handle_Craft();

        	            break; 
				
        	        case HELM_HEADER:
        	            printf("from helm %x %x \r\n",incoming_address_MSB,incoming_address_LSB);

        	            break;
        	            
        	        case IBUTTON_HELM_HEADER:
        	            printf("from helm %x %x (iButton) \r\n",incoming_address_MSB,incoming_address_LSB);

        	            break;    
				    default:
			//	        printf("...with no recognizable header (%x) \r\n",header_in);
				        break;		
        	    }	 //end header_in switch
    } //end if(Check_Message_Flag())

}  //end message machine


// **********************************************************************************
// ************************* message handling helper function
// **********************************************************************************
void Handle_Admiral(void) 
// handles messages with the "Admiral" header
// first tests for proper admiral address
// then deals with the commands
// based on content

{
    // check for address...if admirals, deal with the message
    if ((incoming_address_MSB == ADMIRAL_ADDRESS_MSB)
        &&(incoming_address_LSB == ADMIRAL_ADDRESS_LSB)) 
        {

         
            printf ("...from Admiralty, with an Admiral header\r\n");
            // navigation in should be zero, just check the special
           
            switch (special_in) 
            {
                case START_GAME:

                  //  printf("ADM: Start Game received\r\n");
                    
                    
                    //make sure we're paired
                    if(game_state == PAIRED)
                    {
                        
                        // ack
                        Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);

                        Set_XBee_Bytes(0x80, 0x00, 0x00);
                         while(1)					  // send one byte

                            {
                                 if(SendingFSM() ) break;       
                            } 
                         Set_XBee_Address(0xDD, 0xEE);

                        // end ack
                        
                        Set_Standdown_LED(PLAYING_GAME);
                        game_state = PLAYING_GAME;
                    } /*else
                    {
                        //send waiting for ibutton 
                            Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);
                            Set_XBee_Bytes(PING_RESPONSE, 0x01, 0x00);
                            while(1)					  // send one byte
                                {
                                     if(SendingFSM() ) break;       
                                } 
                                Set_XBee_Address(0xDD, 0xEE);   

                    }*/

                    break;
                    
         		 case END_GAME:
                  //  printf("ADM: End Game received\r\n");
                     // ack
                    Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);

                    Set_XBee_Bytes(0x80, 0x00, 0x00);
                     while(1)					  // send one byte

                        {
                             if(SendingFSM() ) break;       
                        } 
                     Set_XBee_Address(0xDD, 0xEE);

                    // end ack
                    
                    PTU = 0xFF;
                    game_state = ENGAGEMENT_OVER;

                    break;
                    
                case BLUE_GOAL:
                //    printf("ADM: Blue Goal Active\r\n");
                    Set_Base(BLUE);											 
                    break;

                    
            	 case RED_GOAL:
            	//    printf("ADM: Red Goal Active\r\n");
                    Set_Base(RED);
                    break;

                    
         		 case HARD_RESET:
                 //   printf("ADM: Hard Reset received\r\n");
                 // reset our saved values
                 // revert to start game state
                      paired_Address_LSB = 0;
                      paired_Address_MSB = 0;

                      iButton_LSB = 0;
                      iButton_MSB = 0;
                      game_state = WAITING_FOR_IBUTTON;

                      PTU = 0x00; // clear all LEDs v
                      
                      TIM0_TIE     &= ~(_S12_C4I);  // turn off the 2nd timer interrupt


                    break;
                    
                 case PING:
                
                    printf("ADM: Ping received\r\n");

                       // we ping back to the amdiral
                    // respond to ping appropriately 
                    switch (game_state) 
                    {

                        case    WAITING_FOR_IBUTTON:
                           
                            Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);

                            Set_XBee_Bytes(PING_RESPONSE, 0x01, 0x00);
                            while(1)					  // send one byte

                                {
                                     if(SendingFSM() ) break;       
                                } 
                                Set_XBee_Address(0xDD, 0xEE);

                            break;
                            
                        case    SEND_IBUTTON_MESSAGE:
                              Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);

                            Set_XBee_Bytes(PING_RESPONSE, 0x02,  iButton_LSB);
                            while(1)					  // send one byte

                                {
                                     if(SendingFSM() ) break;  
                                }  
                                Set_XBee_Address(0xDD, 0xEE);

                            break; 
         
                         case    LOOKING_FOR_WATERCRAFT:
                            Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);

                            Set_XBee_Bytes(PING_RESPONSE, 0x02,  iButton_LSB);
                            while(1)					  // send one byte

                                {
                                     if(SendingFSM() ) break;  
                                }  
                                Set_XBee_Address(0xDD, 0xEE);

                            break; 
                         case    PLAYING_GAME:
                            Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);

                            Set_XBee_Bytes(PING_RESPONSE, 0x04,  paired_Address_LSB);
                            while(1)					  // send one byte

                                {
                                     if(SendingFSM() ) break;  
                                } 
                                Set_XBee_Address(0xDD, 0xEE);

                            break;
                            
                        case    PAIRED:
                            Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);

                        	Set_XBee_Bytes(PING_RESPONSE, 0x04, paired_Address_LSB);
                            while(1)					  // send one byte

                                {
                                     if(SendingFSM() ) break;  
                                } 
                                Set_XBee_Address(0xDD, 0xEE);

                            break;
                         default:
                            Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);

                            Set_XBee_Bytes(0x80, 0x00, 0x00);
                              while(1)					  // send one byte

                                {
                                     if(SendingFSM() ) break;  
                                } 
                                Set_XBee_Address(0xDD, 0xEE);

                            break;  
                        
                    }//end switch (game_state) 
                   
                     
                    break;
                    
                 default:
                    printf("ADM: Invalid Admiral Command\r\n");

                    break;   
                  
         
             } // end switch special byte
            
        }  // end IF check of admiral address
}  // end handle admiral 


// Handle Craft messages *********************************************************************************
void Handle_Craft(void) 
{

   switch (game_state) 
   {
        case    LOOKING_FOR_WATERCRAFT:
            if (special_in == 0x01) // if we get a matched command

            {
                 paired_Address_MSB = incoming_address_MSB;
                 paired_Address_LSB = incoming_address_LSB; 
                 
                 puts("successfully paired\r\n");

                 
                 // show which boat we've got
                 DisplayBoatNumber(paired_Address_LSB); 
                 printf("paired to team %x\r\n", paired_Address_LSB);  
                
                // show our team affiliation 

                 if (iButton_LSB & BIT0HI)  // if odd 
                 {
                    printf("RED TEAM\r\n");

                    Set_Affiliation(RED);
                 } else 
                 {
                    printf("BLUE TEAM\r\n");
                    Set_Affiliation(BLUE); 
                 }

                 
                 // state transition
                 game_state = PAIRED;   			         
            }
             break;
         
        
        
        case     PLAYING_GAME:

            // check for address
            
            if( (incoming_address_MSB!=paired_Address_MSB)||(incoming_address_LSB!=paired_Address_LSB)) 
            {
                puts("we're getting messages from the wrong boat\r\n");

                break;     
            }
        
            if (special_in == 0x02) 	  // if this is a stand down
            {

               // send our ACK
                Set_XBee_Address(paired_Address_MSB, paired_Address_LSB);   // we want to send back to the boat
                Set_XBee_Bytes(0x80, 0x00,  0x00);

                while(1)					  // send one byte
                {
                     if(SendingFSM() ) break;  
                }  
                
                Set_XBee_Address(ADMIRAL_ADDRESS_MSB, ADMIRAL_ADDRESS_LSB);   // we want to send back to the boat

                Set_XBee_Bytes(0x80, 0x00,  0x00);
                while(1)					  // send one byte

                {
                     if(SendingFSM() ) break;  
                }  
                // start TIMER // <-----------------------------------------------------# # # # # #
                Set_XBee_Address(0xDD, 0xEE);

                
                animateFlag = FLASH_PAIRED;
                game_state = STANDING_DOWN; 
            }
        break;

        
        default:
            printf("Craft is sending us messages when we don't want them\r\n");
            break;    
        
        
    
   }

}



void Import_Message_Machine(void)
{
    static int i = 0;

    for(i=0;i<12;i++)
    {																             
        Message_In[i] = Get_XBee_Byte(i);  //Put entire XBee message int Message_In    

    }  
    header_in = Message_In[8];
    navigation_in = Message_In[9];

    special_in = Message_In[10];
         //   printf("header in is %x, navigation in is %x, special in is %x\r\n",header_in,navigation_in,special_in);

    incoming_address_MSB = Message_In[4]; 
    incoming_address_LSB = Message_In[5];  
}