Subversion Repositories Code-Repo

Rev

Rev 158 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
157 Kevin 1
#include <xc.h>
2
#include <stdio.h>
3
#include <string.h>
155 Kevin 4
#include "defines.h"
158 Kevin 5
#include "comm_xbee.h"
6
#include "base_UART.h"
155 Kevin 7
 
157 Kevin 8
static XBEE_DATA *xbee_data_p;
155 Kevin 9
static void *xbee_data_frame;
158 Kevin 10
//static void *xbee_frame;
155 Kevin 11
 
12
/* Initialize variables used by this library */
157 Kevin 13
void XBee_Init(XBEE_DATA *data) {
14
    xbee_data_p = data;
155 Kevin 15
    XBEE_CTS_TRIS = 1; // RB0 is CTS, set by XBee chip
16
    XBEE_RTS_TRIS = 0; // RB1 is RTS, set by PIC
17
 
18
    XBEE_CTS_LAT = 0; // Pin set high to signal stop sending data to XBee
19
    XBEE_RTS_LAT = 0; // Pin set high to indicate stop sending data to PIC
20
 
21
    xbee_data_p->dataind = 0;
22
    xbee_data_p->checksum_sum = 0;
23
    xbee_data_p->frame_rdy = 0;
24
    xbee_data_p->escape_flag = 0;
25
    xbee_data_p->read_state = XBEE_STATE_READ_START;
26
 
27
//    memset(&xbee_data, 0, 32);
28
 
29
    // Grab a pointer to where the unique frame array starts
30
    xbee_data_frame = &(xbee_data_p->rcv_frame.FRAME);
158 Kevin 31
//    xbee_frame = &(xbee_data_p->rcv_frame);
155 Kevin 32
}
33
 
34
/* Here we handle the serial input from the UART interrupt */
157 Kevin 35
void XBee_Serial_In(char c) {
155 Kevin 36
    // For some reason writing the length straight to xbee_data doesnt seem to work
37
    //  so we work around it by pointing to the length bytes directly
158 Kevin 38
//    XBEE_ADDRESS_16 *length = xbee_frame + 1;
155 Kevin 39
 
40
#ifdef XBEE_USE_ESCAPE_CHAR
41
    if (c == XBEE_ESCAPE_CHAR) {
42
        // Next byte needs is an escaped char
43
        xbee_data_p->escape_flag = 1;
44
        return;
45
    }
46
 
47
    if (xbee_data_p->escape_flag) {
48
        // XOR byte with 0x20 to get escaped char
49
        c ^= XBEE_ESCAPE_VAL;
50
        xbee_data_p->escape_flag = 0;
51
    }
52
#endif
53
    // Reset on start bit and start saving data
54
    if (c == XBEE_START_DELIMITER) {
55
        // On detect start delimiter, clear out initial array
56
        xbee_data_p->dataind = 0;
57
        xbee_data_p->checksum_sum = 0;
58
        xbee_data_p->frame_rdy = 0;
59
        xbee_data_p->read_state = XBEE_STATE_READ_LENGTH_HIGH;
158 Kevin 60
//        *((char *)xbee_frame) = XBEE_START_DELIMITER;
61
        xbee_data_p->rcv_frame.start_delimiter = XBEE_START_DELIMITER;
62
 
155 Kevin 63
    } else {
64
        switch (xbee_data_p->read_state) {
65
            case XBEE_STATE_READ_START:
66
                // Do nothing and wait till start bit is read
67
                break;
68
            case XBEE_STATE_READ_LENGTH_HIGH:
69
                // Read length (MSB)
158 Kevin 70
//                length->INT_16.char_value[1] = c;
71
                xbee_data_p->rcv_frame.length.INT_16.char_value[1] = c;
155 Kevin 72
                xbee_data_p->read_state = XBEE_STATE_READ_LENGTH_LOW;
73
                break;
74
            case XBEE_STATE_READ_LENGTH_LOW:
75
                // Read length (LSB)
158 Kevin 76
//                length->INT_16.char_value[0] = c;
77
                xbee_data_p->rcv_frame.length.INT_16.char_value[0] = c;
155 Kevin 78
                xbee_data_p->read_state = XBEE_STATE_READ_FRAME_DATA;
79
                break;
80
            case XBEE_STATE_READ_FRAME_DATA:
81
                // Read unique frame data
82
                if (xbee_data_p->dataind < xbee_data_p->rcv_frame.length.INT_16.int_value) {
83
                    *((char*) xbee_data_frame + xbee_data_p->dataind) = c;
84
                    xbee_data_p->checksum_sum += c;
85
                    xbee_data_p->dataind++;
86
                }
87
                // If total length is read, the next byte is the expected checksum
88
                if (xbee_data_p->dataind == xbee_data_p->rcv_frame.length.INT_16.int_value) {
89
                    xbee_data_p->read_state = XBEE_STATE_READ_CHECKSUM;
90
                }
91
                break;
92
            case XBEE_STATE_READ_CHECKSUM:
93
                // Calculate and compare checksum
94
                if (0xFF - xbee_data_p->checksum_sum == c) {
95
                    // Frame was recieved successfully
96
                    xbee_data_p->frame_rdy = 1;
97
//                    XBee_Process_Received_Frame();
98
                } else {
99
                    // If checksum does not match, drop frame
157 Kevin 100
                    char output[32];
101
                    sprintf(output, "XBEE: checksum mismatch\r\n");
102
                    DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 103
                }
104
                xbee_data_p->read_state = XBEE_STATE_READ_START;
105
                break;
106
        }
107
    }
108
}
109
 
