Subversion Repositories Code-Repo

Rev

Rev 115 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
113 Kevin 1
#include "maindefs.h"
2
#include "msg_queues.h"
3
#include "interrupts.h"
4
#include "uart.h"
5
#include "i2c.h"
6
#include "adc.h"
7
#include "timers.h"
8
#include "xbee.h"
9
#include "led_driver.h"
10
#include "pwm.h"
11
#include "delays.h"
12
#include "pin_interrupts.h"
13
#include "buffer.h"
14
#include "imu.h"
15
#include "sleep.h"
16
 
114 Kevin 17
#ifdef _REMOTE
113 Kevin 18
#pragma config WDTEN = OFF          // Turn off watchdog timer
19
#pragma config XINST = OFF          // Turn off extended instruction set
20
#pragma config OSC = HSPLL          // Use external oscillator (101)
21
#pragma config IOL1WAY = OFF        // IOLOCK bit can be set and cleared as needed
114 Kevin 22
#endif
23
#ifdef _BASE_STATION
24
#pragma config WDTEN = OFF          // Turn off watchdog timer
25
#pragma config XINST = OFF          // Turn off extended instruction set
26
#pragma config OSC = INTOSCPLL      // Use internal oscillator
27
#pragma config IOL1WAY = OFF        // IOLOCK bit can be set and cleared as needed
28
#endif
113 Kevin 29
 
30
/* ----------- IO Pins -----------
31
 * RA0 - LED Display Latch Enable (V1) or Display CLK (V2) (PPS)
114 Kevin 32
 * RA1 - LED Display CLK (V1) (PPS)    or Display DIN (V2) (PPS)
33
 * RA2 - LED Display DIN (V1) (PPS)    or Display Latch Enable (V2)
113 Kevin 34
 * RA3 - LED Display Output Enable
35
 * RA4 - [CANNOT BE USED (VDDCORE/VCAP)]
36
 * RA5 - IR Reciever (PPS)
37
 * RA6 - Oscillator
38
 * RA7 - Oscillator
39
 * 
40
 * RC0 - PWM Output (IR) (PPS, Ports B and C only)
41
 * RC1 - PWM Output (IR) (PPS, Ports B and C only)
42
 * RC2 - LED Output (PPS, Ports B and C only)
43
 * RC3 - I2C SCL
44
 * RC4 - I2C SDA
45
 * RC5 - XBee Sleep (PPS)
46
 * RC6 - UART Debug Output
47
 * RC7 - UART Debug Input
48
 *
49
 * RB0 - XBee CTS (PPS)
50
 * RB1 - XBee RTS (PPS)
51
 * RB2 - XBee Tx (PPS)
52
 * RB3 - XBee Rx (PPS)
53
 * RB4 - Button Input (Port B Interrupt on Change)
54
 * RB5 - Button Input (Port B Interrupt on Change)
55
 * RB6 - Button Input (Port B Interrupt on Change)
56
 * RB7 - Button Input (Port B Interrupt on Change)
57
 * ---------------------------- */
58
 
59
#pragma udata msgbuffer
60
unsigned char msgbuffer[MSGLEN];
61
#pragma udata
62
 
