Project

General

Profile

Statistics
| Revision:

root / branches / wireless / code / projects / libwireless / xbee_computer.c @ 1601

History | View | Annotate | Download (6.79 KB)

1
// this is all the xbee.c computer code
2

    
3
#include <stdio.h>
4
#include <stdlib.h>
5

    
6
#ifndef ROBOT
7

    
8
#include <fcntl.h>
9
#include <unistd.h>
10
#include <pthread.h>
11
#include <errno.h>
12
#include <termios.h>
13

    
14
#endif
15

    
16

    
17
#define XBEE_GET_PACKET_TIMEOUT 1000
18

    
19
#ifndef ROBOT
20
static int xbee_read(char* buf, int size);
21
#endif
22

    
23
#ifndef ROBOT
24
static char* xbee_com_port = XBEE_PORT_DEFAULT;
25
static int xbee_stream;
26
static pthread_t* xbee_listen_thread;
27
#endif
28

    
29
#ifndef ROBOT
30

    
31
// Computer code
32

    
33
/**
34
 * Thread that listens to the xbee.
35
 **/
36
static void* listen_to_xbee(void* x)
37
{
38
        char c;
39
        while (1)
40
        {
41
                if (xbee_read(&c, 1) != 0) {
42
                        WL_DEBUG_PRINT("xbee_read failed.\n");
43
                        return NULL;
44
                }
45

    
46
                arrival_buf[buffer_last] = c;
47
                int t = buffer_last + 1;
48
                if (t == XBEE_BUFFER_SIZE)
49
                        t = 0;
50
                if (t == buffer_first)
51
                {
52
                        WL_DEBUG_PRINT("Out of space in buffer.\n");
53
                }
54
                buffer_last = t;
55

    
56
                usleep(1000);
57
        }
58

    
59
        return NULL;
60
}
61

    
62
#endif
63

    
64
/**
65
 * Initializes the XBee library so that other functions may be used.
66
 **/
