0,0 → 1,227 |
#include "maindefs.h" |
#include "msg_queues.h" |
#include "xbee.h" |
#include "timers.h" |
#include <usart.h> |
#include <delays.h> |
|
#pragma udata xbee_data |
XBEE_FRAME data_frame; |
#pragma udata |
XBEE_DATA *xbee_data_ptr; |
void *xbee_data_array_ptr; |
|
/* 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 |
TRISCbits.TRISC5 = 0; // RC5 is Sleep |
|
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 |
LATCbits.LATC5 = 0; // Pin set high to sleep XBee module |
|
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_ptr->rcv_frame.FRAME = &data_frame; |
|
// Grab a pointer to where the unique frame array starts |
xbee_data_array_ptr = xbee_data_ptr->rcv_frame.FRAME; |
} |
|
/* Here we handle the serial input from the UART interrupt */ |
void xbee_read_serial(unsigned char c) { |
// 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; |
} else { |
switch(xbee_data_ptr->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; |
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; |
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 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; |
} |
break; |
case XBEE_STATE_READ_CHECKSUM: |
// Calculate and compare checksum |
if (0xFF - xbee_data_ptr->checksum_sum == c) { |
// Frame was recieved successfully |
xbee_process_recieved_frame(); |
xbee_data_ptr->read_state = XBEE_STATE_READ_START; |
} else { |
// If checksum does not match, drop frame |
DBG_PRINT_XBEE("XBEE: checksum mismatch\r\n"); |
xbee_data_ptr->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)) { |
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); |
} |
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"); |
} |
} |
|
//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()); |
// } |
//} |
|
void xbee_process_transmit_frame(void *data, unsigned char length) { |
unsigned char i; |
unsigned char checksum = 0; |
|
Write2USART(XBEE_START_DELIMITER); |
while (Busy2USART() || xbee_read_CTS()); |
Write2USART(0x00); |
while (Busy2USART() || xbee_read_CTS()); |
Write2USART(length); |
while (Busy2USART() || xbee_read_CTS()); |
for (i = 0; i < length; i++) { |
Write2USART(*((unsigned char *) data + i)); |
checksum += *((unsigned char *) data + i); |
while (Busy2USART() || xbee_read_CTS()); |
} |
Write2USART(0xFF - checksum); |
while (Busy2USART()); |
} |
|
void xbee_set_RTS(unsigned char c) { |
if (c) { |
LATBbits.LATB1 = 1; // Set high to stop receiving data |
} else { |
LATBbits.LATB1 = 0; // Set low to resume receiving data |
} |
} |
|
unsigned char xbee_read_CTS() { |
unsigned char c = PORTBbits.RB0; |
if (c) { |
return 0x1; // High indicates stop sending data |
} else { |
return 0x0; // Low indicates ok to send data |
} |
} |
|
void xbee_sleep() { |
LATCbits.LATC5 = 1; |
} |
|
void xbee_wake() { |
LATCbits.LATC5 = 0; |
} |