Revision 336
Updated wireless to use a circular buffer instead of a queue using malloc. Tested on both the computer and robots with a token ring, and was successful.
xbee.c | ||
---|---|---|
41 | 41 |
#include <unistd.h> |
42 | 42 |
#include <pthread.h> |
43 | 43 |
#include <errno.h> |
44 |
#include <termios.h> |
|
44 | 45 |
|
45 | 46 |
#else |
46 | 47 |
|
... | ... | |
53 | 54 |
#include <stdlib.h> |
54 | 55 |
#include <string.h> |
55 | 56 |
|
56 |
#include <queue.h> |
|
57 |
|
|
58 | 57 |
#define XBEE_FRAME_START 0x7E |
59 | 58 |
|
60 | 59 |
/*Frame Types*/ |
... | ... | |
83 | 82 |
void xbee_enter_command_mode(void); |
84 | 83 |
void xbee_exit_command_mode(void); |
85 | 84 |
void xbee_enter_api_mode(void); |
85 |
void xbee_exit_api_mode(void); |
|
86 | 86 |
void xbee_wait_for_string(char* s, int len); |
87 | 87 |
void xbee_wait_for_ok(void); |
88 | 88 |
|
... | ... | |
101 | 101 |
/*Global Variables*/ |
102 | 102 |
|
103 | 103 |
#ifndef ROBOT |
104 |
char* xbee_com_port; |
|
104 |
char* xbee_com_port = XBEE_PORT_DEFAULT;
|
|
105 | 105 |
int xbee_stream; |
106 | 106 |
pthread_t* xbee_listen_thread; |
107 | 107 |
#endif |
108 | 108 |
|
109 |
Queue* xbee_queue; |
|
109 |
// TODO: is this a good size? |
|
110 |
#define XBEE_BUFFER_SIZE 256 |
|
111 |
// a buffer for data received from the XBee |
|
112 |
char arrival_buf[XBEE_BUFFER_SIZE]; |
|
113 |
// location of last unread byte in buffer |
|
114 |
volatile int buffer_last = 0; |
|
115 |
// first unread byte in buffer |
|
116 |
volatile int buffer_first = 0; |
|
110 | 117 |
|
118 |
|
|
111 | 119 |
//used to store packets as they are read |
112 | 120 |
char xbee_buf[128]; |
113 | 121 |
int currentBufPos = 0; |
... | ... | |
125 | 133 |
|
126 | 134 |
/** |
127 | 135 |
* Interrupt for the robot. Adds bytes received from the xbee |
128 |
* to the queue.
|
|
136 |
* to the buffer.
|
|
129 | 137 |
**/ |
130 | 138 |
#ifndef FIREFLY |
131 | 139 |
ISR(USART1_RX_vect) |
132 | 140 |
{ |
133 | 141 |
char c = UDR1; |
134 |
queue_add(xbee_queue, (void*)(int)c); |
|
142 |
arrival_buf[buffer_last] = c; |
|
143 |
int t = buffer_last + 1; |
|
144 |
if (t == XBEE_BUFFER_SIZE) |
|
145 |
t = 0; |
|
146 |
if (t == buffer_first) |
|
147 |
{ |
|
148 |
WL_DEBUG_PRINT("Out of space in buffer.\n"); |
|
149 |
} |
|
150 |
buffer_last = t; |
|
135 | 151 |
} |
136 | 152 |
#else |
137 | 153 |
SIGNAL(SIG_USART0_RECV) |
138 | 154 |
{ |
139 | 155 |
char c = UDR0; |
140 |
queue_add(xbee_queue, (void*)(int)c); |
|
156 |
arrival_buf[buffer_last] = c; |
|
157 |
int t = buffer_last + 1; |
|
158 |
if (t == XBEE_BUFFER_SIZE) |
|
159 |
t = 0; |
|
160 |
if (t == buffer_first) |
|
161 |
{ |
|
162 |
WL_DEBUG_PRINT("Out of space in buffer.\n"); |
|
163 |
} |
|
164 |
buffer_last = t; |
|
141 | 165 |
} |
142 | 166 |
#endif |
143 | 167 |
|
... | ... | |
152 | 176 |
while (1) |
153 | 177 |
{ |
154 | 178 |
xbee_read(&c, 1); |
155 |
queue_add(xbee_queue, (void*)(int)c); |
|
179 |
arrival_buf[buffer_last] = c; |
|
180 |
int t = buffer_last + 1; |
|
181 |
if (t == XBEE_BUFFER_SIZE) |
|
182 |
t = 0; |
|
183 |
if (t == buffer_first) |
|
184 |
{ |
|
185 |
WL_DEBUG_PRINT("Out of space in buffer.\n"); |
|
186 |
} |
|
187 |
buffer_last = t; |
|
156 | 188 |
} |
157 | 189 |
return 0; |
158 | 190 |
} |
... | ... | |
162 | 194 |
/** |
163 | 195 |
* Initializes the XBee library so that other functions may be used. |
164 | 196 |
**/ |
165 |
void xbee_lib_init(void)
|
|
197 |
int xbee_lib_init(void)
|
|
166 | 198 |
{ |
167 |
xbee_queue = queue_create(); |
|
168 |
|
|
199 |
arrival_buf[0] = 'A'; |
|
200 |
arrival_buf[1] = 'A'; |
|
201 |
arrival_buf[2] = 'A'; |
|
169 | 202 |
#ifdef ROBOT |
170 | 203 |
|
171 | 204 |
//enable the receiving interrupt |
... | ... | |
176 | 209 |
#endif |
177 | 210 |
sei(); |
178 | 211 |
#else |
212 |
printf("Connecting to port %s.\n", xbee_com_port); |
|
179 | 213 |
xbee_stream = open(xbee_com_port, O_RDWR); |
180 |
if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0) |
|
181 |
xbee_stream = open(XBEE_PORT2, O_RDWR); |
|
182 |
if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0) |
|
214 |
if (xbee_stream == -1/* || lockf(xbee_stream, F_TEST, 0) != 0*/) |
|
183 | 215 |
{ |
184 |
printf("Failed to open connection to XBee on port %s\r\n",xbee_com_port); |
|
185 |
exit(0);
|
|
216 |
printf("Failed to open connection to XBee on port %s\r\n", xbee_com_port);
|
|
217 |
return -1;
|
|
186 | 218 |
} |
187 |
lockf(xbee_stream, F_LOCK, 0); |
|
188 | 219 |
|
220 |
// set baud rate, etc. correctly |
|
221 |
struct termios options; |
|
222 |
|
|
223 |
tcgetattr(xbee_stream, &options); |
|
224 |
cfsetispeed(&options, B9600); |
|
225 |
cfsetospeed(&options, B9600); |
|
226 |
options.c_iflag &= ~ICRNL; |
|
227 |
options.c_oflag &= ~OCRNL; |
|
228 |
options.c_cflag |= (CLOCAL | CREAD); |
|
229 |
options.c_cflag &= ~PARENB; |
|
230 |
options.c_cflag &= ~CSTOPB; |
|
231 |
options.c_cflag &= ~CSIZE; |
|
232 |
options.c_cflag |= CS8; |
|
233 |
options.c_lflag &= ~ICANON; |
|
234 |
options.c_cc[VMIN] = 1; |
|
235 |
options.c_cc[VTIME] = 50; |
|
236 |
|
|
237 |
if (tcsetattr(xbee_stream, TCSANOW, &options)) |
|
238 |
{ |
|
239 |
fprintf(stderr, "Error setting attributes.\n"); |
|
240 |
return -1; |
|
241 |
} |
|
242 |
|
|
243 |
//lockf(xbee_stream, F_LOCK, 0); |
|
244 |
|
|
189 | 245 |
xbee_listen_thread = |
190 | 246 |
(pthread_t*)malloc(sizeof(pthread_t)); |
247 |
if (xbee_listen_thread == NULL) |
|
248 |
{ |
|
249 |
fprintf(stderr, "%s: Malloc failed.\n", __FUNCTION__); |
|
250 |
return -1; |
|
251 |
} |
|
191 | 252 |
|
192 |
int ret = pthread_create(xbee_listen_thread, NULL,
|
|
253 |
int ret = pthread_create(xbee_listen_thread, NULL, |
|
193 | 254 |
listen_to_xbee, NULL); |
194 | 255 |
if (ret) |
195 | 256 |
{ |
196 |
printf("Failed to create listener thread.\r\n");
|
|
197 |
exit(0);
|
|
257 |
fprintf(stderr, "Failed to create listener thread.\r\n");
|
|
258 |
return -1;
|
|
198 | 259 |
} |
260 |
|
|
199 | 261 |
#endif |
200 | 262 |
xbee_enter_command_mode(); |
201 | 263 |
xbee_enter_api_mode(); |
... | ... | |
204 | 266 |
|
205 | 267 |
//wait to return until the address is set |
206 | 268 |
while (xbee_address == 0) xbee_get_packet(NULL); |
269 |
|
|
270 |
|
|
271 |
return 0; |
|
207 | 272 |
} |
208 | 273 |
|
209 | 274 |
/** |
... | ... | |
218 | 283 |
lockf(xbee_stream, F_ULOCK, 0); |
219 | 284 |
close(xbee_stream); |
220 | 285 |
#endif |
221 |
queue_destroy(xbee_queue); |
|
222 | 286 |
} |
223 | 287 |
|
224 | 288 |
/** |
... | ... | |
302 | 366 |
} |
303 | 367 |
|
304 | 368 |
/** |
369 |
* Exit API mode. (warning - does not check for response) |
|
370 |
**/ |
|
371 |
void xbee_exit_api_mode() |
|
372 |
{ |
|
373 |
xbee_send_string("ATAP 0\r"); |
|
374 |
} |
|
375 |
|
|
376 |
/** |
|
305 | 377 |
* Wait until the string "OK\r" is received from the XBee. |
306 | 378 |
**/ |
307 | 379 |
void xbee_wait_for_ok() |
... | ... | |
321 | 393 |
char* curr = s; |
322 | 394 |
while (curr - s < len) |
323 | 395 |
{ |
324 |
if (queue_is_empty(xbee_queue)) |
|
396 |
// check if buffer is empty |
|
397 |
if (buffer_last == buffer_first) |
|
325 | 398 |
continue; |
326 |
char c = (char)(int)queue_remove(xbee_queue); |
|
399 |
char c = arrival_buf[buffer_first++]; |
|
400 |
if (buffer_first == XBEE_BUFFER_SIZE) |
|
401 |
buffer_first = 0; |
|
327 | 402 |
if (c == *curr) |
328 | 403 |
curr++; |
329 | 404 |
else |
... | ... | |
531 | 606 |
if (currentBufPos == 0) |
532 | 607 |
{ |
533 | 608 |
do |
534 |
if (queue_is_empty(xbee_queue)) |
|
609 |
{ |
|
610 |
if (buffer_first == XBEE_BUFFER_SIZE) |
|
611 |
buffer_first = 0; |
|
612 |
// check if buffer is empty |
|
613 |
if (buffer_first == buffer_last) |
|
535 | 614 |
return -1; |
536 |
while ((char)(int)queue_remove(xbee_queue) != XBEE_FRAME_START); |
|
615 |
} |
|
616 |
while (arrival_buf[buffer_first++] != XBEE_FRAME_START); |
|
617 |
if (buffer_first == XBEE_BUFFER_SIZE) |
|
618 |
buffer_first = 0; |
|
537 | 619 |
xbee_buf[0] = XBEE_FRAME_START; |
538 | 620 |
currentBufPos++; |
539 | 621 |
} |
... | ... | |
555 | 637 |
return -1; |
556 | 638 |
} |
557 | 639 |
} |
558 |
if (queue_is_empty(xbee_queue)) |
|
640 |
// check if buffer is empty |
|
641 |
if (buffer_first == buffer_last) |
|
559 | 642 |
return -1; |
560 |
xbee_buf[currentBufPos++] = (char)(int)queue_remove(xbee_queue); |
|
643 |
xbee_buf[currentBufPos++] = arrival_buf[buffer_first++]; |
|
644 |
if (buffer_first == XBEE_BUFFER_SIZE) |
|
645 |
buffer_first = 0; |
|
561 | 646 |
} |
562 | 647 |
|
563 | 648 |
currentBufPos = 0; |
... | ... | |
781 | 866 |
} |
782 | 867 |
|
783 | 868 |
#ifndef ROBOT |
784 |
void xbee_set_com_port(char* port){ |
|
785 |
//printf("Port being passed is %s\n",port); |
|
786 |
xbee_com_port = (char *) malloc(strlen(port)); |
|
787 |
strcpy(xbee_com_port,port); |
|
869 |
void xbee_set_com_port(char* port) |
|
870 |
{ |
|
871 |
xbee_com_port = port; |
|
788 | 872 |
} |
789 | 873 |
#endif |
790 | 874 |
|
Also available in: Unified diff