Rev 147 | Blame | Last modification | View Log | Download | RSS feed
#include "defines.h"#include "xbee.h"#include <string.h>#pragma udata XBEE_BUFFERstatic XBEE_DATA xbee_data;#pragma udatastatic XBEE_DATA *xbee_data_p = &xbee_data;static void *xbee_data_frame;static void *xbee_frame;/* Initialize variables used by this library */void XBee_Init() {XBEE_CTS_TRIS = 1; // RB0 is CTS, set by XBee chipXBEE_RTS_TRIS = 0; // RB1 is RTS, set by PICXBEE_CTS_LAT = 0; // Pin set high to signal stop sending data to XBeeXBEE_RTS_LAT = 0; // Pin set high to indicate stop sending data to PICxbee_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 startsxbee_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(unsigned 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 directlyXBEE_ADDRESS_16 *length = xbee_frame + 1;#ifdef XBEE_USE_ESCAPE_CHARif (c == XBEE_ESCAPE_CHAR) {// Next byte needs is an escaped charxbee_data_p->escape_flag = 1;return;}if (xbee_data_p->escape_flag) {// XOR byte with 0x20 to get escaped charc ^= XBEE_ESCAPE_VAL;xbee_data_p->escape_flag = 0;}#endif// Reset on start bit and start saving dataif (c == XBEE_START_DELIMITER) {// On detect start delimiter, clear out initial arrayxbee_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;*((unsigned char *)xbee_frame) = XBEE_START_DELIMITER;} else {switch (xbee_data_p->read_state) {case XBEE_STATE_READ_START:// Do nothing and wait till start bit is readbreak;case XBEE_STATE_READ_LENGTH_HIGH:// Read length (MSB)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->read_state = XBEE_STATE_READ_FRAME_DATA;break;case XBEE_STATE_READ_FRAME_DATA:// Read unique frame dataif (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 checksumif (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 checksumif (0xFF - xbee_data_p->checksum_sum == c) {// Frame was recieved successfullyxbee_data_p->frame_rdy = 1;// XBee_Process_Received_Frame();} else {// If checksum does not match, drop frameDBG_PRINT_XBEE("XBEE: checksum mismatch\r\n");}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 typeswitch (*((unsigned char *) xbee_data_frame)) {case XBEE_RX_AT_COMMAND_RESPONSE:DBG_PRINT_XBEE("XBEE: parsing recieved AT command response frame\r\n");break;case XBEE_RX_DATA_PACKET:DBG_PRINT_XBEE("XBEE: parsing recieved data frame\r\n");break;case XBEE_RX_DATA_TX_STATUS:DBG_PRINT_XBEE("XBEE: parsing recieved TX status frame\r\n");break;case XBEE_RX_IO_DATA_SAMPLE:DBG_PRINT_XBEE("XBEE: parsing recieved IO data sample frame\r\n");break;case XBEE_RX_EXPLICIT_COMMAND:DBG_PRINT_XBEE("XBEE: parsing recieved explicit command frame\r\n");break;case XBEE_RX_REMOTE_AT_COMMAND_RESPONSE:DBG_PRINT_XBEE("XBEE: parsing recieved remote AT command frame\r\n");break;case XBEE_RX_ROUTE_RECORD:DBG_PRINT_XBEE("XBEE: parsing recieved route record frame\r\n");break;case XBEE_RX_NODE_IDENTIFICATION:DBG_PRINT_XBEE("XBEE: parsing recieved node identification frame\r\n");break;case XBEE_RX_FRAME_MODEM_STATUS:DBG_PRINT_XBEE("XBEE: parsing recieved modem status frame\r\n");break;default:DBG_PRINT_XBEE("XBEE: (ERROR) unrecognized frame type\r\n");}}unsigned int XBee_Get_Received_Frame(unsigned 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 statusreturn xbee_data_p->rcv_frame.length.INT_16.int_value;}}void XBee_Process_Transmit_Frame(unsigned char *data, unsigned char length) {#ifdef XBEE_USE_ESCAPE_CHARunsigned int i = 0;unsigned char chksum = 0;// Write the start bit and lengthUART1_WriteC(XBEE_START_DELIMITER);UART1_WriteC(0);UART1_WriteC(length);// Write the frame datafor (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 checksumif (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);}#elseunsigned int i = 0;unsigned 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(unsigned 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}}unsigned char XBee_Read_CTS() {unsigned 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;}