Subversion Repositories Code-Repo

Rev

Rev 116 | 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
117 Kevin 103
    OSCCONbits.IDLEN = 1;   // Set CPU to IDLE on sleep instruction
113 Kevin 104
    /* -------------------------------------------------------------------- */
105
 
106
    // Set all ports as digial I/O
107
    ANCON0 = 0xFF;
108
    ANCON1 = 0x1F;
109
 
110
    uart_init(); // Initialize the UART handler code
111
    xbee_init(&xbee_data); // Initialize the XBee handler code
112
    i2c_init(&i2c_data); // Initialize the I2C handler code
113
    buffer_init(&buffer_data);
114
    //    adc_init();                 // Initialize the ADC
115
    MQ_init(); // Initialize message queues before enabling any interrupts
116
    timers_init(); // Initialize timers
117
    led_driver_init(); // Initialize the driver for the LED display
118
    port_b_int_init(); // Initialze Port B interrupt handler
114 Kevin 119
#ifdef _BASE_STATION
120
    intx_init();    // IR receiver input
121
#endif
113 Kevin 122
    pwm_init(); // Initialize the PWM output driver
123
 
124
    interrupt_enable(); // Enable high-priority interrupts and low-priority interrupts
125
    interrupt_init(); // Initialize the interrupt priorities
114 Kevin 126
#ifdef _BASE_STATION
127
    i2c_configure_slave(BASE_STATION_ADDRESS);
115 Kevin 128
    led_driver_num(BASE_STATION_ADDRESS);
114 Kevin 129
#endif
130
#ifdef _REMOTE
113 Kevin 131
    i2c_configure_master(); // Configure the hardware i2c device as a master
132
    imu_init();
114 Kevin 133
#endif
113 Kevin 134
 
135
    DBG_PRINT_MAIN("\r\nMain: Program Started\r\n");
136
 
114 Kevin 137
#ifdef _BASE_STATION
138
    sleep();
139
#endif
140
#ifdef _REMOTE
113 Kevin 141
    // Turn on LED until XBee is connected to network
114 Kevin 142
    pwm_LED_on();
143
#endif
113 Kevin 144
 
145
    // Loop and process recieved messages from interrupts