110
/* This processes the frame data within the interrupt. Dont use this. */
111
void XBee_Process_Received_Frame() {
112
//    DBG_PRINT_XBEE("Length: %d\r\n", xbee_data_p->rcv_frame.length.INT_16.int_value);
113
    // Here we process the received frame depending on the frame type
157 Kevin 114
    char output[64];
115
    switch (*((char *) xbee_data_frame)) {
155 Kevin 116
        case XBEE_RX_AT_COMMAND_RESPONSE:
157 Kevin 117
            sprintf(output, "XBEE: parsing recieved AT command response frame\r\n");
118
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 119
            break;
120
        case XBEE_RX_DATA_PACKET:
157 Kevin 121
            sprintf(output, "XBEE: parsing recieved data frame\r\n");
122
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 123
            break;
124
        case XBEE_RX_DATA_TX_STATUS:
157 Kevin 125
            sprintf(output, "XBEE: parsing recieved TX status frame\r\n");
126
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 127
            break;
128
        case XBEE_RX_IO_DATA_SAMPLE:
157 Kevin 129
            sprintf(output, "XBEE: parsing recieved IO data sample frame\r\n");
130
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 131
            break;
132
        case XBEE_RX_EXPLICIT_COMMAND:
157 Kevin 133
            sprintf(output, "XBEE: parsing recieved explicit command frame\r\n");
134
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 135
            break;
136
        case XBEE_RX_REMOTE_AT_COMMAND_RESPONSE:
157 Kevin 137
            sprintf(output, "XBEE: parsing recieved remote AT command frame\r\n");
138
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 139
            break;
140
        case XBEE_RX_ROUTE_RECORD:
157 Kevin 141
            sprintf(output, "XBEE: parsing recieved route record frame\r\n");
142
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 143
            break;
144
        case XBEE_RX_NODE_IDENTIFICATION:
157 Kevin 145
            sprintf(output, "XBEE: parsing recieved node identification frame\r\n");
146
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 147
            break;
148
        case XBEE_RX_FRAME_MODEM_STATUS:
157 Kevin 149
            sprintf(output, "XBEE: parsing recieved modem status frame\r\n");
150
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 151
            break;
152
        default:
157 Kevin 153
            sprintf(output, "XBEE: (ERROR) unrecognized frame type\r\n");
154
            DBG_PRINT_XBEE(output, strlen(output));
155 Kevin 155
    }
156
}
157
 
157 Kevin 158
unsigned int XBee_Get_Received_Frame(char *frame) {
155 Kevin 159
    if (!xbee_data_p->frame_rdy) {
160
        return 0;
161
    } else {
162
        memcpy(frame, xbee_data_frame, xbee_data_p->rcv_frame.length.INT_16.int_value);
163
        xbee_data_p->frame_rdy = 0; // Reset frame ready status
164
        return xbee_data_p->rcv_frame.length.INT_16.int_value;
165
    }
166
}
167
 
