Revision 793
Updated bay board wireless library... Doesn't work at all.
branches/autonomous_recharging/code/projects/libwireless/bayboardTest/main.c | ||
---|---|---|
1 | 1 |
#include <bayboard_lib.h> |
2 | 2 |
#include <wireless.h> |
3 | 3 |
#include <wl_token_ring.h> |
4 |
#include <xbee.h> |
|
5 |
#include <ctype.h> |
|
6 | 4 |
|
7 |
void test_bom_on (void)
|
|
5 |
int main(int argc, char** argv)
|
|
8 | 6 |
{ |
9 |
set_orb(0,200,0); |
|
10 |
delay_ms(50); |
|
11 |
} |
|
12 |
|
|
13 |
void test_bom_off(void) |
|
14 |
{ |
|
15 |
set_orb(200,0,200); |
|
16 |
delay_ms(50); |
|
17 |
} |
|
18 |
|
|
19 |
int test_nothing(void) |
|
20 |
{ |
|
21 |
return -1; |
|
22 |
} |
|
23 |
|
|
24 |
void do_nothing (void) { |
|
25 |
|
|
26 |
} |
|
27 |
|
|
28 |
int main(void) |
|
29 |
{ |
|
30 | 7 |
bayboard_init(ALL_ON); |
31 |
//xbee_lib_init(); |
|
32 |
|
|
33 |
set_orb(200,0,0); |
|
34 |
|
|
8 |
usb_puts("Start.\n"); |
|
9 |
set_orb(0, 0, 200); |
|
35 | 10 |
wl_init(); |
36 |
if(wl_token_ring_register() < 0) { |
|
37 |
set_orb(200,0,0); |
|
38 |
return -1; |
|
39 |
} |
|
40 |
if(wl_token_ring_join() < 0) { |
|
41 |
set_orb(200,0,0); |
|
42 |
return -1; |
|
43 |
} |
|
44 |
|
|
45 |
set_orb(0,200,0); |
|
46 |
usb_puts("== start ==\n"); |
|
47 |
delay_ms(200); |
|
48 |
|
|
49 |
//bom_init(0); |
|
50 |
|
|
51 |
//int c; |
|
52 |
//char buf[20]; |
|
53 |
while (1) { |
|
54 |
wl_do(); |
|
55 |
} |
|
56 |
|
|
11 |
set_orb(0, 200, 0); |
|
12 |
/*if (wl_token_ring_register() < 0) |
|
13 |
usb_puts("Failed to register token ring.\n"); |
|
14 |
if (wl_token_ring_join() < 0) |
|
15 |
usb_puts("Failed to join token ring.\n");*/ |
|
16 |
usb_puts("Wireless initialized.\n"); |
|
17 |
//while (1) |
|
18 |
// wl_do(); |
|
57 | 19 |
return 0; |
58 |
|
|
59 | 20 |
} |
60 | 21 |
|
61 |
|
branches/autonomous_recharging/code/projects/libwireless/bayboardTest/Makefile | ||
---|---|---|
14 | 14 |
USE_WIRELESS = 1 |
15 | 15 |
|
16 | 16 |
# com1 = serial port. Use lpt1 to connect to parallel port. |
17 |
AVRDUDE_PORT = /dev/ttyUSB0
|
|
17 |
AVRDUDE_PORT = /dev/ttyUSB1
|
|
18 | 18 |
# |
19 | 19 |
# |
20 | 20 |
################################### |
branches/autonomous_recharging/code/projects/libwireless/lib/wl_token_ring.c | ||
---|---|---|
42 | 42 |
#include <sensor_matrix.h> |
43 | 43 |
|
44 | 44 |
#ifdef ROBOT |
45 |
#ifndef FIREFLY |
|
46 |
#ifdef BAYBOARD |
|
47 |
#include <lbom.h> |
|
48 |
#else |
|
49 |
#include <bom.h> |
|
50 |
#endif |
|
51 |
#endif |
|
45 |
#ifndef FIREFLY |
|
46 |
#include <bom.h> |
|
47 |
#endif |
|
52 | 48 |
#include <time.h> |
53 | 49 |
#endif |
54 | 50 |
|
51 |
//TODO: why is this in both this file and sensor_matrix.c? If it is needed in both places, |
|
52 |
// put it in sensor_matrix.h. This file already includes sensor_matrix.h |
|
55 | 53 |
#define DEFAULT_SENSOR_MATRIX_SIZE 20 |
56 | 54 |
|
57 | 55 |
/*Ring States*/ |
... | ... | |
63 | 61 |
#define LEAVING 4 |
64 | 62 |
|
65 | 63 |
/*Frame Types*/ |
66 |
#define TOKEN_JOIN_ACCEPT_FRAME 1 |
|
64 |
#define TOKEN_JOIN_ACCEPT_FRAME 1 |
|
65 |
#define WL_TOKEN_PASS_FRAME 2 |
|
67 | 66 |
|
68 | 67 |
/*Function Prototypes*/ |
69 | 68 |
|
... | ... | |
79 | 78 |
static void wl_token_get_token(void); |
80 | 79 |
|
81 | 80 |
/*Packet Handling Routines*/ |
82 |
static void wl_token_pass_receive(int source, char nextRobot, unsigned char* sensorData, int sensorDataLength); |
|
81 |
static void wl_token_pass_receive(int source); |
|
82 |
static void wl_token_sensor_matrix_receive(int source, unsigned char* sensorData, int sensorDataLength); |
|
83 | 83 |
static void wl_token_bom_on_receive(int source); |
84 | 84 |
static void wl_token_join_receive(int source); |
85 | 85 |
static void wl_token_join_accept_receive(int source); |
86 | 86 |
|
87 | 87 |
/*Global Variables*/ |
88 | 88 |
|
89 |
//the sensor matrix |
|
90 |
static SensorMatrix* sensorMatrix; |
|
91 |
|
|
92 | 89 |
//the robot we are waiting to say it has received the token. -1 if unspecified |
93 | 90 |
static int wl_token_next_robot = -1; |
94 | 91 |
|
... | ... | |
110 | 107 |
// the amount of time a robot has had its BOM on for |
111 | 108 |
static int bom_on_count = 0; |
112 | 109 |
|
110 |
#ifndef ROBOT |
|
113 | 111 |
static void do_nothing(void) {} |
114 | 112 |
static int get_nothing(void) {return -1;} |
113 |
#endif |
|
115 | 114 |
|
116 | 115 |
#ifdef ROBOT |
117 | 116 |
#ifndef FIREFLY |
118 |
#ifdef BAYBOARD |
|
119 | 117 |
static void (*bom_on_function) (void) = bom_on; |
120 | 118 |
static void (*bom_off_function) (void) = bom_off; |
121 |
static int (*get_max_bom_function) (void) = get_nothing; |
|
122 |
#else |
|
123 |
static void (*bom_on_function) (void) = bom_on; |
|
124 |
static void (*bom_off_function) (void) = bom_off; |
|
125 | 119 |
static int (*get_max_bom_function) (void) = get_max_bom; |
126 |
#endif |
|
127 | 120 |
#else |
128 | 121 |
static void (*bom_on_function) (void) = do_nothing; |
129 | 122 |
static void (*bom_off_function) (void) = do_nothing; |
... | ... | |
136 | 129 |
#endif |
137 | 130 |
|
138 | 131 |
static PacketGroupHandler wl_token_ring_handler = |
139 |
{wl_token_ring_timeout_handler, |
|
132 |
{WL_TOKEN_RING_GROUP, wl_token_ring_timeout_handler,
|
|
140 | 133 |
wl_token_ring_response_handler, wl_token_ring_receive_handler, |
141 |
wl_token_ring_cleanup, WL_TOKEN_RING_GROUP};
|
|
134 |
wl_token_ring_cleanup};
|
|
142 | 135 |
|
143 | 136 |
/** |
144 | 137 |
* Causes the robot to join an existing token ring, or create one |
... | ... | |
163 | 156 |
* alerting others of its location, but continues storing the |
164 | 157 |
* locations of other robots. |
165 | 158 |
**/ |
159 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
160 |
// it reduces code size or not should be done to be sure. |
|
166 | 161 |
void wl_token_ring_leave() |
167 | 162 |
{ |
168 | 163 |
ringState = LEAVING; |
... | ... | |
184 | 179 |
return -1; |
185 | 180 |
} |
186 | 181 |
|
187 |
sensorMatrix = sensor_matrix_create();
|
|
182 |
sensor_matrix_create(); |
|
188 | 183 |
//add ourselves to the sensor matrix |
189 |
sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 0);
|
|
184 |
sensor_matrix_set_in_ring(wl_get_xbee_id(), 0); |
|
190 | 185 |
|
191 | 186 |
wl_register_packet_group(&wl_token_ring_handler); |
192 | 187 |
|
... | ... | |
196 | 191 |
/** |
197 | 192 |
* Removes the packet group from the wireless library. |
198 | 193 |
**/ |
194 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
195 |
// it reduces code size or not should be done to be sure. |
|
199 | 196 |
void wl_token_ring_unregister() |
200 | 197 |
{ |
201 | 198 |
wl_unregister_packet_group(&wl_token_ring_handler); |
... | ... | |
224 | 221 |
/** |
225 | 222 |
* Called to cleanup the token ring packet group. |
226 | 223 |
**/ |
224 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
225 |
// it reduces code size or not should be done to be sure. |
|
227 | 226 |
static void wl_token_ring_cleanup() |
228 | 227 |
{ |
229 |
sensor_matrix_destroy(sensorMatrix); |
|
230 | 228 |
} |
231 | 229 |
|
232 | 230 |
/** |
... | ... | |
241 | 239 |
//also, declare that person dead, as long as it isn't us |
242 | 240 |
if (wl_token_next_robot != wl_get_xbee_id()) |
243 | 241 |
{ |
244 |
sensor_matrix_set_in_ring(sensorMatrix, wl_token_next_robot, 0);
|
|
242 |
sensor_matrix_set_in_ring(wl_token_next_robot, 0); |
|
245 | 243 |
WL_DEBUG_PRINT("Robot "); |
246 | 244 |
WL_DEBUG_PRINT_INT(wl_token_next_robot); |
247 | 245 |
WL_DEBUG_PRINT(" has died.\r\n"); |
... | ... | |
258 | 256 |
//we must start our own token ring, no one is responding to us |
259 | 257 |
if (joinDelay == 0) |
260 | 258 |
{ |
261 |
if (sensor_matrix_get_joined(sensorMatrix) == 0)
|
|
259 |
if (sensor_matrix_get_joined() == 0) |
|
262 | 260 |
{ |
263 | 261 |
WL_DEBUG_PRINT("Creating our own token ring, no robots seem to exist.\r\n"); |
264 |
sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 1);
|
|
262 |
sensor_matrix_set_in_ring(wl_get_xbee_id(), 1); |
|
265 | 263 |
ringState = MEMBER; |
266 | 264 |
//this will make us pass the token to ourself |
267 | 265 |
//repeatedly, and other robots when they join |
... | ... | |
316 | 314 |
switch (type) |
317 | 315 |
{ |
318 | 316 |
case WL_TOKEN_PASS: |
319 |
if (length < 1) |
|
320 |
{ |
|
321 |
WL_DEBUG_PRINT("Malformed Token Pass packet received.\r\n"); |
|
322 |
return; |
|
323 |
} |
|
324 |
wl_token_pass_receive(source, packet[0], packet + 1, length - 1); |
|
317 |
wl_token_pass_receive(source); |
|
325 | 318 |
break; |
319 |
case WL_TOKEN_SENSOR_MATRIX: |
|
320 |
wl_token_sensor_matrix_receive(source, packet, length); |
|
321 |
break; |
|
326 | 322 |
case WL_TOKEN_BOM_ON: |
327 | 323 |
//add the robot to the sensor matrix if it is not already there |
328 | 324 |
wl_token_bom_on_receive(source); |
... | ... | |
352 | 348 |
{ |
353 | 349 |
if (wl_token_is_robot_in_ring(dest) && |
354 | 350 |
(source == wl_get_xbee_id() || wl_token_is_robot_in_ring(source))) { |
355 |
return sensor_matrix_get_reading(sensorMatrix, source, dest);
|
|
351 |
return sensor_matrix_get_reading(source, dest); |
|
356 | 352 |
} |
357 | 353 |
|
358 | 354 |
return -1; |
... | ... | |
366 | 362 |
* @return a BOM reading from us to robot dest, in the range |
367 | 363 |
* 0-15, or -1 if it is unkown |
368 | 364 |
**/ |
365 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
366 |
// it reduces code size or not should be done to be sure. |
|
369 | 367 |
int wl_token_get_my_sensor_reading(int dest) |
370 | 368 |
{ |
371 | 369 |
return wl_token_get_sensor_reading(wl_get_xbee_id(), dest); |
... | ... | |
377 | 375 |
* |
378 | 376 |
* @return the number of robots in the token ring |
379 | 377 |
**/ |
378 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
379 |
// it reduces code size or not should be done to be sure. |
|
380 | 380 |
int wl_token_get_robots_in_ring(void) |
381 | 381 |
{ |
382 |
return sensor_matrix_get_joined(sensorMatrix);
|
|
382 |
return sensor_matrix_get_joined(); |
|
383 | 383 |
} |
384 | 384 |
|
385 | 385 |
/** |
... | ... | |
389 | 389 |
* @param robot the robot to check for whether it is in the token ring |
390 | 390 |
* @return nonzero if the robot is in the token ring, zero otherwise |
391 | 391 |
**/ |
392 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
393 |
// it reduces code size or not should be done to be sure. |
|
392 | 394 |
int wl_token_is_robot_in_ring(int robot) |
393 | 395 |
{ |
394 |
return sensor_matrix_get_in_ring(sensorMatrix, robot);
|
|
396 |
return sensor_matrix_get_in_ring(robot); |
|
395 | 397 |
} |
396 | 398 |
|
397 | 399 |
/** |
... | ... | |
402 | 404 |
void wl_token_iterator_begin(void) |
403 | 405 |
{ |
404 | 406 |
int i = 0; |
405 |
|
|
406 |
while (!sensor_matrix_get_in_ring(sensorMatrix, i) && i < sensor_matrix_get_size(sensorMatrix)) { |
|
407 |
//TODO: the compiler may or may not optimize this such that my comment is useless: |
|
408 |
// instead of calling sensor_matrix_get_size every iteration of the while loop and incurring |
|
409 |
// the overhead of a function call each iteration, call it only once before the loop and store |
|
410 |
// the value in a variable and check against that variable in the loop condition |
|
411 |
while (!sensor_matrix_get_in_ring(i) && i < sensor_matrix_get_size()) { |
|
407 | 412 |
i++; |
408 | 413 |
} |
409 | 414 |
|
410 |
if (i == sensor_matrix_get_size(sensorMatrix)) { |
|
415 |
//TODO: if you do the above comment, then you can compare this to the variable also |
|
416 |
if (i == sensor_matrix_get_size()) { |
|
411 | 417 |
i = -1; |
412 | 418 |
} |
413 | 419 |
|
... | ... | |
423 | 429 |
* |
424 | 430 |
* @see wl_token_iterator_begin, wl_token_iterator_next |
425 | 431 |
**/ |
432 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
433 |
// it reduces code size or not should be done to be sure. |
|
426 | 434 |
int wl_token_iterator_has_next(void) |
427 | 435 |
{ |
428 | 436 |
return iteratorCount != -1; |
... | ... | |
442 | 450 |
return result; |
443 | 451 |
} |
444 | 452 |
|
453 |
//TODO: the compiler may or may not optimize this such that my comment is useless: |
|
454 |
// instead of calling sensor_matrix_get_size every iteration of the while loop and incurring |
|
455 |
// the overhead of a function call each iteration, call it only once before the loop and store |
|
456 |
// the value in a variable and check against that variable in the loop condition |
|
445 | 457 |
iteratorCount++; |
446 |
while (!sensor_matrix_get_in_ring(sensorMatrix, iteratorCount)
|
|
447 |
&& iteratorCount < sensor_matrix_get_size(sensorMatrix)) {
|
|
458 |
while (!sensor_matrix_get_in_ring(iteratorCount) |
|
459 |
&& iteratorCount < sensor_matrix_get_size()) { |
|
448 | 460 |
iteratorCount++; |
449 | 461 |
} |
450 | 462 |
|
451 |
if (iteratorCount == sensor_matrix_get_size(sensorMatrix)) { |
|
463 |
//TODO: if you do the above comment, then you can compare this to the variable also |
|
464 |
if (iteratorCount == sensor_matrix_get_size()) { |
|
452 | 465 |
iteratorCount = -1; |
453 | 466 |
} |
454 | 467 |
|
... | ... | |
460 | 473 |
* |
461 | 474 |
* @return the number of robots in the token ring |
462 | 475 |
**/ |
476 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
477 |
// it reduces code size or not should be done to be sure. |
|
463 | 478 |
int wl_token_get_num_robots(void) |
464 | 479 |
{ |
465 |
return sensor_matrix_get_joined(sensorMatrix);
|
|
480 |
return sensor_matrix_get_joined(); |
|
466 | 481 |
} |
467 | 482 |
|
468 | 483 |
/** |
... | ... | |
470 | 485 |
* |
471 | 486 |
* @return the number of robots in the sensor matrix |
472 | 487 |
**/ |
488 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
489 |
// it reduces code size or not should be done to be sure. |
|
473 | 490 |
int wl_token_get_matrix_size(void) |
474 | 491 |
{ |
475 |
return sensor_matrix_get_size(sensorMatrix);
|
|
492 |
return sensor_matrix_get_size(); |
|
476 | 493 |
} |
477 | 494 |
|
478 | 495 |
/** |
479 | 496 |
* This method is called when we receive a token pass packet. |
497 |
* |
|
498 |
* @param source the robot who passed the token to us. |
|
499 |
**/ |
|
500 |
static void wl_token_pass_receive(int source) |
|
501 |
{ |
|
502 |
WL_DEBUG_PRINT("Received token from "); |
|
503 |
WL_DEBUG_PRINT_INT(source); |
|
504 |
WL_DEBUG_PRINT(", expected "); |
|
505 |
WL_DEBUG_PRINT_INT(wl_token_next_robot); |
|
506 |
WL_DEBUG_PRINT(".\n"); |
|
507 |
// this prevents two tokens from being passed around at a time (second clause is in case we are joining) |
|
508 |
if ((source != wl_token_next_robot && wl_get_xbee_id() != wl_token_next_robot) && bom_on_count <= DEATH_DELAY / 2 && |
|
509 |
ringState != ACCEPTED) |
|
510 |
{ |
|
511 |
WL_DEBUG_PRINT("Received token pass when a robot should not have died yet.\n"); |
|
512 |
WL_DEBUG_PRINT("There are probably two tokens going around, packet ignored.\n"); |
|
513 |
return; |
|
514 |
} |
|
515 |
bom_on_count = -1; |
|
516 |
deathDelay = -1; |
|
517 |
sensor_matrix_set_in_ring(source, 1); |
|
518 |
wl_token_get_token(); |
|
519 |
} |
|
520 |
|
|
521 |
/** |
|
522 |
* This method is called when we receive a token pass packet. |
|
480 | 523 |
* @param source is the robot it came from |
481 | 524 |
* @param nextRobot is the robot the token was passed to |
482 | 525 |
* @param sensorData a char with an id followed by a char with the sensor |
483 | 526 |
* reading for that robot, repeated for sensorDataLength bytes |
484 | 527 |
* @param sensorDataLength the length in bytes of sensorData |
485 | 528 |
*/ |
486 |
static void wl_token_pass_receive(int source, char nextRobot, unsigned char* sensorData, int sensorDataLength)
|
|
529 |
static void wl_token_sensor_matrix_receive(int source, unsigned char* sensorData, int sensorDataLength)
|
|
487 | 530 |
{ |
488 | 531 |
int i, j; |
532 |
char nextRobot; |
|
489 | 533 |
|
490 |
// this prevents two tokens from being passed around at a time (second clause is in case we are joining) |
|
491 |
if (source != wl_token_next_robot && bom_on_count <= DEATH_DELAY / 2 && |
|
492 |
ringState != ACCEPTED) |
|
493 |
{ |
|
494 |
WL_DEBUG_PRINT("Received token pass when a robot should not have died yet.\n"); |
|
495 |
WL_DEBUG_PRINT("There are probably two tokens going around, packet ignored.\n"); |
|
496 |
return; |
|
497 |
} |
|
498 |
|
|
499 | 534 |
bom_on_count = -1; |
500 | 535 |
deathDelay = -1; |
501 |
WL_DEBUG_PRINT("Received the token from robot"); |
|
502 |
WL_DEBUG_PRINT_INT(source); |
|
503 |
WL_DEBUG_PRINT(", next robot is "); |
|
504 |
WL_DEBUG_PRINT_INT((int)nextRobot); |
|
505 |
WL_DEBUG_PRINT(" \r\n"); |
|
506 |
sensor_matrix_set_in_ring(sensorMatrix, source, 1); |
|
536 |
sensor_matrix_set_in_ring(source, 1); |
|
507 | 537 |
|
508 | 538 |
//with this packet, we are passed the id of the next robot in the ring |
509 | 539 |
//and the sensor matrix, a list of id and sensor reading pairs (two bytes for both) |
510 | 540 |
j = 0; |
511 |
for (i = 0; i < sensor_matrix_get_size(sensorMatrix); i++) |
|
541 |
//TODO: the compiler may or may not optimize this such that my comment is useless: |
|
542 |
// instead of calling sensor_matrix_get_size every iteration of the while loop and incurring |
|
543 |
// the overhead of a function call each iteration, call it only once before the loop and store |
|
544 |
// the value in a variable and check against that variable in the loop condition |
|
545 |
for (i = 0; i < sensor_matrix_get_size(); i++) |
|
512 | 546 |
{ |
513 | 547 |
if (i == source) { |
514 | 548 |
continue; |
... | ... | |
523 | 557 |
accepted = -1; |
524 | 558 |
WL_DEBUG_PRINT("Someone accepted the robot we did.\r\n"); |
525 | 559 |
} |
526 |
sensor_matrix_set_reading(sensorMatrix, source, i,
|
|
560 |
sensor_matrix_set_reading(source, i, |
|
527 | 561 |
sensorData[2 * j + 1]); |
528 |
sensor_matrix_set_in_ring(sensorMatrix, i, 1); |
|
562 |
if (!sensor_matrix_get_in_ring(i)) |
|
563 |
{ |
|
564 |
WL_DEBUG_PRINT("Robot "); |
|
565 |
WL_DEBUG_PRINT_INT(i); |
|
566 |
WL_DEBUG_PRINT(" has been added to the sensor matrix of robot "); |
|
567 |
WL_DEBUG_PRINT_INT(wl_get_xbee_id()); |
|
568 |
WL_DEBUG_PRINT(" due to a packet from robot "); |
|
569 |
WL_DEBUG_PRINT_INT(source); |
|
570 |
WL_DEBUG_PRINT(".\r\n"); |
|
571 |
} |
|
572 |
sensor_matrix_set_in_ring(i, 1); |
|
529 | 573 |
j++; |
530 | 574 |
} |
531 | 575 |
else |
532 | 576 |
{ |
533 |
if (sensor_matrix_get_in_ring(sensorMatrix, i))
|
|
577 |
if (sensor_matrix_get_in_ring(i)) |
|
534 | 578 |
{ |
535 | 579 |
WL_DEBUG_PRINT("Robot "); |
536 | 580 |
WL_DEBUG_PRINT_INT(i); |
... | ... | |
539 | 583 |
WL_DEBUG_PRINT(" due to a packet from robot "); |
540 | 584 |
WL_DEBUG_PRINT_INT(source); |
541 | 585 |
WL_DEBUG_PRINT(".\r\n"); |
542 |
sensor_matrix_set_in_ring(sensorMatrix, i, 0);
|
|
586 |
sensor_matrix_set_in_ring(i, 0); |
|
543 | 587 |
} |
544 | 588 |
|
545 | 589 |
if (i == wl_get_xbee_id() && ringState == MEMBER) |
... | ... | |
554 | 598 |
//the person who accepted us is dead... let's ask again |
555 | 599 |
if (i == acceptor) |
556 | 600 |
{ |
557 |
sensor_matrix_set_in_ring(sensorMatrix, |
|
558 |
wl_get_xbee_id(), 1); |
|
601 |
sensor_matrix_set_in_ring(wl_get_xbee_id(), 0); |
|
559 | 602 |
ringState = NONMEMBER; |
560 | 603 |
acceptor = -1; |
561 | 604 |
wl_token_ring_join(); |
562 | 605 |
} |
563 | 606 |
} |
564 | 607 |
} |
608 |
|
|
609 |
// get the next robot in the token ring |
|
610 |
i = source + 1; |
|
611 |
while (1) |
|
612 |
{ |
|
613 |
if (i == sensor_matrix_get_size()) { |
|
614 |
i = 0; |
|
615 |
} |
|
565 | 616 |
|
566 |
wl_token_next_robot = nextRobot; |
|
617 |
if (sensor_matrix_get_in_ring(i) || i == source) |
|
618 |
{ |
|
619 |
nextRobot = (char)i; |
|
620 |
break; |
|
621 |
} |
|
567 | 622 |
|
623 |
i++; |
|
624 |
} |
|
625 |
|
|
626 |
if (nextRobot != wl_get_xbee_id()) |
|
627 |
wl_token_next_robot = nextRobot; |
|
628 |
|
|
568 | 629 |
deathDelay = get_token_distance(wl_get_xbee_id(), nextRobot) * DEATH_DELAY; |
569 | 630 |
|
570 |
//we have the token |
|
571 |
if (wl_token_next_robot == wl_get_xbee_id()) { |
|
572 |
wl_token_get_token(); |
|
573 |
} |
|
631 |
if (sensor_matrix_get_joined() == 0 && ringState == JOINING) |
|
632 |
wl_send_robot_to_robot_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_PASS, NULL, 0, nextRobot, WL_TOKEN_PASS_FRAME); |
|
574 | 633 |
} |
575 | 634 |
|
576 | 635 |
/** |
... | ... | |
588 | 647 |
int count = 1; |
589 | 648 |
while (1) |
590 | 649 |
{ |
591 |
if (curr == sensor_matrix_get_size(sensorMatrix)) |
|
650 |
//TODO: the compiler may or may not optimize this such that my comment is useless: |
|
651 |
// instead of calling sensor_matrix_get_size every iteration of the while loop and incurring |
|
652 |
// the overhead of a function call each iteration, call it only once before the loop and store |
|
653 |
// the value in a variable and check against that variable in the loop condition |
|
654 |
if (curr == sensor_matrix_get_size()) |
|
592 | 655 |
curr = 0; |
593 | 656 |
if (curr == robot2) |
594 | 657 |
break; |
595 |
if (sensor_matrix_get_in_ring(sensorMatrix, curr))
|
|
658 |
if (sensor_matrix_get_in_ring(curr)) |
|
596 | 659 |
count++; |
597 | 660 |
curr++; |
598 | 661 |
} |
... | ... | |
604 | 667 |
**/ |
605 | 668 |
static int wl_token_pass_token() |
606 | 669 |
{ |
607 |
char nextRobot; |
|
670 |
char nextRobot = 0xFF;
|
|
608 | 671 |
int i = wl_get_xbee_id() + 1; |
672 |
char buf[2 * sensor_matrix_get_size()]; |
|
609 | 673 |
if (accepted == -1) |
610 | 674 |
{ |
611 | 675 |
while (1) |
612 | 676 |
{ |
613 |
if (i == sensor_matrix_get_size(sensorMatrix)) { |
|
677 |
//TODO: the compiler may or may not optimize this such that my comment is useless: |
|
678 |
// instead of calling sensor_matrix_get_size every iteration of the while loop and incurring |
|
679 |
// the overhead of a function call each iteration, call it only once before the loop and store |
|
680 |
// the value in a variable and check against that variable in the loop condition |
|
681 |
if (i == sensor_matrix_get_size()) { |
|
614 | 682 |
i = 0; |
615 | 683 |
} |
616 | 684 |
|
617 |
if (sensor_matrix_get_in_ring(sensorMatrix, i))
|
|
685 |
if (sensor_matrix_get_in_ring(i)) |
|
618 | 686 |
{ |
619 | 687 |
nextRobot = (char)i; |
620 | 688 |
break; |
... | ... | |
627 | 695 |
{ |
628 | 696 |
WL_DEBUG_PRINT("Accepting new robot, sending it the token.\r\n"); |
629 | 697 |
//add a new robot to the token ring |
630 |
sensor_matrix_set_in_ring(sensorMatrix, accepted, 1);
|
|
698 |
sensor_matrix_set_in_ring(accepted, 1); |
|
631 | 699 |
nextRobot = accepted; |
632 | 700 |
accepted = -1; |
633 | 701 |
} |
634 | 702 |
|
635 |
//we don't include ourself |
|
636 |
int packetSize = 1 + 2 * (sensor_matrix_get_joined(sensorMatrix) - 1); |
|
637 |
char* buf = (char*)malloc(packetSize * sizeof(char)); |
|
638 |
if (!buf) |
|
639 |
{ |
|
640 |
WL_DEBUG_PRINT_INT(packetSize); |
|
641 |
WL_DEBUG_PRINT("Out of memory - pass token.\r\n"); |
|
642 |
free(buf); |
|
643 |
return -1; |
|
644 |
} |
|
645 |
buf[0] = nextRobot; |
|
646 |
|
|
647 | 703 |
int j = 0; |
648 |
for (i = 0; i < sensor_matrix_get_size(sensorMatrix); i++) { |
|
649 |
if (sensor_matrix_get_in_ring(sensorMatrix, i) && i != wl_get_xbee_id()) |
|
704 |
//TODO: the compiler may or may not optimize this such that my comment is useless: |
|
705 |
// instead of calling sensor_matrix_get_size every iteration of the while loop and incurring |
|
706 |
// the overhead of a function call each iteration, call it only once before the loop and store |
|
707 |
// the value in a variable and check against that variable in the loop condition |
|
708 |
for (i = 0; i < sensor_matrix_get_size(); i++) { |
|
709 |
if (sensor_matrix_get_in_ring(i) && i != wl_get_xbee_id()) |
|
650 | 710 |
{ |
651 |
buf[2*j + 1] = i;
|
|
652 |
buf[2*j + 2] = sensor_matrix_get_reading(sensorMatrix, wl_get_xbee_id(), i);
|
|
711 |
buf[2*j] = i; |
|
712 |
buf[2*j + 1] = sensor_matrix_get_reading(wl_get_xbee_id(), i);
|
|
653 | 713 |
j++; |
654 | 714 |
} |
655 | 715 |
} |
656 | 716 |
|
717 |
int packetSize = 2 * j * sizeof(char); |
|
657 | 718 |
WL_DEBUG_PRINT("Passing the token to robot "); |
658 |
WL_DEBUG_PRINT_INT(buf[0]);
|
|
719 |
WL_DEBUG_PRINT_INT(nextRobot);
|
|
659 | 720 |
WL_DEBUG_PRINT(".\r\n"); |
660 |
if (wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_PASS, buf, packetSize, 3) != 0) { |
|
661 |
free(buf); |
|
721 |
if (wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_SENSOR_MATRIX, buf, packetSize, 0) != 0) |
|
662 | 722 |
return -1; |
663 |
} |
|
723 |
if (wl_send_robot_to_robot_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_PASS, NULL, 0, nextRobot, WL_TOKEN_PASS_FRAME)) |
|
724 |
return -1; |
|
664 | 725 |
|
665 | 726 |
wl_token_next_robot = nextRobot; |
666 | 727 |
deathDelay = DEATH_DELAY; |
667 |
free(buf); |
|
668 | 728 |
|
669 | 729 |
return 0; |
670 | 730 |
} |
... | ... | |
684 | 744 |
|
685 | 745 |
bom_on_count = 0; |
686 | 746 |
|
687 |
sensor_matrix_set_reading(sensorMatrix, wl_get_xbee_id(),
|
|
747 |
sensor_matrix_set_reading(wl_get_xbee_id(), |
|
688 | 748 |
source, get_max_bom_function()); |
689 | 749 |
} |
690 | 750 |
|
... | ... | |
700 | 760 |
WL_DEBUG_PRINT("We have the token.\r\n"); |
701 | 761 |
if (ringState == ACCEPTED) |
702 | 762 |
{ |
703 |
sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 1);
|
|
763 |
sensor_matrix_set_in_ring(wl_get_xbee_id(), 1); |
|
704 | 764 |
WL_DEBUG_PRINT("Now a member of the token ring.\r\n"); |
705 | 765 |
ringState = MEMBER; |
706 | 766 |
joinDelay = -1; |
... | ... | |
708 | 768 |
|
709 | 769 |
if (ringState == LEAVING || ringState == NONMEMBER) |
710 | 770 |
{ |
711 |
sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 0);
|
|
771 |
sensor_matrix_set_in_ring(wl_get_xbee_id(), 0); |
|
712 | 772 |
if (ringState == NONMEMBER) |
713 | 773 |
{ |
714 | 774 |
WL_DEBUG_PRINT("We should have left the token ring, but didn't.\r\n"); |
... | ... | |
725 | 785 |
#endif |
726 | 786 |
bom_off_function(); |
727 | 787 |
|
728 |
if (!sensor_matrix_get_in_ring(sensorMatrix, wl_get_xbee_id()))
|
|
788 |
if (!sensor_matrix_get_in_ring(wl_get_xbee_id())) |
|
729 | 789 |
{ |
730 | 790 |
WL_DEBUG_PRINT("Removed from sensor matrix while flashing BOM.\r\n"); |
731 | 791 |
return; |
... | ... | |
763 | 823 |
while (1) |
764 | 824 |
{ |
765 | 825 |
if (i < 0) |
766 |
i = sensor_matrix_get_size(sensorMatrix) - 1; |
|
826 |
i = sensor_matrix_get_size() - 1; |
|
827 |
|
|
767 | 828 |
//we must send a join acceptance |
768 | 829 |
if (i == wl_get_xbee_id()) |
769 | 830 |
break; |
770 | 831 |
|
771 | 832 |
//another robot will handle it |
772 |
if (sensor_matrix_get_in_ring(sensorMatrix, i))
|
|
833 |
if (sensor_matrix_get_in_ring(i)) |
|
773 | 834 |
return; |
835 |
|
|
774 | 836 |
i--; |
775 | 837 |
} |
776 | 838 |
|
... | ... | |
783 | 845 |
WL_DEBUG_PRINT(" into the token ring.\r\n"); |
784 | 846 |
|
785 | 847 |
// the token ring has not started yet |
786 |
if (sensor_matrix_get_joined(sensorMatrix) == 1)
|
|
848 |
if (sensor_matrix_get_joined() == 1) |
|
787 | 849 |
wl_token_pass_token(); |
788 | 850 |
} |
789 | 851 |
|
... | ... | |
804 | 866 |
acceptor = source; |
805 | 867 |
|
806 | 868 |
//add ourselves to the token ring |
807 |
sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 1);
|
|
869 |
sensor_matrix_set_in_ring(wl_get_xbee_id(), 1); |
|
808 | 870 |
} |
branches/autonomous_recharging/code/projects/libwireless/lib/sensor_matrix.h | ||
---|---|---|
46 | 46 |
* @{ |
47 | 47 |
**/ |
48 | 48 |
|
49 |
#define MAXIMUM_XBEE_ID 0x10 |
|
50 |
#define READING_UNKNOWN 0xFF |
|
51 |
|
|
49 | 52 |
/** |
50 | 53 |
* @struct SensorMatrix |
51 | 54 |
* |
52 | 55 |
* A sensor matrix. |
53 | 56 |
**/ |
57 |
//TODO: the order of member variables in this struct should be changed in case the compile packs the struct |
|
58 |
// In order to achieve the best packing, the variables should be listed in order of decreasing memory size. |
|
59 |
// Thus, pointers should be first, followed by int, followed by char. |
|
54 | 60 |
typedef struct |
55 | 61 |
{ |
56 | 62 |
/** |
63 |
* The number of robots in the token ring. |
|
64 |
**/ |
|
65 |
int numJoined; |
|
66 |
/** |
|
57 | 67 |
* The matrix. Each row represents the readings of one |
58 | 68 |
* robot. |
59 | 69 |
**/ |
60 |
int** matrix; |
|
61 |
|
|
70 |
unsigned char matrix[MAXIMUM_XBEE_ID][MAXIMUM_XBEE_ID]; |
|
62 | 71 |
/** |
63 | 72 |
* The element representing a robot is true if that robot |
64 | 73 |
* is in the token ring and false otherwise. |
65 | 74 |
**/ |
66 |
char* joined; |
|
67 |
|
|
68 |
/** |
|
69 |
* The number of robots in the token ring. |
|
70 |
**/ |
|
71 |
int numJoined; |
|
72 |
|
|
73 |
/** |
|
74 |
* The size of the sensor matrix. |
|
75 |
**/ |
|
76 |
int size; |
|
75 |
unsigned char joined[MAXIMUM_XBEE_ID]; |
|
77 | 76 |
} SensorMatrix; |
78 | 77 |
|
79 | 78 |
/**@brief Create a sensor matrix **/ |
80 |
SensorMatrix* sensor_matrix_create(void); |
|
81 |
/**@brief Destroy a sensor matrix **/ |
|
82 |
void sensor_matrix_destroy(SensorMatrix* m); |
|
83 |
/**@brief Add a robot to a sensor matrix **/ |
|
84 |
void sensor_matrix_add_robot(SensorMatrix* m, int id); |
|
85 |
/**@brief Remove a robot from a sensor matrix **/ |
|
86 |
void sensor_matrix_remove_robot(SensorMatrix* m, int id); |
|
79 |
void sensor_matrix_create(void); |
|
87 | 80 |
/**@brief Set a reading in a sensor matrix **/ |
88 |
void sensor_matrix_set_reading(SensorMatrix* m, int observer, int robot, int reading);
|
|
81 |
void sensor_matrix_set_reading(int observer, int robot, int reading); |
|
89 | 82 |
/**@brief Get a reading in a sensor matrix **/ |
90 |
int sensor_matrix_get_reading(SensorMatrix* m, int observer, int robot);
|
|
83 |
int sensor_matrix_get_reading(int observer, int robot); |
|
91 | 84 |
/**@brief Set whether the robot is in the token ring **/ |
92 |
void sensor_matrix_set_in_ring(SensorMatrix* m, int robot, int in);
|
|
85 |
void sensor_matrix_set_in_ring(int robot, int in); |
|
93 | 86 |
/**@brief Get whether the robot is in the sensor ring **/ |
94 |
int sensor_matrix_get_in_ring(SensorMatrix* m, int robot); |
|
95 |
/**@brief Get the size of the sensor matrix **/ |
|
96 |
int sensor_matrix_get_size(SensorMatrix* m); |
|
87 |
int sensor_matrix_get_in_ring(int robot); |
|
97 | 88 |
/**@brief Get the number of robots which have joined the token ring **/ |
98 |
int sensor_matrix_get_joined(SensorMatrix* m); |
|
89 |
int sensor_matrix_get_joined(void); |
|
90 |
/**@brief Get the maximum size of the sensor matrix **/ |
|
91 |
int sensor_matrix_get_size(void); |
|
99 | 92 |
|
100 | 93 |
/** @} **/ //end defgroup |
101 | 94 |
|
102 | 95 |
|
103 | 96 |
#endif |
97 |
|
branches/autonomous_recharging/code/projects/libwireless/lib/wireless.h | ||
---|---|---|
40 | 40 |
/** |
41 | 41 |
* The maximum number of packet groups. |
42 | 42 |
**/ |
43 |
#define WL_MAX_PACKET_GROUPS 4 |
|
43 |
//TODO: a PacketGroupHandler is at least 10 bytes (I don't know if function pointers are 2 bytes |
|
44 |
// or 4 bytes). That means that in the c file, your array of packet groups is at least 160 bytes. |
|
45 |
// Normally that might be fine (the robot's avr chips have 4k SRAM), but austin's chip only has |
|
46 |
// 1k SRAM, so if this number can be reduced or if the size of the struct could be reduced, that would be a plus. |
|
47 |
#define WL_MAX_PACKET_GROUPS 16 |
|
44 | 48 |
|
45 | 49 |
/** |
46 | 50 |
* @defgroup wireless Wireless |
... | ... | |
72 | 76 |
* handlers for various events which can occur related to a packet |
73 | 77 |
* group. |
74 | 78 |
**/ |
79 |
//TODO: the order of member variables in this struct should be changed in case the compile packs the struct |
|
80 |
// In order to achieve the best packing, the variables should be listed in order of decreasing memory size. |
|
81 |
// Thus, pointers should be first, followed by int, followed by char. |
|
75 | 82 |
typedef struct |
76 | 83 |
{ |
77 | 84 |
/** |
85 |
* The group code for this packet group. This number |
|
86 |
* must be unique. The maximum number of packet groups |
|
87 |
* is defined by WL_MAX_PACKET_GROUPS. |
|
88 |
**/ |
|
89 |
//TODO: if this number must be less than or equal to WL_MAX_PACKET_GROUPS, don't you only need |
|
90 |
// one byte for it and it can be made an unsigned char? |
|
91 |
unsigned int groupCode; |
|
92 |
|
|
93 |
/** |
|
78 | 94 |
* Called every half second (not in interrupt, |
79 | 95 |
* but in wl_do). |
80 | 96 |
**/ |
... | ... | |
107 | 123 |
**/ |
108 | 124 |
void (*unregister) (void); |
109 | 125 |
|
110 |
/** |
|
111 |
* The group code for this packet group. This number |
|
112 |
* must be unique. The maximum number of packet groups |
|
113 |
* is defined by WL_MAX_PACKET_GROUPS. |
|
114 |
**/ |
|
115 |
unsigned int groupCode; |
|
116 |
|
|
117 | 126 |
} PacketGroupHandler; |
118 | 127 |
|
119 | 128 |
/**@brief Initialize the wireless library **/ |
branches/autonomous_recharging/code/projects/libwireless/lib/xbee.c | ||
---|---|---|
48 | 48 |
#include <serial.h> |
49 | 49 |
#include <avr/interrupt.h> |
50 | 50 |
|
51 |
#include <ctype.h> |
|
52 |
|
|
53 | 51 |
#endif |
54 | 52 |
|
55 | 53 |
#include <stdio.h> |
... | ... | |
101 | 99 |
static int xbee_send_modify_at_command(char* command, char* value); |
102 | 100 |
|
103 | 101 |
/*Global Variables*/ |
104 |
#define MAX_XBEE_FRAME_SIZE 32 |
|
105 | 102 |
|
106 |
|
|
107 | 103 |
#ifndef ROBOT |
108 | 104 |
static char* xbee_com_port = XBEE_PORT_DEFAULT; |
109 | 105 |
static int xbee_stream; |
... | ... | |
112 | 108 |
|
113 | 109 |
// TODO: is this a good size? |
114 | 110 |
#define XBEE_BUFFER_SIZE 128 |
111 |
#define PACKET_BUFFER_SIZE 108 |
|
115 | 112 |
// a buffer for data received from the XBee |
116 | 113 |
char arrival_buf[XBEE_BUFFER_SIZE]; |
117 | 114 |
// location of last unread byte in buffer |
... | ... | |
121 | 118 |
|
122 | 119 |
|
123 | 120 |
//used to store packets as they are read |
124 |
static char xbee_buf[MAX_XBEE_FRAME_SIZE];
|
|
121 |
static char xbee_buf[PACKET_BUFFER_SIZE];
|
|
125 | 122 |
static int currentBufPos = 0; |
126 | 123 |
|
127 | 124 |
//XBee status |
... | ... | |
131 | 128 |
static int xbee_pending_channel = XBEE_CHANNEL_DEFAULT; |
132 | 129 |
static volatile unsigned int xbee_address = 0; |
133 | 130 |
|
134 |
#ifndef ROBOT |
|
135 |
void printHex(char * s, int len) { |
|
136 |
int i; |
|
137 |
for (i = 0; i < len; i++) { |
|
138 |
printf("0x%x ", (int)(s[i])); |
|
139 |
} |
|
140 |
printf("\n"); |
|
141 |
} |
|
142 |
#endif |
|
143 |
|
|
144 |
|
|
145 | 131 |
/*Function Implementations*/ |
146 | 132 |
|
147 | 133 |
#ifdef ROBOT |
... | ... | |
150 | 136 |
* Interrupt for the robot. Adds bytes received from the xbee |
151 | 137 |
* to the buffer. |
152 | 138 |
**/ |
153 |
#ifdef FIREFLY |
|
154 |
SIGNAL(SIG_USART0_RECV) |
|
155 |
{ |
|
156 |
usb_puts("In USART0 interrupt\n"); |
|
157 |
char c = UDR0; |
|
158 |
arrival_buf[buffer_last] = c; |
|
159 |
int t = buffer_last + 1; |
|
160 |
if (t == XBEE_BUFFER_SIZE) |
|
161 |
t = 0; |
|
162 |
if (t == buffer_first) |
|
163 |
{ |
|
164 |
WL_DEBUG_PRINT("Out of space in buffer.\n"); |
|
165 |
} |
|
166 |
buffer_last = t; |
|
167 |
} |
|
168 |
#else |
|
169 |
#ifdef BAYBOARD |
|
139 |
#ifndef FIREFLY |
|
170 | 140 |
ISR(USART1_RX_vect) |
171 | 141 |
{ |
172 | 142 |
char c = UDR1; |
173 |
|
|
174 |
/* |
|
175 |
char buf[30]; |
|
176 |
char buf2[5]; |
|
177 |
buf2[0] = '\\'; |
|
178 |
if (c == '\b') { |
|
179 |
buf2[1] = 'b'; |
|
180 |
buf2[2] = '\0'; |
|
181 |
} |
|
182 |
else if (c == '\n') { |
|
183 |
buf2[1] = 'n'; |
|
184 |
buf2[2] = '\0'; |
|
185 |
} |
|
186 |
else if (c == '\r') { |
|
187 |
buf2[1] = 'r'; |
|
188 |
buf2[2] = '\0'; |
|
189 |
} |
|
190 |
else if (c == '\t') { |
|
191 |
buf2[1] = 't'; |
|
192 |
buf2[2] = '\0'; |
|
193 |
} |
|
194 |
else if (!isprint(c)) { |
|
195 |
sprintf(buf2, "0x%.2x", c); |
|
196 |
} |
|
197 |
else { |
|
198 |
buf2[0] = c; |
|
199 |
buf2[1] = '\0'; |
|
200 |
} |
|
201 |
sprintf(buf, "In USART1 interrupt [%s]\n", buf2); |
|
202 |
usb_puts(buf); |
|
203 |
*/ |
|
204 |
|
|
205 | 143 |
arrival_buf[buffer_last] = c; |
206 | 144 |
int t = buffer_last + 1; |
207 | 145 |
if (t == XBEE_BUFFER_SIZE) |
208 | 146 |
t = 0; |
209 | 147 |
if (t == buffer_first) |
210 |
{
|
|
211 |
WL_DEBUG_PRINT("Out of space in buffer.\n");
|
|
212 |
}
|
|
148 |
{
|
|
149 |
WL_DEBUG_PRINT("\nOut of space in buffer.\n");
|
|
150 |
}
|
|
213 | 151 |
buffer_last = t; |
214 | 152 |
} |
215 | 153 |
#else |
216 |
ISR(USART1_RX_vect)
|
|
154 |
SIGNAL(SIG_USART0_RECV)
|
|
217 | 155 |
{ |
218 |
char c = UDR1;
|
|
156 |
char c = UDR0;
|
|
219 | 157 |
arrival_buf[buffer_last] = c; |
220 | 158 |
int t = buffer_last + 1; |
221 | 159 |
if (t == XBEE_BUFFER_SIZE) |
222 | 160 |
t = 0; |
223 | 161 |
if (t == buffer_first) |
224 |
{
|
|
225 |
WL_DEBUG_PRINT("Out of space in buffer.\n");
|
|
226 |
}
|
|
162 |
{
|
|
163 |
WL_DEBUG_PRINT("Out of space in buffer.\n");
|
|
164 |
}
|
|
227 | 165 |
buffer_last = t; |
228 | 166 |
} |
229 | 167 |
#endif |
230 |
#endif |
|
231 | 168 |
|
232 | 169 |
#else |
233 | 170 |
|
... | ... | |
240 | 177 |
{ |
241 | 178 |
char c; |
242 | 179 |
while (1) |
243 |
{
|
|
244 |
if (xbee_read(&c, 1) != 0) {
|
|
245 |
fprintf(stderr, "xbee_read failed.\n");
|
|
246 |
return NULL;
|
|
247 |
}
|
|
180 |
{
|
|
181 |
if (xbee_read(&c, 1) != 0) {
|
|
182 |
WL_DEBUG_PRINT("xbee_read failed.\n");
|
|
183 |
return NULL;
|
|
184 |
}
|
|
248 | 185 |
|
249 |
//DEBUGGING PRINT |
|
250 |
//printf("interrupt: %c (%d)\n", c, (int)c); |
|
251 |
arrival_buf[buffer_last] = c; |
|
252 |
int t = buffer_last + 1; |
|
253 |
if (t == XBEE_BUFFER_SIZE) |
|
254 |
t = 0; |
|
255 |
if (t == buffer_first) |
|
256 |
{ |
|
257 |
WL_DEBUG_PRINT("Out of space in buffer.\n"); |
|
258 |
} |
|
259 |
buffer_last = t; |
|
186 |
arrival_buf[buffer_last] = c; |
|
187 |
int t = buffer_last + 1; |
|
188 |
if (t == XBEE_BUFFER_SIZE) |
|
189 |
t = 0; |
|
190 |
if (t == buffer_first) |
|
191 |
{ |
|
192 |
WL_DEBUG_PRINT("Out of space in buffer.\n"); |
|
193 |
} |
|
194 |
buffer_last = t; |
|
260 | 195 |
|
261 |
usleep(1000);
|
|
262 |
}
|
|
196 |
usleep(1000);
|
|
197 |
}
|
|
263 | 198 |
|
264 | 199 |
return NULL; |
265 | 200 |
} |
... | ... | |
271 | 206 |
**/ |
272 | 207 |
int xbee_lib_init() |
273 | 208 |
{ |
274 |
arrival_buf[0] = 'A'; |
|
275 |
arrival_buf[1] = 'A'; |
|
276 |
arrival_buf[2] = 'A'; |
|
209 |
WL_DEBUG_PRINT("in xbee_init\n"); |
|
277 | 210 |
#ifdef ROBOT |
278 | 211 |
|
279 | 212 |
//enable the receiving interrupt |
... | ... | |
281 | 214 |
UCSR0B |= _BV(RXCIE) | _BV(RXEN); |
282 | 215 |
#else |
283 | 216 |
#ifdef BAYBOARD |
284 |
UCSR1B |= _BV(RXCIE0);
|
|
217 |
UCSR1B |= _BV(RXCIE1);
|
|
285 | 218 |
#else |
286 | 219 |
UCSR1B |= _BV(RXCIE); |
287 | 220 |
#endif |
288 | 221 |
#endif |
289 | 222 |
sei(); |
290 | 223 |
#else |
291 |
printf("Connecting to port %s.\n", xbee_com_port); |
|
292 | 224 |
xbee_stream = open(xbee_com_port, O_RDWR); |
293 | 225 |
if (xbee_stream == -1/* || lockf(xbee_stream, F_TEST, 0) != 0*/) |
294 |
{ |
|
295 |
printf("Failed to open connection to XBee on port %s\r\n", xbee_com_port); |
|
296 |
return -1; |
|
297 |
} else { |
|
298 |
printf("Successfully opened connection to XBee on port %s\r\n", xbee_com_port); |
|
226 |
{ |
|
227 |
WL_DEBUG_PRINT("Failed to open connection to XBee on port "); |
|
228 |
WL_DEBUG_PRINT_INT(xbee_com_port); |
|
229 |
WL_DEBUG_PRINT(".\n"); |
|
230 |
return -1; |
|
231 |
} else { |
|
232 |
WL_DEBUG_PRINT("Successfully opened connection to XBee on port "); |
|
233 |
WL_DEBUG_PRINT_INT(xbee_com_port); |
|
234 |
WL_DEBUG_PRINT(".\n"); |
|
299 | 235 |
} |
300 | 236 |
|
301 | 237 |
// set baud rate, etc. correctly |
... | ... | |
316 | 252 |
options.c_cc[VTIME] = 50; |
317 | 253 |
|
318 | 254 |
if (tcsetattr(xbee_stream, TCSANOW, &options)) |
319 |
{ |
|
320 |
fprintf(stderr, "Error setting attributes.\n"); |
|
321 |
return -1; |
|
322 |
} else { |
|
323 |
//printf("Successfully set termios attributes.\n"); |
|
255 |
{ |
|
256 |
WL_DEBUG_PRINT("Error setting attributes.\n"); |
|
257 |
return -1; |
|
324 | 258 |
} |
325 | 259 |
|
326 |
//lockf(xbee_stream, F_LOCK, 0); |
|
327 |
|
|
328 | 260 |
xbee_listen_thread = (pthread_t*)malloc(sizeof(pthread_t)); |
329 | 261 |
if (xbee_listen_thread == NULL) |
330 |
{
|
|
331 |
fprintf(stderr, "%s: Malloc failed.\n", __FUNCTION__);
|
|
332 |
return -1;
|
|
333 |
}
|
|
262 |
{
|
|
263 |
WL_DEBUG_PRINT("Malloc failed.\n");
|
|
264 |
return -1;
|
|
265 |
}
|
|
334 | 266 |
|
335 | 267 |
int ret = pthread_create(xbee_listen_thread, NULL, listen_to_xbee, NULL); |
336 | 268 |
if (ret) |
337 |
{ |
|
338 |
fprintf(stderr, "Failed to create listener thread.\r\n"); |
|
339 |
return -1; |
|
340 |
} else { |
|
341 |
//printf("Successfully created listener thread.\n"); |
|
269 |
{ |
|
270 |
WL_DEBUG_PRINT("Failed to create listener thread.\n"); |
|
271 |
return -1; |
|
342 | 272 |
} |
343 | 273 |
#endif |
344 | 274 |
|
345 |
//DEBUGGING PRINT |
|
346 |
//printf("about to call xbee_enter_command_mode\n"); |
|
275 |
WL_DEBUG_PRINT("Entering command mode.\n"); |
|
347 | 276 |
|
348 | 277 |
if (xbee_enter_command_mode() != 0) { |
349 |
#ifndef ROBOT |
|
350 |
printf("Error returned from xbee_enter_command_mode\n"); |
|
351 |
#endif |
|
352 | 278 |
return -1; |
353 | 279 |
} |
354 | 280 |
|
355 |
//DEBUGGING PRINT |
|
356 |
//printf("about to call xbee_enter_api_mode\n"); |
|
281 |
WL_DEBUG_PRINT("Entered command mode.\n"); |
|
357 | 282 |
|
358 | 283 |
if (xbee_enter_api_mode() != 0) { |
359 |
#ifndef ROBOT |
|
360 |
printf("Error returned from xbee_enter_api_mode\n"); |
|
361 |
#endif |
|
362 | 284 |
return -1; |
363 | 285 |
} |
364 | 286 |
|
365 |
//DEBUGGING PRINT |
|
366 |
//printf("about to call xbee_exit_command_mode\n"); |
|
287 |
WL_DEBUG_PRINT("Entered api mode.\n"); |
|
367 | 288 |
|
368 | 289 |
if (xbee_exit_command_mode() != 0) { |
369 |
#ifndef ROBOT |
|
370 |
printf("Error returned from xbee_exit_command_mode\n"); |
|
371 |
#endif |
|
372 | 290 |
return -1; |
373 | 291 |
} |
374 | 292 |
|
375 |
//DEBUGGING PRINT |
|
376 |
//printf("about to call xbee_send_read_at_command\n"); |
|
293 |
WL_DEBUG_PRINT("Left command mode.\n"); |
|
377 | 294 |
|
378 | 295 |
if (xbee_send_read_at_command("MY")) { |
379 |
#ifndef ROBOT |
|
380 |
printf("Error returned from xbee_send_read_at_command\n"); |
|
381 |
#endif |
|
382 | 296 |
return -1; |
383 | 297 |
} |
298 |
WL_DEBUG_PRINT("Getting ATMY address.\n"); |
|
384 | 299 |
|
385 | 300 |
#ifndef ROBOT |
386 |
//printf("About to enter while loop to get xbee_address.\n"); |
|
387 | 301 |
int i; |
388 | 302 |
for (i = 0; xbee_address == 0 && i < XBEE_GET_PACKET_TIMEOUT; i++) { |
389 | 303 |
ret = xbee_get_packet(NULL); |
... | ... | |
391 | 305 |
usleep(1000); |
392 | 306 |
|
393 | 307 |
if (ret == -1) { |
394 |
//printf("xbee_get_packet(NULL) failed.\n");
|
|
395 |
return -1;
|
|
308 |
WL_DEBUG_PRINT("xbee_get_packet(NULL) failed.\n");
|
|
309 |
return -1;
|
|
396 | 310 |
} |
397 | 311 |
} |
398 |
|
|
399 |
// printf("After exiting while loop to get xbee_address.\n"); |
|
400 | 312 |
#else |
401 | 313 |
//wait to return until the address is set |
314 |
//TODO: this shouldn't wait indefinitely. There should be some sort of reasonable timeout |
|
315 |
// so if the address is never set right, an error can be returned instead of having the |
|
316 |
// robot hang forever |
|
402 | 317 |
while (xbee_address == 0) { |
403 | 318 |
xbee_get_packet(NULL); |
404 | 319 |
} |
405 | 320 |
#endif |
321 |
WL_DEBUG_PRINT("Got ATMY address.\n"); |
|
406 | 322 |
|
407 | 323 |
#ifndef ROBOT |
408 | 324 |
if (i == XBEE_GET_PACKET_TIMEOUT) { // We timed-out. |
409 | 325 |
|
410 |
printf("xbee_get_packet timed out.\n");
|
|
326 |
WL_DEBUG_PRINT("xbee_get_packet timed out.\n");
|
|
411 | 327 |
return -1; |
412 | 328 |
} else { |
413 | 329 |
return 0; |
... | ... | |
423 | 339 |
**/ |
424 | 340 |
void xbee_terminate() |
425 | 341 |
{ |
426 |
#ifndef ROBOT |
|
342 |
#ifndef ROBOT
|
|
427 | 343 |
pthread_cancel(*xbee_listen_thread); |
428 | 344 |
free(xbee_listen_thread); |
429 | 345 |
lockf(xbee_stream, F_ULOCK, 0); |
430 | 346 |
close(xbee_stream); |
431 |
#endif |
|
347 |
#endif
|
|
432 | 348 |
} |
433 | 349 |
|
434 | 350 |
/** |
... | ... | |
448 | 364 |
return 0; |
449 | 365 |
|
450 | 366 |
#else |
451 |
//DEBUGGING PRINT |
|
452 |
//printf("in xbee_send "); |
|
453 |
//printHex(buf, size); |
|
454 | 367 |
|
455 | 368 |
int ret = write(xbee_stream, buf, size); |
456 | 369 |
//success |
457 | 370 |
if (ret == size) |
458 | 371 |
return 0; |
459 | 372 |
if (ret == -1) |
460 |
{
|
|
461 |
//interrupted by system signal, probably timer interrupt.
|
|
462 |
//just try again
|
|
463 |
if (errno == 4)
|
|
464 |
{
|
|
465 |
return xbee_send(buf, size);
|
|
466 |
}
|
|
467 |
printf("Failed to write to xbee, error %i.\r\n", errno);
|
|
468 |
return -1;
|
|
469 |
}
|
|
373 |
{
|
|
374 |
//interrupted by system signal, probably timer interrupt.
|
|
375 |
//just try again
|
|
376 |
if (errno == 4)
|
|
377 |
{
|
|
378 |
return xbee_send(buf, size);
|
|
379 |
}
|
|
380 |
WL_DEBUG_PRINT("Failed to write to xbee\r\n");
|
|
381 |
return -1;
|
|
382 |
}
|
|
470 | 383 |
|
471 | 384 |
//write was interrupted after writing ret bytes |
472 | 385 |
return xbee_send(buf + ret, size - ret); |
... | ... | |
478 | 391 |
* |
479 | 392 |
* @param c the string to send to the XBEE |
480 | 393 |
**/ |
394 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
395 |
// it reduces code size or not should be done to be sure. |
|
481 | 396 |
static int xbee_send_string(char* c) |
482 | 397 |
{ |
483 | 398 |
return xbee_send(c, strlen(c)); |
... | ... | |
487 | 402 |
static int xbee_read(char* buf, int size) |
488 | 403 |
{ |
489 | 404 |
if (read(xbee_stream, buf, size) == -1) { |
490 |
printf("Failed to read from xbee.\r\n");
|
|
405 |
WL_DEBUG_PRINT("Failed to read from xbee.\r\n");
|
|
491 | 406 |
return -1; |
492 | 407 |
} |
493 | 408 |
|
... | ... | |
504 | 419 |
return -1; |
505 | 420 |
} |
506 | 421 |
|
507 |
#ifndef ROBOT |
|
508 |
// printf("In xbee_enter_command_mode about to call xbee_wait_for_ok()\n"); |
|
509 |
#endif |
|
510 |
|
|
511 | 422 |
if (xbee_wait_for_ok() != 0) { |
512 |
#ifndef ROBOT |
|
513 |
printf("xbee_wait_for_ok failed.\n"); |
|
514 |
#endif |
|
515 | 423 |
return -1; |
516 |
} else {
|
|
424 |
} |
|
517 | 425 |
return 0; |
518 |
} |
|
519 | 426 |
} |
520 | 427 |
|
521 | 428 |
/** |
... | ... | |
546 | 453 |
} |
547 | 454 |
|
548 | 455 |
/** |
549 |
* Exit API mode. (warning - does not check for response) |
|
550 |
**/ |
|
551 |
static int xbee_exit_api_mode() |
|
552 |
{ |
|
553 |
return xbee_send_string("ATAP 0\r"); |
|
554 |
} |
|
555 |
|
|
556 |
/** |
|
557 | 456 |
* Wait until the string "OK\r" is received from the XBee. |
558 | 457 |
**/ |
458 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
459 |
// it reduces code size or not should be done to be sure. |
|
559 | 460 |
static int xbee_wait_for_ok() |
560 | 461 |
{ |
561 |
//DEBUGGING PRINT |
|
562 |
//printf("\tin xbee_wait_for_ok\n"); |
|
563 | 462 |
return xbee_wait_for_string("OK\r", 3); |
564 | 463 |
} |
565 | 464 |
|
... | ... | |
572 | 471 |
**/ |
573 | 472 |
static int xbee_wait_for_string(char* s, int len) |
574 | 473 |
{ |
575 |
//DEBUGGING PRINT |
|
576 |
//printf("\t in xbee_wait_for_string\n"); |
|
577 |
|
|
578 |
#ifndef ROBOT |
|
579 |
//printf("In xbee_wait_for_string.\n"); |
|
580 |
#endif |
|
581 |
|
|
582 | 474 |
char* curr = s; |
583 | 475 |
while (curr - s < len) { |
584 | 476 |
// check if buffer is empty |
585 | 477 |
if (buffer_last != buffer_first) { |
586 |
#ifdef ROBOT |
|
587 |
cli(); |
|
588 |
#endif |
|
589 | 478 |
char c = arrival_buf[buffer_first++]; |
479 |
usb_putc(c); |
|
480 |
usb_putc('\n'); |
|
590 | 481 |
if (buffer_first == XBEE_BUFFER_SIZE) { |
591 | 482 |
buffer_first = 0; |
592 | 483 |
} |
593 |
#ifdef ROBOT |
|
594 |
sei(); |
|
595 |
#endif |
|
596 |
//DEBUGGING PRINT |
|
597 |
//printf("\t\t c is %c (%d)\n", c, (int)c); |
|
598 | 484 |
|
599 | 485 |
if (c == *curr) { |
600 | 486 |
curr++; |
... | ... | |
667 | 553 |
**/ |
668 | 554 |
static int xbee_send_frame(char* buf, int len) |
669 | 555 |
{ |
670 |
//printf("in %s and len is %d\n", __FUNCTION__, len); |
|
671 |
|
|
672 | 556 |
char prefix[3]; |
673 | 557 |
prefix[0] = XBEE_FRAME_START; |
674 | 558 |
prefix[1] = (len & 0xFF00) >> 8; |
... | ... | |
697 | 581 |
* use ID to read the PAN ID and MY to return the XBee ID. |
698 | 582 |
* See the XBee reference guide for a complete listing. |
699 | 583 |
**/ |
584 |
//TODO: this function is so simple, it *may* be beneficial to inline this function. testing of if |
|
585 |
// it reduces code size or not should be done to be sure. |
|
700 | 586 |
static int xbee_send_read_at_command(char* command) |
701 | 587 |
{ |
702 | 588 |
return xbee_send_modify_at_command(command, NULL); |
... | ... | |
711 | 597 |
**/ |
712 | 598 |
static int xbee_send_modify_at_command(char* command, char* value) |
713 | 599 |
{ |
714 |
//printf("in %s with command %s and value %s\n", __FUNCTION__, command, value); |
|
715 |
|
|
716 | 600 |
char buf[16]; |
717 | 601 |
int i; |
718 | 602 |
|
... | ... | |
722 | 606 |
buf[3] = command[1]; |
723 | 607 |
int valueLen = 0; |
724 | 608 |
if (value != NULL) |
725 |
{
|
|
726 |
valueLen = strlen(value);
|
|
727 |
if (valueLen > 8)
|
|
728 |
{
|
|
729 |
WL_DEBUG_PRINT("AT Command too large.\r\n");
|
|
730 |
return -1;
|
|
731 |
}
|
|
609 |
{
|
|
610 |
valueLen = strlen(value);
|
|
611 |
if (valueLen > 8)
|
|
612 |
{
|
|
613 |
WL_DEBUG_PRINT("AT Command too large.\r\n");
|
|
614 |
return -1;
|
|
615 |
}
|
|
732 | 616 |
|
733 |
for (i = 0; i < valueLen; i++) {
|
|
734 |
buf[4 + i] = value[i];
|
|
735 |
}
|
|
736 |
}
|
|
617 |
for (i = 0; i < valueLen; i++) {
|
|
618 |
buf[4 + i] = value[i];
|
|
619 |
}
|
|
620 |
}
|
|
737 | 621 |
|
738 | 622 |
return xbee_send_frame(buf, 4 + valueLen); |
739 | 623 |
} |
... | ... | |
765 | 649 |
unsigned char checksum = 0; |
766 | 650 |
|
767 | 651 |
if (len > 100) |
768 |
{
|
|
769 |
WL_DEBUG_PRINT("Packet is too large.\r\n");
|
|
770 |
return -1;
|
|
771 |
}
|
|
652 |
{
|
|
653 |
WL_DEBUG_PRINT("Packet is too large.\r\n");
|
|
654 |
return -1;
|
|
655 |
}
|
|
772 | 656 |
|
773 | 657 |
//data for sending request |
774 | 658 |
buf[0] = XBEE_FRAME_TX_REQUEST_16; |
... | ... | |
845 | 729 |
{ |
846 | 730 |
//start reading a packet with XBEE_FRAME_START |
847 | 731 |
if (currentBufPos == 0) |
848 |
{ |
|
849 |
#ifdef ROBOT |
|
850 |
cli(); |
|
851 |
#endif |
|
852 |
do |
|
853 |
{ |
|
854 |
if (buffer_first == XBEE_BUFFER_SIZE) |
|
855 |
buffer_first = 0; |
|
856 |
// check if buffer is empty |
|
857 |
if (buffer_first == buffer_last) { |
|
858 |
#ifdef ROBOT |
|
859 |
sei(); |
|
860 |
#endif |
|
861 |
return 0; |
|
862 |
} |
|
863 |
} while (arrival_buf[buffer_first++] != XBEE_FRAME_START); |
|
732 |
{ |
|
733 |
do |
|
734 |
{ |
|
735 |
if (buffer_first == XBEE_BUFFER_SIZE) |
|
736 |
buffer_first = 0; |
|
737 |
// check if buffer is empty |
|
738 |
if (buffer_first == buffer_last) { |
|
739 |
return 0; |
|
740 |
} |
|
741 |
} while (arrival_buf[buffer_first++] != XBEE_FRAME_START); |
|
864 | 742 |
|
865 |
if (buffer_first == XBEE_BUFFER_SIZE) { |
|
866 |
buffer_first = 0; |
|
867 |
} |
|
868 |
#ifdef ROBOT |
|
869 |
sei(); |
|
870 |
#endif |
|
871 |
xbee_buf[0] = XBEE_FRAME_START; |
|
872 |
currentBufPos++; |
|
873 |
} |
|
743 |
if (buffer_first == XBEE_BUFFER_SIZE) { |
|
744 |
buffer_first = 0; |
|
745 |
} |
|
746 |
xbee_buf[0] = XBEE_FRAME_START; |
|
747 |
currentBufPos++; |
|
748 |
} |
|
874 | 749 |
|
875 | 750 |
int len = -1; |
876 | 751 |
if (currentBufPos >= 3) { |
... | ... | |
878 | 753 |
} |
879 | 754 |
|
880 | 755 |
while (len == -1 //packet length has not been read yet |
881 |
|| currentBufPos < len + 4) |
|
882 |
{ |
|
883 |
if (currentBufPos == 3) |
|
884 |
{ |
|
885 |
len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8); |
|
886 |
if (len > 120) |
|
887 |
{ |
|
888 |
WL_DEBUG_PRINT("Packet too large. Probably error in XBee transmission.\n"); |
|
889 |
currentBufPos = 0; |
|
890 |
return -1; |
|
891 |
} |
|
892 |
} |
|
756 |
|| currentBufPos < len + 4) |
|
757 |
{ |
|
758 |
if (currentBufPos == 3) |
|
759 |
{ |
|
760 |
len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8); |
|
761 |
if (len > 120) |
|
762 |
{ |
|
763 |
WL_DEBUG_PRINT("Packet too large. Probably error in XBee transmission.\n"); |
|
764 |
currentBufPos = 0; |
Also available in: Unified diff