Project

General

Profile

Revision 1600

wireless: xbee update. still not finished, but the major changes are in here. Also added a function for microsecond delays to time.c

View differences:

branches/wireless/code/projects/unit_tests/main.c
15 15
    // RUN_TEST(testlcd);
16 16
    //RUN_TEST(testlights);
17 17
    //RUN_TEST(testmotors);
18
    RUN_TEST(testrangefinder);
18
    //RUN_TEST(testrangefinder);
19 19
    // RUN_TEST(testtokenring);
20 20
    // RUN_TEST(testwireless);
21 21
    //RUN_TEST(testxbee);
branches/wireless/code/projects/libwireless/xbee_computer.c
1
// this is all the xbee.c computer code
2

  
3

  
4
static int xbee_send(char* buf, int size)
5
#else
6

  
7
	int ret = write(xbee_stream, buf, size);
8
	//success
9
	if (ret == size)
10
		return 0;
11
	if (ret == -1)
12
	{
13
		//interrupted by system signal, probably timer interrupt.
14
		//just try again
15
		if (errno == 4)
16
		{
17
			return xbee_send(buf, size);
18
		}
19
		WL_DEBUG_PRINT("Failed to write to xbee\r\n");
20
		return -1;
21
	}
22

  
23
	//write was interrupted after writing ret bytes
24
	return xbee_send(buf + ret, size - ret);
25
#endif
26

  
27

  
28
#ifndef ROBOT
29
static int xbee_read(char* buf, int size)
30
{
31
	if (read(xbee_stream, buf, size) == -1) {
32
		WL_DEBUG_PRINT("Failed to read from xbee.\r\n");
33
		return -1;
34
	}
35

  
36
	return 0;
37
}
38
#endif
39

  
40

  
41
#ifndef ROBOT
42
void xbee_set_com_port(char* port)
43
{
44
	xbee_com_port = port;
45
}
46
#endif
47

  
branches/wireless/code/projects/libwireless/xbee.c
100 100
static pthread_t* xbee_listen_thread;
101 101
#endif
102 102

  
103
// TODO: clarify buffers, what they're used for, etc
104 103

  
105
// a buffer for data received from the XBee
106
char arrival_buf[XBEE_BUFFER_SIZE];
107
// location of last unread byte in buffer
108
volatile int buffer_last = 0;
109
// first unread byte in buffer
110
volatile int buffer_first = 0;
111

  
112

  
113
// old xbee buf
114
static char xbee_buf[PACKET_BUFFER_SIZE];
115
static int currentBufPos = 0;
116

  
117 104
// array for basic packets
118 105
static uint8_t xbee_basic_buf[PACKET_BUFFER_SIZE];
119 106

  
......
134 121
// aka, the first free byte in other buffer
135 122
static uint8_t other_buf_last = 0;
136 123

  
137
//XBee status
138
static unsigned int xbee_panID = XBEE_PAN_DEFAULT;
139
static unsigned int xbee_pending_panID = XBEE_PAN_DEFAULT;
140
static int xbee_channel = XBEE_CHANNEL_DEFAULT;
141
static int xbee_pending_channel = XBEE_CHANNEL_DEFAULT;
142
static volatile unsigned int xbee_address = 0;
143 124

  
125
// TODO: do we need these?
126
static uint16_t xbee_panID = XBEE_PAN_DEFAULT;
127
static uint8_t xbee_channel = XBEE_CHANNEL_DEFAULT;
128
static uint16_t xbee_address = 0;
144 129

  
130

  
131
// xbee status
132
#define XBEE_API_OFF 0x0
133
#define XBEE_API_ON 0x1
134
#define XBEE_API_ESCAPE 0x2
135
#define XBEE_NORMAL 0x00
136
#define XBEE_COMMAND_WAIT 0x80
137
#define XBEE_COMMAND_RESPONSE 0xC0
138
static uint8_t xbee_status = XBEE_API_OFF|XBEE_NORMAL;
139

  
140
// xbee command response (for PAN, channel, address, etc)
141
static uint8_t xbee_command[4];
142

  
145 143
// external ack handler (wireless_send.c)
146 144
extern void ackhandle(uint8_t num,uint8_t val);
147 145

  
148 146
/**@addtogroup xbee
149 147
 * @{ **/
150 148

  
151

  
152 149
/*Function Implementations*/
153 150

  
154 151
#ifdef ROBOT
......
171 168
	uint8_t apitype = PORT; // get frame start byte
172 169
  uint16_t i=0;
173 170
  uint16_t len=0;
171
  
172
  // check that we're in API mode
173
  if (xbee_status&0x03 == XBEE_API_OFF || apitype != XBEE_FRAME_START) {
174
    // not in API mode
175
    if (xbee_status&0xC0) == XBEE_COMMAND_WAIT) {
176
      // get rest of command and put in basic buf
177
      xbee_basic_buf[0] = apitype;
178
      if (xbee_basic_buf[i] != '\r') {
179
        while(i < PACKET_BUFFER_SIZE) {
180
          if (FLAG) {
181
            xbee_basic_buf[i] = PORT;
182
            if (xbee_basic_buf[i] == '\r')
183
              break;
184
          }
185
        }
186
      }
187
      // signal handler that command response is done
188
      xbee_status |= XBEE_COMMAND_RESPONSE;
189
    }
