Rev 114 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#include "maindefs.h"#include "msg_queues.h"#include "interrupts.h"#include "uart.h"#include "i2c.h"#include "adc.h"#include "timers.h"#include "xbee.h"#include "led_driver.h"#include "pwm.h"#include "delays.h"#include "pin_interrupts.h"#include "buffer.h"#include "imu.h"#include "sleep.h"#pragma config WDTEN = OFF // Turn off watchdog timer#pragma config XINST = OFF // Turn off extended instruction set#pragma config OSC = HSPLL // Use external oscillator (101)#pragma config IOL1WAY = OFF // IOLOCK bit can be set and cleared as needed/* ----------- IO Pins -----------* RA0 - LED Display Latch Enable (V1) or Display CLK (V2) (PPS)* RA1 - LED Display CLK (V1) or Display DIN (V2) (PPS)* RA2 - LED Display DIN (V1) or Display Clock (V2)* RA3 - LED Display Output Enable* RA4 - [CANNOT BE USED (VDDCORE/VCAP)]* RA5 - IR Reciever (PPS)* RA6 - Oscillator* RA7 - Oscillator** RC0 - PWM Output (IR) (PPS, Ports B and C only)* RC1 - PWM Output (IR) (PPS, Ports B and C only)* RC2 - LED Output (PPS, Ports B and C only)* RC3 - I2C SCL* RC4 - I2C SDA* RC5 - XBee Sleep (PPS)* RC6 - UART Debug Output* RC7 - UART Debug Input** RB0 - XBee CTS (PPS)* RB1 - XBee RTS (PPS)* RB2 - XBee Tx (PPS)* RB3 - XBee Rx (PPS)* RB4 - Button Input (Port B Interrupt on Change)* RB5 - Button Input (Port B Interrupt on Change)* RB6 - Button Input (Port B Interrupt on Change)* RB7 - Button Input (Port B Interrupt on Change)* ---------------------------- */#pragma udata msgbufferunsigned char msgbuffer[MSGLEN];#pragma udatavoid main(void) {XBEE_DATA xbee_data;I2C_DATA i2c_data;BUFFER_DATA buffer_data;char length;unsigned char msgtype;unsigned char i = 0;unsigned char counter = 0;enum I2C_STATE i2c_state = I2C_STATE_IDLE;enum XBEE_STATE xbee_state = XBEE_STATE_WAITING_TO_JOIN;// Pointers to allow parsing of xbee data from arbitrary byte arrayXBEE_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;XBEE_RX_IO_DATA_SAMPLE_FRAME *frame_io_sample;XBEE_RX_EXPLICIT_COMMAND_FRAME *frame_explicit_cmd;XBEE_RX_REMOTE_AT_COMMAND_FRAME *frame_remote_at_cmd;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;/* --------------------- Oscillator Configuration --------------------- */OSCTUNEbits.PLLEN = 1; // Enable 4x PLLOSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHzOSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source/* -------------------------------------------------------------------- */// Set all ports as digial I/OANCON0 = 0xFF;ANCON1 = 0x1F;uart_init(); // Initialize the UART handler codexbee_init(&xbee_data); // Initialize the XBee handler codei2c_init(&i2c_data); // Initialize the I2C handler codebuffer_init(&buffer_data);// adc_init(); // Initialize the ADCMQ_init(); // Initialize message queues before enabling any interruptstimers_init(); // Initialize timersled_driver_init(); // Initialize the driver for the LED displayport_b_int_init(); // Initialze Port B interrupt handler// intx_init(); // IR receiver inputpwm_init(); // Initialize the PWM output driverinterrupt_enable(); // Enable high-priority interrupts and low-priority interruptsinterrupt_init(); // Initialize the interrupt prioritiesi2c_configure_master(); // Configure the hardware i2c device as a masterimu_init();Delay10KTCYx(255);DBG_PRINT_MAIN("\r\nMain: Program Started\r\n");// Turn on LED until XBee is connected to networkpwm_LED_start();// Loop and process recieved messages from interruptswhile (1) {// Call a routine that blocks until either message queues are not emptyMQ_wait_on_incoming_msg_queues();// Process high priority message queuelength = MQ_recvmsg_ToMainFromHigh(MSGLEN, &msgtype, (void *) msgbuffer);if (length < 0) {// No message, check the error code to see if it is concernif (length != MSG_QUEUE_EMPTY) {DBG_PRINT_MAIN("Main: (ERROR) Bad high priority receive, code = %d\r\n", length);}} else {switch (msgtype) {/* --- I2C Message Handlers ----------------------------------*/case MSGTYPE_OVERRUN:DBG_PRINT_MAIN("Main: (ERROR) UART overrun detected, type = %d\r\n", msgtype);break;case MSGTYPE_I2C_DBG:DBG_PRINT_MAIN("Main: I2C Dbg Data Recieved: ");for (i = 0; i < length; i++) {DBG_PRINT_MAIN("%X ", msgbuffer[i]);}DBG_PRINT_MAIN("\r\n");break;case MSGTYPE_I2C_DATA:DBG_PRINT_MAIN("Main: I2C Data Recieved: ");for (i = 0; i < length - 1; i++) {DBG_PRINT_MAIN("%X ", msgbuffer[i]);}DBG_PRINT_MAIN(" Event Count: %d", msgbuffer[length - 1]);DBG_PRINT_MAIN("\r\n");switch (msgbuffer[0]) {case 0x2:length = 1;// Return size of stored data in bufferif (buffer_data.stored_length > MSGLEN) {msgbuffer[0] = MSGLEN;} else {msgbuffer[0] = buffer_data.stored_length;}DBG_PRINT_MAIN("Main: (I2C Return 0x2) Returning %X\r\n", msgbuffer[0]);MQ_sendmsg_FromMainToHigh(length, MSGTYPE_I2C_REPLY, (void *) msgbuffer);break;case 0x4:// Return data stored in bufferif (buffer_data.stored_length > MSGLEN) {length = MSGLEN;buffer_read(MSGLEN, msgbuffer);} else {length = buffer_data.stored_length;buffer_read(buffer_data.stored_length, msgbuffer);}MQ_sendmsg_FromMainToHigh(length, MSGTYPE_I2C_REPLY, (void *) msgbuffer);break;case 0x6:break;case 0x7:break;case 0x8:break;case 0x9:break;default:DBG_PRINT_MAIN("Main: (ERROR) Unexpected message type recieved: %d\r\n", msgbuffer[0]);break;};break;case MSGTYPE_I2C_MASTER_SEND_COMPLETE:DBG_PRINT_MAIN("Main: I2C Master Send Complete\r\n");break;case MSGTYPE_I2C_MASTER_SEND_FAILED:DBG_PRINT_MAIN("Main: (ERROR) I2C Master Send Failed\r\n");break;case MSGTYPE_I2C_MASTER_RECV_COMPLETE:DBG_PRINT_MAIN("Main: I2C Master Receive Complete\r\n");DBG_PRINT_MAIN("Main: (I2C Data) ");for (i = 0; i < length; i++) {DBG_PRINT_MAIN("%X ", msgbuffer[i]);}if (buffer_free_space() >= 7) {// Insert recorded value into bufferif (i2c_state == I2C_STATE_READ_ACC) {buffer_insert_one(RETURNID_ACC);buffer_insert(6, msgbuffer);} else if (i2c_state == I2C_STATE_READ_GYRO) {buffer_insert_one(RETURNID_GYRO);buffer_insert(6, msgbuffer);}} else {// Send data to base station}DBG_PRINT_MAIN("\r\n");break;case MSGTYPE_I2C_MASTER_RECV_FAILED:DBG_PRINT_MAIN("Main: (ERROR) I2C Master Receive Failed\r\n");break;/* -----------------------------------------------------------*//* --- XBee Message Handlers ---------------------------------*/case MSGTYPE_XBEE_RX_AT_COMMAND_RESPONSE:DBG_PRINT_MAIN("Main: XBee AT command 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[0]);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("%X ", frame_data_packet->data[i]);}DBG_PRINT_MAIN("\r\n");break;case MSGTYPE_XBEE_RX_DATA_PACKET:DBG_PRINT_MAIN("Main: XBee data packet frame\r\n");frame_data_packet = (void *) msgbuffer;DBG_PRINT_MAIN("Data: ");for (i = 0; i < length - XBEE_RX_DATA_PACKET_FRAME_SIZE; i++) {DBG_PRINT_MAIN("%X ", frame_data_packet->data[i]);}DBG_PRINT_MAIN("\r\n");// Store received data into bufferbuffer_insert(length - XBEE_RX_DATA_PACKET_FRAME_SIZE, frame_data_packet->data);// Send value of first byte received to LED displayled_driver_num(frame_data_packet->data[0]);break;case MSGTYPE_XBEE_RX_DATA_TX_STATUS:DBG_PRINT_MAIN("Main: XBee TX status frame\r\n");frame_tx_status = (void *) msgbuffer;DBG_PRINT_MAIN("Destination: %X\r\n", frame_tx_status->destination_16);DBG_PRINT_MAIN("Transmit Retry Count: %X\r\n", frame_tx_status->transmit_retry_count);DBG_PRINT_MAIN("Delivery Status: %X\r\n", frame_tx_status->delivery_status);DBG_PRINT_MAIN("Discovery Status: %X\r\n", frame_tx_status->discovery_status);break;case MSGTYPE_XBEE_RX_IO_DATA_SAMPLE:DBG_PRINT_MAIN("Main: XBee IO data sample frame\r\n");frame_io_sample = (void *) msgbuffer;break;case MSGTYPE_XBEE_RX_EXPLICIT_COMMAND:DBG_PRINT_MAIN("Main: XBee explicit command frame\r\n");frame_explicit_cmd = (void *) msgbuffer;break;case MSGTYPE_XBEE_RX_REMOTE_AT_COMMAND_RESPONSE:DBG_PRINT_MAIN("Main: XBee remote AT command response frame\r\n");frame_remote_at_cmd = (void *) msgbuffer;break;case MSGTYPE_XBEE_RX_ROUTE_RECORD:DBG_PRINT_MAIN("Main: XBee route record frame\r\n");frame_route_record = (void *) msgbuffer;break;case MSGTYPE_XBEE_RX_NODE_IDENTIFICATION:DBG_PRINT_MAIN("Main: XBee node identification frame\r\n");frame_node_identification = (void *) msgbuffer;break;case MSGTYPE_XBEE_RX_FRAME_MODEM_STATUS:DBG_PRINT_MAIN("Main: XBee modem status frame\r\n");frame_modem_status = (void *) msgbuffer;DBG_PRINT_MAIN("Status: %X (", frame_modem_status->status);switch(frame_modem_status->status) {case 0:DBG_PRINT_MAIN("Hardware Reset");xbee_state = XBEE_STATE_WAITING_TO_JOIN;break;case 1:DBG_PRINT_MAIN("Watchdog Timer Reset");break;case 2:DBG_PRINT_MAIN("Joined Network");xbee_state = XBEE_STATE_JOINED_NETWORK;// Turn off LED after XBee has joined networkpwm_LED_stop();break;case 3:DBG_PRINT_MAIN("Disassociated");break;case 6:DBG_PRINT_MAIN("Coordinator Started");break;case 7:DBG_PRINT_MAIN("Network Security Key Updated");break;case 0x11:DBG_PRINT_MAIN("Modem Config Changed While Joining");break;}DBG_PRINT_MAIN(")\r\n");break;/* -----------------------------------------------------------*/};continue;}// Process low priority queuelength = MQ_recvmsg_ToMainFromLow(MSGLEN, &msgtype, (void *) msgbuffer);if (length < 0) {// No message, check the error code to see if it is concernif (length != MSG_QUEUE_EMPTY) {DBG_PRINT_MAIN("Main: (ERROR) Bad low priority receive, code = %d\r\n", length);}} else {switch (msgtype) {/* --- Port B Interrupt Handlers -----------------------------*/case MSGTYPE_PORTB_4_DOWN:DBG_PRINT_MAIN("Main: Port B4 Down\r\n");remote_wake(); // Wake up all componentstimer1_enable(); // Set timer to start data pollingbreak;case MSGTYPE_PORTB_4_UP:DBG_PRINT_MAIN("Main: Port B4 Up\r\n");timer1_disable(); // Stop data polling timeri2c_state = I2C_STATE_IDLE;timer0_enable(); // Set timer to sleep componentsbreak;case MSGTYPE_PORTB_5_DOWN:DBG_PRINT_MAIN("Main: Port B5 Down\r\n");remote_wake(); // Wake up all componentstimer3_enable(); // Enable PWM timerbreak;case MSGTYPE_PORTB_5_UP:DBG_PRINT_MAIN("Main: Port B5 Up\r\n");timer3_disable(); // Disable PWM timertimer0_enable(); // Set timer to sleep componentsbreak;case MSGTYPE_PORTB_6_DOWN:DBG_PRINT_MAIN("Main: Port B6 Down\r\n");remote_wake(); // Wake up all componentsbreak;case MSGTYPE_PORTB_6_UP:DBG_PRINT_MAIN("Main: Port B6 Up\r\n");timer0_enable(); // Set timer to sleep componentsbreak;case MSGTYPE_PORTB_7_DOWN:DBG_PRINT_MAIN("Main: Port B7 Down\r\n");remote_wake(); // Wake up all componentsbreak;case MSGTYPE_PORTB_7_UP:DBG_PRINT_MAIN("Main: Port B7 Up\r\n");timer0_enable(); // Set timer to sleep componentsbreak;case MSGTYPE_INT1:// DBG_PRINT_MAIN("Main: INT1 Interrupt\r\n");break;/* -----------------------------------------------------------*//* --- Timer Interrupt Handlers ------------------------------*/case MSGTYPE_TIMER0:DBG_PRINT_MAIN("Main: Timer 0 Interrupt\r\n");remote_sleep();break;// case MSGTYPE_ADC_NEWVALUE:// // Get the value in the ADC// adc_last_value = *((unsigned int*) msgbuffer);// adc_last_value_shifted = adc_last_value >> 4;// DBG_PRINT_MAIN("Main: ADC Value = %d\r\n", adc_last_value);//// adc_start();// break;case MSGTYPE_TIMER1:DBG_PRINT_MAIN("Main: Timer 1 Interrupt\r\n");/* XBee Demo */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_16.INT_16.int_value = 0x0000;frame_tx_data->broadcast_radius = 0;frame_tx_data->options = 0x01; // Disable ACKframe_tx_data->data[0] = counter;led_driver_num(counter);counter++;if (counter == 100)counter = 0;length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;xbee_process_transmit_frame((void *) msgbuffer, length);/* Read values from accelerometer and gyroscope */if (i2c_state == I2C_STATE_READ_GYRO) {imu_read_acc();i2c_state = I2C_STATE_READ_ACC;} else if (i2c_state == I2C_STATE_READ_ACC) {imu_read_gyro();i2c_state = I2C_STATE_READ_GYRO;} else { // I2C_STATE_IDLEimu_read_acc();i2c_state = I2C_STATE_READ_ACC;}break;default:DBG_PRINT_MAIN("Main: (ERROR) Unexpected msg in low queue, length = %d, type = %d\r\n", length, msgtype);for (i = 0; i < length; i++) {DBG_PRINT_MAIN("%X ", msgbuffer[i]);}DBG_PRINT_MAIN("\r\n");break;};continue;}}}