Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

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