190
    return;
191
  }
192
    
174 193
  // get length and type
175 194
  while(i<3) {
176 195
    if (FLAG) {
......
187 206
  // do something based on the type
188 207
  i=1;
189 208
  switch(apitype) {
190
  case 0x88:
209
  case XBEE_FRAME_AT_COMMAND_RESPONSE:
191 210
    // AT command response
211
    if (xbee_status&0xC0 == XBEE_COMMAND_RESPONSE)
212
      return; // we're currently processing a command, so drop the incoming one
192 213
    uint16_t atcommand=0;
193 214
    uint8_t ptr=basic_buf_last;
194 215
    while(i<len) {
......
203 224
          apitype = PORT; // get status
204 225
        else {
205 226
          // put the command response on the basic buf temporarily
206
          if (ptr == basic_buf_first) {
207
            // buffer full
208
            WL_DEBUG_PRINT("basic buffer full\r\n");
227
          if (xbee_basic_buf_add(&ptr,PORT) != 0)
209 228
            break;
210
          }
211
          xbee_basic_buf[ptr++]=PORT;
212
          if (ptr == PACKET_BUFFER_SIZE)
213
            ptr = 0;
214 229
        }
215 230
        i++;
216 231
      }
217
    }
218
    // handle AT command
219
    xbee_handle_at_command_response(atcommand,apitype,xbee_basic_buf+basic_buf_last,len-5);
232
    }  
233
    // handle AT command  
234
    xbee_handle_at_command_response(atcommand,apitype,i-5); // TODO: rewrite function
220 235
    break;
221
  case 0x89:
236
  case XBEE_FRAME_TX_STATUS:
222 237
    // TX status
223 238
    uint8_t frameid=0;
224 239
    while(i<len) {
......
233 248
      }
234 249
    }
235 250
    break;
236
  case 0x80:
251
  case XBEE_FRAME_RX_64:
237 252
    // receive a packet with 64bit address
238
    break; // not implemented yet
239
  case 0x81:
253
    break; // TODO: implement this (even if we don't use it)
254
  case XBEE_FRAME_RX_16:
240 255
    // receive a packet with 16bit address
241 256
    uint16_t source = 0;
242 257
    uint8_t framenum = 0;
......
265 280
          if (group == 0) {
266 281
            ptr = basic_buf_last+1;
267 282
            // add source to buffer
268
            if (ptr == basic_buf_first) {
269
              // buffer full
270
              WL_DEBUG_PRINT("basic buffer full\r\n");
283
            if (xbee_basic_buf_add(&ptr,(uint8_t)((source&0xFF00)>>8)) != 0)
271 284
              break;
272
            }
273
            xbee_basic_buf[ptr++] = (uint8_t)((source&0xFF00)>>8);
274
            if (ptr == PACKET_BUFFER_SIZE)
275
              ptr = 0;
276
            if (ptr == basic_buf_first) {
277
              // buffer full
278
              WL_DEBUG_PRINT("basic buffer full\r\n");
285
            if (xbee_basic_buf_add(&ptr,(uint8_t)(source&0x00FF)) != 0)
279 286
              break;
280
            }
281
            xbee_basic_buf[ptr++] = (uint8_t)(source&0x00FF);
282
            if (ptr == PACKET_BUFFER_SIZE)
283
              ptr = 0;
284 287
          } else {
285 288
            ptr = other_buf_last+1;
286
            // add source and group to buffer            
287
            if (ptr == other_buf_first) {
288
              // buffer full
289
              WL_DEBUG_PRINT("other buffer full\r\n");
289
            // add source and group to buffer
290
            if (xbee_other_buf_add(&ptr,group) != 0)
290 291
              break;
291
            }
292
            xbee_other_buf[ptr++] = group;
293
            if (ptr == PACKET_BUFFER_SIZE)
294
              ptr = 0;
295
            if (ptr == other_buf_first) {
296
              // buffer full
297
              WL_DEBUG_PRINT("other buffer full\r\n");
292
            if (xbee_other_buf_add(&ptr,(uint8_t)((source&0xFF00)>>8)) != 0)
298 293
              break;
299
            }
300
            xbee_other_buf[ptr++] = (uint8_t)((source&0xFF00)>>8);
301
            if (ptr == PACKET_BUFFER_SIZE)
302
              ptr = 0;
303
            if (ptr == other_buf_first) {
304
              // buffer full
305
              WL_DEBUG_PRINT("other buffer full\r\n");
294
            if (xbee_other_buf_add(&ptr,(uint8_t)(source&0x00FF)) != 0)
306 295
              break;
307
            }
308
            xbee_other_buf[ptr++] = (uint8_t)(source&0x00FF);
309
            if (ptr == PACKET_BUFFER_SIZE)
310
              ptr = 0;
311 296
          }
312 297
        }
