C Code
#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;
}