0,0 → 1,255 |
#include <xc.h> |
#include <stdio.h> |
#include <string.h> |
#include "defines.h" |
#include "comm_xbee.h" |
#include "base_UART.h" |
|
static XBEE_DATA *xbee_data_p; |
static void *xbee_data_frame; |
//static void *xbee_frame; |
|
/* Initialize variables used by this library */ |
void XBee_Init(XBEE_DATA *data) { |
xbee_data_p = data; |
XBEE_CTS_TRIS = 1; // RB0 is CTS, set by XBee chip |
XBEE_RTS_TRIS = 0; // RB1 is RTS, set by PIC |
|
XBEE_CTS_LAT = 0; // Pin set high to signal stop sending data to XBee |
XBEE_RTS_LAT = 0; // Pin set high to indicate stop sending data to PIC |
|
xbee_data_p->dataind = 0; |
xbee_data_p->checksum_sum = 0; |
xbee_data_p->frame_rdy = 0; |
xbee_data_p->escape_flag = 0; |
xbee_data_p->read_state = XBEE_STATE_READ_START; |
|
// memset(&xbee_data, 0, 32); |
|
// Grab a pointer to where the unique frame array starts |
xbee_data_frame = &(xbee_data_p->rcv_frame.FRAME); |
// xbee_frame = &(xbee_data_p->rcv_frame); |
} |
|
/* Here we handle the serial input from the UART interrupt */ |
void XBee_Serial_In(char c) { |
// For some reason writing the length straight to xbee_data doesnt seem to work |
// so we work around it by pointing to the length bytes directly |
// XBEE_ADDRESS_16 *length = xbee_frame + 1; |
|
#ifdef XBEE_USE_ESCAPE_CHAR |
if (c == XBEE_ESCAPE_CHAR) { |
// Next byte needs is an escaped char |
xbee_data_p->escape_flag = 1; |
return; |
} |
|
if (xbee_data_p->escape_flag) { |
// XOR byte with 0x20 to get escaped char |
c ^= XBEE_ESCAPE_VAL; |
xbee_data_p->escape_flag = 0; |
} |
#endif |
// Reset on start bit and start saving data |
if (c == XBEE_START_DELIMITER) { |
// On detect start delimiter, clear out initial array |
xbee_data_p->dataind = 0; |
xbee_data_p->checksum_sum = 0; |
xbee_data_p->frame_rdy = 0; |
xbee_data_p->read_state = XBEE_STATE_READ_LENGTH_HIGH; |
// *((char *)xbee_frame) = XBEE_START_DELIMITER; |
xbee_data_p->rcv_frame.start_delimiter = XBEE_START_DELIMITER; |
|
} else { |
switch (xbee_data_p->read_state) { |
case XBEE_STATE_READ_START: |
// Do nothing and wait till start bit is read |
break; |
case XBEE_STATE_READ_LENGTH_HIGH: |
// Read length (MSB) |
// length->INT_16.char_value[1] = c; |
xbee_data_p->rcv_frame.length.INT_16.char_value[1] = c; |
xbee_data_p->read_state = XBEE_STATE_READ_LENGTH_LOW; |
break; |
case XBEE_STATE_READ_LENGTH_LOW: |
// Read length (LSB) |
// length->INT_16.char_value[0] = c; |
xbee_data_p->rcv_frame.length.INT_16.char_value[0] = c; |
xbee_data_p->read_state = XBEE_STATE_READ_FRAME_DATA; |
break; |
case XBEE_STATE_READ_FRAME_DATA: |
// Read unique frame data |
if (xbee_data_p->dataind < xbee_data_p->rcv_frame.length.INT_16.int_value) { |
*((char*) xbee_data_frame + xbee_data_p->dataind) = c; |
xbee_data_p->checksum_sum += c; |
xbee_data_p->dataind++; |
} |
// If total length is read, the next byte is the expected checksum |
if (xbee_data_p->dataind == xbee_data_p->rcv_frame.length.INT_16.int_value) { |
xbee_data_p->read_state = XBEE_STATE_READ_CHECKSUM; |
} |
break; |
case XBEE_STATE_READ_CHECKSUM: |
// Calculate and compare checksum |
if (0xFF - xbee_data_p->checksum_sum == c) { |
// Frame was recieved successfully |
xbee_data_p->frame_rdy = 1; |
// XBee_Process_Received_Frame(); |
} else { |
// If checksum does not match, drop frame |
char output[32]; |
sprintf(output, "XBEE: checksum mismatch\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
} |
xbee_data_p->read_state = XBEE_STATE_READ_START; |
break; |
} |
} |
} |
|
/* This processes the frame data within the interrupt. Dont use this. */ |
void XBee_Process_Received_Frame() { |
// DBG_PRINT_XBEE("Length: %d\r\n", xbee_data_p->rcv_frame.length.INT_16.int_value); |
// Here we process the received frame depending on the frame type |
char output[64]; |
switch (*((char *) xbee_data_frame)) { |
case XBEE_RX_AT_COMMAND_RESPONSE: |
sprintf(output, "XBEE: parsing recieved AT command response frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
case XBEE_RX_DATA_PACKET: |
sprintf(output, "XBEE: parsing recieved data frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
case XBEE_RX_DATA_TX_STATUS: |
sprintf(output, "XBEE: parsing recieved TX status frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
case XBEE_RX_IO_DATA_SAMPLE: |
sprintf(output, "XBEE: parsing recieved IO data sample frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
case XBEE_RX_EXPLICIT_COMMAND: |
sprintf(output, "XBEE: parsing recieved explicit command frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
case XBEE_RX_REMOTE_AT_COMMAND_RESPONSE: |
sprintf(output, "XBEE: parsing recieved remote AT command frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
case XBEE_RX_ROUTE_RECORD: |
sprintf(output, "XBEE: parsing recieved route record frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
case XBEE_RX_NODE_IDENTIFICATION: |
sprintf(output, "XBEE: parsing recieved node identification frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
case XBEE_RX_FRAME_MODEM_STATUS: |
sprintf(output, "XBEE: parsing recieved modem status frame\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
break; |
default: |
sprintf(output, "XBEE: (ERROR) unrecognized frame type\r\n"); |
DBG_PRINT_XBEE(output, strlen(output)); |
} |
} |
|
unsigned int XBee_Get_Received_Frame(char *frame) { |
if (!xbee_data_p->frame_rdy) { |
return 0; |
} else { |
memcpy(frame, xbee_data_frame, xbee_data_p->rcv_frame.length.INT_16.int_value); |
xbee_data_p->frame_rdy = 0; // Reset frame ready status |
return xbee_data_p->rcv_frame.length.INT_16.int_value; |
} |
} |
|
void XBee_Process_Transmit_Frame(char *data, char length) { |
#ifdef XBEE_USE_ESCAPE_CHAR |
unsigned int i = 0; |
char chksum = 0; |
|
// Write the start bit and length |
UART1_WriteC(XBEE_START_DELIMITER); |
UART1_WriteC(0); |
UART1_WriteC(length); |
|
// Write the frame data |
for (i = 0; i < length; i++) { |
chksum += data[i]; |
if (data[i] == XBEE_START_DELIMITER || \ |
data[i] == XBEE_ESCAPE_CHAR || \ |
data[i] == XBEE_XON || \ |
data[i] == XBEE_XOFF) { |
UART1_WriteC(XBEE_ESCAPE_CHAR); |
UART1_WriteC(data[i] ^ XBEE_ESCAPE_VAL); |
} else { |
UART1_WriteC(data[i]); |
} |
} |
// Write the checksum |
if (chksum == XBEE_START_DELIMITER || \ |
chksum == XBEE_ESCAPE_CHAR || \ |
chksum == XBEE_XON || \ |
chksum == XBEE_XOFF) { |
UART1_WriteC(XBEE_ESCAPE_CHAR); |
UART1_WriteC(chksum ^ XBEE_ESCAPE_VAL); |
} else { |
UART1_WriteC(0xFF - chksum); |
} |
#else |
unsigned int i = 0; |
char chksum = 0; |
|
UART1_WriteC(XBEE_START_DELIMITER); |
UART1_WriteC(0); |
UART1_WriteC(length); |
for (i = 0; i < length; i++) { |
chksum += data[i]; |
UART1_WriteC(data[i]); |
} |
UART1_WriteC(0xFF - chksum); |
#endif |
} |
|
void XBee_Set_RTS(char c) { |
if (c) { |
XBEE_RTS_LAT = 1; // Set high to stop receiving data |
} else { |
XBEE_RTS_LAT = 0; // Set low to resume receiving data |
} |
} |
|
char XBee_Read_CTS() { |
char c = XBEE_CTS_PORT; |
if (c) { |
return 0x1; // High indicates stop sending data |
} else { |
return 0x0; // Low indicates ok to send data |
} |
} |
|
void XBee_Convert_Endian_64(XBEE_ADDRESS_64 *src) { |
char tmp[2]; |
tmp[0] = src->UPPER_32.char_value[3]; |
tmp[1] = src->UPPER_32.char_value[2]; |
src->UPPER_32.char_value[3] = src->UPPER_32.char_value[0]; |
src->UPPER_32.char_value[2] = src->UPPER_32.char_value[1]; |
src->UPPER_32.char_value[1] = tmp[1]; |
src->UPPER_32.char_value[0] = tmp[0]; |
|
tmp[0] = src->LOWER_32.char_value[3]; |
tmp[1] = src->LOWER_32.char_value[2]; |
src->LOWER_32.char_value[3] = src->LOWER_32.char_value[0]; |
src->LOWER_32.char_value[2] = src->LOWER_32.char_value[1]; |
src->LOWER_32.char_value[1] = tmp[1]; |
src->LOWER_32.char_value[0] = tmp[0]; |
} |
|
void XBee_Convert_Endian_16(XBEE_ADDRESS_16 *src) { |
char tmp; |
tmp = src->INT_16.char_value[0]; |
src->INT_16.char_value[0] = src->INT_16.char_value[1]; |
src->INT_16.char_value[1] = tmp; |
} |