146
    while (1) {
147
        // Call a routine that blocks until either message queues are not empty
148
        MQ_wait_on_incoming_msg_queues();
149
 
150
        // Process high priority message queue
151
        length = MQ_recvmsg_ToMainFromHigh(MSGLEN, &msgtype, (void *) msgbuffer);
152
        if (length < 0) {
153
            // No message, check the error code to see if it is concern
154
            if (length != MSG_QUEUE_EMPTY) {
155
                DBG_PRINT_MAIN("Main: (ERROR) Bad high priority receive, code = %d\r\n", length);
156
            }
157
        } else {
158
            switch (msgtype) {
159
                    /* --- I2C Message Handlers ----------------------------------*/
114 Kevin 160
#ifdef _BASE_STATION
113 Kevin 161
                case MSGTYPE_OVERRUN:
162
                    DBG_PRINT_MAIN("Main: (ERROR) UART overrun detected, type = %d\r\n", msgtype);
163
                    break;
164
                case MSGTYPE_I2C_DBG:
165
                    DBG_PRINT_MAIN("Main: I2C Dbg Data Recieved: ");
166
                    for (i = 0; i < length; i++) {
114 Kevin 167
                        DBG_PRINT_MAIN("%02X ", msgbuffer[i]);
113 Kevin 168
                    }
169
                    DBG_PRINT_MAIN("\r\n");
170
                    break;
171
                case MSGTYPE_I2C_DATA:
172
                    DBG_PRINT_MAIN("Main: I2C Data Recieved: ");
173
                    for (i = 0; i < length - 1; i++) {
114 Kevin 174
                        DBG_PRINT_MAIN("%02X ", msgbuffer[i]);
113 Kevin 175
                    }
176
                    DBG_PRINT_MAIN(" Event Count: %d", msgbuffer[length - 1]);
177
                    DBG_PRINT_MAIN("\r\n");
178
                    switch (msgbuffer[0]) {
179
                        case 0x2:
180
                            length = 1;
181
                            // Return size of stored data in buffer
182
                            if (buffer_data.stored_length > MSGLEN) {
183
                                msgbuffer[0] = MSGLEN;
184
                            } else {
185
                                msgbuffer[0] = buffer_data.stored_length;
186
                            }
115 Kevin 187
                            i2c_last_req_size = msgbuffer[0];
188
                            DBG_PRINT_MAIN("Main: (I2C Return 0x2) Returning %d\r\n", msgbuffer[0]);
113 Kevin 189
                            MQ_sendmsg_FromMainToHigh(length, MSGTYPE_I2C_REPLY, (void *) msgbuffer);
190
                            break;
191
                        case 0x4:
192
                            // Return data stored in buffer
115 Kevin 193
                            buffer_read(i2c_last_req_size, msgbuffer);
194
                            DBG_PRINT_MAIN("Main: (I2C Return 0x4) Returning %d bytes\r\n", i2c_last_req_size);
195
                            MQ_sendmsg_FromMainToHigh(i2c_last_req_size, MSGTYPE_I2C_REPLY, (void *) msgbuffer);
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
117 Kevin 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) {
508
                /* --- Port B Interrupt Handlers -----------------------------*/
509
                case MSGTYPE_PORTB_4_DOWN:
510
                    DBG_PRINT_MAIN("Main: Port B4 Down\r\n");
114 Kevin 511
#ifdef _REMOTE
512
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
513
                        wake(); // Wake up all components
514
                        timer1_enable(); // Set timer to start data polling
515
                        pwm_LED_on();
516
                    }
517
#endif
113 Kevin 518
                    break;
519
                case MSGTYPE_PORTB_4_UP:
520
                    DBG_PRINT_MAIN("Main: Port B4 Up\r\n");
114 Kevin 521
#ifdef _REMOTE
522
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
523
                        wake();
524
                        timer1_disable(); // Stop data polling timer
525
 
526
                        // Send remaining buffer data to base station
527
                        frame_tx_data = (void *) msgbuffer;
528
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
529
                        frame_tx_data->frame_id = 0;
115 Kevin 530
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
531
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 532
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 533
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 534
                        ConvertEndian16(&frame_tx_data->destination_16);
535
                        frame_tx_data->broadcast_radius = 0;
536
                        frame_tx_data->options = 0x01;  // Disable ACK
537
 
538
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + buffer_data.stored_length;
539
                        buffer_read(buffer_data.stored_length, frame_tx_data->data);
540
                        xbee_process_transmit_frame((void *) msgbuffer, length);
541
 
116 Kevin 542
                        frame_tx_data->data[0] = RETURNID_DATA_FIN;
543
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
544
                        xbee_process_transmit_frame((void *) msgbuffer, length);
545
 
114 Kevin 546
                        i2c_state = I2C_STATE_IDLE;
547
                        pwm_LED_off();
548
                        sleep();
549
                    }
550
#endif
113 Kevin 551
                    break;
552
                case MSGTYPE_PORTB_5_DOWN:
553
                    DBG_PRINT_MAIN("Main: Port B5 Down\r\n");
114 Kevin 554
#ifdef _REMOTE
555
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
556
                        wake(); // Wake up all components
557
                        timer3_enable(); // Enable PWM timer
558
                        frame_tx_data = (void *) msgbuffer;
559
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
560
                        frame_tx_data->frame_id = 0;
115 Kevin 561
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
562
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 563
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 564
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 565
                        ConvertEndian16(&frame_tx_data->destination_16);
566
                        frame_tx_data->broadcast_radius = 0;
567
                        frame_tx_data->options = 0x01; // Disable ACK
568
                        frame_tx_data->data[0] = RETURNID_CONN;
569
 
570
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
571
                        xbee_process_transmit_frame((void *) msgbuffer, length);
572
                    }
573
#endif
113 Kevin 574
                    break;
575
                case MSGTYPE_PORTB_5_UP:
576
                    DBG_PRINT_MAIN("Main: Port B5 Up\r\n");
114 Kevin 577
#ifdef _REMOTE
578
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
579
                        timer3_disable(); // Disable PWM timer
580
                        sleep();
581
                    }
582
#endif
113 Kevin 583
                    break;
584
                case MSGTYPE_PORTB_6_DOWN:
585
                    DBG_PRINT_MAIN("Main: Port B6 Down\r\n");
114 Kevin 586
#ifdef _REMOTE
587
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
588
                        wake(); // Wake up all components
589
                        frame_tx_data = (void *) msgbuffer;
590
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
591
                        frame_tx_data->frame_id = 0;
115 Kevin 592
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
593
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 594
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 595
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 596
                        ConvertEndian16(&frame_tx_data->destination_16);
597
                        frame_tx_data->broadcast_radius = 0;
598
                        frame_tx_data->options = 0x01; // Disable ACK
115 Kevin 599
                        frame_tx_data->data[0] = RETURNID_BTN2;
114 Kevin 600
 
601
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
602
                        xbee_process_transmit_frame((void *) msgbuffer, length);
603
                    }
604
#endif
113 Kevin 605
                    break;
606
                case MSGTYPE_PORTB_6_UP:
607
                    DBG_PRINT_MAIN("Main: Port B6 Up\r\n");
114 Kevin 608
#ifdef _REMOTE
609
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
610
                        sleep();
611
                    }
612
#endif
113 Kevin 613
                    break;
614
                case MSGTYPE_PORTB_7_DOWN:
615
                    DBG_PRINT_MAIN("Main: Port B7 Down\r\n");
