Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 126 → Rev 127

/PIC Stuff/PIC_27J13/xbee.c
1,150 → 1,134
#include "maindefs.h"
#include "msg_queues.h"
#include "xbee.h"
#include <usart.h>
#include <delays.h>
#include <string.h>
 
static XBEE_DATA *xbee_data_ptr;
static void *xbee_data_array_ptr;
static XBEE_DATA xbee_data;
static void *xbee_data_frame;
static void *xbee_frame;
 
/* Initialize variables used by this library */
void xbee_init(XBEE_DATA *xd) {
TRISBbits.TRISB0 = 1; // RB0 is CTS, set by XBee chip
TRISBbits.TRISB1 = 0; // RB1 is RTS, set by PIC
void XBee_Init() {
XBEE_CTS_TRIS = 1; // RB0 is CTS, set by XBee chip
XBEE_RTS_TRIS = 0; // RB1 is RTS, set by PIC
 
LATBbits.LATB0 = 0; // Pin set high to signal stop sending data to XBee
LATBbits.LATB1 = 0; // Pin set high to indicate stop sending data to 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_ptr = xd;
xbee_data_ptr->dataind = 0;
xbee_data_ptr->checksum_sum = 0;
xbee_data_ptr->read_state = XBEE_STATE_READ_START;
xbee_data.dataind = 0;
xbee_data.checksum_sum = 0;
xbee_data.frame_rdy = 0;
xbee_data.escape_flag = 0;
xbee_data.read_state = XBEE_STATE_READ_START;
 
// memset(&xbee_data, 0, 32);
// Grab a pointer to where the unique frame array starts
xbee_data_array_ptr = &(xbee_data_ptr->rcv_frame.FRAME);
xbee_data_frame = &(xbee_data.rcv_frame.FRAME);
xbee_frame = &(xbee_data.rcv_frame);
}
 
/* Here we handle the serial input from the UART interrupt */
void xbee_read_serial(unsigned char c) {
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 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.escape_flag = 1;
return;
}
 
if (xbee_data.escape_flag) {
// XOR byte with 0x20 to get escaped char
c ^= XBEE_ESCAPE_VAL;
xbee_data.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_ptr->dataind = 0;
xbee_data_ptr->checksum_sum = 0;
xbee_data_ptr->rcv_frame.start_delimiter = XBEE_START_DELIMITER;
xbee_data_ptr->read_state = XBEE_STATE_READ_LENGTH_HIGH;
xbee_data.dataind = 0;
xbee_data.checksum_sum = 0;
xbee_data.frame_rdy = 0;
xbee_data.read_state = XBEE_STATE_READ_LENGTH_HIGH;
*((unsigned char *)xbee_frame) = XBEE_START_DELIMITER;
} else {
switch(xbee_data_ptr->read_state) {
switch (xbee_data.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)
xbee_data_ptr->rcv_frame.length.INT_16.char_value[1] = c;
xbee_data_ptr->read_state = XBEE_STATE_READ_LENGTH_LOW;
length->INT_16.char_value[1] = c;
xbee_data.read_state = XBEE_STATE_READ_LENGTH_LOW;
break;
case XBEE_STATE_READ_LENGTH_LOW:
// Read length (LSB)
xbee_data_ptr->rcv_frame.length.INT_16.char_value[0] = c;
xbee_data_ptr->read_state = XBEE_STATE_READ_FRAME_DATA;
length->INT_16.char_value[0] = c;
xbee_data.read_state = XBEE_STATE_READ_FRAME_DATA;
break;
case XBEE_STATE_READ_FRAME_DATA:
// Read unique frame data
if (xbee_data_ptr->dataind < xbee_data_ptr->rcv_frame.length.INT_16.int_value) {
*((char*)xbee_data_array_ptr + xbee_data_ptr->dataind) = c;
xbee_data_ptr->checksum_sum += c;
xbee_data_ptr->dataind++;
if (xbee_data.dataind < xbee_data.rcv_frame.length.INT_16.int_value) {
*((char*) xbee_data_frame + xbee_data.dataind) = c;
xbee_data.checksum_sum += c;
xbee_data.dataind++;
}
// If total length is read, the next byte is the expected checksum
if (xbee_data_ptr->dataind == xbee_data_ptr->rcv_frame.length.INT_16.int_value) {
xbee_data_ptr->read_state = XBEE_STATE_READ_CHECKSUM;
if (xbee_data.dataind == xbee_data.rcv_frame.length.INT_16.int_value) {
xbee_data.read_state = XBEE_STATE_READ_CHECKSUM;
}
break;
case XBEE_STATE_READ_CHECKSUM:
// Calculate and compare checksum
if (0xFF - xbee_data_ptr->checksum_sum == c) {
if (0xFF - xbee_data.checksum_sum == c) {
// Frame was recieved successfully
xbee_process_recieved_frame();
xbee_data_ptr->read_state = XBEE_STATE_READ_START;
xbee_data.frame_rdy = 1;
// XBee_Process_Received_Frame();
} else {
// If checksum does not match, drop frame
// If checksum does not match, drop frame
DBG_PRINT_XBEE("XBEE: checksum mismatch\r\n");
xbee_data_ptr->read_state = XBEE_STATE_READ_START;
}
xbee_data.read_state = XBEE_STATE_READ_START;
break;
}
}
}
 
/* This is called when a full frame arrives to process the frame data */
void xbee_process_recieved_frame() {
char ret_status;
// Here we want to process each frame and send the data to Main()
// Send the frame to main() with the message type depending on the frame type
switch(*((unsigned char *) xbee_data_array_ptr)) {
/* 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.rcv_frame.length.INT_16.int_value);
// Here we process the received frame depending on the frame type
switch (*((unsigned char *) xbee_data_frame)) {
case XBEE_RX_AT_COMMAND_RESPONSE:
DBG_PRINT_XBEE("XBEE: parsing recieved AT command response frame\r\n");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_AT_COMMAND_RESPONSE, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
break;
case XBEE_RX_DATA_PACKET:
DBG_PRINT_XBEE("XBEE: parsing recieved data recieved frame\r\n");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_DATA_PACKET, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
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");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_DATA_TX_STATUS, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
break;
case XBEE_RX_IO_DATA_SAMPLE:
DBG_PRINT_XBEE("XBEE: parsing recieved IO data sample frame\r\n");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_IO_DATA_SAMPLE, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
break;
case XBEE_RX_EXPLICIT_COMMAND:
DBG_PRINT_XBEE("XBEE: parsing recieved explicit command frame\r\n");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_EXPLICIT_COMMAND, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
break;
case XBEE_RX_REMOTE_AT_COMMAND_RESPONSE:
DBG_PRINT_XBEE("XBEE: parsing recieved remote AT command frame\r\n");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_REMOTE_AT_COMMAND_RESPONSE, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
break;
case XBEE_RX_ROUTE_RECORD:
DBG_PRINT_XBEE("XBEE: parsing recieved route record frame\r\n");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_ROUTE_RECORD, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
break;
case XBEE_RX_NODE_IDENTIFICATION:
DBG_PRINT_XBEE("XBEE: parsing recieved node identification frame\r\n");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_NODE_IDENTIFICATION, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
break;
case XBEE_RX_FRAME_MODEM_STATUS:
DBG_PRINT_XBEE("XBEE: parsing recieved modem status frame\r\n");
ret_status = MQ_sendmsg_ToMainFromHigh(xbee_data_ptr->rcv_frame.length.INT_16.char_value[0], MSGTYPE_XBEE_RX_FRAME_MODEM_STATUS, (void *)xbee_data_array_ptr);
if (ret_status < 0) {
DBG_PRINT_XBEE("XBEE: (ERROR) send message to main failed with error %x\r\n", ret_status);
}
break;
default:
DBG_PRINT_XBEE("XBEE: (ERROR) unrecognized frame type\r\n");
151,58 → 135,74
}
}
 
//void xbee_process_transmit_frame_interrupt(void) {
// unsigned char i;
// char length;
//
// if (MQ_peek_FromMainToHigh() == MSGTYPE_XBEE_TX_FRAME) {
// length = MQ_recvmsg_FromMainToHigh(MSGLEN, (unsigned char *) xbee_data_ptr->msgtype, (void *) xbee_data_array_ptr);
// xbee_data_ptr->checksum_sum = 0;
// Write2USART(XBEE_START_DELIMITER);
// while (Busy2USART());
// Write2USART(0x00);
// while (Busy2USART());
// Write2USART(length);
// while (Busy2USART());
// for (i = 0; i < length; i++) {
// Write2USART(*((unsigned char *) xbee_data_array_ptr + i));
// xbee_data_ptr->checksum_sum += *((unsigned char *) xbee_data_array_ptr + i);
// while (Busy2USART());
// }
// Write2USART(0xFF - xbee_data_ptr->checksum_sum);
// while (Busy2USART());
// }
//}
unsigned int XBee_Get_Received_Frame(unsigned char *frame) {
if (!xbee_data.frame_rdy) {
return 0;
} else {
memcpy(frame, xbee_data_frame, xbee_data.rcv_frame.length.INT_16.int_value);
xbee_data.frame_rdy = 0; // Reset frame ready status
return xbee_data.rcv_frame.length.INT_16.int_value;
}
}
 
void xbee_process_transmit_frame(void *data, unsigned char length) {
unsigned char i;
unsigned char checksum = 0;
void XBee_Process_Transmit_Frame(unsigned char *data, unsigned char length) {
#ifdef XBEE_USE_ESCAPE_CHAR
unsigned int i = 0;
unsigned char chksum = 0;
 
Write2USART(XBEE_START_DELIMITER);
while (Busy2USART() || xbee_read_CTS());
Write2USART(0x00);
while (Busy2USART() || xbee_read_CTS());
Write2USART(length);
while (Busy2USART() || xbee_read_CTS());
// 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++) {
Write2USART(*((unsigned char *) data + i));
checksum += *((unsigned char *) data + i);
while (Busy2USART() || xbee_read_CTS());
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]);
}
}
Write2USART(0xFF - checksum);
while (Busy2USART());
// 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;
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) {
void XBee_Set_RTS(unsigned char c) {
if (c) {
LATBbits.LATB1 = 1; // Set high to stop receiving data
XBEE_RTS_LAT = 1; // Set high to stop receiving data
} else {
LATBbits.LATB1 = 0; // Set low to resume receiving data
XBEE_RTS_LAT = 0; // Set low to resume receiving data
}
}
 
unsigned char xbee_read_CTS() {
unsigned char c = PORTBbits.RB0;
unsigned char XBee_Read_CTS() {
unsigned char c = XBEE_CTS_PORT;
if (c) {
return 0x1; // High indicates stop sending data
} else {
209,3 → 209,27
return 0x0; // Low indicates ok to send data
}
}
 
void XBee_ConvertEndian64(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_ConvertEndian16(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;
}