Subversion Repositories Code-Repo

Rev

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

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