Revision 1604
wireless: software retransmit done. serial functions moved to xbee.c
xbee.c | ||
---|---|---|
95 | 95 |
// aka, the first free byte in other buffer |
96 | 96 |
static uint8_t other_buf_last = 0; |
97 | 97 |
|
98 |
|
|
99 | 98 |
// xbee status |
100 | 99 |
#define XBEE_API_OFF 0x0 |
101 | 100 |
#define XBEE_API_ON 0x1 |
... | ... | |
103 | 102 |
#define XBEE_NORMAL 0x00 |
104 | 103 |
#define XBEE_COMMAND_WAIT 0x80 |
105 | 104 |
#define XBEE_COMMAND_RESPONSE 0xC0 |
105 |
#define XBEE_INITD 0x08 |
|
106 | 106 |
static uint8_t xbee_status = XBEE_API_OFF|XBEE_NORMAL; |
107 | 107 |
|
108 | 108 |
// xbee command response (for PAN, channel, address, etc) |
... | ... | |
303 | 303 |
} // end of interrupt |
304 | 304 |
|
305 | 305 |
|
306 |
|
|
307 | 306 |
/* adds a byte to the basic buffer */ |
308 | 307 |
int8_t xbee_basic_buf_add(uint8_t *ptr, uint8_t byte) { |
309 | 308 |
if (*ptr == basic_buf_first) { |
... | ... | |
340 | 339 |
/** |
341 | 340 |
* Initializes the XBee library so that other functions may be used. |
342 | 341 |
**/ |
343 |
int8_t xbee_lib_init()
|
|
342 |
int8_t xbee_init() |
|
344 | 343 |
{ |
345 |
// do serial.c xbee init TODO: merge this into xbee.c
|
|
346 |
if (xbee_init() != 0) { |
|
347 |
usb_puts("xbee_init error");
|
|
348 |
return WL_ERROR_INIT_FAILED;
|
|
344 |
WL_DEBUG_PRINT("in xbee_init\n");
|
|
345 |
|
|
346 |
if(xbee_status&0x08 == XBEE_INITD) {
|
|
347 |
return WL_ERROR_INIT_ALREADY_INITD;
|
|
349 | 348 |
} |
350 |
|
|
351 |
WL_DEBUG_PRINT("in xbee_init\n");
|
|
352 |
|
|
353 |
//enable the receiving interrupt
|
|
349 |
|
|
350 |
// Set startup baud rate of 9600
|
|
351 |
// Set frame format: 8data, 1stop bit, asynchronous normal mode |
|
352 |
// Enable receiver and transmitter and the receiving interrupt
|
|
354 | 353 |
#ifdef FIREFLY |
355 |
UCSR0B |= _BV(RXCIE) | _BV(RXEN); |
|
354 |
UCSR0A |= (1<<U2X0); |
|
355 |
UBRR0H = 0x00; |
|
356 |
UBRR0L = 103; |
|
357 |
UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01); |
|
358 |
UCSR0B |= (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0); |
|
356 | 359 |
#else |
357 |
#ifdef BAYBOARD |
|
358 |
UCSR1B |= _BV(RXCIE1); |
|
359 |
#else |
|
360 |
UCSR1B |= _BV(RXCIE); |
|
360 |
// Bayboard or robot |
|
361 |
UCSR1A |= (1<<U2X1); |
|
362 |
UBRR1H = 0x00; |
|
363 |
UBRR1L = 103; |
|
364 |
UCSR1C |= (1<<UCSZ10) | (1<<UCSZ11); |
|
365 |
UCSR1B |= (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE1); |
|
361 | 366 |
#endif |
362 |
#endif |
|
363 | 367 |
sei(); |
364 | 368 |
|
365 | 369 |
WL_DEBUG_PRINT("Entering command mode.\r\n"); |
... | ... | |
398 | 402 |
WL_DEBUG_PRINT("got ok from exiting command mode\r\n"); |
399 | 403 |
|
400 | 404 |
// set UART baud |
405 |
#ifdef FIREFLY |
|
401 | 406 |
#if (XBEE_BAUD == 115200) |
407 |
UBRR0H = 0x00; |
|
408 |
UBRR0L = 8; |
|
409 |
#elif (XBEE_BAUD == 57600) |
|
410 |
UBRR0H = 0x00; |
|
411 |
UBRR0L = 16; |
|
412 |
#elif (XBEE_BAUD == 38400) |
|
413 |
UBRR0H = 0x00; |
|
414 |
UBRR0L = 25; |
|
415 |
#elif (XBEE_BAUD == 19200) |
|
416 |
UBRR0H = 0x00; |
|
417 |
UBRR0L = 51; |
|
418 |
#elif (XBEE_BAUD == 9600) |
|
419 |
/* this is the default baud rate, so do nothing |
|
420 |
UBRR0H = 0x00; |
|
421 |
UBRR0L = 103;*/ |
|
422 |
#else |
|
423 |
WL_DEBUG_PRINT("undefined baud rate\r\n"); |
|
424 |
return WL_ERROR_BUAD; |
|
425 |
#endif |
|
426 |
#else // Bayboard or robot |
|
427 |
#if (XBEE_BAUD == 115200) |
|
402 | 428 |
UBRR1H = 0x00; |
403 | 429 |
UBRR1L = 8; |
404 |
UCSR1A |= _BV(U2X1); |
|
405 | 430 |
#elif (XBEE_BAUD == 57600) |
406 | 431 |
UBRR1H = 0x00; |
407 | 432 |
UBRR1L = 16; |
408 |
UCSR1A |= _BV(U2X1); |
|
409 | 433 |
#elif (XBEE_BAUD == 38400) |
410 | 434 |
UBRR1H = 0x00; |
411 | 435 |
UBRR1L = 25; |
412 |
UCSR1A |= _BV(U2X1); |
|
413 | 436 |
#elif (XBEE_BAUD == 19200) |
414 | 437 |
UBRR1H = 0x00; |
415 | 438 |
UBRR1L = 51; |
416 |
UCSR1A |= _BV(U2X1); |
|
417 | 439 |
#elif (XBEE_BAUD == 9600) |
418 | 440 |
/* this is the default baud rate, so do nothing |
419 | 441 |
UBRR1H = 0x00; |
420 |
UBRR1L = 103; |
|
421 |
UCSR1A |= _BV(U2X1);*/ |
|
442 |
UBRR1L = 103;*/ |
|
422 | 443 |
#else |
423 | 444 |
WL_DEBUG_PRINT("undefined baud rate\r\n"); |
424 | 445 |
return WL_ERROR_BUAD; |
425 | 446 |
#endif |
447 |
#endif |
|
426 | 448 |
delay_ms(50); |
427 | 449 |
|
428 | 450 |
// enter command mode |
... | ... | |
447 | 469 |
|
448 | 470 |
// TODO: we should set the MY address to the robot address from eeprom |
449 | 471 |
|
472 |
|
|
473 |
// set status |
|
474 |
xbee_status |= XBEE_INITD; |
|
475 |
|
|
450 | 476 |
return WL_SUCCESS; |
451 | 477 |
} |
452 | 478 |
|
453 | 479 |
/** |
454 | 480 |
* Call when finished using the XBee library. |
455 | 481 |
**/ |
456 |
void xbee_terminate()
|
|
482 |
int8_t xbee_terminate()
|
|
457 | 483 |
{ |
458 |
xbee_exit_api_mode(); |
|
484 |
if (xbee_exit_api_mode() != WL_SUCCESS) { |
|
485 |
WL_DEBUG_PRINT("xbee termination failed\r\n"); |
|
486 |
return WL_ERROR_TERMINATION_FAILED; |
|
487 |
} |
|
488 |
xbee_status = xbee_status&0xF7; // clean initd status |
|
489 |
return WL_SUCCESS; |
|
459 | 490 |
} |
460 | 491 |
|
461 | 492 |
/** |
493 |
* Sends a character to the XBee. |
|
494 |
* |
|
495 |
* @param c the byte to send |
|
496 |
* @return 0 for success, nonzero for failure |
|
497 |
**/ |
|
498 |
int xbee_putc(char c) { |
|
499 |
if(!(xbee_status&XBEE_INITD)) |
|
500 |
return WL_ERROR_LIBRARY_NOT_INITD; |
|
501 |
|
|
502 |
// Wait until buffer is clear for sending |
|
503 |
// Then load buffer with your character |
|
504 |
#ifdef FIREFLY |
|
505 |
loop_until_bit_is_set(UCSR0A, UDRE0); |
|
506 |
UDR0 = c; |
|
507 |
#else |
|
508 |
loop_until_bit_is_set(UCSR1A, UDRE1); |
|
509 |
UDR1 = c; |
|
510 |
#endif |
|
511 |
|
|
512 |
return WL_SUCCESS; |
|
513 |
} |
|
514 |
|
|
515 |
/** |
|
516 |
* Returns the first byte in the buffer received from xbee. |
|
517 |
* This function blocks execution until a character has been |
|
518 |
* received. xbee_init must be called before this function |
|
519 |
* may be used. |
|
520 |
* |
|
521 |
* @return the first character in the xbee buffer, -1 on error |
|
522 |
* |
|
523 |
* @see xbee_init, xbee_getc_nb |
|
524 |
**/ |
|
525 |
int16_t xbee_getc(void) { |
|
526 |
if(!(xbee_status&XBEE_INITD)) |
|
527 |
return WL_ERROR_LIBRARY_NOT_INITD; |
|
528 |
|
|
529 |
// Wait for the receive buffer to be filled |
|
530 |
// Then read the receive buffer |
|
531 |
#ifdef FIREFLY |
|
532 |
loop_until_bit_is_set(UCSR0A, RXC0); |
|
533 |
return UDR0; |
|
534 |
#else |
|
535 |
loop_until_bit_is_set(UCSR1A, RXC1); |
|
536 |
return UDR1; |
|
537 |
#endif |
|
538 |
} |
|
539 |
|
|
540 |
/** |
|
541 |
* Non blocking version of xbee_getc. If a byte is present in the buffer, |
|
542 |
* it is returned, otherwise -1 is returned immediately. xbee_init |
|
543 |
* must be called before this function can be used. |
|
544 |
* |
|
545 |
* @param c The received byte. This will be set if a byte has been received. |
|
546 |
* |
|
547 |
* @return -1 If no byte is available, 0 otherwise, positive for error |
|
548 |
* |
|
549 |
* @see xbee_getc |
|
550 |
**/ |
|
551 |
int8_t xbee_getc_nb(uint8_t *c) { |
|
552 |
if(!(xbee_status&XBEE_INITD)) |
|
553 |
return WL_ERROR_LIBRARY_NOT_INITD; |
|
554 |
|
|
555 |
// check if the receive buffer is filled |
|
556 |
#ifdef FIREFLY |
|
557 |
if (UCSR0A & (1<<RXC0)) { |
|
558 |
(*c) = UDR0; |
|
559 |
#else |
|
560 |
if (UCSR1A & (1<<RXC1)) { |
|
561 |
(*c) = UDR1; |
|
562 |
#endif |
|
563 |
return WL_SUCCESS; |
|
564 |
} |
|
565 |
return -1; // Return empty |
|
566 |
} |
|
567 |
|
|
568 |
/** |
|
462 | 569 |
* Send a buffer buf of size bytes to the XBee. |
463 | 570 |
* |
464 | 571 |
* @param buf the buffer of data to send |
... | ... | |
509 | 616 |
static int8_t xbee_exit_command_mode() |
510 | 617 |
{ |
511 | 618 |
if (xbee_send_string("ATCN\r") != 0) { |
512 |
return -1;
|
|
619 |
return WL_ERROR_SEND;
|
|
513 | 620 |
} |
514 |
|
|
515 | 621 |
xbee_wait_for_ok(); |
516 | 622 |
|
517 |
return 0;
|
|
623 |
return WL_SUCCESS;
|
|
518 | 624 |
} |
519 | 625 |
|
520 | 626 |
/** |
521 | 627 |
* Enter API mode. |
522 | 628 |
**/ |
523 |
static int xbee_enter_api_mode() |
|
629 |
static int8_t xbee_enter_api_mode()
|
|
524 | 630 |
{ |
525 | 631 |
if (xbee_send_string("ATAP 1\r") != 0) { |
526 |
return -1;
|
|
632 |
return WL_ERROR_SEND;
|
|
527 | 633 |
} |
528 | 634 |
xbee_wait_for_ok(); |
529 | 635 |
|
530 | 636 |
xbee_status = (xbee_status&0xFC)|XBEE_API_ON; |
531 | 637 |
|
532 |
return 0;
|
|
638 |
return WL_SUCCESS;
|
|
533 | 639 |
} |
534 | 640 |
|
535 | 641 |
/** |
536 | 642 |
* Enter API mode 2. |
537 | 643 |
**/ |
538 |
static int xbee_enter_api_mode2() |
|
644 |
static int8_t xbee_enter_api_mode2()
|
|
539 | 645 |
{ |
540 | 646 |
if (xbee_send_string("ATAP 2\r") != 0) { |
541 |
return -1;
|
|
647 |
return WL_ERROR_SEND;
|
|
542 | 648 |
} |
543 | 649 |
xbee_wait_for_ok(); |
544 | 650 |
|
545 | 651 |
xbee_status = (xbee_status&0xFC)|XBEE_API_ESCAPE; |
546 | 652 |
|
547 |
return 0;
|
|
653 |
return WL_SUCCESS;
|
|
548 | 654 |
} |
549 | 655 |
|
550 | 656 |
/** |
551 | 657 |
* Exit API mode. |
552 | 658 |
**/ |
553 |
static int xbee_exit_api_mode() |
|
659 |
static int8_t xbee_exit_api_mode()
|
|
554 | 660 |
{ |
555 |
if (xbee_send_modify_at_command("AP","0") != 0) {
|
|
556 |
return -1;
|
|
557 |
}
|
|
661 |
if (xbee_status&0xC0 == XBEE_COMMAND_WAIT
|
|
662 |
|| xbee_status&0xC0 == XBEE_COMMAND_RESPONSE)
|
|
663 |
return WL_ERROR_XBEE_COMMAND; // can't do command right now
|
|
558 | 664 |
|
559 |
xbee_status = (xbee_status&0xFC)|XBEE_API_OFF; |
|
560 |
|
|
561 |
return 0; |
|
665 |
int16_t i=0; |
|
666 |
// change status to command wait |
|
667 |
xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT; |
|
668 |
xbee_send_modify_at_command("AP","0",1); // send command |
|
669 |
// wait for up to 30 ms |
|
670 |
while(xbee_status&0xC0 != XBEE_COMMAND_RESPONSE && i++ < 10000) { |
|
671 |
delay_us(1); // wait 3us |
|
672 |
} |
|
673 |
if (i < 1000 && xbee_command[0] == 'A' && xbee_command[1] == 'P') { |
|
674 |
i = WL_SUCCESS; |
|
675 |
else |
|
676 |
i = WL_ERROR_XBEE_COMMAND; // set error code |
|
677 |
xbee_status = (xbee_status&0x3C)|XBEE_API_OFF; // reset status |
|
678 |
return (int8_t)i; // return |
|
562 | 679 |
} |
563 | 680 |
|
564 | 681 |
/** |
... | ... | |
571 | 688 |
|
572 | 689 |
/** |
573 | 690 |
* Delay until the specified string is received from |
574 |
* the XBee. Discards all other XBee data.
|
|
691 |
* the XBee. |
|
575 | 692 |
* |
576 |
* ********* Robot often hangs here ****************
|
|
693 |
* Only works when not in API mode
|
|
577 | 694 |
* |
578 | 695 |
* @param s the string to receive |
579 | 696 |
* @param len the length of the string |
... | ... | |
670 | 787 |
* @return the checksum of the packet, which will |
671 | 788 |
* become the last byte sent in the packet |
672 | 789 |
**/ |
673 |
char xbee_compute_checksum(uint8_t* buf, uint16_t len)
|
|
790 |
uint8_t xbee_compute_checksum(uint8_t* buf, uint16_t len)
|
|
674 | 791 |
{ |
675 | 792 |
uint8_t sum = 0; |
676 | 793 |
while(--len > 0) { |
... | ... | |
681 | 798 |
} |
682 | 799 |
|
683 | 800 |
/** |
801 |
* Adds buf to the previous checksum total |
|
802 |
* |
|
803 |
* @param buf a byte buffer to add to the checksum |
|
804 |
* @param len the length of the buffer |
|
805 |
* @param sum the previous sum |
|
806 |
* |
|
807 |
* @return error code |
|
808 |
**/ |
|
809 |
static int8_t xbee_checksum_add(uint8_t *buf, uint8_t len, uint8_t* sum) { |
|
810 |
if (buf == NULL || sum == NULL) |
|
811 |
return WL_ERROR_ARGUMENT; |
|
812 |
while(--len > 0) { |
|
813 |
*sum += buf[len]; |
|
814 |
} |
|
815 |
*sum += buf[0]; |
|
816 |
} |
|
817 |
|
|
818 |
|
|
819 |
/** |
|
820 |
* Sends header information. Header information includes |
|
821 |
* XBEE_FRAME_START and the packet length, as two bytes. |
|
822 |
* |
|
823 |
* @param type the packet type |
|
824 |
* @param len the size in bytes of the packet data |
|
825 |
* |
|
826 |
**/ |
|
827 |
static int8_t xbee_send_header(uint8_t type, uint16_t len) |
|
828 |
{ |
|
829 |
//packet prefix |
|
830 |
if (xbee_putc(XBEE_FRAME_START) != WL_SUCCESS) |
|
831 |
return WL_ERROR_SEND; |
|
832 |
if (xbee_putc((uint8_t)((len & 0xFF00) >> 8)) != WL_SUCCESS) |
|
833 |
return WL_ERROR_SEND; |
|
834 |
if (xbee_putc((uint8_t)(len & 0x00FF)) != WL_SUCCESS) |
|
835 |
return WL_ERROR_SEND; |
|
836 |
|
|
837 |
if (xbee_send(buf, len) != WL_SUCCESS) |
|
838 |
return WL_ERROR_SEND; |
|
839 |
|
|
840 |
if (xbee_putc(checksum) != WL_SUCCESS) |
|
841 |
return WL_ERROR_SEND; |
|
842 |
|
|
843 |
return WL_SUCCESS; |
|
844 |
} |
|
845 |
|
|
846 |
/** |
|
684 | 847 |
* Adds header information and checksum to the given |
685 | 848 |
* packet and sends it. Header information includes |
686 | 849 |
* XBEE_FRAME_START and the packet length, as two bytes. |
... | ... | |
691 | 854 |
**/ |
692 | 855 |
static int8_t xbee_send_frame(uint8_t* buf, uint16_t len) |
693 | 856 |
{ |
694 |
uint8_t prefix[3]; |
|
695 |
prefix[0] = XBEE_FRAME_START; |
|
696 |
prefix[1] = (len & 0xFF00) >> 8; |
|
697 |
prefix[2] = len & 0x00FF; |
|
698 | 857 |
uint8_t checksum = xbee_compute_checksum(buf, len); |
858 |
|
|
859 |
//packet prefix |
|
860 |
if (xbee_putc(XBEE_FRAME_START) != WL_SUCCESS) |
|
861 |
return WL_ERROR_SEND; |
|
862 |
if (xbee_putc((uint8_t)((len & 0xFF00) >> 8)) != WL_SUCCESS) |
|
863 |
return WL_ERROR_SEND; |
|
864 |
if (xbee_putc((uint8_t)(len & 0x00FF)) != WL_SUCCESS) |
|
865 |
return WL_ERROR_SEND; |
|
699 | 866 |
|
700 |
if (xbee_send(prefix, 3) != 0) {
|
|
867 |
if (xbee_send(buf, len) != WL_SUCCESS)
|
|
701 | 868 |
return WL_ERROR_SEND; |
702 |
} |
|
703 |
|
|
704 |
if (xbee_send(buf, len) != 0) { |
|
869 |
|
|
870 |
if (xbee_putc(checksum) != WL_SUCCESS) |
|
705 | 871 |
return WL_ERROR_SEND; |
706 |
} |
|
707 |
|
|
708 |
if (xbee_send(&checksum, 1) != 0) { |
|
709 |
return WL_ERROR_SEND; |
|
710 |
} |
|
711 |
|
|
872 |
|
|
712 | 873 |
return WL_SUCCESS; |
713 | 874 |
} |
714 | 875 |
|
... | ... | |
771 | 932 |
* the XBee alerts us as to whether or not our message |
772 | 933 |
* was received. |
773 | 934 |
**/ |
774 |
int xbee_send_packet(char* packet, int len, int dest, char options, char frame)
|
|
935 |
int8_t xbee_send_packet(uint8_t* packet, uint8_t len, uint16_t dest, uint8_t options, uint8_t frame)
|
|
775 | 936 |
{ |
776 |
char buf[5]; |
|
777 |
char prefix[3]; |
|
778 |
int i; |
|
779 |
unsigned char checksum = 0; |
|
937 |
uint8_t sum = XBEE_FRAME_TX_REQUEST_16; |
|
938 |
uint8_t i = 0; |
|
780 | 939 |
|
781 | 940 |
if (len > 100) |
782 | 941 |
{ |
783 | 942 |
WL_DEBUG_PRINT("Packet is too large.\r\n"); |
784 |
return -1;
|
|
943 |
return WL_ERROR_ARGUMENT;
|
|
785 | 944 |
} |
945 |
|
|
946 |
// calculate checksum |
|
947 |
for(;i<len;i++) |
|
948 |
sum += packet[len]; |
|
949 |
sum += frame; |
|
950 |
sum += (dest&0xFF00) >> 8; |
|
951 |
sum += dest&0x00FF; |
|
952 |
sum += options; |
|
953 |
sum = 0xFF - sum; |
|
786 | 954 |
|
787 |
//data for sending request |
|
788 |
buf[0] = XBEE_FRAME_TX_REQUEST_16; |
|
789 |
buf[1] = frame; |
|
790 |
buf[2] = (dest >> 8) & 0xFF; |
|
791 |
buf[3] = dest & 0xFF; |
|
792 |
buf[4] = options; |
|
955 |
//packet prefix |
|
956 |
if (xbee_putc(XBEE_FRAME_START) != WL_SUCCESS) |
|
957 |
return WL_ERROR_SEND; |
|
958 |
if (xbee_putc(0x00) != WL_SUCCESS) |
|
959 |
return WL_ERROR_SEND; |
|
960 |
if (xbee_putc(len+5) != WL_SUCCESS) |
|
961 |
return WL_ERROR_SEND; |
|
962 |
|
|
963 |
//send header for TX request |
|
964 |
if (xbee_putc(XBEE_FRAME_TX_REQUEST_16) != WL_SUCCESS) |
|
965 |
return WL_ERROR_SEND; |
|
966 |
if (xbee_putc(frame) != WL_SUCCESS) |
|
967 |
return WL_ERROR_SEND; |
|
968 |
if (xbee_putc((uint8_t)((dest&0xFF00) >> 8)) != WL_SUCCESS) |
|
969 |
return WL_ERROR_SEND; |
|
970 |
if (xbee_putc((uint8_t)(dest&0x00FF)) != WL_SUCCESS) |
|
971 |
return WL_ERROR_SEND; |
|
972 |
if (xbee_putc(options) != WL_SUCCESS) |
|
973 |
return WL_ERROR_SEND; |
|
793 | 974 |
|
794 |
//packet prefix, do this here so we don't need an extra buffer |
|
795 |
prefix[0] = XBEE_FRAME_START; |
|
796 |
prefix[1] = ((5 + len) & 0xFF00) >> 8; |
|
797 |
prefix[2] = (5 + len) & 0xFF; |
|
975 |
// send packet |
|
976 |
if (xbee_send(packet, len) != WL_SUCCESS) |
|
977 |
return WL_ERROR_SEND; |
|
798 | 978 |
|
799 |
for (i = 0; i < 5; i++) |
|
800 |
checksum += (unsigned char)buf[i]; |
|
801 |
for (i = 0; i < len; i++) |
|
802 |
checksum += (unsigned char)packet[i]; |
|
803 |
checksum = 0xFF - checksum; |
|
979 |
// send checksum |
|
980 |
if (xbee_putc(sum) != WL_SUCCESS) |
|
981 |
return WL_ERROR_SEND; |
|
804 | 982 |
|
805 |
if (xbee_send(prefix, 3) != 0) { |
|
806 |
return -1; |
|
807 |
} |
|
808 |
|
|
809 |
if (xbee_send(buf, 5) != 0) { |
|
810 |
return -1; |
|
811 |
} |
|
812 |
|
|
813 |
if (xbee_send(packet, len) != 0) { |
|
814 |
return -1; |
|
815 |
} |
|
816 |
|
|
817 |
if (xbee_send((char*)&checksum, 1) != 0) { |
|
818 |
return -1; |
|
819 |
} |
|
820 |
|
|
821 |
return 0; |
|
983 |
return WL_SUCCESS; |
|
822 | 984 |
} |
823 | 985 |
|
824 | 986 |
/** |
Also available in: Unified diff