27,12 → 27,6 |
#pragma config IOL1WAY = OFF // IOLOCK bit can be set and cleared as needed |
#endif |
|
/* ----- To Do ----- |
* Verify polling base station over I2C works |
* Implement send data to remote on corresponding I2C command |
* Verify operation with multiple base stations |
* -------------- */ |
|
/* ----------- IO Pins ----------- |
* RA0 - LED Display Latch Enable (V1) or Display CLK (V2) (PPS) |
* RA1 - LED Display CLK (V1) (PPS) or Display DIN (V2) (PPS) |
73,15 → 67,25 |
int length; |
unsigned char msgtype; |
unsigned char i = 0; |
unsigned char counter = 0; |
unsigned char IR_receive_flag = 0; |
unsigned int xbee_parent_address = 0; |
#ifdef _BASE_STATION |
volatile unsigned char IR_receive_flag = 0; |
unsigned char i2c_last_req_size = 0; |
XBEE_ADDRESS_64 last_recv_address = {0}; |
XBEE_ADDRESS_16 remote_address_16; |
XBEE_ADDRESS_64 remote_address_64; |
#endif |
#ifdef _REMOTE |
unsigned int xbee_parent_address_16 = 0; |
enum I2C_STATE i2c_state = I2C_STATE_IDLE; |
enum XBEE_STATE xbee_state = XBEE_STATE_WAITING_TO_JOIN; |
XBEE_ADDRESS_64 last_recv_address = {0}; |
XBEE_ADDRESS_16 converter16; |
XBEE_ADDRESS_16 parent_address_16; |
XBEE_ADDRESS_64 parent_address_64; |
#endif |
|
// Pointers to allow parsing of xbee data from arbitrary byte array |
XBEE_TX_DATA_PACKET_FRAME *frame_tx_data; |
XBEE_TX_AT_COMMAND_FRAME *frame_tx_at_command; |
|
// Pointers to allow parsing of xbee data from arbitrary byte array |
XBEE_RX_AT_COMMAND_RESPONSE_FRAME *frame_at_cmd_response; |
XBEE_RX_DATA_PACKET_FRAME *frame_data_packet; |
XBEE_RX_DATA_TX_STATUS_FRAME *frame_tx_status; |
91,10 → 95,7 |
XBEE_RX_ROUTE_RECORD_FRAME *frame_route_record; |
XBEE_RX_NODE_IDENTIFICATION_INDICATOR_FRAME *frame_node_identification; |
XBEE_RX_MODEM_STATUS_FRAME *frame_modem_status; |
|
XBEE_TX_DATA_PACKET_FRAME *frame_tx_data; |
XBEE_TX_AT_COMMAND_FRAME *frame_tx_at_command; |
|
|
/* --------------------- Oscillator Configuration --------------------- */ |
OSCTUNEbits.PLLEN = 1; // Enable 4x PLL |
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz |
123,6 → 124,7 |
interrupt_init(); // Initialize the interrupt priorities |
#ifdef _BASE_STATION |
i2c_configure_slave(BASE_STATION_ADDRESS); |
led_driver_num(BASE_STATION_ADDRESS); |
#endif |
#ifdef _REMOTE |
i2c_configure_master(); // Configure the hardware i2c device as a master |
181,30 → 183,58 |
} else { |
msgbuffer[0] = buffer_data.stored_length; |
} |
DBG_PRINT_MAIN("Main: (I2C Return 0x2) Returning %d bytes\r\n", length); |
i2c_last_req_size = msgbuffer[0]; |
DBG_PRINT_MAIN("Main: (I2C Return 0x2) Returning %d\r\n", msgbuffer[0]); |
MQ_sendmsg_FromMainToHigh(length, MSGTYPE_I2C_REPLY, (void *) msgbuffer); |
break; |
case 0x4: |
// Return data stored in buffer |
if (buffer_data.stored_length > MSGLEN) { |
length = MSGLEN; |
buffer_read(MSGLEN, msgbuffer); |
} else { |
length = buffer_data.stored_length; |
buffer_read(buffer_data.stored_length, msgbuffer); |
} |
DBG_PRINT_MAIN("Main: (I2C Return 0x4) Returning %d bytes\r\n", length); |
MQ_sendmsg_FromMainToHigh(length, MSGTYPE_I2C_REPLY, (void *) msgbuffer); |
buffer_read(i2c_last_req_size, msgbuffer); |
DBG_PRINT_MAIN("Main: (I2C Return 0x4) Returning %d bytes\r\n", i2c_last_req_size); |
MQ_sendmsg_FromMainToHigh(i2c_last_req_size, MSGTYPE_I2C_REPLY, (void *) msgbuffer); |
pwm_LED_off(); // Turn off LED if it was on |
break; |
case 0x6: |
// Return status of IR signal input |
length = 1; |
msgbuffer[0] = IR_receive_flag; |
DBG_PRINT_MAIN("Main: Returning IR state %d\r\n", IR_receive_flag); |
MQ_sendmsg_FromMainToHigh(length, MSGTYPE_I2C_REPLY, (void *) msgbuffer); |
break; |
case 0x7: |
// Send value to specified remote |
|
remote_address_64.UPPER_32.char_value[0] = msgbuffer[1]; |
remote_address_64.UPPER_32.char_value[1] = msgbuffer[2]; |
remote_address_64.UPPER_32.char_value[2] = msgbuffer[3]; |
remote_address_64.UPPER_32.char_value[3] = msgbuffer[4]; |
remote_address_64.LOWER_32.char_value[0] = msgbuffer[5]; |
remote_address_64.LOWER_32.char_value[1] = msgbuffer[6]; |
remote_address_64.LOWER_32.char_value[2] = msgbuffer[7]; |
remote_address_64.LOWER_32.char_value[3] = msgbuffer[8]; |
remote_address_16.INT_16.char_value[0] = msgbuffer[9]; |
remote_address_16.INT_16.char_value[1] = msgbuffer[10]; |
DBG_PRINT_MAIN("Main: Sending %X to (64) %08lX %08lX (16) %04X\r\n", |
msgbuffer[11], |
remote_address_64.UPPER_32.long_value, |
remote_address_64.LOWER_32.long_value, |
remote_address_16.INT_16.int_value); |
|
frame_tx_data = (void *) msgbuffer; |
frame_tx_data->data[0] = msgbuffer[11]; |
frame_tx_data->frame_type = XBEE_TX_DATA_PACKET; |
frame_tx_data->frame_id = 0; |
frame_tx_data->destination_64.UPPER_32.long_value = remote_address_64.UPPER_32.long_value; |
frame_tx_data->destination_64.LOWER_32.long_value = remote_address_64.LOWER_32.long_value; |
ConvertEndian64(&frame_tx_data->destination_64); |
frame_tx_data->destination_16.INT_16.int_value = remote_address_16.INT_16.int_value; |
ConvertEndian16(&frame_tx_data->destination_16); |
frame_tx_data->broadcast_radius = 0; |
frame_tx_data->options = 0x01; // Disable ACK |
|
length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1; |
xbee_process_transmit_frame((void *) msgbuffer, length); |
break; |
case 0x8: |
break; |
case 0x9: |
break; |
default: |
DBG_PRINT_MAIN("Main: (ERROR) Unexpected message type recieved: %d\r\n", msgbuffer[0]); |
break; |
241,10 → 271,10 |
frame_tx_data = (void *) msgbuffer; |
frame_tx_data->frame_type = XBEE_TX_DATA_PACKET; |
frame_tx_data->frame_id = 0; |
frame_tx_data->destination_64.UPPER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.LOWER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value; |
frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value; |
ConvertEndian64(&frame_tx_data->destination_64); |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address; |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16; |
ConvertEndian16(&frame_tx_data->destination_16); |
frame_tx_data->broadcast_radius = 0; |
frame_tx_data->options = 0x01; // Disable ACK |
263,23 → 293,65 |
|
/* --- XBee Message Handlers ---------------------------------*/ |
case MSGTYPE_XBEE_RX_AT_COMMAND_RESPONSE: |
DBG_PRINT_MAIN("\r\n"); |
frame_at_cmd_response = (void *) msgbuffer; |
DBG_PRINT_MAIN("Main: XBee AT command response frame\r\n"); |
frame_at_cmd_response = (void *) msgbuffer; |
DBG_PRINT_MAIN("Command: %c%c\r\n", frame_at_cmd_response->command[0], frame_at_cmd_response->command[1]); |
DBG_PRINT_MAIN("Status: %d\r\n", frame_at_cmd_response->command_status); |
DBG_PRINT_MAIN("Data: "); |
for (i = 0; i < length - XBEE_RX_AT_COMMAND_RESPONSE_FRAME_SIZE; i++) { |
DBG_PRINT_MAIN("%02X ", frame_data_packet->data[i]); |
DBG_PRINT_MAIN("%02X ", frame_at_cmd_response->data[i]); |
} |
DBG_PRINT_MAIN("\r\n"); |
#ifdef _REMOTE |
// Parse response from 'MP' command |
if (frame_at_cmd_response->command[0] == 'M' && |
frame_at_cmd_response->command[1] == 'P') { |
converter16.INT_16.char_value[0] = frame_at_cmd_response->data[0]; |
converter16.INT_16.char_value[1] = frame_at_cmd_response->data[1]; |
ConvertEndian16(&converter16); |
xbee_parent_address = converter16.INT_16.int_value; |
parent_address_16.INT_16.char_value[0] = frame_at_cmd_response->data[0]; |
parent_address_16.INT_16.char_value[1] = frame_at_cmd_response->data[1]; |
ConvertEndian16(&parent_address_16); |
xbee_parent_address_16 = parent_address_16.INT_16.int_value; |
|
DBG_PRINT_MAIN("Main: XBee parent address (16): %04X\r\n", xbee_parent_address_16); |
// Set broadcast radius to 1 |
frame_tx_at_command = (void *) msgbuffer; |
frame_tx_at_command->frame_type = XBEE_TX_AT_COMMAND; |
frame_tx_at_command->frame_id = 1; |
frame_tx_at_command->command[0] = 'B'; |
frame_tx_at_command->command[1] = 'H'; |
frame_tx_at_command->data[0] = 1; |
length = XBEE_TX_AT_COMMAND_FRAME_SIZE + 1; |
xbee_process_transmit_frame((void *) msgbuffer, length); |
|
// Query for parent node info |
frame_tx_at_command = (void *) msgbuffer; |
frame_tx_at_command->frame_type = XBEE_TX_AT_COMMAND; |
frame_tx_at_command->frame_id = 1; |
frame_tx_at_command->command[0] = 'N'; |
frame_tx_at_command->command[1] = 'D'; |
length = XBEE_TX_AT_COMMAND_FRAME_SIZE; |
xbee_process_transmit_frame((void *) msgbuffer, length); |
} |
// Parse response from 'ND' command |
else if (frame_at_cmd_response->command[0] == 'N' && |
frame_at_cmd_response->command[1] == 'D') { |
parent_address_64.UPPER_32.char_value[0] = frame_at_cmd_response->data[2]; |
parent_address_64.UPPER_32.char_value[1] = frame_at_cmd_response->data[3]; |
parent_address_64.UPPER_32.char_value[2] = frame_at_cmd_response->data[4]; |
parent_address_64.UPPER_32.char_value[3] = frame_at_cmd_response->data[5]; |
parent_address_64.LOWER_32.char_value[0] = frame_at_cmd_response->data[6]; |
parent_address_64.LOWER_32.char_value[1] = frame_at_cmd_response->data[7]; |
parent_address_64.LOWER_32.char_value[2] = frame_at_cmd_response->data[8]; |
parent_address_64.LOWER_32.char_value[3] = frame_at_cmd_response->data[9]; |
ConvertEndian64(&parent_address_64); |
|
DBG_PRINT_MAIN("Main: XBee parent address (64): %08lX %08lX\r\n", |
parent_address_64.UPPER_32.long_value, |
parent_address_64.LOWER_32.long_value); |
|
xbee_state = XBEE_STATE_JOINED_NETWORK; |
// Turn off LED after XBee has joined network |
pwm_LED_off(); |
} |
#endif |
break; |
302,12 → 374,13 |
DBG_PRINT_MAIN("\r\n"); |
#ifdef _BASE_STATION |
|
DBG_PRINT_MAIN("Buffer Free Space: %d\r\n", buffer_free_space()); |
if (frame_data_packet->source_64.LOWER_32.long_value != last_recv_address.LOWER_32.long_value || |
frame_data_packet->source_64.UPPER_32.long_value != last_recv_address.UPPER_32.long_value) { |
// Receive data from new remote |
// Save remote's 64 and 16 bit addresses |
buffer_insert_one(RETURNID_NEW_REMOTE_SRC); |
buffer_insert(4, frame_data_packet->source_64.UPPER_32.char_value); |
buffer_insert(4, frame_data_packet->source_64.LOWER_32.char_value); |
buffer_insert(2, frame_data_packet->source_16.INT_16.char_value); |
// Save data |
buffer_insert(length - XBEE_RX_DATA_PACKET_FRAME_SIZE, frame_data_packet->data); |
// Save address of sender |
321,6 → 394,9 |
// Send value of first byte received to LED display |
led_driver_num(frame_data_packet->data[0]); |
#endif |
#ifdef _REMOTE |
led_driver_num(frame_data_packet->data[0]); |
#endif |
sleep(); |
break; |
case MSGTYPE_XBEE_RX_DATA_TX_STATUS: |
365,8 → 441,12 |
frame_node_identification->remote_64.LOWER_32.long_value |
); |
DBG_PRINT_MAIN("Remote 16: %04X\r\n", frame_node_identification->remote_16.INT_16.int_value); |
DBG_PRINT_MAIN("Remote 16: %04X\r\n", frame_node_identification->parent_16.INT_16.int_value); |
DBG_PRINT_MAIN("Parent 16: %04X\r\n", frame_node_identification->parent_16.INT_16.int_value); |
DBG_PRINT_MAIN("Receive Options: %02X\r\n", frame_node_identification->recieve_options); |
buffer_insert_one(RETURNID_NEW_REMOTE_CON); |
buffer_insert(4, frame_node_identification->remote_64.UPPER_32.char_value); |
buffer_insert(4, frame_node_identification->remote_64.LOWER_32.char_value); |
buffer_insert(2, frame_node_identification->remote_16.INT_16.char_value); |
break; |
case MSGTYPE_XBEE_RX_FRAME_MODEM_STATUS: |
DBG_PRINT_MAIN("Main: XBee modem status frame\r\n"); |
375,7 → 455,9 |
switch(frame_modem_status->status) { |
case 0: |
DBG_PRINT_MAIN("Hardware Reset"); |
#ifdef _REMOTE |
xbee_state = XBEE_STATE_WAITING_TO_JOIN; |
#endif |
break; |
case 1: |
DBG_PRINT_MAIN("Watchdog Timer Reset"); |
382,9 → 464,6 |
break; |
case 2: |
DBG_PRINT_MAIN("Joined Network"); |
#ifdef _BASE_STATION |
xbee_state = XBEE_STATE_JOINED_NETWORK; |
#endif |
#ifdef _REMOTE |
// Query for parent's address |
frame_tx_at_command = (void *) msgbuffer; |
392,14 → 471,13 |
frame_tx_at_command->frame_id = 1; |
frame_tx_at_command->command[0] = 'M'; |
frame_tx_at_command->command[1] = 'P'; |
// length = XBEE_TX_AT_COMMAND_FRAME_SIZE; |
xbee_process_transmit_frame((void *) msgbuffer, 4); |
// Turn off LED after XBee has joined network |
pwm_LED_off(); |
length = XBEE_TX_AT_COMMAND_FRAME_SIZE; |
xbee_process_transmit_frame((void *) msgbuffer, length); |
#endif |
break; |
case 3: |
DBG_PRINT_MAIN("Disassociated"); |
pwm_LED_on(); |
break; |
case 6: |
DBG_PRINT_MAIN("Coordinator Started"); |
415,7 → 493,7 |
break; |
/* -----------------------------------------------------------*/ |
}; |
continue; |
// continue; |
} |
|
// Process low priority queue |
427,6 → 505,16 |
} |
} else { |
switch (msgtype) { |
case MSGTYPE_INT1: |
#ifdef _BASE_STATION |
wake(); |
IR_receive_flag = 1; |
pwm_LED_on(); |
// timer2_enable(); // Enable timer 2 to turn off LED |
sleep(); |
// DBG_PRINT_MAIN("Main: INT1 Interrupt\r\n"); |
#endif |
break; |
/* --- Port B Interrupt Handlers -----------------------------*/ |
case MSGTYPE_PORTB_4_DOWN: |
DBG_PRINT_MAIN("Main: Port B4 Down\r\n"); |
449,10 → 537,10 |
frame_tx_data = (void *) msgbuffer; |
frame_tx_data->frame_type = XBEE_TX_DATA_PACKET; |
frame_tx_data->frame_id = 0; |
frame_tx_data->destination_64.UPPER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.LOWER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value; |
frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value; |
ConvertEndian64(&frame_tx_data->destination_64); |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address; |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16; |
ConvertEndian16(&frame_tx_data->destination_16); |
frame_tx_data->broadcast_radius = 0; |
frame_tx_data->options = 0x01; // Disable ACK |
476,10 → 564,10 |
frame_tx_data = (void *) msgbuffer; |
frame_tx_data->frame_type = XBEE_TX_DATA_PACKET; |
frame_tx_data->frame_id = 0; |
frame_tx_data->destination_64.UPPER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.LOWER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value; |
frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value; |
ConvertEndian64(&frame_tx_data->destination_64); |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address; |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16; |
ConvertEndian16(&frame_tx_data->destination_16); |
frame_tx_data->broadcast_radius = 0; |
frame_tx_data->options = 0x01; // Disable ACK |
507,14 → 595,14 |
frame_tx_data = (void *) msgbuffer; |
frame_tx_data->frame_type = XBEE_TX_DATA_PACKET; |
frame_tx_data->frame_id = 0; |
frame_tx_data->destination_64.UPPER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.LOWER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value; |
frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value; |
ConvertEndian64(&frame_tx_data->destination_64); |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address; |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16; |
ConvertEndian16(&frame_tx_data->destination_16); |
frame_tx_data->broadcast_radius = 0; |
frame_tx_data->options = 0x01; // Disable ACK |
frame_tx_data->data[0] = RETURNID_BTN1; |
frame_tx_data->data[0] = RETURNID_BTN2; |
|
length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1; |
xbee_process_transmit_frame((void *) msgbuffer, length); |
537,17 → 625,17 |
frame_tx_data = (void *) msgbuffer; |
frame_tx_data->frame_type = XBEE_TX_DATA_PACKET; |
frame_tx_data->frame_id = 0; |
frame_tx_data->destination_64.UPPER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.LOWER_32.long_value = 0x00000000; |
frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value; |
frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value; |
ConvertEndian64(&frame_tx_data->destination_64); |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address; |
frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16; |
ConvertEndian16(&frame_tx_data->destination_16); |
frame_tx_data->broadcast_radius = 0; |
frame_tx_data->options = 0x01; // Disable ACK |
frame_tx_data->data[0] = RETURNID_BTN2; |
frame_tx_data->data[0] = RETURNID_BTN1; |
|
length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1; |
xbee_process_transmit_frame((void *) msgbuffer, length); |
xbee_process_transmit_frame((void *) msgbuffer, length);; |
} |
#endif |
break; |
559,21 → 647,13 |
} |
#endif |
break; |
case MSGTYPE_INT1: |
#ifdef _BASE_STATION |
IR_receive_flag = 1; |
pwm_LED_toggle(); |
Delay10KTCYx(1); |
pwm_LED_toggle(); |
sleep(); |
// DBG_PRINT_MAIN("Main: INT1 Interrupt\r\n"); |
#endif |
break; |
/* -----------------------------------------------------------*/ |
/* --- Timer Interrupt Handlers ------------------------------*/ |
case MSGTYPE_TIMER0: |
DBG_PRINT_MAIN("Main: Timer 0 Interrupt\r\n"); |
IR_receive_flag = 0; |
pwm_LED_off(); |
IR_receive_flag = 0; // Reset IR receive flag |
INTCON3bits.INT1IE = 1; // Turn on INT1 interrupt |
sleep_enable(); |
break; |
case MSGTYPE_TIMER1: |
613,6 → 693,14 |
} |
#endif |
break; |
case MSGTYPE_TIMER2: |
DBG_PRINT_MAIN("Main: Timer 2 Interrupt\r\n"); |
#ifdef _BASE_STATION |
IR_receive_flag = 0; |
pwm_LED_off(); |
INTCON3bits.INT1IE = 1; // Turn on INT1 interrupt |
#endif |
break; |
// case MSGTYPE_ADC_NEWVALUE: |
// // Get the value in the ADC |
// adc_last_value = *((unsigned int*) msgbuffer); |