114 Kevin 616
#ifdef _REMOTE
617
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
618
                        wake(); // Wake up all components
619
                        frame_tx_data = (void *) msgbuffer;
620
                        frame_tx_data->frame_type = XBEE_TX_DATA_PACKET;
621
                        frame_tx_data->frame_id = 0;
115 Kevin 622
                        frame_tx_data->destination_64.UPPER_32.long_value = parent_address_64.UPPER_32.long_value;
623
                        frame_tx_data->destination_64.LOWER_32.long_value = parent_address_64.LOWER_32.long_value;
114 Kevin 624
                        ConvertEndian64(&frame_tx_data->destination_64);
115 Kevin 625
                        frame_tx_data->destination_16.INT_16.int_value = xbee_parent_address_16;
114 Kevin 626
                        ConvertEndian16(&frame_tx_data->destination_16);
627
                        frame_tx_data->broadcast_radius = 0;
628
                        frame_tx_data->options = 0x01; // Disable ACK
115 Kevin 629
                        frame_tx_data->data[0] = RETURNID_BTN1;
114 Kevin 630
 
631
                        length = XBEE_TX_DATA_PACKET_FRAME_SIZE + 1;
115 Kevin 632
                        xbee_process_transmit_frame((void *) msgbuffer, length);;
114 Kevin 633
                    }
634
#endif
113 Kevin 635
                    break;
636
                case MSGTYPE_PORTB_7_UP:
637
                    DBG_PRINT_MAIN("Main: Port B7 Up\r\n");
114 Kevin 638
#ifdef _REMOTE
639
                    if (xbee_state == XBEE_STATE_JOINED_NETWORK) {
640
                        sleep();
641
                    }
642
#endif
113 Kevin 643
                    break;
644
                    /* -----------------------------------------------------------*/
117 Kevin 645
                case MSGTYPE_INT1:
646
#ifdef _BASE_STATION
647
                    wake();
648
                    IR_receive_flag = 1;
649
                    sleep();
650
//                    DBG_PRINT_MAIN("Main: INT1 Interrupt\r\n");
651
#endif
652
                    break;
113 Kevin 653
                    /* --- Timer Interrupt Handlers ------------------------------*/
654
                case MSGTYPE_TIMER0:
655
                    DBG_PRINT_MAIN("Main: Timer 0 Interrupt\r\n");
116 Kevin 656
#ifdef _BASE_STATION
115 Kevin 657
                    IR_receive_flag = 0;    // Reset IR receive flag
658
                    INTCON3bits.INT1IE = 1; // Turn on INT1 interrupt
116 Kevin 659
#endif
114 Kevin 660
                    sleep_enable();
113 Kevin 661
                    break;
662
                case MSGTYPE_TIMER1:
663
                    DBG_PRINT_MAIN("Main: Timer 1 Interrupt\r\n");
114 Kevin 664
#ifdef _REMOTE
113 Kevin 665
                    /* Read values from accelerometer and gyroscope */
666
                    if (i2c_state == I2C_STATE_READ_GYRO) {
667
                        imu_read_acc();
668
                        i2c_state = I2C_STATE_READ_ACC;
669
                    } else if (i2c_state == I2C_STATE_READ_ACC) {
670
                        imu_read_gyro();
671
                        i2c_state = I2C_STATE_READ_GYRO;
672
                    } else {    // I2C_STATE_IDLE
673
                        imu_read_acc();
674
                        i2c_state = I2C_STATE_READ_ACC;
675
                    }
114 Kevin 676
#endif
113 Kevin 677
                    break;
115 Kevin 678
                case MSGTYPE_TIMER2:
679
                    DBG_PRINT_MAIN("Main: Timer 2 Interrupt\r\n");
680
#ifdef _BASE_STATION
117 Kevin 681
//                    IR_receive_flag = 0;
682
//                    pwm_LED_off();
683
//                    INTCON3bits.INT1IE = 1; // Turn on INT1 interrupt
115 Kevin 684
#endif
685
                    break;
114 Kevin 686
//                case MSGTYPE_ADC_NEWVALUE:
687
//                    // Get the value in the ADC
688
//                    adc_last_value = *((unsigned int*) msgbuffer);
689
//                    adc_last_value_shifted = adc_last_value >> 4;
690
//                    DBG_PRINT_MAIN("Main: ADC Value = %d\r\n", adc_last_value);
691
//
692
//                    adc_start();
693
//                    break;
113 Kevin 694
                default:
695
                    DBG_PRINT_MAIN("Main: (ERROR) Unexpected msg in low queue, length = %d, type = %d\r\n", length, msgtype);
696
                    for (i = 0; i < length; i++) {
697
                        DBG_PRINT_MAIN("%X ", msgbuffer[i]);
698
                    }
699
                    DBG_PRINT_MAIN("\r\n");
700
                    break;
701
            };
702
            continue;
703
        }
704
    }
114 Kevin 705
}