63
void main(void) {
64
    XBEE_DATA xbee_data;
65
    I2C_DATA i2c_data;
66
    BUFFER_DATA buffer_data;
114 Kevin 67
    int length;
113 Kevin 68
    unsigned char msgtype;
69
    unsigned char i = 0;
115 Kevin 70
#ifdef _BASE_STATION
71
    volatile unsigned char IR_receive_flag = 0;
72
    unsigned char i2c_last_req_size = 0;
73
    XBEE_ADDRESS_64 last_recv_address = {0};
74
    XBEE_ADDRESS_16 remote_address_16;
75
    XBEE_ADDRESS_64 remote_address_64;
76
#endif
77
#ifdef _REMOTE
78
    unsigned int xbee_parent_address_16 = 0;
113 Kevin 79
    enum I2C_STATE i2c_state = I2C_STATE_IDLE;
80
    enum XBEE_STATE xbee_state = XBEE_STATE_WAITING_TO_JOIN;
115 Kevin 81
    XBEE_ADDRESS_16 parent_address_16;
82
    XBEE_ADDRESS_64 parent_address_64;
83
#endif
84
 
85
    // Pointers to allow parsing of xbee data from arbitrary byte array
86
    XBEE_TX_DATA_PACKET_FRAME *frame_tx_data;
87
    XBEE_TX_AT_COMMAND_FRAME *frame_tx_at_command;
113 Kevin 88
 
89
    XBEE_RX_AT_COMMAND_RESPONSE_FRAME *frame_at_cmd_response;
90
    XBEE_RX_DATA_PACKET_FRAME *frame_data_packet;
91
    XBEE_RX_DATA_TX_STATUS_FRAME *frame_tx_status;
92
    XBEE_RX_IO_DATA_SAMPLE_FRAME *frame_io_sample;
93
    XBEE_RX_EXPLICIT_COMMAND_FRAME *frame_explicit_cmd;
94
    XBEE_RX_REMOTE_AT_COMMAND_FRAME *frame_remote_at_cmd;
95
    XBEE_RX_ROUTE_RECORD_FRAME *frame_route_record;
96
    XBEE_RX_NODE_IDENTIFICATION_INDICATOR_FRAME *frame_node_identification;
97
    XBEE_RX_MODEM_STATUS_FRAME *frame_modem_status;
115 Kevin 98
 
113 Kevin 99
    /* --------------------- Oscillator Configuration --------------------- */
100
    OSCTUNEbits.PLLEN = 1;          // Enable 4x PLL
101
    OSCCONbits.IRCF = 0b111;        // Set INTOSC postscaler to 8MHz
114 Kevin 102
    OSCCONbits.SCS = 0b00; // Use PLL as primary clock source
113 Kevin 103
    /* -------------------------------------------------------------------- */
104
 
105
    // Set all ports as digial I/O
106
    ANCON0 = 0xFF;
107
    ANCON1 = 0x1F;
108
 
109
    uart_init(); // Initialize the UART handler code
110
    xbee_init(&xbee_data); // Initialize the XBee handler code
111
    i2c_init(&i2c_data); // Initialize the I2C handler code
112
    buffer_init(&buffer_data);
113
    //    adc_init();                 // Initialize the ADC
114
    MQ_init(); // Initialize message queues before enabling any interrupts
115
    timers_init(); // Initialize timers
116
    led_driver_init(); // Initialize the driver for the LED display
117
    port_b_int_init(); // Initialze Port B interrupt handler
114 Kevin 118
#ifdef _BASE_STATION
119
    intx_init();    // IR receiver input
120
#endif
113 Kevin 121
    pwm_init(); // Initialize the PWM output driver
122
 
123
    interrupt_enable(); // Enable high-priority interrupts and low-priority interrupts
124
    interrupt_init(); // Initialize the interrupt priorities
114 Kevin 125
#ifdef _BASE_STATION
126
    i2c_configure_slave(BASE_STATION_ADDRESS);
115 Kevin 127
    led_driver_num(BASE_STATION_ADDRESS);
114 Kevin 128
#endif
129
#ifdef _REMOTE
113 Kevin 130
    i2c_configure_master(); // Configure the hardware i2c device as a master
131
    imu_init();
114 Kevin 132
#endif
113 Kevin 133
 
134
    DBG_PRINT_MAIN("\r\nMain: Program Started\r\n");
135
 
114 Kevin 136
#ifdef _BASE_STATION
137
    sleep();
138
#endif
139
#ifdef _REMOTE
113 Kevin 140
    // Turn on LED until XBee is connected to network
114 Kevin 141
    pwm_LED_on();
142
#endif
113 Kevin 143
 
144
    // Loop and process recieved messages from interrupts
145
    while (1) {
146
        // Call a routine that blocks until either message queues are not empty
147
        MQ_wait_on_incoming_msg_queues();
148
 
149
        // Process high priority message queue
150
        length = MQ_recvmsg_ToMainFromHigh(MSGLEN, &msgtype, (void *) msgbuffer);
151
        if (length < 0) {
152
            // No message, check the error code to see if it is concern
153
            if (length != MSG_QUEUE_EMPTY) {
154
                DBG_PRINT_MAIN("Main: (ERROR) Bad high priority receive, code = %d\r\n", length);
155
            }
156
        } else {
157
            switch (msgtype) {
158
                    /* --- I2C Message Handlers ----------------------------------*/
114 Kevin 159
#ifdef _BASE_STATION
113 Kevin 160
                case MSGTYPE_OVERRUN:
161
                    DBG_PRINT_MAIN("Main: (ERROR) UART overrun detected, type = %d\r\n", msgtype);
162
                    break;
163
                case MSGTYPE_I2C_DBG:
164
                    DBG_PRINT_MAIN("Main: I2C Dbg Data Recieved: ");
165
                    for (i = 0; i < length; i++) {
114 Kevin 166
                        DBG_PRINT_MAIN("%02X ", msgbuffer[i]);
113 Kevin 167
                    }
168
                    DBG_PRINT_MAIN("\r\n");
169
                    break;
170
                case MSGTYPE_I2C_DATA:
171
                    DBG_PRINT_MAIN("Main: I2C Data Recieved: ");
172
                    for (i = 0; i < length - 1; i++) {
114 Kevin 173
                        DBG_PRINT_MAIN("%02X ", msgbuffer[i]);
113 Kevin 174
                    }
175
                    DBG_PRINT_MAIN(" Event Count: %d", msgbuffer[length - 1]);
176
                    DBG_PRINT_MAIN("\r\n");
177
                    switch (msgbuffer[0]) {
178
                        case 0x2:
179
                            length = 1;
180
                            // Return size of stored data in buffer
181
                            if (buffer_data.stored_length > MSGLEN) {
182
                                msgbuffer[0] = MSGLEN;
183
                            } else {
184
                                msgbuffer[0] = buffer_data.stored_length;
185
                            }
115 Kevin 186
                            i2c_last_req_size = msgbuffer[0];
187
                            DBG_PRINT_MAIN("Main: (I2C Return 0x2) Returning %d\r\n", msgbuffer[0]);
113 Kevin 188
                            MQ_sendmsg_FromMainToHigh(length, MSGTYPE_I2C_REPLY, (void *) msgbuffer);
189
                            break;
190
                        case 0x4:
191
                            // Return data stored in buffer
115 Kevin 192
                            buffer_read(i2c_last_req_size, msgbuffer);
193
                            DBG_PRINT_MAIN("Main: (I2C Return 0x4) Returning %d bytes\r\n", i2c_last_req_size);
194
                            MQ_sendmsg_FromMainToHigh(i2c_last_req_size, MSGTYPE_I2C_REPLY, (void *) msgbuffer);
114 Kevin 195
                            pwm_LED_off();  // Turn off LED if it was on
113 Kevin 196
                            break;
197
                        case 0x6:
115 Kevin 198
                            // Return status of IR signal input
199
                            length = 1;
200
                            msgbuffer[0] = IR_receive_flag;
201
                            DBG_PRINT_MAIN("Main: Returning IR state %d\r\n", IR_receive_flag);
202
                            MQ_sendmsg_FromMainToHigh(length, MSGTYPE_I2C_REPLY, (void *) msgbuffer);
113 Kevin 203
                            break;
204
                        case 0x7:
115 Kevin 205
                            // Send value to specified remote
206
 
207
                            remote_address_64.UPPER_32.char_value[0] = msgbuffer[1];
208
                            remote_address_64.UPPER_32.char_value[1] = msgbuffer[2];
209
                            remote_address_64.UPPER_32.char_value[2] = msgbuffer[3];
210
                            remote_address_64.UPPER_32.char_value[3] = msgbuffer[4];
211
                            remote_address_64.LOWER_32.char_value[0] = msgbuffer[5];
212
                            remote_address_64.LOWER_32.char_value[1] = msgbuffer[6];
213
                            remote_address_64.LOWER_32.char_value[2] = msgbuffer[7];
214
                            remote_address_64.LOWER_32.char_value[3] = msgbuffer[8];
215
                            remote_address_16.INT_16.char_value[0] = msgbuffer[9];
216
                            remote_address_16.INT_16.char_value[1] = msgbuffer[10];
217
                            DBG_PRINT_MAIN("Main: Sending %X to (64) %08lX %08lX (16) %04X\r\n",
218
                                    msgbuffer[11],
219
                                    remote_address_64.UPPER_32.long_value,
220
                                    remote_address_64.LOWER_32.long_value,
221
                                    remote_address_16.INT_16.int_value);
222
 
223
                            frame_tx_data = (void *) msgbuffer;
224
                            frame_tx_data->data[0] = msgbuffer[11];
225
                            frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
226
                            frame_tx_data->frame_id = 0;
227
                            frame_tx_data->destination_64.UPPER_32.long_value = remote_address_64.UPPER_32.long_value;
228
                            frame_tx_data->destination_64.LOWER_32.long_value = remote_address_64.LOWER_32.long_value;
229
                            ConvertEndian64(&frame_tx_data->destination_64);
230
                            frame_tx_data->destination_16.INT_16.int_value = remote_address_16.INT_16.int_value;
231
                            ConvertEndian16(&frame_tx_data->destination_16);
232
                            frame_tx_data->broadcast_radius = 0;
233
                            frame_tx_data->options = 0x01; // Disable ACK
234
 
235
                            length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
236
                            xbee_process_transmit_frame((void *) msgbuffer, length);
113 Kevin 237
                            break;
238
                        default:
239
                            DBG_PRINT_MAIN("Main: (ERROR) Unexpected message type recieved: %d\r\n", msgbuffer[0]);
240
                            break;
241
                    };
242
                    break;
114 Kevin 243
#endif
244
#ifdef _REMOTE
113 Kevin 245
                case MSGTYPE_I2C_MASTER_SEND_COMPLETE:
246
                    DBG_PRINT_MAIN("Main: I2C Master Send Complete\r\n");
247
                    break;
248
                case MSGTYPE_I2C_MASTER_SEND_FAILED:
249
                    DBG_PRINT_MAIN("Main: (ERROR) I2C Master Send Failed\r\n");
250
                    break;
251
                case MSGTYPE_I2C_MASTER_RECV_COMPLETE:
252
                    DBG_PRINT_MAIN("Main: I2C Master Receive Complete\r\n");
253
                    DBG_PRINT_MAIN("Main: (I2C Data) ");
254
                    for (i = 0; i < length; i++) {
114 Kevin 255
                        DBG_PRINT_MAIN("%02X ", msgbuffer[i]);
113 Kevin 256
                    }
114 Kevin 257
                    DBG_PRINT_MAIN("\r\n");
258
 
259
                    // Insert recorded value into buffer
260
                    if (i2c_state == I2C_STATE_READ_ACC) {
261
                        buffer_insert_one(RETURNID_ACC);
262
                        buffer_insert(6, msgbuffer);
263
                    } else if (i2c_state == I2C_STATE_READ_GYRO) {
264
                        buffer_insert_one(RETURNID_GYRO);
265
                        buffer_insert(6, msgbuffer);
266
                    }
113 Kevin 267
 
114 Kevin 268
                    if (buffer_free_space() < 7) {
269
                        wake();
113 Kevin 270
                        // Send data to base station
114 Kevin 271
                        frame_tx_data = (void *) msgbuffer;
272
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
273
                        frame_tx_data->frame_id = 0;
115 Kevin 274
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
275
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 276
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 277
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 278
                        ConvertEndian16(&frame_tx_data->destination_16);
279
                        frame_tx_data->broadcast_radius = 0;
280
                        frame_tx_data->options = 0x01;  // Disable ACK
113 Kevin 281
 
114 Kevin 282
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + buffer_data.stored_length;
283
                        buffer_read(buffer_data.stored_length, frame_tx_data->data);
284
                        xbee_process_transmit_frame((void *) msgbuffer, length);
113 Kevin 285
                    }
114 Kevin 286
 
113 Kevin 287
                    break;
288
                case MSGTYPE_I2C_MASTER_RECV_FAILED:
289
                    DBG_PRINT_MAIN("Main: (ERROR) I2C Master Receive Failed\r\n");
290
                    break;
114 Kevin 291
#endif
113 Kevin 292
                    /* -----------------------------------------------------------*/
293
 
294
                    /* --- XBee Message Handlers ---------------------------------*/
295
                case MSGTYPE_XBEE_RX_AT_COMMAND_RESPONSE:
115 Kevin 296
                    DBG_PRINT_MAIN("\r\n");
297
                    frame_at_cmd_response = (void *) msgbuffer;
114 Kevin 298
                    DBG_PRINT_MAIN("Main: XBee AT command response frame\r\n");
299
                    DBG_PRINT_MAIN("Command: %c%c\r\n", frame_at_cmd_response->command[0], frame_at_cmd_response->command[1]);
113 Kevin 300
                    DBG_PRINT_MAIN("Status: %d\r\n", frame_at_cmd_response->command_status);
301
                    DBG_PRINT_MAIN("Data: ");
302
                    for (i = 0; i < length - XBEE_RX_AT_COMMAND_RESPONSE_FRAME_SIZE; i++) {
115 Kevin 303
                        DBG_PRINT_MAIN("%02X ", frame_at_cmd_response->data[i]);
113 Kevin 304
                    }
305
                    DBG_PRINT_MAIN("\r\n");
114 Kevin 306
#ifdef _REMOTE
115 Kevin 307
                    // Parse response from 'MP' command
114 Kevin 308
                    if (frame_at_cmd_response->command[0] == 'M' &&
309
                            frame_at_cmd_response->command[1] == 'P') {
115 Kevin 310
                        parent_address_16.INT_16.char_value[0] = frame_at_cmd_response->data[0];
311
                        parent_address_16.INT_16.char_value[1] = frame_at_cmd_response->data[1];
312
                        ConvertEndian16(&parent_address_16);
313
                        xbee_parent_address_16 = parent_address_16.INT_16.int_value;
314
 
315
                        DBG_PRINT_MAIN("Main: XBee parent address (16): %04X\r\n", xbee_parent_address_16);
316
                        // Set broadcast radius to 1
317
                        frame_tx_at_command = (void *) msgbuffer;
318
                        frame_tx_at_command->frame_type = XBEE_TX_AT_COMMAND;
319
                        frame_tx_at_command->frame_id = 1;
320
                        frame_tx_at_command->command[0] = 'B';
321
                        frame_tx_at_command->command[1] = 'H';
322
                        frame_tx_at_command->data[0] = 1;
323
                        length = XBEE_TX_AT_COMMAND_FRAME_SIZE + 1;
324
                        xbee_process_transmit_frame((void *) msgbuffer, length);
325
 
326
                        // Query for parent node info
327
                        frame_tx_at_command = (void *) msgbuffer;
328
                        frame_tx_at_command->frame_type = XBEE_TX_AT_COMMAND;
329
                        frame_tx_at_command->frame_id = 1;
330
                        frame_tx_at_command->command[0] = 'N';
331
                        frame_tx_at_command->command[1] = 'D';
332
                        length = XBEE_TX_AT_COMMAND_FRAME_SIZE;
333
                        xbee_process_transmit_frame((void *) msgbuffer, length);
334
                    }
335
                    // Parse response from 'ND' command
336
                    else if (frame_at_cmd_response->command[0] == 'N' &&
337
                            frame_at_cmd_response->command[1] == 'D') {
338
                        parent_address_64.UPPER_32.char_value[0] = frame_at_cmd_response->data[2];
339
                        parent_address_64.UPPER_32.char_value[1] = frame_at_cmd_response->data[3];
340
                        parent_address_64.UPPER_32.char_value[2] = frame_at_cmd_response->data[4];
341
                        parent_address_64.UPPER_32.char_value[3] = frame_at_cmd_response->data[5];
342
                        parent_address_64.LOWER_32.char_value[0] = frame_at_cmd_response->data[6];
343
                        parent_address_64.LOWER_32.char_value[1] = frame_at_cmd_response->data[7];
344
                        parent_address_64.LOWER_32.char_value[2] = frame_at_cmd_response->data[8];
345
                        parent_address_64.LOWER_32.char_value[3] = frame_at_cmd_response->data[9];
346
                        ConvertEndian64(&parent_address_64);
347
 
348
                        DBG_PRINT_MAIN("Main: XBee parent address (64): %08lX %08lX\r\n",
349
                                parent_address_64.UPPER_32.long_value,
350
                                parent_address_64.LOWER_32.long_value);
351
 
114 Kevin 352
                        xbee_state = XBEE_STATE_JOINED_NETWORK;
115 Kevin 353
                        // Turn off LED after XBee has joined network
354
                        pwm_LED_off();
114 Kevin 355
                    }
356
#endif
113 Kevin 357
                    break;
358
                case MSGTYPE_XBEE_RX_DATA_PACKET:
114 Kevin 359
                    wake();
113 Kevin 360
                    DBG_PRINT_MAIN("Main: XBee data packet frame\r\n");
361
                    frame_data_packet = (void *) msgbuffer;
114 Kevin 362
                    ConvertEndian64(&frame_data_packet->source_64);
363
                    ConvertEndian16(&frame_data_packet->source_16);
364
                    DBG_PRINT_MAIN("Source 64: %08lX-%08lX\r\n",
365
                            frame_data_packet->source_64.UPPER_32.long_value,
366
                            frame_data_packet->source_64.LOWER_32.long_value
367
                            );
368
                    DBG_PRINT_MAIN("Source 16: %04X\r\n", frame_data_packet->source_16.INT_16.int_value);
369
                    DBG_PRINT_MAIN("Options: 0x%02X\r\n", frame_data_packet->recieve_options);
113 Kevin 370
                    DBG_PRINT_MAIN("Data: ");
371
                    for (i = 0; i < length - XBEE_RX_DATA_PACKET_FRAME_SIZE; i++) {
114 Kevin 372
                        DBG_PRINT_MAIN("%02X ", frame_data_packet->data[i]);
113 Kevin 373
                    }
374
                    DBG_PRINT_MAIN("\r\n");
114 Kevin 375
#ifdef _BASE_STATION
376
 
377
                    if (frame_data_packet->source_64.LOWER_32.long_value != last_recv_address.LOWER_32.long_value ||
378
                            frame_data_packet->source_64.UPPER_32.long_value != last_recv_address.UPPER_32.long_value) {
115 Kevin 379
                        // Save remote's 64 and 16 bit addresses
380
                        buffer_insert_one(RETURNID_NEW_REMOTE_SRC);
114 Kevin 381
                        buffer_insert(4, frame_data_packet->source_64.UPPER_32.char_value);
382
                        buffer_insert(4, frame_data_packet->source_64.LOWER_32.char_value);
115 Kevin 383
                        buffer_insert(2, frame_data_packet->source_16.INT_16.char_value);
114 Kevin 384
                        // Save data
385
                        buffer_insert(length - XBEE_RX_DATA_PACKET_FRAME_SIZE, frame_data_packet->data);
386
                        // Save address of sender
387
                        last_recv_address.UPPER_32.long_value = frame_data_packet->source_64.UPPER_32.long_value;
388
                        last_recv_address.LOWER_32.long_value = frame_data_packet->source_64.LOWER_32.long_value;
389
                    } else {
390
                        // Receive data from same remote that previously sent data
391
                        buffer_insert(length - XBEE_RX_DATA_PACKET_FRAME_SIZE, frame_data_packet->data);
392
                    }
393
 
113 Kevin 394
                    // Send value of first byte received to LED display
395
                    led_driver_num(frame_data_packet->data[0]);
114 Kevin 396
#endif
115 Kevin 397
#ifdef _REMOTE
398
                    led_driver_num(frame_data_packet->data[0]);
399
#endif
114 Kevin 400
                    sleep();
113 Kevin 401
                    break;
402
                case MSGTYPE_XBEE_RX_DATA_TX_STATUS:
403
                    DBG_PRINT_MAIN("Main: XBee TX status frame\r\n");
404
                    frame_tx_status = (void *) msgbuffer;
114 Kevin 405
                    DBG_PRINT_MAIN("Destination: %02X\r\n", frame_tx_status->destination_16);
406
                    DBG_PRINT_MAIN("Transmit Retry Count: %02X\r\n", frame_tx_status->transmit_retry_count);
407
                    DBG_PRINT_MAIN("Delivery Status: %02X\r\n", frame_tx_status->delivery_status);
408
                    DBG_PRINT_MAIN("Discovery Status: %02X\r\n", frame_tx_status->discovery_status);
113 Kevin 409
                    break;
410
                case MSGTYPE_XBEE_RX_IO_DATA_SAMPLE:
411
                    DBG_PRINT_MAIN("Main: XBee IO data sample frame\r\n");
412
                    frame_io_sample = (void *) msgbuffer;
413
                    break;
414
                case MSGTYPE_XBEE_RX_EXPLICIT_COMMAND:
415
                    DBG_PRINT_MAIN("Main: XBee explicit command frame\r\n");
416
                    frame_explicit_cmd = (void *) msgbuffer;
417
                    break;
418
                case MSGTYPE_XBEE_RX_REMOTE_AT_COMMAND_RESPONSE:
419
                    DBG_PRINT_MAIN("Main: XBee remote AT command response frame\r\n");
420
                    frame_remote_at_cmd = (void *) msgbuffer;
421
                    break;
422
                case MSGTYPE_XBEE_RX_ROUTE_RECORD:
423
                    DBG_PRINT_MAIN("Main: XBee route record frame\r\n");
424
                    frame_route_record = (void *) msgbuffer;
425
                    break;
426
                case MSGTYPE_XBEE_RX_NODE_IDENTIFICATION:
427
                    DBG_PRINT_MAIN("Main: XBee node identification frame\r\n");
428
                    frame_node_identification = (void *) msgbuffer;
114 Kevin 429
                    ConvertEndian64(&frame_node_identification->source_64);
430
                    ConvertEndian64(&frame_node_identification->remote_64);
431
                    ConvertEndian16(&frame_node_identification->source_16);
432
                    ConvertEndian16(&frame_node_identification->remote_16);
433
                    ConvertEndian16(&frame_node_identification->parent_16);
434
                    DBG_PRINT_MAIN("Source 64: %08lX-%08lX\r\n",
435
                            frame_node_identification->source_64.UPPER_32.long_value,
436
                            frame_node_identification->source_64.LOWER_32.long_value
437
                            );
438
                    DBG_PRINT_MAIN("Source 16: %04X\r\n", frame_node_identification->source_16.INT_16.int_value);
439
                    DBG_PRINT_MAIN("Remote 64: %08lX-%08lX\r\n",
440
                            frame_node_identification->remote_64.UPPER_32.long_value,
441
                            frame_node_identification->remote_64.LOWER_32.long_value
442
                            );
443
                    DBG_PRINT_MAIN("Remote 16: %04X\r\n", frame_node_identification->remote_16.INT_16.int_value);
115 Kevin 444
                    DBG_PRINT_MAIN("Parent 16: %04X\r\n", frame_node_identification->parent_16.INT_16.int_value);
114 Kevin 445
                    DBG_PRINT_MAIN("Receive Options: %02X\r\n", frame_node_identification->recieve_options);
115 Kevin 446
                    buffer_insert_one(RETURNID_NEW_REMOTE_CON);
447
                    buffer_insert(4, frame_node_identification->remote_64.UPPER_32.char_value);
448
                    buffer_insert(4, frame_node_identification->remote_64.LOWER_32.char_value);
449
                    buffer_insert(2, frame_node_identification->remote_16.INT_16.char_value);
113 Kevin 450
                    break;
451
                case MSGTYPE_XBEE_RX_FRAME_MODEM_STATUS:
452
                    DBG_PRINT_MAIN("Main: XBee modem status frame\r\n");
453
                    frame_modem_status = (void *) msgbuffer;
114 Kevin 454
                    DBG_PRINT_MAIN("Status: %02X (", frame_modem_status->status);
113 Kevin 455
                    switch(frame_modem_status->status) {
456
                        case 0:
457
                            DBG_PRINT_MAIN("Hardware Reset");
115 Kevin 458
#ifdef _REMOTE
113 Kevin 459
                            xbee_state = XBEE_STATE_WAITING_TO_JOIN;
115 Kevin 460
#endif
113 Kevin 461
                            break;
462
                        case 1:
463
                            DBG_PRINT_MAIN("Watchdog Timer Reset");
464
                            break;
465
                        case 2:
466
                            DBG_PRINT_MAIN("Joined Network");
114 Kevin 467
#ifdef _REMOTE
468
                            // Query for parent's address
469
                            frame_tx_at_command = (void *) msgbuffer;
470
                            frame_tx_at_command->frame_type = XBEE_TX_AT_COMMAND;
471
                            frame_tx_at_command->frame_id = 1;
472
                            frame_tx_at_command->command[0] = 'M';
473
                            frame_tx_at_command->command[1] = 'P';
115 Kevin 474
                            length = XBEE_TX_AT_COMMAND_FRAME_SIZE;
475
                            xbee_process_transmit_frame((void *) msgbuffer, length);
114 Kevin 476
#endif
113 Kevin 477
                            break;
478
                        case 3:
479
                            DBG_PRINT_MAIN("Disassociated");
115 Kevin 480
                            pwm_LED_on();
113 Kevin 481
                            break;
482
                        case 6:
483
                            DBG_PRINT_MAIN("Coordinator Started");
484
                            break;
485
                        case 7:
486
                            DBG_PRINT_MAIN("Network Security Key Updated");
487
                            break;
488
                        case 0x11:
489
                            DBG_PRINT_MAIN("Modem Config Changed While Joining");
490
                            break;
491
                    }
492
                    DBG_PRINT_MAIN(")\r\n");
493
                    break;
494
                    /* -----------------------------------------------------------*/
495
            };
115 Kevin 496
//            continue;
113 Kevin 497
        }
498
 
499
        // Process low priority queue
500
        length = MQ_recvmsg_ToMainFromLow(MSGLEN, &msgtype, (void *) msgbuffer);
501
        if (length < 0) {
502
            // No message, check the error code to see if it is concern
503
            if (length != MSG_QUEUE_EMPTY) {
504
                DBG_PRINT_MAIN("Main: (ERROR) Bad low priority receive, code = %d\r\n", length);
505
            }
506
        } else {
507
            switch (msgtype) {
115 Kevin 508
                case MSGTYPE_INT1:
509
#ifdef _BASE_STATION
510
                    wake();
511
                    IR_receive_flag = 1;
512
                    pwm_LED_on();
513
//                    timer2_enable();    // Enable timer 2 to turn off LED
514
                    sleep();
515
//                    DBG_PRINT_MAIN("Main: INT1 Interrupt\r\n");
516
#endif
517
                    break;
113 Kevin 518
                /* --- Port B Interrupt Handlers -----------------------------*/
519
                case MSGTYPE_PORTB_4_DOWN:
520
                    DBG_PRINT_MAIN("Main: Port B4 Down\r\n");
114 Kevin 521
#ifdef _REMOTE
522
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
523
                        wake(); // Wake up all components
524
                        timer1_enable(); // Set timer to start data polling
525
                        pwm_LED_on();
526
                    }
527
#endif
113 Kevin 528
                    break;
529
                case MSGTYPE_PORTB_4_UP:
530
                    DBG_PRINT_MAIN("Main: Port B4 Up\r\n");
114 Kevin 531
#ifdef _REMOTE
532
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
533
                        wake();
534
                        timer1_disable(); // Stop data polling timer
535
 
536
                        // Send remaining buffer data to base station
537
                        frame_tx_data = (void *) msgbuffer;
538
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
539
                        frame_tx_data->frame_id = 0;
115 Kevin 540
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
541
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 542
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 543
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 544
                        ConvertEndian16(&frame_tx_data->destination_16);
545
                        frame_tx_data->broadcast_radius = 0;
546
                        frame_tx_data->options = 0x01;  // Disable ACK
547
 
548
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + buffer_data.stored_length;
549
                        buffer_read(buffer_data.stored_length, frame_tx_data->data);
550
                        xbee_process_transmit_frame((void *) msgbuffer, length);
551
 
116 Kevin 552
                        frame_tx_data->data[0] = RETURNID_DATA_FIN;
553
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
554
                        xbee_process_transmit_frame((void *) msgbuffer, length);
555
 
114 Kevin 556
                        i2c_state = I2C_STATE_IDLE;
557
                        pwm_LED_off();
558
                        sleep();
559
                    }
560
#endif
113 Kevin 561
                    break;
562
                case MSGTYPE_PORTB_5_DOWN:
563
                    DBG_PRINT_MAIN("Main: Port B5 Down\r\n");
114 Kevin 564
#ifdef _REMOTE
565
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
566
                        wake(); // Wake up all components
567
                        timer3_enable(); // Enable PWM timer
568
                        frame_tx_data = (void *) msgbuffer;
569
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
570
                        frame_tx_data->frame_id = 0;
115 Kevin 571
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
572
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 573
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 574
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 575
                        ConvertEndian16(&frame_tx_data->destination_16);
576
                        frame_tx_data->broadcast_radius = 0;
577
                        frame_tx_data->options = 0x01; // Disable ACK
578
                        frame_tx_data->data[0] = RETURNID_CONN;
579
 
580
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
581
                        xbee_process_transmit_frame((void *) msgbuffer, length);
582
                    }
583
#endif
113 Kevin 584
                    break;
585
                case MSGTYPE_PORTB_5_UP:
586
                    DBG_PRINT_MAIN("Main: Port B5 Up\r\n");
114 Kevin 587
#ifdef _REMOTE
588
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
589
                        timer3_disable(); // Disable PWM timer
590
                        sleep();
591
                    }