157 Kevin 168
void XBee_Process_Transmit_Frame(char *data, char length) {
155 Kevin 169
#ifdef XBEE_USE_ESCAPE_CHAR
170
    unsigned int i = 0;
157 Kevin 171
    char chksum = 0;
155 Kevin 172
 
173
    // Write the start bit and length
174
    UART1_WriteC(XBEE_START_DELIMITER);
175
    UART1_WriteC(0);
176
    UART1_WriteC(length);
177
 
178
    // Write the frame data
179
    for (i = 0; i < length; i++) {
180
        chksum += data[i];
181
        if (data[i] == XBEE_START_DELIMITER ||     \
182
                data[i] == XBEE_ESCAPE_CHAR ||     \
183
                data[i] == XBEE_XON ||     \
184
                data[i] == XBEE_XOFF) {
185
            UART1_WriteC(XBEE_ESCAPE_CHAR);
186
            UART1_WriteC(data[i] ^ XBEE_ESCAPE_VAL);
187
        } else {
188
            UART1_WriteC(data[i]);
189
        }
190
    }
191
    // Write the checksum
192
    if (chksum == XBEE_START_DELIMITER ||     \
193
                chksum == XBEE_ESCAPE_CHAR ||     \
194
                chksum == XBEE_XON ||     \
195
                chksum == XBEE_XOFF) {
196
        UART1_WriteC(XBEE_ESCAPE_CHAR);
197
        UART1_WriteC(chksum ^ XBEE_ESCAPE_VAL);
198
    } else {
199
        UART1_WriteC(0xFF - chksum);
200
    }
201
#else
202
    unsigned int i = 0;
157 Kevin 203
    char chksum = 0;
155 Kevin 204
 
205
    UART1_WriteC(XBEE_START_DELIMITER);
206
    UART1_WriteC(0);
207
    UART1_WriteC(length);
208
    for (i = 0; i < length; i++) {
209
        chksum += data[i];
210
        UART1_WriteC(data[i]);
211
    }
212
    UART1_WriteC(0xFF - chksum);
213
#endif
214
}
215
 
157 Kevin 216
void XBee_Set_RTS(char c) {
155 Kevin 217
    if (c) {
218
        XBEE_RTS_LAT = 1; // Set high to stop receiving data
219
    } else {
220
        XBEE_RTS_LAT = 0; // Set low to resume receiving data
221
    }
222
}
223
 
157 Kevin 224
char XBee_Read_CTS() {
225
    char c = XBEE_CTS_PORT;
155 Kevin 226
    if (c) {
227
        return 0x1; // High indicates stop sending data
228
    } else {
229
        return 0x0; // Low indicates ok to send data
230
    }
231
}
232
 
233
void XBee_Convert_Endian_64(XBEE_ADDRESS_64 *src) {
234
    char tmp[2];
235
    tmp[0] = src->UPPER_32.char_value[3];
236
    tmp[1] = src->UPPER_32.char_value[2];
237
    src->UPPER_32.char_value[3] = src->UPPER_32.char_value[0];
238
    src->UPPER_32.char_value[2] = src->UPPER_32.char_value[1];
239
    src->UPPER_32.char_value[1] = tmp[1];
240
    src->UPPER_32.char_value[0] = tmp[0];
241
 
242
    tmp[0] = src->LOWER_32.char_value[3];
243
    tmp[1] = src->LOWER_32.char_value[2];
244
    src->LOWER_32.char_value[3] = src->LOWER_32.char_value[0];
245
    src->LOWER_32.char_value[2] = src->LOWER_32.char_value[1];
246
    src->LOWER_32.char_value[1] = tmp[1];
247
    src->LOWER_32.char_value[0] = tmp[0];
248
}
249
 
250
void XBee_Convert_Endian_16(XBEE_ADDRESS_16 *src) {
251
    char tmp;
252
    tmp = src->INT_16.char_value[0];
253
    src->INT_16.char_value[0] = src->INT_16.char_value[1];
254
    src->INT_16.char_value[1] = tmp;
255
}