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
#include <hidef.h>      /* common defines and macros */
#include <mc9s12e128.h>     /* derivative information */
#include <S12E128bits.h>

#include <stdio.h>
#include "XBee.h"



#pragma LINK_INFO DERIVATIVE "SampleS12"


#define IDLE 0x00
#define RX_START 0X01
#define RX_LENGTH_MSB 0x02
#define RX_LENGTH_LSB 0x03
#define RX_API_CMD      0x04
#define RX_SOURCE_MSB      0x05
#define RX_SOURCE_LSB      0x06
#define RX_SIGNAL       0x07
#define RX_OPTIONS      0x08
#define RX_HEADER   0x09
#define RX_NAVIGATION   0x0A
#define RX_SPECIAL      0x0B
#define RX_CHECKSUM     0x0C
#define BYTE_RECEIVED   0x0D
#define NO_EVENT        0x0E


#define TX_BEGIN           0x00
#define TX_START        0x01
#define TX_LENGTH_MSB   0x02
#define TX_LENGTH_LSB   0x03
#define TX_API_ID       0x04
#define TX_FRAME_ID     0x05
#define TX_DESTINATION_MSB  0x06
#define TX_DESTINATION_LSB  0x07
#define TX_OPTIONS			0x08
#define TX_HEADER			0x09
#define TX_NAVIGATION       0x0A
#define TX_SPECIAL          0x0B
#define TX_CHECKSUM         0x0C
#define TX_FINISH           0x0D


#define NO_NEW_DATA_IN  0x00
#define NEW_DATA_IN     0x01

#define NO_DATA_SENT    0x00
#define DATA_SENT       0x01


#define NEW_MESSAGE	    0x01
#define NO_NEW_MESSAGE  0x00


void DoServices(char event);
char CheckEvents(void);

char SCI_receive(void);
char SCI_send(unsigned char data);

void Send_Command(unsigned char header,unsigned char navigation,unsigned char special);

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

static unsigned char header_out = 0x00;
static unsigned char navigation_out = 0x00;

static unsigned char special_out = 0x00;
//static unsigned char header_out = 0x00;     //these are now global
//static unsigned char navigation_out = 0x00;
//static unsigned char special_out = 0x00;



#define start       0
#define length_msb  1
#define length_lsb  2
#define api_cmd     3
#define source_msb  4
#define source_lsb  5
#define signal      6
#define options     7
#define header_in   8
#define navigation_in   9
#define special_in      10
#define checksum_in     11


static unsigned char XBee_Message_In[12];

static char New_Message_Flag = 0x00;


unsigned char data_in;    //newest received byte from SCI goes in here
unsigned char event;
unsigned char Send_Data = 0x01;    //flag, set when there's data to be sent


void XBee_Init(void)
{
   static char dummy; 
   puts("XBee: Starting XBee_Init function \r\n");

   SCI1BDH = 0x00 ;  //set baud rate to 9600
   SCI1BDL = 0x9C;  

   SCI1CR2 = _S12_TE | _S12_RE | _S12_RIE ;  
   
   //dummy = SCI_receive(); //clears interrupt flag

   puts("XBee: Finished XBee_Init function \r\n"); 
    
}

char CheckEvents(void)
{

        
       if(SCI_receive() == NEW_DATA_IN)
       {

            //printf("New data, changing state to RX_LENGTH_MSB\r\n");
            //event = RX_LENGTH_MSB;
            return BYTE_RECEIVED;
    
       }
       
//       if(SCI_send() == DATA_SENT)

    return NO_EVENT;   
}

void DoServices(char event)
{

    //call ReceivingFSM and SendingFSM constantly, update header_out, navigation_out and special_out
    //to send these bytes. Must update destination_MSB and destination_LSB to watercraft value after
    //synching.  (0xFFFF beforehand) 
   
   
   //data in goes to header, navigation and special
    if(event == BYTE_RECEIVED)
    {

        ReceivingFSM();
    }
        

    SendingFSM();   //go through FSM to send data (if data should be sent)       
}


char SendingFSM(void)

// sends the appropriate bytes
// based on a "send_state" index
// so it cycles trhough the whole message
// returns 0x00 until it's finishes
// so we can poll for a complete send
{


    static unsigned char checksum_out;
    static unsigned char send_state = TX_START;

    //if(Send_Data)    //Send_Data is a flag
    //{
        
        switch(send_state)
         {
            
            case TX_START:
                if(SCI_send(0x7E) == DATA_SENT) send_state = TX_LENGTH_MSB; 
                break;

            case TX_LENGTH_MSB:
                if(SCI_send(0x00) == DATA_SENT) send_state = TX_LENGTH_LSB;

                break;
            case TX_LENGTH_LSB:
            	 if(SCI_send(0x08) == DATA_SENT) send_state = TX_API_ID;

            	 break;
            case TX_API_ID:
                if(SCI_send(0x01) == DATA_SENT) send_state = TX_FRAME_ID;

                break;
            case TX_FRAME_ID:
                if(SCI_send(0x00) == DATA_SENT) send_state = TX_DESTINATION_MSB;

                break;
            case TX_DESTINATION_MSB:
                if(SCI_send(destination_MSB) == DATA_SENT) send_state = TX_DESTINATION_LSB;

                break;
            case TX_DESTINATION_LSB:
                if(SCI_send(destination_LSB) == DATA_SENT) send_state = TX_OPTIONS;

                break;
            case TX_OPTIONS:
                if(SCI_send(0x02) == DATA_SENT) send_state = TX_HEADER;

                break;
            case TX_HEADER:
                if(SCI_send(header_out) == DATA_SENT) send_state = TX_NAVIGATION;

                break;
            case TX_NAVIGATION:
                if(SCI_send(navigation_out) == DATA_SENT) send_state = TX_SPECIAL;

                break;
            case TX_SPECIAL:
                if(SCI_send(special_out) == DATA_SENT) send_state = TX_CHECKSUM;

                break;
            case TX_CHECKSUM:
                checksum_out = (0x03+destination_LSB+destination_MSB+header_out+navigation_out+special_out);

                checksum_out = 0xFF-checksum_out;
                if(SCI_send(checksum_out) == DATA_SENT) send_state = TX_FINISH;

                break;
            case TX_FINISH:
                Send_Data = 0x00; //clear flag; will not transmit until set 
                //printf("Finished sending %x, %x, %x to %x %x \r\n",header_out,navigation_out,special_out,destination_MSB,destination_LSB);   

                send_state = TX_START;
                return 0x01;            //finished sending data
        }

   // }
            return 0x00;
}