592
#endif
113 Kevin 593
                    break;
594
                case MSGTYPE_PORTB_6_DOWN:
595
                    DBG_PRINT_MAIN("Main: Port B6 Down\r\n");
114 Kevin 596
#ifdef _REMOTE
597
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
598
                        wake(); // Wake up all components
599
                        frame_tx_data = (void *) msgbuffer;
600
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
601
                        frame_tx_data->frame_id = 0;
115 Kevin 602
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
603
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 604
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 605
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 606
                        ConvertEndian16(&frame_tx_data->destination_16);
607
                        frame_tx_data->broadcast_radius = 0;
608
                        frame_tx_data->options = 0x01; // Disable ACK
115 Kevin 609
                        frame_tx_data->data[0] = RETURNID_BTN2;
114 Kevin 610
 
611
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
612
                        xbee_process_transmit_frame((void *) msgbuffer, length);
613
                    }
614
#endif
113 Kevin 615
                    break;
616
                case MSGTYPE_PORTB_6_UP:
617
                    DBG_PRINT_MAIN("Main: Port B6 Up\r\n");
114 Kevin 618
#ifdef _REMOTE
619
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
620
                        sleep();
621
                    }
622
#endif
113 Kevin 623
                    break;
624
                case MSGTYPE_PORTB_7_DOWN:
625
                    DBG_PRINT_MAIN("Main: Port B7 Down\r\n");
114 Kevin 626
#ifdef _REMOTE
627
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
628
                        wake(); // Wake up all components
629
                        frame_tx_data = (void *) msgbuffer;
630
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
631
                        frame_tx_data->frame_id = 0;
115 Kevin 632
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
633
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 634
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 635
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 636
                        ConvertEndian16(&frame_tx_data->destination_16);
637
                        frame_tx_data->broadcast_radius = 0;
638
                        frame_tx_data->options = 0x01; // Disable ACK
115 Kevin 639
                        frame_tx_data->data[0] = RETURNID_BTN1;
114 Kevin 640
 
641
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
115 Kevin 642
                        xbee_process_transmit_frame((void *) msgbuffer, length);;
114 Kevin 643
                    }
644
#endif
113 Kevin 645
                    break;
646
                case MSGTYPE_PORTB_7_UP:
647
                    DBG_PRINT_MAIN("Main: Port B7 Up\r\n");
114 Kevin 648
#ifdef _REMOTE
649
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
650
                        sleep();
651
                    }
652
#endif
113 Kevin 653
                    break;
654
                    /* -----------------------------------------------------------*/
655
                    /* --- Timer Interrupt Handlers ------------------------------*/