67
int8_t xbee_lib_init()
68
{
69
  // do serial.c xbee init     TODO: merge this into xbee.c
70
  if (xbee_init() != 0) {
71
    usb_puts("xbee_init error");
72
    return WL_ERROR_INIT_FAILED;
73
  }
74

    
75
        WL_DEBUG_PRINT("in xbee_init\n");
76
#ifdef ROBOT
77

    
78
        //enable the receiving interrupt
79
#ifdef FIREFLY
80
        UCSR0B |= _BV(RXCIE) | _BV(RXEN);
81
#else
82
#ifdef BAYBOARD
83
        UCSR1B |= _BV(RXCIE1);
84
#else
85
        UCSR1B |= _BV(RXCIE);
86
#endif
87
#endif
88
        sei();
89
#else
90
        xbee_stream = open(xbee_com_port, O_RDWR);
91
        if (xbee_stream == -1/* || lockf(xbee_stream, F_TEST, 0) != 0*/)
92
        {
93
                WL_DEBUG_PRINT("Failed to open connection to XBee on port ");
94
                WL_DEBUG_PRINT_INT(xbee_com_port);
95
                WL_DEBUG_PRINT(".\n");
96
                return -1;
97
        } else {
98
          WL_DEBUG_PRINT("Successfully opened connection to XBee on port ");
99
                WL_DEBUG_PRINT_INT(xbee_com_port);
100
                WL_DEBUG_PRINT(".\n");
101
        }
102

    
103
        // set baud rate, etc. correctly
104
        struct termios options;
105

    
106
        tcgetattr(xbee_stream, &options);
107
        cfsetispeed(&options, B9600);
108
        cfsetospeed(&options, B9600);
109
        options.c_iflag &= ~ICRNL;
110
        options.c_oflag &= ~OCRNL;
111
        options.c_cflag |= (CLOCAL | CREAD);
112
        options.c_cflag &= ~PARENB;
113
        options.c_cflag &= ~CSTOPB;
114
        options.c_cflag &= ~CSIZE;
115
        options.c_cflag |= CS8;
116
        options.c_lflag &= ~ICANON;
117
        options.c_cc[VMIN] = 1;
118
        options.c_cc[VTIME] = 50;
119

    
120
        if (tcsetattr(xbee_stream, TCSANOW, &options))
121
        {
122
                WL_DEBUG_PRINT("Error setting attributes.\n");
123
                return -1;
124
        }
125

    
126
        xbee_listen_thread = (pthread_t*)malloc(sizeof(pthread_t));
127
        if (xbee_listen_thread == NULL)
128
        {
129
                WL_DEBUG_PRINT("Malloc failed.\n");
130
                return -1;
131
        }
132

    
133
        int ret = pthread_create(xbee_listen_thread, NULL, listen_to_xbee, NULL);
134
        if (ret)
135
        {
136
                WL_DEBUG_PRINT("Failed to create listener thread.\n");
137
                return -1;
138
        }
139
#endif
140

    
141
        WL_DEBUG_PRINT("Entering command mode.\r\n");
142

    
143
        if (xbee_enter_command_mode() != 0) {
144
    usb_puts("error entering command mode\r\n");
145
                return -1;
146
        }
147

    
148
        WL_DEBUG_PRINT("Entered command mode.\r\n");
149

    
150
  // reset baud rate
151
  WL_DEBUG_PRINT("Resetting Baud to ");
152
  WL_DEBUG_PRINT(XBEE_BAUD_STR);
153
  WL_DEBUG_PRINT("\r\n");
154
  
155
  // set baud on xbee
156
//#if (XBEE_BAUD == 250000)
157
#if (XBEE_BAUD == 115200)
158
  xbee_send_string("ATBD7\r\n");
159
#elif (XBEE_BAUD == 57600)
160
  xbee_send_string("ATBD6\r\n");
161
#elif (XBEE_BAUD == 38400)
162
  xbee_send_string("ATBD5\r\n");
163
#elif (XBEE_BAUD == 19200)
164
  xbee_send_string("ATBD4\r\n");
165
#elif (XBEE_BAUD == 9600)
166
  // already at this baud rate
167
  //xbee_send_string("ATBD3\r\n");
168
#else
169
  WL_DEBUG_PRINT("undefined baud rate\r\n");
170
#endif  
171
  // exit command mode
172
  xbee_wait_for_ok();
173
  WL_DEBUG_PRINT("got ok from baud reset\r\n");
174
  xbee_send_string("ATCN\r\n");
175
  xbee_wait_for_ok();
176
  WL_DEBUG_PRINT("got ok from exiting command mode\r\n");
177
  
178
  // set UART baud
179
#if (XBEE_BAUD == 250000)
180
  UBRR1H = 0x00;
181
  UBRR1L = 3;
182
  UCSR1A |= _BV(U2X1);
183
#elif (XBEE_BAUD == 115200)
184
  UBRR1H = 0x00;
185
  UBRR1L = 8;
186
  UCSR1A |= _BV(U2X1);
187
#elif (XBEE_BAUD == 57600)
188
  UBRR1H = 0x00;
189
  UBRR1L = 16;
190
  UCSR1A |= _BV(U2X1);
191
#elif (XBEE_BAUD == 38400)
192
  UBRR1H = 0x00;
193
  UBRR1L = 25;
194
  UCSR1A |= _BV(U2X1);
195
#elif (XBEE_BAUD == 19200)
196
  UBRR1H = 0x00;
197
  UBRR1L = 51;
198
  UCSR1A |= _BV(U2X1);
199
#elif (XBEE_BAUD == 9600)
200
  /* this is the default baud rate, so do nothing
201
  UBRR1H = 0x00;
202
  UBRR1L = 103;
203
  UCSR1A |= _BV(U2X1);*/
204
#else //Baud rate is defined in the header file, we should not get here
205
  return 0;
206
#endif
207
  delay_ms(50);
208

    
209
  // enter command mode
210
  WL_DEBUG_PRINT("entering command mode 2\r\n");
211
  xbee_send_string("+++");
212
  xbee_wait_for_ok();
213
  WL_DEBUG_PRINT("entered command mode 2\r\n");
214
  
215
  if (xbee_enter_api_mode() != 0) {
216
    WL_DEBUG_PRINT("can't enter api mode\r\n");
217
                return -1;
218
        }
219

    
220
        WL_DEBUG_PRINT("Entered api mode.\r\n");
221

    
222
        if (xbee_exit_command_mode() != 0) {
223
    WL_DEBUG_PRINT("can't exit command mode\r\n");
224
          return -1;
225
        }
226
        
227
        WL_DEBUG_PRINT("Left command mode.\r\n");
228
  
229
  // get baud rate
230
        if (xbee_send_read_at_command("BD")) {
231
    WL_DEBUG_PRINT("can't send BD command\r\n");
232
                return -1;
233
        }
234
        WL_DEBUG_PRINT("Getting ATBD rate.\n");
235
  
236
  // get MY address
237
        if (xbee_send_read_at_command("MY")) {
238
    WL_DEBUG_PRINT("can't send my command\r\n");
239
                return -1;
240
        }
241
        WL_DEBUG_PRINT("Getting ATMY address.\n");
242

    
243
#ifndef ROBOT
244
        int i;
245
        for (i = 0; xbee_address == 0 && i < XBEE_GET_PACKET_TIMEOUT; i++) {
246
          ret = xbee_get_packet(NULL);
247

    
248
          usleep(1000);
249
          
250
/*           if (ret == -1) { */
251
/*             WL_DEBUG_PRINT("xbee_get_packet(NULL) failed.\n"); */
252
/*             return -1; */
253
/*           } */
254
        }
255
#else
256
        //wait to return until the address is set
257
  //TODO: this shouldn't wait indefinitely.  There should be some sort of reasonable timeout
258
  // so if the address is never set right, an error can be returned instead of having the
259
  // robot hang forever
260
        while (xbee_address == 0) {
261
          xbee_get_packet(NULL);
262
        }
263
#endif
264
        WL_DEBUG_PRINT("Got ATMY address.\n");
265

    
266
#ifndef ROBOT
267
        if (i == XBEE_GET_PACKET_TIMEOUT) { // We timed-out.
268

    
269
          WL_DEBUG_PRINT("xbee_get_packet timed out.\n");
270
          return -1;
271
        } else {
272
          return 0;
273
        }
274
#else
275
        return 0;
276
#endif
277
}
278

    
279
void xbee_terminate()
280
{
281
        #ifndef ROBOT
282
        pthread_cancel(*xbee_listen_thread);
283
    pthread_join(*xbee_listen_thread, NULL);
284
        free(xbee_listen_thread);
285
        lockf(xbee_stream, F_ULOCK, 0);
286
        close(xbee_stream);
287
  #else
288
  xbee_exit_api_mode();
289
        #endif
290
}
291

    
292

    
293

    
294
static int xbee_send(char* buf, int size)
295
#ifndef ROBOT
296

    
297
        int ret = write(xbee_stream, buf, size);
298
        //success
299
        if (ret == size)
300
                return 0;
301
        if (ret == -1)
302
        {
303
                //interrupted by system signal, probably timer interrupt.
304
                //just try again
305
                if (errno == 4)
306
                {
307
                        return xbee_send(buf, size);
308
                }
309
                WL_DEBUG_PRINT("Failed to write to xbee\r\n");
310
                return -1;
311
        }
312

    
313
        //write was interrupted after writing ret bytes
314
        return xbee_send(buf + ret, size - ret);
315
#endif
316

    
317

    
318
#ifndef ROBOT
319
static int xbee_read(char* buf, int size)
320
{
321
        if (read(xbee_stream, buf, size) == -1) {
322
                WL_DEBUG_PRINT("Failed to read from xbee.\r\n");
323
                return -1;
324
        }
325

    
326
        return 0;
327
}
328
#endif
329

    
330

    
331
#ifndef ROBOT
332
void xbee_set_com_port(char* port)
333
{
334
        xbee_com_port = port;
335
}
336
#endif
337