void ReceivingFSM(void)

// receives all bytes, stores them in Xbee_Message_In
// to be pulled out later by Import_Message_Machine
{


    static unsigned char state = IDLE;

    if(SCI_receive() == NEW_DATA_IN)    //call SCI_receive, put data into data_in
    {
        
         switch(state)
        {

            
            case IDLE:
                //start = data_in;
                XBee_Message_In[start] = data_in;

                //this makes sure that 
                //we're not starting to
                //receive in the middle 
                 //of a message:
                if(XBee_Message_In[start] == 0x7E)           
                {                       
                    state = RX_LENGTH_MSB;
                }

                break;
            case RX_LENGTH_MSB:
                //length_msb = data_in;
                XBee_Message_In[length_msb] = data_in;

                state = RX_LENGTH_LSB;
                break;
            case RX_LENGTH_LSB:

                //length_lsb = data_in;
                XBee_Message_In[length_lsb] = data_in;
                state = RX_API_CMD;

                break;
            case RX_API_CMD:
                 //api_cmd = data_in;
                 XBee_Message_In[api_cmd] = data_in;

                 state = RX_SOURCE_MSB;
                 break;
            case RX_SOURCE_MSB:

                //source_msb = data_in;
                XBee_Message_In[source_msb] = data_in;
                state = RX_SOURCE_LSB;

                break;
            case RX_SOURCE_LSB:
                //source_lsb = data_in;
                XBee_Message_In[source_lsb] = data_in;

                state = RX_SIGNAL;
                break;
            case RX_SIGNAL:

                //signal = data_in;
                XBee_Message_In[signal] = data_in;
                state = RX_OPTIONS;

                break;
            case RX_OPTIONS:
                //options = data_in;
                XBee_Message_In[options] = data_in;

                state = RX_HEADER;
                break;
             case RX_HEADER:

                //header_in = data_in;
                XBee_Message_In[header_in] = data_in;
                state = RX_NAVIGATION;

                break;
            case RX_NAVIGATION:
                //navigation_in = data_in;
                XBee_Message_In[navigation_in] = data_in;

                state = RX_SPECIAL;
                break;
            case RX_SPECIAL:

                //special_in = data_in;
                XBee_Message_In[special_in] = data_in;
                state = RX_CHECKSUM;

                break;
            case RX_CHECKSUM:
                //checksum_in = data_in;
                XBee_Message_In[checksum_in] = data_in;

                state = IDLE;
                New_Message_Flag = NEW_MESSAGE;
            
            
                if((XBee_Message_In[source_msb] == 0xAF) && (XBee_Message_In[source_lsb] == 0x08))

                printf("Received %x %x %x from %x %x \r\n", XBee_Message_In[header_in],XBee_Message_In[navigation_in],XBee_Message_In[special_in],XBee_Message_In[source_msb],XBee_Message_In[source_lsb]);

    
                break;	   //receive complete (checksum case)
         }
    }    
}

void Send_Command(unsigned char header,unsigned char navigation,unsigned char special)
{


    header_out = header;
    navigation_out = navigation;

    special_out = special;
     Send_Data = 0x01;  //set flag to start sending data   

}

 char SCI_receive(void)
 {
     char dummy;

    if(SCI1SR1 & _S12_RDRF)
  	{
  		
  		
  		dummy = SCI1SR1;     //must read this to reset the interrupt flag

  		data_in = SCI1DRL;
  		
  	//	printf("Received: %i \r\n",data_in);
  		return NEW_DATA_IN;
  	} 
  	return NO_NEW_DATA_IN;			 
 }

 
 
 char SCI_send(unsigned char data)
{
   

    if((SCI1SR1 & _S12_TDRE))
    {

 			

        if(SCI1SR1 & _S12_TC)
        {
 				
            //printf("SCI_send sending data %u \r\n",data);
            SCI1DRL = data;

            return DATA_SENT;  		   
        }  
 	
     }
        return NO_DATA_SENT;
 
}




unsigned char Get_XBee_Byte(char index)
{

    
      //  array XBee_Message_In set in recievingFSM
     
        return XBee_Message_In[index];  
}


void Set_XBee_Address(unsigned char MSB, unsigned char LSB)
{

  //  printf("XBee: Setting craft address to %x %x \r\n",MSB,LSB);
     destination_MSB = MSB;
     destination_LSB = LSB;
    
    
}


void Set_XBee_Bytes(unsigned char header_byte, unsigned char navigation_byte, unsigned char special_byte)
{

    

       header_out = header_byte;
       navigation_out = navigation_byte;
       special_out = special_byte;                     
}




char Check_Message_Flag(void)	  
{
    
    return New_Message_Flag;     
}

   	 
void Clear_Message_Flag(void)
{  
   New_Message_Flag = NO_NEW_MESSAGE;    
}