656
                case MSGTYPE_TIMER0:
657
                    DBG_PRINT_MAIN("Main: Timer 0 Interrupt\r\n");
116 Kevin 658
#ifdef _BASE_STATION
115 Kevin 659
                    pwm_LED_off();
660
                    IR_receive_flag = 0;    // Reset IR receive flag
661
                    INTCON3bits.INT1IE = 1; // Turn on INT1 interrupt
116 Kevin 662
#endif
114 Kevin 663
                    sleep_enable();
113 Kevin 664
                    break;
665
                case MSGTYPE_TIMER1:
666
                    DBG_PRINT_MAIN("Main: Timer 1 Interrupt\r\n");
114 Kevin 667
#ifdef _REMOTE
668
//                    /* XBee Demo */
669
//                    frame_tx_data = (void *) msgbuffer;
670
//                    frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
671
//                    frame_tx_data->frame_id = 0;
672
//                    frame_tx_data->destination_64.UPPER_32.long_value = 0x00000000;
673
//                    frame_tx_data->destination_64.LOWER_32.long_value = 0x00000000;
674
//                    ConvertEndian64(&frame_tx_data->destination_64);
675
//                    frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address;
676
//                    ConvertEndian16(&frame_tx_data->destination_16);
677
//                    frame_tx_data->broadcast_radius = 1;
678
//                    frame_tx_data->options = 0x01; // Disable ACK
679
//                    frame_tx_data->data[0] = counter;
680
//
681
//                    led_driver_num(counter);
682
//                    counter++;
683
//                    if (counter == 100)
684
//                        counter = 0;
685
//
686
//                    length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
687
//                    xbee_process_transmit_frame((void *) msgbuffer, length);
113 Kevin 688
 