313
        else {
298
        else { // TODO: handle escaped characters supported by APIv2
314 299
          // put packet data on the correct buffer
315
          if (group == 0) {
316
            if (ptr == basic_buf_first) {
317
              // buffer full
318
              WL_DEBUG_PRINT("basic buffer full\r\n");
319
              break;
320
            }
321
            xbee_basic_buf[ptr++]=PORT;
322
            if (ptr == PACKET_BUFFER_SIZE)
323
              ptr = 0;
324
          } else {
325
            if (ptr == other_buf_first) {
326
              // buffer full
327
              WL_DEBUG_PRINT("other buffer full\r\n");
328
              break;
329
            }
330
            xbee_other_buf[ptr++]=PORT;
331
            if (ptr == PACKET_BUFFER_SIZE)
332
              ptr = 0;
333
          }
300
          if (group == 0 && xbee_basic_buf_add(&ptr,PORT) != 0)
301
            break;
302
          else if (xbee_other_buf_add(&ptr,PORT) != 0)
303
            break;
334 304
        }
335 305
        i++;
336 306
      }
337 307
    }
338
    if (ptr != 0xFF) {
308
    if (ptr != 0xFF && i > 6) {
339 309
      if (group == 0) {
340 310
        xbee_basic_buf[basic_buf_last] = i-6; // set length
341 311
        basic_buf_last = ptr;
......
356 326
      }
357 327
    }
358 328
    break;
329
  } // end of switch statement
330
  while (1) {
331
    if (FLAG) {
332
      apitype = PORT; // get checksum, and ignore
333
      break;
334
    }
359 335
  }
360 336
} // end of interrupt
361 337

  
......
394 370

  
395 371
#endif
396 372

  
373
/* adds a byte to the basic buffer */
374
int8_t xbee_basic_buf_add(uint8_t *ptr, uint8_t byte) {
375
  if (*ptr == basic_buf_first) {
376
    // buffer full
377
    WL_DEBUG_PRINT("basic buffer full\r\n");
378
    return -1;
379
  }
380
  xbee_basic_buf[(*ptr)++] = byte);
381
  if (*ptr == PACKET_BUFFER_SIZE)
382
    *ptr = 0;
383
  return 0;
384
}
385
/* adds a byte to the other buffer */
386
int8_t xbee_other_buf_add(uint8_t *ptr, uint8_t byte) {
387
  if (*ptr == other_buf_first) {
388
    // buffer full
389
    WL_DEBUG_PRINT("other buffer full\r\n");
390
    return -1;
391
  }
392
  xbee_other_buf[(*ptr)++] = byte;
393
  if (ptr == PACKET_BUFFER_SIZE)
394
    *ptr = 0;
395
  return 0;
396
}
397

  
398

  
397 399
/**
398 400
 * Initializes the XBee library so that other functions may be used.
399 401
 **/
