Revision 409
reduced colonet server cpu usage to near zero
xbee.c | ||
---|---|---|
1 | 1 |
/** |
2 | 2 |
* Copyright (c) 2007 Colony Project |
3 |
*
|
|
3 |
* |
|
4 | 4 |
* Permission is hereby granted, free of charge, to any person |
5 | 5 |
* obtaining a copy of this software and associated documentation |
6 | 6 |
* files (the "Software"), to deal in the Software without |
... | ... | |
9 | 9 |
* copies of the Software, and to permit persons to whom the |
10 | 10 |
* Software is furnished to do so, subject to the following |
11 | 11 |
* conditions: |
12 |
*
|
|
12 |
* |
|
13 | 13 |
* The above copyright notice and this permission notice shall be |
14 | 14 |
* included in all copies or substantial portions of the Software. |
15 |
*
|
|
15 |
* |
|
16 | 16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
17 | 17 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
18 | 18 |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
... | ... | |
79 | 79 |
/*Command Mode Functions |
80 | 80 |
* Called during initialization. |
81 | 81 |
*/ |
82 |
void xbee_enter_command_mode(void); |
|
83 |
void xbee_exit_command_mode(void); |
|
84 |
void xbee_enter_api_mode(void); |
|
85 |
void xbee_exit_api_mode(void); |
|
86 |
void xbee_wait_for_string(char* s, int len); |
|
87 |
void xbee_wait_for_ok(void); |
|
82 |
static void xbee_enter_command_mode(void);
|
|
83 |
static void xbee_exit_command_mode(void);
|
|
84 |
static void xbee_enter_api_mode(void);
|
|
85 |
static void xbee_exit_api_mode(void);
|
|
86 |
static void xbee_wait_for_string(char* s, int len);
|
|
87 |
static void xbee_wait_for_ok(void);
|
|
88 | 88 |
|
89 | 89 |
/*API Mode Functions*/ |
90 | 90 |
|
... | ... | |
184 | 184 |
WL_DEBUG_PRINT("Out of space in buffer.\n"); |
185 | 185 |
} |
186 | 186 |
buffer_last = t; |
187 |
|
|
188 |
usleep(1000); |
|
187 | 189 |
} |
188 | 190 |
return 0; |
189 | 191 |
} |
... | ... | |
215 | 217 |
printf("Failed to open connection to XBee on port %s\r\n", xbee_com_port); |
216 | 218 |
return -1; |
217 | 219 |
} |
218 |
|
|
220 |
|
|
219 | 221 |
// set baud rate, etc. correctly |
220 | 222 |
struct termios options; |
221 | 223 |
|
... | ... | |
240 | 242 |
} |
241 | 243 |
|
242 | 244 |
//lockf(xbee_stream, F_LOCK, 0); |
243 |
|
|
244 |
xbee_listen_thread = |
|
245 |
(pthread_t*)malloc(sizeof(pthread_t)); |
|
245 |
|
|
246 |
xbee_listen_thread = (pthread_t*)malloc(sizeof(pthread_t)); |
|
246 | 247 |
if (xbee_listen_thread == NULL) |
247 | 248 |
{ |
248 | 249 |
fprintf(stderr, "%s: Malloc failed.\n", __FUNCTION__); |
249 | 250 |
return -1; |
250 | 251 |
} |
251 |
|
|
252 |
int ret = pthread_create(xbee_listen_thread, NULL, |
|
253 |
listen_to_xbee, NULL); |
|
252 |
|
|
253 |
int ret = pthread_create(xbee_listen_thread, NULL, listen_to_xbee, NULL); |
|
254 | 254 |
if (ret) |
255 | 255 |
{ |
256 | 256 |
fprintf(stderr, "Failed to create listener thread.\r\n"); |
257 | 257 |
return -1; |
258 | 258 |
} |
259 |
|
|
259 |
|
|
260 | 260 |
#endif |
261 | 261 |
xbee_enter_command_mode(); |
262 | 262 |
xbee_enter_api_mode(); |
263 | 263 |
xbee_exit_command_mode(); |
264 | 264 |
xbee_send_read_at_command("MY"); |
265 |
|
|
265 |
|
|
266 | 266 |
//wait to return until the address is set |
267 | 267 |
while (xbee_address == 0) xbee_get_packet(NULL); |
268 | 268 |
|
... | ... | |
286 | 286 |
|
287 | 287 |
/** |
288 | 288 |
* Send a buffer buf of size bytes to the XBee. |
289 |
*
|
|
289 |
* |
|
290 | 290 |
* @param buf the buffer of data to send |
291 | 291 |
* @param size the number of bytes to send |
292 | 292 |
**/ |
... | ... | |
341 | 341 |
/** |
342 | 342 |
* Enter into command mode. |
343 | 343 |
**/ |
344 |
void xbee_enter_command_mode() |
|
344 |
static void xbee_enter_command_mode()
|
|
345 | 345 |
{ |
346 | 346 |
xbee_send_string("+++"); |
347 | 347 |
xbee_wait_for_ok(); |
... | ... | |
350 | 350 |
/** |
351 | 351 |
* Exit from command mode. |
352 | 352 |
**/ |
353 |
void xbee_exit_command_mode() |
|
353 |
static void xbee_exit_command_mode()
|
|
354 | 354 |
{ |
355 | 355 |
xbee_send_string("ATCN\r"); |
356 | 356 |
xbee_wait_for_ok(); |
... | ... | |
359 | 359 |
/** |
360 | 360 |
* Enter API mode. |
361 | 361 |
**/ |
362 |
void xbee_enter_api_mode() |
|
362 |
static void xbee_enter_api_mode()
|
|
363 | 363 |
{ |
364 | 364 |
xbee_send_string("ATAP 1\r"); |
365 | 365 |
xbee_wait_for_ok(); |
... | ... | |
368 | 368 |
/** |
369 | 369 |
* Exit API mode. (warning - does not check for response) |
370 | 370 |
**/ |
371 |
void xbee_exit_api_mode() |
|
371 |
static void xbee_exit_api_mode()
|
|
372 | 372 |
{ |
373 | 373 |
xbee_send_string("ATAP 0\r"); |
374 | 374 |
} |
... | ... | |
376 | 376 |
/** |
377 | 377 |
* Wait until the string "OK\r" is received from the XBee. |
378 | 378 |
**/ |
379 |
void xbee_wait_for_ok() |
|
379 |
static void xbee_wait_for_ok()
|
|
380 | 380 |
{ |
381 | 381 |
xbee_wait_for_string("OK\r", 3); |
382 | 382 |
} |
... | ... | |
388 | 388 |
* @param s the string to receive |
389 | 389 |
* @param len the length of the string |
390 | 390 |
**/ |
391 |
void xbee_wait_for_string(char* s, int len) |
|
391 |
static void xbee_wait_for_string(char* s, int len)
|
|
392 | 392 |
{ |
393 |
char* curr = s; |
|
394 |
while (curr - s < len) |
|
395 |
{ |
|
396 |
// check if buffer is empty |
|
397 |
if (buffer_last == buffer_first) |
|
398 |
continue; |
|
399 |
char c = arrival_buf[buffer_first++]; |
|
400 |
if (buffer_first == XBEE_BUFFER_SIZE) |
|
401 |
buffer_first = 0; |
|
402 |
if (c == *curr) |
|
403 |
curr++; |
|
404 |
else |
|
405 |
curr = s; |
|
406 |
} |
|
393 |
char* curr = s; |
|
394 |
while (curr - s < len) { |
|
395 |
// check if buffer is empty |
|
396 |
if (buffer_last != buffer_first) { |
|
397 |
char c = arrival_buf[buffer_first++]; |
|
398 |
if (buffer_first == XBEE_BUFFER_SIZE) { |
|
399 |
buffer_first = 0; |
|
400 |
} |
|
401 |
|
|
402 |
if (c == *curr) { |
|
403 |
curr++; |
|
404 |
} else { |
|
405 |
curr = s; |
|
406 |
} |
|
407 |
} |
|
408 |
|
|
409 |
usleep(1000); |
|
410 |
} |
|
407 | 411 |
} |
408 | 412 |
|
409 | 413 |
/** |
... | ... | |
490 | 494 |
{ |
491 | 495 |
char buf[16]; |
492 | 496 |
int i; |
493 |
|
|
497 |
|
|
494 | 498 |
buf[0] = XBEE_FRAME_AT_COMMAND; |
495 | 499 |
buf[1] = 1; |
496 | 500 |
buf[2] = command[0]; |
... | ... | |
512 | 516 |
|
513 | 517 |
/** |
514 | 518 |
* Send the specified packet. |
515 |
*
|
|
519 |
* |
|
516 | 520 |
* @param packet the packet data to send |
517 | 521 |
* @param len the number of bytes in the packet |
518 |
*
|
|
522 |
* |
|
519 | 523 |
* @param dest the ID of the XBee to send the packet to, |
520 | 524 |
* or XBEE_BROADCAST to send the message to all robots |
521 | 525 |
* in the PAN. |
522 |
*
|
|
526 |
* |
|
523 | 527 |
* @param options a combination of the flags |
524 |
* XBEE_OPTIONS_NONE, XBEE_OPTIONS_DISABLE_RESPONSE and
|
|
528 |
* XBEE_OPTIONS_NONE, XBEE_OPTIONS_DISABLE_RESPONSE and |
|
525 | 529 |
* XBEE_OPTIONS_BROADCAST_ALL_PANS |
526 | 530 |
* |
527 | 531 |
* @param frame the frame number to associate this packet |
... | ... | |
591 | 595 |
* |
592 | 596 |
* The first byte of the packet will be either |
593 | 597 |
* XBEE_TX_STATUS or XBEE_RX to indicated |
594 |
* a response to a sent message or a received message,
|
|
598 |
* a response to a sent message or a received message, |
|
595 | 599 |
* respectively.<br><br> |
596 | 600 |
* |
597 | 601 |
* For a status response packet:<br> |
598 | 602 |
* The first byte will be XBEE_TX_STATUS.<br> |
599 | 603 |
* The second byte will be the frame number.<br> |
600 | 604 |
* The third byte will be the result. 0 indicates success, |
601 |
* and nonzero indicates that an error ocurred in
|
|
605 |
* and nonzero indicates that an error ocurred in |
|
602 | 606 |
* transmitting the packet.<br><br> |
603 | 607 |
* |
604 | 608 |
* For a received packet:<br> |
... | ... | |
608 | 612 |
* The fourth byte is the signal strength.<br> |
609 | 613 |
* The fifth byte is 1 if the packet were sent to |
610 | 614 |
* a specific address, and 2 if it is a broadcast packet.<br><br> |
611 |
*
|
|
615 |
* |
|
612 | 616 |
* @param dest set to the packet data |
613 | 617 |
* @return the length of the packet, or -1 if no packet |
614 | 618 |
* is available |
... | ... | |
636 | 640 |
int len = -1; |
637 | 641 |
if (currentBufPos >= 3) |
638 | 642 |
len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8); |
639 |
|
|
643 |
|
|
640 | 644 |
while (len == -1 //packet length has not been read yet |
641 | 645 |
|| currentBufPos < len + 4) |
642 | 646 |
{ |
... | ... | |
657 | 661 |
if (buffer_first == XBEE_BUFFER_SIZE) |
658 | 662 |
buffer_first = 0; |
659 | 663 |
} |
660 |
|
|
664 |
|
|
661 | 665 |
currentBufPos = 0; |
662 |
|
|
666 |
|
|
663 | 667 |
if (!xbee_verify_checksum(xbee_buf, len + 4)) |
664 | 668 |
{ |
665 | 669 |
WL_DEBUG_PRINT("XBee checksum failed.\r\n"); |
... | ... | |
669 | 673 |
//we will take care of the packet |
670 | 674 |
if (xbee_handle_packet(xbee_buf + 3, len)) |
671 | 675 |
return -1; |
672 |
|
|
676 |
|
|
673 | 677 |
if (dest == NULL) |
674 | 678 |
return -1; |
675 |
|
|
679 |
|
|
676 | 680 |
int i; |
677 | 681 |
for (i = 3; i < len + 3; i++) |
678 | 682 |
dest[i - 3] = xbee_buf[i]; |
... | ... | |
731 | 735 |
WL_DEBUG_PRINT("AT"); |
732 | 736 |
WL_DEBUG_PRINT(command); |
733 | 737 |
WL_DEBUG_PRINT(" command was successful.\r\n"); |
734 |
|
|
738 |
|
|
735 | 739 |
if (command[0] == 'I' && command[1] == 'D') |
736 | 740 |
{ |
737 | 741 |
xbee_panID = xbee_pending_panID; |
... | ... | |
749 | 753 |
WL_DEBUG_PRINT(".\r\n"); |
750 | 754 |
return; |
751 | 755 |
} |
752 |
|
|
756 |
|
|
753 | 757 |
if (command[0] == 'M' && command[1] == 'Y' && extraLen != 0) |
754 | 758 |
{ |
755 | 759 |
xbee_address = 0; |
... | ... | |
778 | 782 |
* |
779 | 783 |
* @param packet the packet to handle |
780 | 784 |
* @param len the length of the packet |
781 |
*
|
|
785 |
* |
|
782 | 786 |
* @return 1 if we have handled the packet, 0 otherwise |
783 | 787 |
*/ |
784 | 788 |
int xbee_handle_packet(char* packet, int len) |
... | ... | |
789 | 793 |
WL_DEBUG_PRINT("Non-positive packet length.\r\n"); |
790 | 794 |
return 0; |
791 | 795 |
} |
792 |
|
|
796 |
|
|
793 | 797 |
switch ((unsigned char)packet[0]) //packet type |
794 | 798 |
{ |
795 | 799 |
case XBEE_FRAME_STATUS: |
... | ... | |
823 | 827 |
|
824 | 828 |
/** |
825 | 829 |
* Get the PAN ID for the XBee. |
826 |
*
|
|
830 |
* |
|
827 | 831 |
* @return the personal area network id, or |
828 | 832 |
* XBEE_PAN_DEFAULT if it has not yet been set. |
829 | 833 |
**/ |
... | ... | |
835 | 839 |
/** |
836 | 840 |
* Set the channel the XBee is using. |
837 | 841 |
* |
838 |
* @param channel the channel the XBee will not use,
|
|
842 |
* @param channel the channel the XBee will not use, |
|
839 | 843 |
* between 0x0B and 0x1A |
840 | 844 |
* |
841 | 845 |
* @see xbee_get_channel |
Also available in: Unified diff