689
                    /* Read values from accelerometer and gyroscope */
690
                    if (i2c_state == I2C_STATE_READ_GYRO) {
691
                        imu_read_acc();
692
                        i2c_state = I2C_STATE_READ_ACC;
693
                    } else if (i2c_state == I2C_STATE_READ_ACC) {
694
                        imu_read_gyro();
695
                        i2c_state = I2C_STATE_READ_GYRO;
696
                    } else {    // I2C_STATE_IDLE
697
                        imu_read_acc();
698
                        i2c_state = I2C_STATE_READ_ACC;
699
                    }
114 Kevin 700
#endif
113 Kevin 701
                    break;
115 Kevin 702
                case MSGTYPE_TIMER2:
703
                    DBG_PRINT_MAIN("Main: Timer 2 Interrupt\r\n");
704
#ifdef _BASE_STATION
705
                    IR_receive_flag = 0;
706
                    pwm_LED_off();
707
                    INTCON3bits.INT1IE = 1; // Turn on INT1 interrupt
708
#endif
709
                    break;
114 Kevin 710
//                case MSGTYPE_ADC_NEWVALUE:
711
//                    // Get the value in the ADC
712
//                    adc_last_value = *((unsigned int*) msgbuffer);
713
//                    adc_last_value_shifted = adc_last_value >> 4;
714
//                    DBG_PRINT_MAIN("Main: ADC Value = %d\r\n", adc_last_value);
715
//
716
//                    adc_start();
717
//                    break;
113 Kevin 718
                default:
719
                    DBG_PRINT_MAIN("Main: (ERROR) Unexpected msg in low queue, length = %d, type = %d\r\n", length, msgtype);
720
                    for (i = 0; i < length; i++) {
721
                        DBG_PRINT_MAIN("%X ", msgbuffer[i]);
722
                    }
723
                    DBG_PRINT_MAIN("\r\n");
724
                    break;
725
            };
726
            continue;
727
        }
728
    }
114 Kevin 729
}