Revision 1604
wireless: software retransmit done. serial functions moved to xbee.c
branches/wireless/code/projects/libwireless/xbee_computer.c | ||
---|---|---|
13 | 13 |
|
14 | 14 |
#endif |
15 | 15 |
|
16 |
#ifdef USE_STDIO |
|
16 | 17 |
|
18 |
#include <stdio.h> |
|
19 |
|
|
20 |
/** |
|
21 |
* For use with fprintf() and related stdio functions |
|
22 |
**/ |
|
23 |
FILE *xbee_fd; |
|
24 |
|
|
25 |
#endif |
|
26 |
|
|
27 |
uint8_t xbee_initd=0; |
|
28 |
|
|
29 |
/** |
|
30 |
* Initializes communication over the XBee. |
|
31 |
* This must be called before any other xbee function |
|
32 |
* may be used. |
|
33 |
**/ |
|
34 |
int xbee_init() { |
|
35 |
|
|
36 |
if(xbee_initd) { |
|
37 |
return ERROR_INIT_ALREADY_INITD; |
|
38 |
} |
|
39 |
|
|
40 |
//Set baud rate |
|
41 |
// - 115200 (both wired and wireless) is UBRR=8, U2X=1 |
|
42 |
// - 9600 is U2X =1, UBRR = 107. |
|
43 |
#if (XBEE_BAUD == 115200) |
|
44 |
UBRR1H = 0x00; |
|
45 |
UBRR1L = 8; |
|
46 |
UCSR1A |= _BV(U2X1); |
|
47 |
#elif (XBEE_BAUD == 9600) |
|
48 |
UBRR1H = 0x00; |
|
49 |
UBRR1L = 103; |
|
50 |
UCSR1A |= _BV(U2X1); |
|
51 |
#else //Baud rate is defined in the header file, we should not get here |
|
52 |
return 0; |
|
53 |
#endif |
|
54 |
|
|
55 |
//Enable receiver and transmitter |
|
56 |
UCSR1B |= (1<<RXEN1)|(1<<TXEN1); |
|
57 |
|
|
58 |
// Set frame format: 8data, 1stop bit, asynchronous normal mode |
|
59 |
UCSR1C |= (1<<UCSZ10) | (1<<UCSZ11); |
|
60 |
|
|
61 |
// if we have enabled the stdio stuff, then we init it here |
|
62 |
#ifdef USE_STDIO |
|
63 |
/* Open the stdio stream corresponding to this port */ |
|
64 |
xbee_fd = fdevopen(xbee_putc, xbee_getc); |
|
65 |
#endif |
|
66 |
|
|
67 |
xbee_initd = 1; |
|
68 |
return 0; |
|
69 |
|
|
70 |
} |
|
71 |
|
|
72 |
|
|
73 |
/**@brief The port to use the XBee from on the computer. **/ |
|
74 |
#ifndef ROBOT |
|
75 |
#define XBEE_PORT_DEFAULT "/dev/ttyUSB1" |
|
76 |
#endif |
|
77 |
|
|
78 |
|
|
79 |
/**@brief Set the com port on a computer, undefined on the robot**/ |
|
80 |
void xbee_set_com_port(char* port); |
|
81 |
|
|
17 | 82 |
#define XBEE_GET_PACKET_TIMEOUT 1000 |
18 | 83 |
|
19 | 84 |
#ifndef ROBOT |
branches/wireless/code/projects/libwireless/wireless.h | ||
---|---|---|
107 | 107 |
/**@brief init_flag when library has been initialized **/ |
108 | 108 |
#define INIT_YES UINT8_C(1) |
109 | 109 |
|
110 |
/**@brief numer of reliable sending retries **/ |
|
111 |
#define NUM_RETRIES UINT8_C(3) |
|
112 |
|
|
110 | 113 |
/**@} **/ // end defines group |
111 | 114 |
|
112 | 115 |
/** |
branches/wireless/code/projects/libwireless/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 |
/** |
branches/wireless/code/projects/libwireless/wireless_send.c | ||
---|---|---|
40 | 40 |
|
41 | 41 |
/** |
42 | 42 |
* Definition for wireless library send packet structure |
43 |
* byte 1: length of packet |
|
43 |
* byte 1: length of packet (from frame number to end of data)
|
|
44 | 44 |
* byte 2: frame number |
45 |
* byte 3: group code |
|
46 |
* bytes 4-n: data |
|
47 |
* (byte n+1: num retries - only saved locally in sending buffer) |
|
45 |
* bytes 3-n: data (dest, options, frame number, group code, packet) |
|
46 |
* byte n+1: num retries |
|
48 | 47 |
* |
49 | 48 |
* Definition for ack buffer |
50 | 49 |
* 2 bit system: 0=still sending |
... | ... | |
60 | 59 |
uint8_t send_buf[PACKET_BUFFER_SIZE]; // sending buffer for retries |
61 | 60 |
uint8_t send_buf_first = 0; // first byte of data on buffer |
62 | 61 |
uint8_t send_buf_last = 0; // next free byte on buffer |
62 |
uint8_t send_buf_num_packets = 0; // number of packets in sending buffer |
|
63 | 63 |
|
64 | 64 |
/* private function prototypes */ |
65 | 65 |
void setack(uint8_t num,uint8_t val); |
66 |
void ackhandle(uint8_t num,uint8_t val); |
|
67 |
int8_t send_buf_add(uint8_t *ptr, uint8_t byte) |
|
68 |
uint8_t send_buf_get(uint8_t *ptr); |
|
66 | 69 |
|
67 |
|
|
68 | 70 |
// the send functions |
69 | 71 |
|
70 | 72 |
/** |
... | ... | |
86 | 88 |
* @return positive packet number for tracking acks, or error code (TBD) |
87 | 89 |
**/ |
88 | 90 |
int16_t wl_send(uint8_t *data, uint8_t length, uint8_t group, uint8_t scope, uint16_t dest, uint8_t mode) { |
89 |
uint8_t packet[length+2]; |
|
90 |
uint8_t options = XBEE_OPTIONS_NONE; |
|
91 |
int16_t ret_val = (int16_t)nextframe; |
|
91 |
uint8_t packet[6]; |
|
92 | 92 |
|
93 |
// build packet |
|
93 |
// build packet header
|
|
94 | 94 |
packet[0] = nextframe; |
95 |
packet[1] = group; |
|
96 |
memcpy(packet+2,data,length); |
|
95 |
packet[1] = (dest&0xFF00)>>8; |
|
96 |
packet[2] = dest&0x00FF; |
|
97 |
packet[3] = XBEE_OPTIONS_NONE; |
|
98 |
packet[4] = nextframe; |
|
99 |
packet[5] = group; |
|
97 | 100 |
|
98 | 101 |
// set scope |
99 | 102 |
if (scope == GLOBAL) |
100 |
options &= XBEE_OPTIONS_BROADCAST_ALL_PANS; |
|
103 |
packet[3] &= XBEE_OPTIONS_BROADCAST_ALL_PANS; |
|
104 |
else if (scope != PAN) { |
|
105 |
WL_DEBUG_PRINT("Error - bad scope in core send function\r\n"); |
|
106 |
return WL_ERROR_SCOPE; |
|
107 |
} |
|
101 | 108 |
|
102 | 109 |
// set mode |
103 | 110 |
if (mode == FAST) { |
104 |
options &= XBEE_OPTIONS_DISABLE_RESPONSE; |
|
105 |
ret_val = 0; |
|
111 |
packet[3] &= XBEE_OPTIONS_DISABLE_RESPONSE; |
|
106 | 112 |
} else if (mode != RELIABLE) { |
107 | 113 |
WL_DEBUG_PRINT("Error - bad mode in core send function\r\n"); |
108 | 114 |
return WL_ERROR_MODE; |
109 | 115 |
} |
116 |
|
|
117 |
// do checksum |
|
118 |
group = XBEE_FRAME_TX_REQUEST_16; |
|
119 |
xbee_checksum_add(packet,6,&group); |
|
120 |
xbee_checksum_add(data,length,&group); |
|
121 |
group = 0xFF-group; |
|
110 | 122 |
|
111 | 123 |
// send the packet |
112 |
if (xbee_send_packet(packet,length,dest,options,(uint_8)ret_val) != 0) {
|
|
113 |
WL_DEBUG_PRINT("Error sending packet from core send function\r\n"); |
|
124 |
if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,length+7) != WL_SUCCESS) {
|
|
125 |
WL_DEBUG_PRINT("1Error sending packet from core send function\r\n");
|
|
114 | 126 |
return WL_ERROR_SEND; |
115 | 127 |
} |
128 |
if (xbee_putc(XBEE_FRAME_TX_REQUEST_16) != WL_SUCCESS) { |
|
129 |
WL_DEBUG_PRINT("2Error sending packet from core send function\r\n"); |
|
130 |
return WL_ERROR_SEND; |
|
131 |
} |
|
132 |
if (xbee_send(packet,6) != WL_SUCCESS) { |
|
133 |
WL_DEBUG_PRINT("3Error sending packet from core send function\r\n"); |
|
134 |
return WL_ERROR_SEND; |
|
135 |
} |
|
136 |
if (xbee_send(data,length) != WL_SUCCESS) { |
|
137 |
WL_DEBUG_PRINT("4Error sending packet from core send function\r\n"); |
|
138 |
return WL_ERROR_SEND; |
|
139 |
} |
|
140 |
if (xbee_putc(group) != WL_SUCCESS) { |
|
141 |
WL_DEBUG_PRINT("5Error sending packet from core send function\r\n"); |
|
142 |
return WL_ERROR_SEND; |
|
143 |
} |
|
116 | 144 |
|
117 | 145 |
// save in ack system |
118 | 146 |
if (mode == FAST) { |
119 | 147 |
setack(nextframe,ACK_OK); // assume the send was successful |
120 | 148 |
} else if (mode == RELIABLE) { |
121 | 149 |
setack(nextframe,SENDING); // set status to SENDING |
122 |
// TODO: save packet on sending buffer |
|
123 |
/* if (buffer full) { |
|
150 |
// save packet on sending buffer |
|
151 |
scope = send_buf_last; // use as ptr to send buffer |
|
152 |
if (send_buf_add(&scope,length+6) != WL_SUCCESS) { // add length |
|
124 | 153 |
WL_DEBUG_PRINT("Error: sending buffer full\r\n"); |
125 |
return WL_ERROR_SENDING_BUFFER_FULL |
|
126 |
} */ |
|
154 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
155 |
} |
|
156 |
for(mode=0;mode<6;mode++) { // add header |
|
157 |
if (send_buf_add(&scope,packet[mode]) != WL_SUCCESS) { |
|
158 |
WL_DEBUG_PRINT("Error: sending buffer full\r\n"); |
|
159 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
160 |
} |
|
161 |
} |
|
162 |
for(mode=0;mode<length;mode++) { // add data |
|
163 |
if (send_buf_add(&scope,data[mode]) != WL_SUCCESS) { |
|
164 |
WL_DEBUG_PRINT("Error: sending buffer full\r\n"); |
|
165 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
166 |
} |
|
167 |
} |
|
168 |
if (send_buf_add(&scope,0) != WL_SUCCESS) { // add num retries=0 |
|
169 |
WL_DEBUG_PRINT("Error: sending buffer full\r\n"); |
|
170 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
171 |
} |
|
172 |
send_buf_last = scope; |
|
173 |
send_buf_num_packets++; |
|
127 | 174 |
} |
128 | 175 |
|
129 | 176 |
// increment frame number |
... | ... | |
273 | 320 |
|
274 | 321 |
/* ack handler */ |
275 | 322 |
void ackhandle(uint8_t num,uint8_t val) { |
323 |
uint8_t len; |
|
276 | 324 |
switch(val) { |
277 | 325 |
case 0: |
278 | 326 |
// success |
279 | 327 |
setack(num,ACK_OK); // set status code |
280 |
// TODO: remove from sending buffer |
|
328 |
// remove from buffer |
|
329 |
val = send_buf_first; |
|
330 |
if (send_buf_num_packets == 0) |
|
331 |
return; |
|
332 |
while (1) { |
|
333 |
len = send_buf_get(&val); |
|
334 |
if (send_buf_get(&val) != num) { |
|
335 |
// not the correct packet, so continue |
|
336 |
val += len; |
|
337 |
if (val >= PACKET_BUFFER_SIZE) |
|
338 |
val -= PACKET_BUFFER_SIZE; |
|
339 |
if (val == send_buf_last) { |
|
340 |
// reached end of bufer, so assume not present |
|
341 |
return; |
|
342 |
} |
|
343 |
} else { |
|
344 |
// remove packet |
|
345 |
num = val+len; |
|
346 |
val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; |
|
347 |
if (num >= PACKET_BUFFER_SIZE) |
|
348 |
num -= PACKET_BUFFER_SIZE; |
|
349 |
while(num != send_buf_last) { |
|
350 |
if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS) |
|
351 |
return; // error |
|
352 |
} |
|
353 |
send_buf_last = val; // set new end of buffer |
|
354 |
return; |
|
355 |
} |
|
356 |
} |
|
281 | 357 |
break; |
282 | 358 |
case 1: |
283 | 359 |
// no ack |
284 |
// TODO: check resend attempts |
|
285 |
setack(num,ACK_FAILURE); |
|
286 |
break; |
|
360 |
// check resend attempts |
|
361 |
val = send_buf_first; |
|
362 |
if (send_buf_num_packets == 0) |
|
363 |
return; |
|
364 |
while (1) { |
|
365 |
len = send_buf_get(&val); |
|
366 |
if (send_buf_get(&val) != num) { |
|
367 |
// not the correct packet, so continue |
|
368 |
val += len; |
|
369 |
if (val >= PACKET_BUFFER_SIZE) |
|
370 |
val -= PACKET_BUFFER_SIZE; |
|
371 |
if (val == send_buf_last) { |
|
372 |
// reached end of bufer, so assume not present |
|
373 |
setack(num,ACK_FAILURE); // mark as failed send |
|
374 |
return; |
|
375 |
} |
|
376 |
} else { |
|
377 |
// check attempts on packet |
|
378 |
num = val+len-1; // set to end of packet |
|
379 |
if (num >= PACKET_BUFFER_SIZE) |
|
380 |
num -= PACKET_BUFFER_SIZE; |
|
381 |
if (send_buf[num] < NUM_RETRIES) { |
|
382 |
val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; // set to start of this packet |
|
383 |
// retry sending |
|
384 |
send_buf[num]++; // increment retries |
|
385 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // go back one byte |
|
386 |
if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,len+1) != WL_SUCCESS) { |
|
387 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
388 |
return; |
|
389 |
} |
|
390 |
len = XBEE_FRAME_TX_REQUEST_16; |
|
391 |
while(val!=num) { |
|
392 |
// compute checksum |
|
393 |
len += send_buf[val]; |
|
394 |
if (xbee_putc(send_buf_get(&val)) != WL_SUCCESS) { // send byte |
|
395 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
396 |
return; |
|
397 |
} |
|
398 |
} |
|
399 |
len = 0xFF - len; |
|
400 |
if (xbee_putc(len) != WL_SUCCESS) { // send |
|
401 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
402 |
return; |
|
403 |
} |
|
404 |
return; |
|
405 |
} else { |
|
406 |
// done sending, mark as failed send |
|
407 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to frame num |
|
408 |
setack(send_buf[val],ACK_FAILURE); |
|
409 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to start of this packet |
|
410 |
// remove packet |
|
411 |
while(num != send_buf_last) { |
|
412 |
if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS) |
|
413 |
return; // error |
|
414 |
} |
|
415 |
return; |
|
416 |
} |
|
417 |
} |
|
418 |
} |
|
419 |
break; // shouldn't get here, but just in case |
|
287 | 420 |
case 2: |
288 | 421 |
// CCA failure |
289 |
// TODO: check resend attempts |
|
290 |
setack(num,CCA_FAILURE); |
|
291 |
break; |
|
422 |
// check resend attempts |
|
423 |
val = send_buf_first; |
|
424 |
if (send_buf_num_packets == 0) |
|
425 |
return; |
|
426 |
while (1) { |
|
427 |
len = send_buf_get(&val); |
|
428 |
if (send_buf_get(&val) != num) { |
|
429 |
// not the correct packet, so continue |
|
430 |
val += len; |
|
431 |
if (val >= PACKET_BUFFER_SIZE) |
|
432 |
val -= PACKET_BUFFER_SIZE; |
|
433 |
if (val == send_buf_last) { |
|
434 |
// reached end of bufer, so assume not present |
|
435 |
setack(num,CCA_FAILURE); // mark as failed send |
|
436 |
return; |
|
437 |
} |
|
438 |
} else { |
|
439 |
// check attempts on packet |
|
440 |
num = val+len-1; // set to end of packet |
|
441 |
if (num >= PACKET_BUFFER_SIZE) |
|
442 |
num -= PACKET_BUFFER_SIZE; |
|
443 |
if (send_buf[num] < NUM_RETRIES) { |
|
444 |
val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; // set to start of this packet |
|
445 |
// retry sending |
|
446 |
send_buf[num]++; // increment retries |
|
447 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // go back one byte |
|
448 |
if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,len+1) != WL_SUCCESS) { |
|
449 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
450 |
return; |
|
451 |
} |
|
452 |
len = XBEE_FRAME_TX_REQUEST_16; |
|
453 |
while(val!=num) { |
|
454 |
// compute checksum |
|
455 |
len += send_buf[val]; |
|
456 |
if (xbee_putc(send_buf_get(&val)) != WL_SUCCESS) { // send byte |
|
457 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
458 |
return; |
|
459 |
} |
|
460 |
} |
|
461 |
len = 0xFF - len; |
|
462 |
if (xbee_putc(len) != WL_SUCCESS) { // send |
|
463 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
464 |
return; |
|
465 |
} |
|
466 |
return; |
|
467 |
} else { |
|
468 |
// done sending, mark as failed send |
|
469 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to frame num |
|
470 |
setack(send_buf[val],CCA_FAILURE); |
|
471 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to start of this packet |
|
472 |
// remove packet |
|
473 |
while(num != send_buf_last) { |
|
474 |
if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS) |
|
475 |
return; // error |
|
476 |
} |
|
477 |
return; |
|
478 |
} |
|
479 |
} |
|
480 |
} |
|
481 |
break; // shouldn't get here, but just in case |
|
482 |
} |
|
292 | 483 |
} |
293 | 484 |
|
485 |
/* adds a byte to the send buffer */ |
|
486 |
int8_t send_buf_add(uint8_t *ptr, uint8_t byte) { |
|
487 |
if (*ptr == send_buf_first) { |
|
488 |
// buffer full |
|
489 |
WL_DEBUG_PRINT("send buffer full\r\n"); |
|
490 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
491 |
} |
|
492 |
send_buf[(*ptr)++] = byte); |
|
493 |
if (*ptr == PACKET_BUFFER_SIZE) |
|
494 |
*ptr = 0; |
|
495 |
return WL_SUCCESS; |
|
496 |
} |
|
497 |
/* gets a byte from the send buffer */ |
|
498 |
uint8_t send_buf_get(uint8_t *ptr) { |
|
499 |
uint8_t byte = xbee_basic_buf[(*ptr)++]; |
|
500 |
if (*ptr == PACKET_BUFFER_SIZE) |
|
501 |
*ptr = 0; |
|
502 |
return byte; |
|
503 |
} |
branches/wireless/code/projects/libwireless/wl_defs.h | ||
---|---|---|
121 | 121 |
|
122 | 122 |
/**@} */ // end error group |
123 | 123 |
|
124 |
// TODO: is this a good size? |
|
125 |
/*Buffer sizes*/ |
|
126 |
#define PACKET_BUFFER_SIZE 128 |
|
127 |
|
|
124 | 128 |
/**@} */ // end wireless group |
125 | 129 |
|
126 | 130 |
#ifdef WL_DEBUG |
branches/wireless/code/projects/libwireless/xbee.h | ||
---|---|---|
57 | 57 |
/**@defgroup xbee_const xbee constants |
58 | 58 |
* @brief These are constants used for the xbee module. |
59 | 59 |
* @{ **/ |
60 |
|
|
61 |
// TODO: move constants to xbee.h so they can be used publicly |
|
62 |
|
|
63 |
/**@brief The port to use the XBee from on the computer. **/ |
|
64 |
#ifndef ROBOT |
|
65 |
#define XBEE_PORT_DEFAULT "/dev/ttyUSB1" |
|
60 |
|
|
61 |
#ifndef XBEE_BAUD |
|
62 |
/** @brief The XBee baud rate **/ |
|
63 |
#define XBEE_BAUD 115200 |
|
66 | 64 |
#endif |
67 | 65 |
|
68 | 66 |
/**@name xbee options |
... | ... | |
104 | 102 |
|
105 | 103 |
/** @} **/ |
106 | 104 |
|
107 |
|
|
108 |
// TODO: is this a good size? |
|
109 |
/*Buffer sizes*/ |
|
110 |
#define XBEE_BUFFER_SIZE 128 |
|
111 |
#define PACKET_BUFFER_SIZE 108 |
|
112 |
|
|
113 | 105 |
/**@} **/ // end const group |
114 | 106 |
|
115 | 107 |
/** |
... | ... | |
121 | 113 |
// TODO: convert all int references to int16_t syntax (see stdint.h) |
122 | 114 |
|
123 | 115 |
/**@brief Initialize the XBee library **/ |
124 |
int xbee_lib_init(void);
|
|
116 |
int8_t xbee_init(void);
|
|
125 | 117 |
/**@brief Uninitialize the XBee library **/ |
126 |
void xbee_terminate(void); |
|
118 |
int8_t xbee_terminate(void); |
|
119 |
/**@brief Send a byte to the xbee **/ |
|
120 |
int8_t xbee_putc(uint8_t c); |
|
121 |
/**@brief Read a byte form the xbee **/ |
|
122 |
int16_t xbee_getc(void); |
|
123 |
/**@brief Read a byte from the xbee (nonblocking) **/ |
|
124 |
int8_t xbee_getc_nb(uint8_t *c); |
|
125 |
/**@brief Send an array of bytes to the xbee **/ |
|
126 |
int8_t xbee_send(uint8_t* buf, uint16_t size); |
|
127 |
/**@brief Add a buffer to the checksum value **/ |
|
128 |
int8_t xbee_checksum_add(uint8_t *buf, uint8_t len, uint8_t* sum); |
|
129 |
/**@brief Send a frame header to the xbee **/ |
|
130 |
int8_t xbee_send_header(uint8_t type, uint16_t len); |
|
127 | 131 |
/**@brief Send a packet to the XBee **/ |
128 |
int xbee_send_packet(char* packet, int len, int dest, char options, char frame);
|
|
132 |
int8_t xbee_send_packet(uint8_t* packet, uint8_t len, uint16_t dest, uint8_t options, uint8_t frame);
|
|
129 | 133 |
/**@brief Set the PAN ID for the XBee **/ |
130 |
int xbee_set_pan_id(int id); |
|
134 |
int16_t xbee_set_pan_id(int id);
|
|
131 | 135 |
/**@brief Get the XBee's PAN ID **/ |
132 |
unsigned int xbee_get_pan_id(void);
|
|
136 |
uint16_t xbee_get_pan_id(void);
|
|
133 | 137 |
/**@brief Set the channel the XBee is currently using **/ |
134 |
int xbee_set_channel(int channel); |
|
138 |
int8_t xbee_set_channel(int channel);
|
|
135 | 139 |
/**@brief Get the channel the XBee is currently using **/ |
136 |
int xbee_get_channel(void); |
|
140 |
int8_t xbee_get_channel(void);
|
|
137 | 141 |
/**@brief Get the XBee's 16-bit address **/ |
138 |
unsigned int xbee_get_address(void); |
|
139 |
/**@brief Set the com port on a computer, undefined on the robot**/ |
|
140 |
void xbee_set_com_port(char* port); |
|
142 |
uint16_t xbee_get_address(void); |
|
141 | 143 |
/**@brief Reset XBee **/ |
142 |
int xbee_reset(void);
|
|
144 |
int8_t xbee_reset(void); // TODO: implement this function
|
|
143 | 145 |
|
144 | 146 |
/**@} **/ //end xbee_funcs group |
145 | 147 |
|
branches/wireless/code/projects/libwireless/wireless.c | ||
---|---|---|
93 | 93 |
// reset packet handler array |
94 | 94 |
memset(wl_packet_handlers, sizeof(PacketGroupHandler)*MAX_PACKET_GROUPS, 0); |
95 | 95 |
|
96 |
// TODO need pass termination error from lower level functions |
|
97 |
xbee_terminate(); |
|
98 |
// if(TERMINATE FAILS) { |
|
99 |
// return WL_ERROR_TERMINATION_FAILED |
|
100 |
// } |
|
96 |
if(xbee_terminate() != WL_SUCCESS) { |
|
97 |
return WL_ERROR_TERMINATION_FAILED |
|
98 |
} |
|
101 | 99 |
|
102 | 100 |
return WL_SUCCESS; |
103 | 101 |
} |
... | ... | |
118 | 116 |
return WL_ERROR_LIBRARY_NOT_INITD; |
119 | 117 |
} |
120 | 118 |
|
121 |
// packet group number exceeds available packets groups |
|
122 |
if(group >= MAX_PACKET_GROUPS) { |
|
119 |
// packet group number exceeds available packets groups |
|
120 |
// or packet group handler already exists |
|
121 |
if(group >= MAX_PACKET_GROUPS || group == 0 |
|
122 |
|| wl_packet_handlers[group].FUNC != NULL) { |
|
123 | 123 |
return WL_ERROR_FAILED_REGISTRATION; |
124 | 124 |
} |
125 |
|
|
126 |
// packet group handler already exists, user needs to unregister first |
|
127 |
if(wl_packet_handlers[group].FUNC != NULL) { |
|
128 |
return WL_ERROR_FAILED_REGISTRATION; |
|
129 |
} |
|
130 | 125 |
|
131 | 126 |
// save packet handler function pointer and priority |
132 | 127 |
wl_packet_handlers[group].FUNC = FUNC; |
branches/wireless/code/projects/libdragonfly/serial.c | ||
---|---|---|
39 | 39 |
#include "serial.h" |
40 | 40 |
|
41 | 41 |
unsigned char usb_initd=0; |
42 |
unsigned char xbee_initd=0; |
|
43 | 42 |
|
44 | 43 |
#ifdef USE_STDIO |
45 | 44 |
|
... | ... | |
50 | 49 |
**/ |
51 | 50 |
FILE *usb_fd; |
52 | 51 |
|
53 |
/** |
|
54 |
* For use with fprintf() and related stdio functions |
|
55 |
**/ |
|
56 |
FILE *xbee_fd; |
|
57 |
|
|
58 | 52 |
#endif |
59 | 53 |
|
60 | 54 |
/** |
... | ... | |
100 | 94 |
|
101 | 95 |
} |
102 | 96 |
|
103 |
/** |
|
104 |
* Initializes communication over the XBee. |
|
105 |
* This must be called before any other xbee function |
|
106 |
* may be used. |
|
107 |
**/ |
|
108 |
int xbee_init() { |
|
109 | 97 |
|
110 |
if(xbee_initd) { |
|
111 |
return ERROR_INIT_ALREADY_INITD; |
|
112 |
} |
|
113 |
|
|
114 |
//Set baud rate |
|
115 |
// - 115200 (both wired and wireless) is UBRR=8, U2X=1 |
|
116 |
// - 9600 is U2X =1, UBRR = 107. |
|
117 |
#if (XBEE_BAUD == 115200) |
|
118 |
UBRR1H = 0x00; |
|
119 |
UBRR1L = 8; |
|
120 |
UCSR1A |= _BV(U2X1); |
|
121 |
#elif (XBEE_BAUD == 9600) |
|
122 |
UBRR1H = 0x00; |
|
123 |
UBRR1L = 103; |
|
124 |
UCSR1A |= _BV(U2X1); |
|
125 |
#else //Baud rate is defined in the header file, we should not get here |
|
126 |
return 0; |
|
127 |
#endif |
|
128 |
|
|
129 |
//Enable receiver and transmitter |
|
130 |
UCSR1B |= (1<<RXEN1)|(1<<TXEN1); |
|
131 |
|
|
132 |
// Set frame format: 8data, 1stop bit, asynchronous normal mode |
|
133 |
UCSR1C |= (1<<UCSZ10) | (1<<UCSZ11); |
|
134 |
|
|
135 |
// if we have enabled the stdio stuff, then we init it here |
|
136 |
#ifdef USE_STDIO |
|
137 |
/* Open the stdio stream corresponding to this port */ |
|
138 |
xbee_fd = fdevopen(xbee_putc, xbee_getc); |
|
139 |
#endif |
|
140 |
|
|
141 |
xbee_initd = 1; |
|
142 |
return 0; |
|
143 |
|
|
144 |
} |
|
145 |
|
|
146 | 98 |
/** |
147 | 99 |
* Sends a character over USB. |
148 | 100 |
* |
... | ... | |
163 | 115 |
} |
164 | 116 |
|
165 | 117 |
/** |
166 |
* Sends a character to the XBee. |
|
167 |
* |
|
168 |
* @param c the character to send |
|
169 |
* @return 0 for success, nonzero for failure |
|
170 |
**/ |
|
171 |
int xbee_putc(char c) { |
|
172 |
|
|
173 |
if(!xbee_initd) |
|
174 |
return ERROR_LIBRARY_NOT_INITD; |
|
175 |
|
|
176 |
// Wait until buffer is clear for sending |
|
177 |
loop_until_bit_is_set(UCSR1A, UDRE1); |
|
178 |
|
|
179 |
// Load buffer with your character |
|
180 |
UDR1 = c; |
|
181 |
return 0; |
|
182 |
} |
|
183 |
|
|
184 |
/** |
|
185 | 118 |
* Sends a sequence of characters over USB. |
186 | 119 |
* |
187 | 120 |
* @param s the string to send |
... | ... | |
245 | 178 |
} |
246 | 179 |
|
247 | 180 |
/** |
248 |
* Returns the first character in the buffer received from USB. |
|
249 |
* This function blocks execution until a character has been |
|
250 |
* received. xbee_init must be called before this function |
|
251 |
* may be used. |
|
252 |
* |
|
253 |
* @return the first character in the xbee buffer, -1 on error |
|
254 |
* |
|
255 |
* @see xbee_init, xbee_getc_nb |
|
256 |
**/ |
|
257 |
int xbee_getc(void) { |
|
258 |
|
|
259 |
if(!usb_initd) |
|
260 |
return -1; |
|
261 |
|
|
262 |
// Wait for the receive buffer to be filled |
|
263 |
loop_until_bit_is_set(UCSR1A, RXC1); |
|
264 |
|
|
265 |
// Read the receive buffer |
|
266 |
return UDR1; |
|
267 |
} |
|
268 |
|
|
269 |
/** |
|
270 | 181 |
* Non blocking version of usb_getc. If a character is present in the buffer, |
271 | 182 |
* it is returned, otherwise -1 is returned immediately. usb_init must be |
272 | 183 |
* called before this function can be used. |
... | ... | |
294 | 205 |
} |
295 | 206 |
} |
296 | 207 |
|
297 |
/** |
|
298 |
* Non blocking version of xbee_getc. If a character is present in the buffer, |
|
299 |
* it is returned, otherwise -1 is returned immediately. xbee_init |
|
300 |
* must be called before this function can be used. |
|
301 |
* |
|
302 |
* @param c the received character. This will be set if a character has |
|
303 |
* been received. |
|
304 |
* |
|
305 |
* @return -1 if no character is available, 0 otherwise, positive for error |
|
306 |
* |
|
307 |
* @see xbee_init, xbee_getc |
|
308 |
**/ |
|
309 |
int xbee_getc_nb(char *c) { |
|
310 |
if(!xbee_initd) |
|
311 |
return ERROR_LIBRARY_NOT_INITD; |
|
312 |
|
|
313 |
// check if the receive buffer is filled |
|
314 |
if (UCSR1A & _BV(RXC1)) { |
|
315 |
// Read the receive buffer |
|
316 |
(*c) = UDR1; |
|
317 |
return 0; |
|
318 |
} else { |
|
319 |
// Return empty |
|
320 |
return -1; |
|
321 |
} |
|
322 |
} |
|
323 |
|
|
324 |
|
|
325 | 208 |
/* |
326 | 209 |
prints an int to serial |
327 | 210 |
|
branches/wireless/code/projects/libdragonfly/serial.h | ||
---|---|---|
107 | 107 |
/** @brief Print a fixed width hexadecimal representation to USB **/ |
108 | 108 |
int usb_puth8(uint8_t value); |
109 | 109 |
/** @brief Alias for usb_puth16 **/ |
110 |
static inline void usb_puth (uint16_t value) { usb_puth16 (value); };
|
|
110 |
static inline void usb_puth(uint16_t value) { usb_puth16 (value); }; |
|
111 | 111 |
|
112 |
|
|
113 | 112 |
/** @} **/ //end addtogroup |
114 | 113 |
|
115 |
/** |
|
116 |
* @defgroup xbee XBee Input / Output |
|
117 |
* @brief Functions for XBee input / output |
|
118 |
* |
|
119 |
* Low level functions for XBee input and output. |
|
120 |
* |
|
121 |
* @{ |
|
122 |
**/ |
|
123 |
|
|
124 |
// if no baud rate is defined for usb, default is set here |
|
125 |
|
|
126 |
// if no baud rate is defined for xbee, default is set here |
|
127 |
#ifndef XBEE_BAUD |
|
128 |
/** @brief the XBee baud rate **/ |
|
129 |
#define XBEE_BAUD 9600 |
|
130 | 114 |
#endif |
131 | 115 |
|
132 |
/** @brief Initialize the XBee **/ |
|
133 |
int xbee_init(void); |
|
134 |
/** @brief Print a character to the XBee **/ |
|
135 |
int xbee_putc(char c); |
|
136 |
/** @brief Read a character from the XBee **/ |
|
137 |
int xbee_getc(void); |
|
138 |
/** @brief Read a character from the XBee without blocking **/ |
|
139 |
int xbee_getc_nb(char *c); |
|
140 |
|
|
141 |
|
|
142 |
|
|
143 |
/** @} **/ //end addtogroup |
|
144 |
|
|
145 |
#endif |
|
146 |
|
Also available in: Unified diff