Project

General

Profile

Revision 1604

wireless: software retransmit done. serial functions moved to xbee.c

View differences:

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