400
int xbee_lib_init()
402
int8_t xbee_lib_init()
401 403
{
404
  // do serial.c xbee init     TODO: merge this into xbee.c
402 405
  if (xbee_init() != 0) {
403 406
    usb_puts("xbee_init error");
404
    return -1;
407
    return WL_ERROR_INIT_FAILED;
405 408
  }
406 409

  
407 410
	WL_DEBUG_PRINT("in xbee_init\n");
......
558 561
	
559 562
	WL_DEBUG_PRINT("Left command mode.\r\n");
560 563
  
561
  // get MY address
564
  // get baud rate
562 565
	if (xbee_send_read_at_command("BD")) {
563 566
    WL_DEBUG_PRINT("can't send BD command\r\n");
564 567
		return -1;
......
631 634
 * @param buf the buffer of data to send
632 635
 * @param size the number of bytes to send
633 636
 **/
634
static int xbee_send(char* buf, int size)
637
static int8_t xbee_send(uint8_t* buf, uint16_t size)
635 638
{
636
#ifdef ROBOT
637
	int i;
638
	for (i = 0; i < size; i++) {
639
		xbee_putc(buf[i]);
640
	}
639
	while(--size > 0)
640
		if (xbee_putc(buf[i]) != WL_SUCCESS)
641
      return WL_ERROR_SEND;
642
	}  
643
  if (xbee_putc(buf[0]) != WL_SUCCESS)
644
    return WL_ERROR_SEND;
641 645

  
642
	return 0;
643

  
644
#else
645

  
646
	int ret = write(xbee_stream, buf, size);
647
	//success
648
	if (ret == size)
649
		return 0;
650
	if (ret == -1)
651
	{
652
		//interrupted by system signal, probably timer interrupt.
653
		//just try again
654
		if (errno == 4)
655
		{
656
			return xbee_send(buf, size);
657
		}
658
		WL_DEBUG_PRINT("Failed to write to xbee\r\n");
659
		return -1;
660
	}
661

  
662
	//write was interrupted after writing ret bytes
663
	return xbee_send(buf + ret, size - ret);
664
#endif
646
	return WL_SUCCESS;
665 647
}
666 648

  
667 649
/**
......
669 651
 *
670 652
 * @param c the string to send to the XBEE
671 653
 **/
672
static int xbee_send_string(char* c)
654
static int8_t xbee_send_string(unsigned char* c)
673 655
{
674 656
	return xbee_send(c, strlen(c));
675 657
}
676 658

  
677
#ifndef ROBOT
678
static int xbee_read(char* buf, int size)
679
{
680
	if (read(xbee_stream, buf, size) == -1) {
681
		WL_DEBUG_PRINT("Failed to read from xbee.\r\n");
682
		return -1;
683
	}
684 659

  
685
	return 0;
686
}
687
#endif
688

  
689 660
/**
690 661
 * Enter into command mode.
691 662
 **/
692
static int xbee_enter_command_mode()
663
static int8_t xbee_enter_command_mode()
693 664
{
694 665
	if (xbee_send_string("+++") != 0) {
695 666
		return -1;
......
704 675
/**
705 676
 * Exit from command mode.
706 677
 **/
707
static int xbee_exit_command_mode()
678
static int8_t xbee_exit_command_mode()
708 679
{
709 680
	if (xbee_send_string("ATCN\r") != 0) {
710 681
		return -1;
......
724 695
		return -1;
725 696
	}
726 697
	xbee_wait_for_ok();
698
  
699
  xbee_status = (xbee_status&0xFC)|XBEE_API_ON;
727 700

  
728 701
	return 0;
729 702
}
730 703

  
731 704
/**
705
 * Enter API mode 2.
706
 **/
707
static int xbee_enter_api_mode2()
708
{
709
	if (xbee_send_string("ATAP 2\r") != 0) {
710
		return -1;
711
	}
712
	xbee_wait_for_ok();
713
  
714
  xbee_status = (xbee_status&0xFC)|XBEE_API_ESCAPE;
715
  
716
	return 0;
717
}
718

  
719
/**
732 720
 * Exit API mode.
733 721
 **/
734 722
static int xbee_exit_api_mode()
......
736 724
	if (xbee_send_modify_at_command("AP","0") != 0) {
737 725
		return -1;
738 726
	}
727
  
728
  xbee_status = (xbee_status&0xFC)|XBEE_API_OFF;
739 729

  
740 730
	return 0;
741 731
}
......
757 747
 * @param s the string to receive
758 748
 * @param len the length of the string
759 749
 **/
760
static int xbee_wait_for_string(char* s, int len)
750
static int8_t xbee_wait_for_string(char* s, int len)
761 751
{
762
	char* curr = s;
763
  unsigned int i=0;
764
	while (curr - s < len) {
765
    WL_DEBUG_PRINT("waiting for string\r\n");
766
		// check if buffer is empty
767
		if (buffer_last != buffer_first) {
768
			char c = arrival_buf[buffer_first++];
769
			if (buffer_first == XBEE_BUFFER_SIZE) {
770
				buffer_first = 0;
771
			}
772
      WL_DEBUG_PRINT("buffer char|");
773
      WL_DEBUG_PRINT_CHAR(c);
774
      WL_DEBUG_PRINT("|\r\n");
752
  uint8_t i=0;
753
  if (xbee_status&0x03 == XBEE_API_OFF) {
754
    // wait until the response is received (only wait 1 second)
755
    while(xbee_status&0xC0 != XBEE_COMMAND_RESPONSE && i++ < 1000) {
756
      delay_us(1);
757
    }
758
    // check response
759
    if (i >= 1000 || memcmp(s,xbee_basic_buf,len) != 0) {
760
      // bad response
761
      WL_DEBUG_PRINT("Bad response when waiting for string ");
762
      WL_DEBUG_PRINT(s);
763
      WL_DEBUG_PRINT("\r\n");
764
      return -1;
765
    }
766
  }
775 767

  
776
			if (c == *curr) {
777
				curr++;
778
			} else {
779
#ifndef ROBOT
780
			  //return -1; // Computer is less forgiving.
781
			  curr = s;
782
#else
783
			  curr = s;
784
#endif
785
			}
786
		} // else buffer is empty.
787

  
788
#ifndef ROBOT
789
		usleep(100);
790
#endif
791
	}
792
  if (i >= 10000)
793
    return -1;
794

  
795 768
	return 0;
796 769
}
797 770

  
798 771
/**
772
 * Delay until we receive a command response.
773
 * (either OK\r or some actual value)
774
 *
775
 * Only works when not in API mode
776
 *
777
 * @param s the string to store the response in
778
 * @param len the length of the string
779
 */
780
static int8_t xbee_wait_for_response(char* s, int len) {
781
  uint8_t i=0;
782
  if (xbee_status&0x03 == XBEE_API_OFF) {
783
    // wait until the response is received (only wait 1 second)
784
    while(xbee_status&0xC0 != XBEE_COMMAND_RESPONSE && i++ < 1000) {
785
      delay_us(1);
786
    }
787
    // check response
788
    if (i >= 1000)
789
      return -1;
790
    } else {
791
      i=strcspn(xbee_basic_buf,"\r");
792
      if (i<PACKET_BUFFER_SIZE) {
793
        memcpy(s,xbee_basic_buf,i);
794
        return 0;
795
      }
796
      else
797
        return -1;      
798
    }
799
  }
800
  // TODO: do something for API mode
801
  
802
  return 0;
803
}
804

  
805
/**
799 806
 * Verifies that the packets checksum is correct.
800 807
 * (If the checksum is correct, the sum of the bytes
801 808
 * is 0xFF.)
......
826 833
 * @return the checksum of the packet, which will
827 834
 * become the last byte sent in the packet
828 835
 **/
829
char xbee_compute_checksum(char* buf, int len)
836
char xbee_compute_checksum(uint8_t* buf, uint16_t len)
830 837
{
831
	int i;
832
	unsigned char sum = 0;
833
	for (i = 0; i < len; i++)
834
		sum += (unsigned char)buf[i];
838
	uint8_t sum = 0;
839
	while(--len > 0) {
840
		sum += buf[len];
841
  }
842
  sum += buf[0];
835 843
	return 0xFF - sum;
836 844
}
837 845

  
......
844 852
 * @param len the size in bytes of the packet data
845 853
 *
846 854
 **/
847
static int xbee_send_frame(char* buf, int len)
855
static int8_t xbee_send_frame(uint8_t* buf, uint16_t len)
848 856
{
849
	char prefix[3];
857
	uint8_t prefix[3];
850 858
	prefix[0] = XBEE_FRAME_START;
851 859
	prefix[1] = (len & 0xFF00) >> 8;
852
	prefix[2] = len & 0xFF;
853
	char checksum = xbee_compute_checksum(buf, len);
860
	prefix[2] = len & 0x00FF;
861
	uint8_t checksum = xbee_compute_checksum(buf, len);
854 862

  
855 863
	if (xbee_send(prefix, 3) != 0) {
856
		return -1;
864
		return WL_ERROR_SEND;
857 865
	}
858 866

  
859 867
	if (xbee_send(buf, len) != 0) {
860
		return -1;
868
		return WL_ERROR_SEND;
861 869
	}
862 870

  
863 871
	if (xbee_send(&checksum, 1) != 0) {
864
		return -1;
872
		return WL_ERROR_SEND;
865 873
	}
866 874

  
867
	return 0;
875
	return WL_SUCCESS;
868 876
}
869 877

  
870 878
/**
......
874 882
 * use ID to read the PAN ID and MY to return the XBee ID.
875 883
 * See the XBee reference guide for a complete listing.
876 884
 **/
877
int xbee_send_read_at_command(char* command)
885
int8_t xbee_send_read_at_command(uint8_t* command)
878 886
{
879
	return xbee_send_modify_at_command(command, NULL);
887
	return xbee_send_modify_at_command(command, NULL, 0);
880 888
}
881 889

  
882 890
/**
......
886 894
 * @param value the value to pass as a parameter
887 895
 * (or NULL if there is no parameter)
888 896
 **/
889
static int xbee_send_modify_at_command(char* command, char* value)
897
static int8_t xbee_send_modify_at_command(uint8_t* command, uint8_t* value, uint8_t len)
890 898
{
891
	char buf[16];
892
	int i;
899
	uint8_t buf[12];
893 900

  
894 901
	buf[0] = XBEE_FRAME_AT_COMMAND;
895 902
	buf[1] = 1;
896 903
	buf[2] = command[0];
897 904
	buf[3] = command[1];
898
	int valueLen = 0;
899 905
	if (value != NULL)
900 906
	{
901
		valueLen = strlen(value);
902
		if (valueLen > 8)
907
		if (len > 8)
903 908
		{
904 909
			WL_DEBUG_PRINT("AT Command too large.\r\n");
905
			return -1;
910
			return WL_ERROR_ARGUMENT;
906 911
		}
907

  
908
		for (i = 0; i < valueLen; i++) {
909
			buf[4 + i] = value[i];
910
		}
912
    memcpy(buf+4,value,len);
911 913
	}
912 914

  
913
	return xbee_send_frame(buf, 4 + valueLen);
915
	return xbee_send_frame(buf, 4 + len);
914 916
}
915 917

  
916 918
/**
......
1222 1224
}
1223 1225

  
1224 1226
/**
1225
 * Attempts to handle the packet if it is dealt with
1226
 * by the library.
1227
 * We will handle the following packet types:
1228
 *    Modem Status
1229
 *    AT Command Response
1230
 *
1231
 * @param packet the packet to handle
1232
 * @param len the length of the packet
1233
 *
1234
 * @return 1 if we have handled the packet, 0 otherwise
1235
 */
1236
static int xbee_handle_packet(char* packet, int len)
1237
{
1238

  
1239
	char command[3] = {1, 2, 3};
1240
	if (len <= 0) //this should not happend
1241
	{
1242
		WL_DEBUG_PRINT("Non-positive packet length.\r\n");
1243
		return 0;
1244
	}
1245

  
1246
	switch ((unsigned char)packet[0]) //packet type
1247
	{
1248
		case XBEE_FRAME_STATUS:
1249
			xbee_handle_status(packet[1]);
1250
			return 1;
1251
		case XBEE_FRAME_AT_COMMAND_RESPONSE:
1252
			command[0] = packet[2];
1253
			command[1] = packet[3];
1254
			command[2] = 0;
1255
			if (xbee_handle_at_command_response(command, packet[4], packet + 5, len - 5) != 0)
1256
        return -1;
1257
      else
1258
        return 1;
1259
	}
1260
	return 0;
1261
}
1262

  
1263
/**
1264 1227
 * Sets the personal area network id.
1265 1228
 *
1266 1229
 * @param id the new personal area network (PAN) id
1267 1230
 **/
1268
int xbee_set_pan_id(int id)
1231
int8_t xbee_set_pan_id(uint16_t id)
1269 1232
{
1270
	char s[3];
1233
	if (xbee_status&0xC0 == XBEE_COMMAND_WAIT
1234
    || xbee_status&0xC0 == XBEE_COMMAND_RESPONSE)
1235
    return WL_ERROR_XBEE_COMMAND; // can't do command right now
1236
  
1237
  int16_t i=0;
1238
  // change status to command wait
1239
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1240
  xbee_send_modify_at_command("ID",id); // send command to set the channel
1241
  // wait for up to 30 ms
1242
  while(xbee_status&0xC0 != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1243
    delay_us(1); // wait 3us
1244
  }
1245
  if (i < 1000 && xbee_command[0] == 'O' && xbee_command[1] == 'K') {
1246
    i = WL_SUCCESS;
1247
  else
1248
    i = WL_ERROR_XBEE_COMMAND; // set error code
1249
  xbee_status = xbee_status&0x3F; // reset status
1250
	return (int8_t)i; // return
1251
	/* old version
1252
  char s[3];
1271 1253
	s[0] = (id >> 8) & 0xFF;
1272 1254
	s[1] = id & 0xFF;
1273 1255
	s[2] = 0;
1274 1256
	xbee_pending_panID = id;
1275
	return xbee_send_modify_at_command("ID", s);
1257
	return xbee_send_modify_at_command("ID", s); */
1276 1258
}
1277 1259

  
1278 1260
/**
......
1281 1263
 * @return the personal area network id, or
1282 1264
 * XBEE_PAN_DEFAULT if it has not yet been set.
1283 1265
 **/
1284
unsigned int xbee_get_pan_id()
1266
uint16_t xbee_get_pan_id()
1285 1267
{
1286
	return xbee_panID;
1268
  if (xbee_status&0xC0 == XBEE_COMMAND_WAIT
1269
    || xbee_status&0xC0 == XBEE_COMMAND_RESPONSE)
1270
    return WL_ERROR_XBEE_COMMAND_16BIT; // can't do command right now
1271
  
1272
  uint16_t i=0;
1273
  // change status to command wait
1274
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1275
  xbee_send_read_at_command("ID"); // send command to get the PAN
1276
  // wait for up to 30 ms
1277
  while(xbee_status&0xC0 != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1278
    delay_us(1); // wait 3us
1279
  }
1280
  if (i < 1000 && xbee_command[0] == 'I' && xbee_command[1] == 'D') {
1281
    i = (xbee_command[2]<<8)|xbee_command[3]; // get PAN
1282
  else
1283
    i = WL_ERROR_XBEE_COMMAND_16BIT; // set error code
1284
  xbee_status = xbee_status&0x3F; // reset status
1285
	return i; // return
1287 1286
}
1288 1287

  
1289 1288
/**
......
1294 1293
 *
1295 1294
 * @see xbee_get_channel
1296 1295
 **/
1297
int xbee_set_channel(int channel)
1296
int8_t xbee_set_channel(uint8_t channel)
1298 1297
{
1299 1298
	if (channel < 0x0B || channel > 0x1A)
1300 1299
	{
......
1302 1301
		return -1;
1303 1302
	}
1304 1303

  
1305
	char s[3];
1306
	s[0] = channel & 0xFF;
1307
	s[1] = 0;
1308
	xbee_pending_channel = channel;
1309

  
1310
	return xbee_send_modify_at_command("CH", s);
1304
	if (xbee_status&0xC0 == XBEE_COMMAND_WAIT
1305
    || xbee_status&0xC0 == XBEE_COMMAND_RESPONSE)
1306
    return WL_ERROR_XBEE_COMMAND; // can't do command right now
1307
  
1308
  int16_t i=0;
1309
  // change status to command wait
1310
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1311
  xbee_send_modify_at_command("CH",channel); // send command to set the channel
1312
  // wait for up to 30 ms
1313
  while(xbee_status&0xC0 != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1314
    delay_us(1); // wait 3us
1315
  }
1316
  if (i < 1000 && xbee_command[0] == 'O' && xbee_command[1] == 'K') {
1317
    i = WL_SUCCESS;
1318
  else
1319
    i = WL_ERROR_XBEE_COMMAND; // set error code
1320
  xbee_status = xbee_status&0x3F; // reset status
1321
	return (int8_t)i; // return
1311 1322
}
1312 1323

  
1313 1324
/**
......
1317 1328
 *
1318 1329
 * @see xbee_set_channel
1319 1330
 **/
1320
int xbee_get_channel(void)
1331
int8_t xbee_get_channel(void)
1321 1332
{
1322
	return xbee_channel;
1333
  if (xbee_status&0xC0 == XBEE_COMMAND_WAIT
1334
    || xbee_status&0xC0 == XBEE_COMMAND_RESPONSE)
1335
    return WL_ERROR_XBEE_COMMAND; // can't do command right now
1336
  
1337
  int16_t i=0;
1338
  // change status to command wait
1339
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1340
  xbee_send_read_at_command("ID"); // send command to get the channel
1341
  // wait for up to 30 ms
1342
  while(xbee_status&0xC0 != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1343
    delay_us(1); // wait 3us
1344
  }
1345
  if (i < 1000 && xbee_command[0] == 'C' && xbee_command[1] == 'H') {
1346
    i = xbee_command[2]; // get channel
1347
  else
1348
    i = WL_ERROR_XBEE_COMMAND; // set error code
1349
  xbee_status = xbee_status&0x3F; // reset status
1350
	return i; // return
1323 1351
}
1324 1352

  
1325 1353
/**
......
1329 1357
 *
1330 1358
 * @return the 16-bit address of the XBee.
1331 1359
 **/
1332
unsigned int xbee_get_address()
1360
uint16_t xbee_get_address()
1333 1361
{
1334
	return xbee_address;
1362
  if (xbee_status&0xC0 == XBEE_COMMAND_WAIT
1363
    || xbee_status&0xC0 == XBEE_COMMAND_RESPONSE)
1364
    return WL_ERROR_XBEE_COMMAND_16BIT; // can't do command right now
1365
  
1366
  uint16_t i=0;
1367
  // change status to command wait
1368
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1369
  xbee_send_read_at_command("MY"); // send command to get the address
1370
  // wait for up to 30 ms
1371
  while(xbee_status&0xC0 != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1372
    delay_us(1); // wait 3us
1373
  }
1374
  if (i < 1000 && xbee_command[0] == 'M' && xbee_command[1] == 'Y') {
1375
    i = (xbee_command[2]<<8)+xbee_command[3]; // get address
1376
  else
1377
    i = WL_ERROR_XBEE_COMMAND_16BIT; // set error code
1378
  xbee_status = xbee_status&0x3F; // reset status
1379
	return i; // return
1335 1380
}
1336 1381

  
1337
#ifndef ROBOT
1338
void xbee_set_com_port(char* port)
1339
{
1340
	xbee_com_port = port;
1341
}
1342
#endif
1343

  
1344 1382
/**@} **/ // end xbee group
1345 1383

  
branches/wireless/code/projects/libwireless/wireless_send.c
44 44
 * byte 2: frame number
45 45
 * byte 3: group code 
46 46
 * bytes 4-n: data
47
 * (byte n+1: num retries - only saved locally in sending buffer)
47 48
 *
48 49
 * Definition for ack buffer
49 50
 * 2 bit system: 0=still sending
......
54 55

  
55 56

  
56 57
/* global variables */
57
uint8_t nextframe = 1;
58
uint8_t ack_buf[64];
58
uint8_t nextframe = 1; // number of next frame
59
uint8_t ack_buf[64]; // ack buffer (holds 255 packet return codes)
60
uint8_t send_buf[PACKET_BUFFER_SIZE]; // sending buffer for retries
61
uint8_t send_buf_first = 0; // first byte of data on buffer
62
uint8_t send_buf_last = 0; // next free byte on buffer
59 63

  
60 64
/* private function prototypes */
61 65
void setack(uint8_t num,uint8_t val);
......
91 95
  packet[1] = group;
92 96
  memcpy(packet+2,data,length);
93 97
  
94
  // set options
98
  // set scope
95 99
  if (scope == GLOBAL)
96 100
    options &= XBEE_OPTIONS_BROADCAST_ALL_PANS;
101
    
102
  // set mode
97 103
  if (mode == FAST) {
98 104
    options &= XBEE_OPTIONS_DISABLE_RESPONSE;
99 105
    ret_val = 0;
100
    setack(nextframe,ACK_OK); // save in ack system
101
  } else if (mode == RELIABLE) {   
102
    // save in ack system
103
    setack(nextframe,SENDING); // save in ack system
104
  } else {
106
  } else if (mode != RELIABLE) {
105 107
    WL_DEBUG_PRINT("Error - bad mode in core send function\r\n");
106 108
    return WL_ERROR_MODE;
107 109
  }
......
112 114
    return WL_ERROR_SEND;
113 115
  }
114 116
  
117
  // save in ack system
118
  if (mode == FAST) {
119
    setack(nextframe,ACK_OK); // assume the send was successful
120
  } else if (mode == RELIABLE) {
121
    setack(nextframe,SENDING); // set status to SENDING
122
    // TODO: save packet on sending buffer
123
    /* if (buffer full) {
124
      WL_DEBUG_PRINT("Error: sending buffer full\r\n");
125
      return WL_ERROR_SENDING_BUFFER_FULL
126
    } */
127
  }
128
  
115 129
  // increment frame number
116 130
  nextframe = (nextframe == 0xFF)?1:nextframe+1;
117
    
118 131

  
119 132
  return ret_val; // return frame number for ack tracking
120 133
}
......
190 203
  uint_8 val=0,i=1;
191 204
  
192 205
  while(1) {
193
    if (ack_buf[i/4]&(0x3<<(i%4)) != 0)
206
    if (ack_buf[i/4]&(0x2<<(i%4)) != 0) // if the ack is in an error state
194 207
      val++;
195 208
    if (i==255)
196 209
      break;
......
263 276
  switch(val) {
264 277
  case 0:
265 278
    // success
266
    setack(num,ACK_OK);
279
    setack(num,ACK_OK); // set status code
280
    // TODO: remove from sending buffer
267 281
    break;
268 282
  case 1:
269 283
    // no ack
284
    // TODO: check resend attempts
270 285
    setack(num,ACK_FAILURE);
271 286
    break;
272 287
  case 2:
273 288
    // CCA failure
289
    // TODO: check resend attempts
274 290
    setack(num,CCA_FAILURE);
275 291
    break;
276 292
}
branches/wireless/code/projects/libwireless/wl_defs.h
107 107
/** @brief Error code for received paacket destination too small for received packet **/
108 108
#define WL_ERROR_TOO_SMALL INT8_C(-15)
109 109

  
110
/** @brief Error code for sending buffer full (the packet was sent, but no retries will be made). **/
111
#define WL_ERROR_SENDING_BUFFER_FULL INT8_C(-16)
110 112

  
113
/** @brief Error code for failed xbee command **/
114
#define WL_ERROR_XBEE_COMMAND INT8_C(-17)
115

  
116
/** @brief Error code for failed 16bit xbee command **/
117
#define WL_ERROR_XBEE_COMMAND_16BIT 0xFEFE
118

  
111 119
/**@} */ // end error group
112 120

  
113 121
/**@} */ // end wireless group
branches/wireless/code/projects/libdragonfly/time.c
57 57

  
58 58
*/
59 59
#include <avr/interrupt.h>
60
#include <util/delay.h>
60
#include <util/delay_basic.h>
61 61

  
62 62
#include "dragonfly_defs.h"
63 63
#include "time.h"
......
65 65

  
66 66
/* Calculate how many cycles to delay for to get 1 ms. Based on F_CPU which should be defined by the makefile */
67 67
#ifdef F_CPU
68
#define WAIT_CYCLES ((F_CPU / 1000) / 10)
68

  
69
#define WAIT_CYCLES (F_CPU / 4000)
70
#if F_CPU < 1000000
71
#define US_WAIT_CYCLES 1
69 72
#else
70
#define WAIT_CYCLES (8000 / 10)
73
#define US_WAIT_CYCLES (F_CPU / 1000 / 1000)
71 74
#endif
72 75

  
76
#else
77
// assume 8 MHz
78
#define WAIT_CYCLES (2000)
79
#define US_WAIT_CYCLES (8)
73 80

  
81
#endif
82

  
83

  
74 84
unsigned char time_initd = 0;
75 85

  
76 86
static volatile int _rtc_val = 0;
......
106 116
 *
107 117
 * @param ms the number of milliseconds to delay for
108 118
 **/
109
void delay_ms(int ms) {
119
void delay_ms(uint16_t ms) {
110 120
    for (; ms > 0; ms--) {
111
        _delay_loop_2(WAIT_CYCLES);
121
        _delay_loop_2(WAIT_CYCLES); // 1 ms delay
112 122
    }
113 123
}
114 124

  
115 125

  
126
/**
127
 * Delays for the specified number of microseconds.
128
 * It depends on F_CPU to be defined in order to calculate how many cycles
129
 * it should delay. If it is not defined, a default clock of 8MHz is assumed.
130
 * 
131
 * We use _delay_loop_1 which will run assembly instructions that should be
132
 * 3 cycles long. Optimizations must be enabled for this to be true.
133
 * That function is called to ensure around 1ms per execution. To generate
134
 * multiple ms we run a for loop of how many milliseconds are desired.
135
 *
136
 * The error should be just the skew on the oscillator as the formula to 
137
 * calculate delay cycles should always be a whole number. The is some skew
138
 * in practice though it is unavoidable. Delaying for less than 1s should make
139
 * the error negligable.
140
 *
141
 * @param us the number of microseconds to delay for
142
 **/
143
void delay_us(uint16_t us) {
144
    us = us/3+1; // divide by three and round up
145
    for (; us > 0; us--) {
146
        _delay_loop_1(US_WAIT_CYCLES); // 3 us delay
147
    }
148
}
149

  
150

  
116 151
/* 	Prescales defined in time.h. SECOND will give you 1 second.
117 152
	More scales are defined in the time.h file.
118 153
	rtc_func is the address to a function that you want called every clock tick. */
branches/wireless/code/projects/libdragonfly/time.h
61 61
/** @brief Four seconds **/
62 62
#define FOUR_SECOND 64
63 63

  
64
/** @brief Delay execution for the specified time **/
65
void delay_ms(int ms) ;
64
/** @brief Delay execution for the specified time in milliseconds. **/
65
void delay_ms(uint16_t ms);
66
/** @brief Delay execution for the specified time in microseconds. **/
67
void delay_us(uint16_t us);
66 68
/** @brief Enable the realtime clock **/
67 69
int rtc_init(int prescale_opt, void (*rtc_func)(void));
68 70
/** @brief Reset the counter of the realtime clock **/

Also available in: Unified diff