Project

General

Profile

Revision 1616

wl: the library fully compiles with all functions written

View differences:

xbee.c
42 42

  
43 43
/* Internal Function Prototypes */
44 44

  
45
// TODO: convert all int references to int16_t syntax (see stdint.h)
46

  
47 45
/* I/O Functions */
48 46
static int8_t xbee_send_string(uint8_t* c);
49 47

  
......
56 54
static int8_t xbee_wait_for_ok(void);
57 55

  
58 56
/* API Mode Functions */
59
static int8_t xbee_handle_packet(uint8_t* packet, uint16_t len);
57
//TODO: does this exist?  static int8_t xbee_handle_packet(uint8_t* packet, uint16_t len);
60 58
static int8_t xbee_handle_at_command_response(uint16_t command, uint8_t result, uint8_t len);
61 59
static int8_t xbee_handle_at_command_response(uint16_t command, uint8_t result, uint8_t len);
62 60
static void xbee_handle_status(uint8_t status);
......
71 69
uint8_t xbee_basic_buf_get(uint8_t *ptr);
72 70
int8_t xbee_other_buf_add(uint8_t *ptr, uint8_t byte);
73 71

  
72
/* private functions */
73
int8_t check_last_receive(uint16_t source,uint8_t framenum);
74
inline uint8_t getStatus(uint8_t mask);
75
inline void setStatus(uint8_t mask,uint8_t value);
74 76

  
75 77
/*Global Variables*/
76 78

  
79
// last few packet sources and frame nums
80
#define NUM_LAST_PACKETS 10
81
struct {
82
  uint16_t source;
83
  uint8_t framenum;
84
} lastPacket[NUM_LAST_PACKETS];
85

  
77 86
// array for basic packets
78 87
static uint8_t xbee_basic_buf[PACKET_BUFFER_SIZE];
79 88

  
......
95 104
static uint8_t other_buf_last = 0;
96 105

  
97 106
// xbee status
98
#define XBEE_API_OFF 0x0
99
#define XBEE_API_ON 0x1
100
#define XBEE_API_ESCAPE 0x2
101
#define XBEE_NORMAL 0x00
107
#define XBEE_API_OFF 0x00
108
#define XBEE_API_ON 0x10
109
#define XBEE_API_ESCAPE 0x20
110
#define XBEE_API_MASK 0x30
102 111
#define XBEE_COMMAND_WAIT 0x80
103 112
#define XBEE_COMMAND_RESPONSE 0xC0
104
#define XBEE_INITD 0x08
105
static uint8_t xbee_status = XBEE_API_OFF|XBEE_NORMAL;
113
#define XBEE_COMMAND_NONE 0x00
114
#define XBEE_COMMAND_MASK 0xC0
115
#define XBEE_NOT_INITD 0xF0
116
#define LAST_PACKET_MASK 0x0F
117
uint8_t xbee_status = XBEE_NOT_INITD;
106 118

  
107 119
// xbee command response (for PAN, channel, address, etc)
108 120
static uint8_t xbee_command[4];
......
136 148
  uint16_t len=0;
137 149
  
138 150
  // check that we're in API mode
139
  if ((xbee_status&0x03) == XBEE_API_OFF || apitype != XBEE_FRAME_START) {
151
  if (getStatus(XBEE_API_MASK) == XBEE_API_OFF || apitype != XBEE_FRAME_START) {
140 152
    // not in API mode
141
    if ((xbee_status&0xC0) == XBEE_COMMAND_WAIT) {
153
    if (getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_WAIT) {
142 154
      // get rest of command and put in basic buf
143 155
      xbee_basic_buf[0] = apitype;
144 156
      if (xbee_basic_buf[i] != '\r') {
......
151 163
        }
152 164
      }
153 165
      // signal handler that command response is done
154
      xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_RESPONSE;
166
      setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_RESPONSE);
155 167
    }
156 168
    return;
157 169
  }
......
174 186
  switch(apitype) {
175 187
  case XBEE_FRAME_AT_COMMAND_RESPONSE: {
176 188
    // AT command response
177
    if ((xbee_status&0xC0) == XBEE_COMMAND_RESPONSE)
189
    if (getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_RESPONSE)
178 190
      return; // we're currently processing a command, so drop the incoming one
179 191
    uint16_t atcommand=0;
180 192
    uint8_t ptr=basic_buf_last;
......
235 247
          apitype = PORT; // get options, and ignore
236 248
        else if (i==5) {
237 249
          framenum = PORT; // get the frame number
238
          if (check_last_receive(source,framenum) != 0) {  // TODO: write function
250
          if (check_last_receive(source,framenum) != WL_SUCCESS) {
239 251
            // we've already received this frame
240 252
            ptr = 0xFF; // signal to skip processing
241 253
            break;
......
334 346
  return 0;
335 347
}
336 348

  
349
/**
350
 * Checks if packet is a duplicate
351
 **/
352
int8_t check_last_receive(uint16_t source,uint8_t framenum) {
353
  uint8_t i=0;
354
  for(;i<NUM_LAST_PACKETS;i++) {
355
    if (lastPacket[i].source == source && lastPacket[i].framenum == framenum)
356
      return -1; // duplicate packet, so return error
357
  }
358
  // save packet source and framenum
359
  i=getStatus(LAST_PACKET_MASK);
360
  lastPacket[i].source = source;
361
  lastPacket[i].framenum = framenum;
362
  if (++i>=NUM_LAST_PACKETS)
363
    i = 0;
364
  setStatus(LAST_PACKET_MASK,i);
365
  return WL_SUCCESS;
366
}
337 367

  
368
/** status functions **/
369
inline uint8_t getStatus(uint8_t mask) { return xbee_status&mask; }
370
inline void setStatus(uint8_t mask,uint8_t value) { xbee_status = (xbee_status&(!mask))|value; }
371

  
372

  
338 373
/**
339 374
 * Initializes the XBee library so that other functions may be used.
340 375
 **/
......
342 377
{
343 378
	WL_DEBUG_PRINT("in xbee_init\n");
344 379
  
345
  if((xbee_status&0x08) == XBEE_INITD) {
380
  if(getStatus(XBEE_NOT_INITD) != XBEE_NOT_INITD) {
346 381
    return WL_ERROR_INIT_ALREADY_INITD;
347 382
  }
348 383
  
384
  // clear last packet buffer
385
  for(int i=0;i<NUM_LAST_PACKETS;i++)
386
    lastPacket[i].source = lastPacket[i].framenum = 0;
387
  
349 388
  // Set startup baud rate of 9600
350 389
	// Set frame format: 8data, 1stop bit, asynchronous normal mode
351 390
  // Enable receiver and transmitter and the receiving interrupt
......
471 510
  
472 511
  
473 512
  // set status
474
  xbee_status |= XBEE_INITD;
513
  setStatus(XBEE_NOT_INITD,XBEE_COMMAND_NONE);
475 514
  
476 515
	return WL_SUCCESS;
477 516
}
......
485 524
    WL_DEBUG_PRINT("xbee termination failed\r\n");
486 525
    return WL_ERROR_TERMINATION_FAILED;
487 526
  }
488
  xbee_status = xbee_status&0xF7; // clean initd status
527
  setStatus(XBEE_NOT_INITD,XBEE_NOT_INITD); // clean initd status
489 528
  return WL_SUCCESS;
490 529
}
491 530

  
......
496 535
 * @return 0 for success, nonzero for failure
497 536
 **/
498 537
int8_t xbee_putc(uint8_t c) {
499
  if(!(xbee_status&XBEE_INITD))
500
    return WL_ERROR_LIBRARY_NOT_INITD;
501 538

  
502 539
  // Wait until buffer is clear for sending
503 540
  // Then load buffer with your character
......
523 560
 * @see xbee_init, xbee_getc_nb
524 561
 **/
525 562
int16_t xbee_getc(void) {
526
  if(!(xbee_status&XBEE_INITD))
527
    return WL_ERROR_LIBRARY_NOT_INITD;
528

  
563
    
529 564
  // Wait for the receive buffer to be filled
530 565
  // Then read the receive buffer
531 566
#ifdef FIREFLY
......
549 584
 * @see xbee_getc
550 585
 **/
551 586
int8_t xbee_getc_nb(uint8_t *c) {
552
  if(!(xbee_status&XBEE_INITD))
553
    return WL_ERROR_LIBRARY_NOT_INITD;
554 587

  
555 588
  // check if the receive buffer is filled
556 589
#ifdef FIREFLY
......
571 604
 * @param buf the buffer of data to send
572 605
 * @param size the number of bytes to send
573 606
 **/
574
static int8_t xbee_send(uint8_t* buf, uint16_t size)
607
int8_t xbee_send(uint8_t* buf, uint16_t size)
575 608
{
576 609
  uint16_t i=0; // check if we need this variable
577 610
	while(i<size) {
......
633 666
	}
634 667
	xbee_wait_for_ok();
635 668
  
636
  xbee_status = (xbee_status&0xFC)|XBEE_API_ON;
669
  setStatus(XBEE_API_MASK,XBEE_API_ON); // set status
637 670

  
638 671
	return WL_SUCCESS;
639 672
}
......
647 680
	}
648 681
	xbee_wait_for_ok();
649 682
  
650
  xbee_status = (xbee_status&0xFC)|XBEE_API_ESCAPE;
683
  setStatus(XBEE_API_MASK,XBEE_API_ESCAPE); // set status
651 684
  
652 685
	return WL_SUCCESS;
653 686
}
......
657 690
 **/
658 691
static int8_t xbee_exit_api_mode()
659 692
{
660
	if ((xbee_status&0xC0) == XBEE_COMMAND_WAIT
661
    || (xbee_status&0xC0) == XBEE_COMMAND_RESPONSE)
693
	if (getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_WAIT
694
    || getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_RESPONSE)
662 695
    return WL_ERROR_XBEE_COMMAND; // can't do command right now
663 696
  
664 697
  int16_t i=0;
665 698
  // change status to command wait
666
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
699
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_WAIT);
667 700
  xbee_send_modify_at_command((uint8_t*)"AP",(uint8_t*)"0",1); // send command
668 701
  // wait for up to 30 ms
669
  while((xbee_status&0xC0) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
702
  while(getStatus(XBEE_COMMAND_MASK) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
670 703
    delay_us(1); // wait 3us
671 704
  }
672 705
  if (i < 1000 && xbee_command[0] == 'A' && xbee_command[1] == 'P')
673 706
    i = WL_SUCCESS;
674 707
  else
675 708
    i = WL_ERROR_XBEE_COMMAND; // set error code
676
  xbee_status = (xbee_status&0x3C)|XBEE_API_OFF; // reset status
709
  setStatus(XBEE_API_MASK,XBEE_API_OFF); // reset status
677 710
	return (int8_t)i; // return
678 711
}
679 712

  
......
697 730
static int8_t xbee_wait_for_string(uint8_t* s, uint16_t len)
698 731
{
699 732
  uint8_t i=0;
700
  if ((xbee_status&0x03) == XBEE_API_OFF) {
733
  if (getStatus(XBEE_API_MASK) == XBEE_API_OFF) {
701 734
    // wait until the response is received (only wait 1 second)
702
    while((xbee_status&0xC0) != XBEE_COMMAND_RESPONSE && i++ < 1000) {
735
    while(getStatus(XBEE_COMMAND_MASK) != XBEE_COMMAND_RESPONSE && i++ < 1000) {
703 736
      delay_us(1);
704 737
    }
705 738
    // check response
......
711 744
      return -1;
712 745
    }
713 746
    
714
    // clear response
715
    xbee_status = xbee_status&0x3F;
747
    setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_NONE); // clear status
716 748
  }
717 749

  
718 750
	return 0;
......
729 761
 */
730 762
static int8_t xbee_wait_for_response(uint8_t* s, int16_t len) {
731 763
  uint8_t i=0;
732
  if ((xbee_status&0x03) == XBEE_API_OFF) {
764
  if (getStatus(XBEE_API_MASK) == XBEE_API_OFF) {
733 765
    // wait until the response is received (only wait 1 second)
734
    while((xbee_status&0xC0) != XBEE_COMMAND_RESPONSE && i++ < 1000) {
766
    while(getStatus(XBEE_COMMAND_MASK) != XBEE_COMMAND_RESPONSE && i++ < 1000) {
735 767
      delay_us(1);
736 768
    }
737 769
    // check response
......
741 773
      i=strcspn((char*)xbee_basic_buf,"\r");
742 774
      if (i<PACKET_BUFFER_SIZE) {
743 775
        memcpy(s,xbee_basic_buf,i);
744
        xbee_status = xbee_status&0x3F; // clear response
776
        setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_NONE); // clear response
745 777
        return 0;
746 778
      }
747 779
      else
......
805 837
 *
806 838
 * @return error code
807 839
 **/
808
static int8_t xbee_checksum_add(uint8_t *buf, uint8_t len, uint8_t* sum) {
840
int8_t xbee_checksum_add(uint8_t *buf, uint8_t len, uint8_t* sum) {
809 841
  if (buf == NULL || sum == NULL)
810 842
    return WL_ERROR_ARGUMENT;
811 843
  while(--len > 0) {
812 844
		*sum += buf[len];
813 845
  }
814 846
  *sum += buf[0];
847
  return WL_SUCCESS;
815 848
}
816 849

  
817 850

  
......
823 856
 * @param len the size in bytes of the packet data
824 857
 *
825 858
 **/
826
static int8_t xbee_send_header(uint8_t type, uint16_t len)
859
int8_t xbee_send_header(uint8_t type, uint16_t len)
827 860
{  
828 861
  //packet prefix
829 862
  if (xbee_putc(XBEE_FRAME_START) != WL_SUCCESS)
......
1056 1089
  }
1057 1090
  
1058 1091
  // signal handler that command response is done
1059
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_RESPONSE;
1092
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_NONE);
1060 1093

  
1061 1094
  return WL_SUCCESS;
1062 1095
}
......
1068 1101
 **/
1069 1102
int8_t xbee_set_pan_id(uint16_t id)
1070 1103
{
1071
	if ((xbee_status&0xC0) == XBEE_COMMAND_WAIT
1072
    || (xbee_status&0xC0) == XBEE_COMMAND_RESPONSE)
1104
	if (getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_WAIT
1105
    || getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_RESPONSE)
1073 1106
    return WL_ERROR_XBEE_COMMAND; // can't do command right now
1074 1107
  
1075 1108
  int16_t i=0;
1076 1109
  // change status to command wait
1077
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1110
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_WAIT);
1078 1111
  xbee_send_modify_at_command((uint8_t*)"ID",(uint8_t*)(&id),2); // send command to set the channel
1079 1112
  // wait for up to 30 ms
1080
  while((xbee_status&0xC0) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1113
  while(getStatus(XBEE_COMMAND_MASK) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1081 1114
    delay_us(1); // wait 3us
1082 1115
  }
1083 1116
  if (i < 1000 && xbee_command[0] == 'O' && xbee_command[1] == 'K')
1084 1117
    i = WL_SUCCESS;
1085 1118
  else
1086 1119
    i = WL_ERROR_XBEE_COMMAND; // set error code
1087
  xbee_status = xbee_status&0x3F; // reset status
1120
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_NONE); // reset status
1088 1121
	return (int8_t)i; // return
1089 1122
}
1090 1123

  
......
1096 1129
 **/
1097 1130
uint16_t xbee_get_pan_id()
1098 1131
{
1099
  if ((xbee_status&0xC0) == XBEE_COMMAND_WAIT
1100
    || (xbee_status&0xC0) == XBEE_COMMAND_RESPONSE)
1132
	if (getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_WAIT
1133
    || getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_RESPONSE)
1101 1134
    return WL_ERROR_XBEE_COMMAND_16BIT; // can't do command right now
1102 1135
  
1103 1136
  uint16_t i=0;
1104 1137
  // change status to command wait
1105
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1138
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_WAIT);
1106 1139
  xbee_send_read_at_command((uint8_t*)"ID"); // send command to get the PAN
1107 1140
  // wait for up to 30 ms
1108
  while((xbee_status&0xC0) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1141
  while(getStatus(XBEE_COMMAND_MASK) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1109 1142
    delay_us(1); // wait 3us
1110 1143
  }
1111 1144
  if (i < 1000 && xbee_command[0] == 'I' && xbee_command[1] == 'D')
1112 1145
    i = (xbee_command[2]<<8)|xbee_command[3]; // get PAN
1113 1146
  else
1114 1147
    i = WL_ERROR_XBEE_COMMAND_16BIT; // set error code
1115
  xbee_status = xbee_status&0x3F; // reset status
1148
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_NONE); // reset status
1116 1149
	return i; // return
1117 1150
}
1118 1151

  
......
1132 1165
		return -1;
1133 1166
	}
1134 1167

  
1135
	if ((xbee_status&0xC0) == XBEE_COMMAND_WAIT
1136
    || (xbee_status&0xC0) == XBEE_COMMAND_RESPONSE)
1168
	if (getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_WAIT
1169
    || getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_RESPONSE)
1137 1170
    return WL_ERROR_XBEE_COMMAND; // can't do command right now
1138 1171
  
1139 1172
  int16_t i=0;
1140 1173
  // change status to command wait
1141
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1174
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_WAIT);
1142 1175
  xbee_send_modify_at_command((uint8_t*)"CH",&channel,1); // send command to set the channel
1143 1176
  // wait for up to 30 ms
1144
  while((xbee_status&0xC0) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1177
  while(getStatus(XBEE_COMMAND_MASK) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1145 1178
    delay_us(1); // wait 3us
1146 1179
  }
1147 1180
  if (i < 1000 && xbee_command[0] == 'O' && xbee_command[1] == 'K')
1148 1181
    i = WL_SUCCESS;
1149 1182
  else
1150 1183
    i = WL_ERROR_XBEE_COMMAND; // set error code
1151
  xbee_status = xbee_status&0x3F; // reset status
1184
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_NONE); // reset status
1152 1185
	return (int8_t)i; // return
1153 1186
}
1154 1187

  
......
1161 1194
 **/
1162 1195
int8_t xbee_get_channel(void)
1163 1196
{
1164
  if ((xbee_status&0xC0) == XBEE_COMMAND_WAIT
1165
    || (xbee_status&0xC0) == XBEE_COMMAND_RESPONSE)
1197
	if (getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_WAIT
1198
    || getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_RESPONSE)
1166 1199
    return WL_ERROR_XBEE_COMMAND; // can't do command right now
1167 1200
  
1168 1201
  int16_t i=0;
1169 1202
  // change status to command wait
1170
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1203
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_WAIT);
1171 1204
  xbee_send_read_at_command((uint8_t*)"ID"); // send command to get the channel
1172 1205
  // wait for up to 30 ms
1173
  while((xbee_status&0xC0) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1206
  while(getStatus(XBEE_COMMAND_MASK) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1174 1207
    delay_us(1); // wait 3us
1175 1208
  }
1176 1209
  if (i < 1000 && xbee_command[0] == 'C' && xbee_command[1] == 'H')
1177 1210
    i = xbee_command[2]; // get channel
1178 1211
  else
1179 1212
    i = WL_ERROR_XBEE_COMMAND; // set error code
1180
  xbee_status = xbee_status&0x3F; // reset status
1213
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_NONE); // reset status
1181 1214
	return i; // return
1182 1215
}
1183 1216

  
......
1190 1223
 **/
1191 1224
uint16_t xbee_get_address(void)
1192 1225
{
1193
  if ((xbee_status&0xC0) == XBEE_COMMAND_WAIT
1194
    || (xbee_status&0xC0) == XBEE_COMMAND_RESPONSE)
1226
	if (getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_WAIT
1227
    || getStatus(XBEE_COMMAND_MASK) == XBEE_COMMAND_RESPONSE)
1195 1228
    return WL_ERROR_XBEE_COMMAND_16BIT; // can't do command right now
1196 1229
  
1197 1230
  uint16_t i=0;
1198 1231
  // change status to command wait
1199
  xbee_status = (xbee_status&0x3F)|XBEE_COMMAND_WAIT;
1232
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_WAIT);
1200 1233
  xbee_send_read_at_command((uint8_t*)"MY"); // send command to get the address
1201 1234
  // wait for up to 30 ms
1202
  while((xbee_status&0xC0) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1235
  while(getStatus(XBEE_COMMAND_MASK) != XBEE_COMMAND_RESPONSE && i++ < 10000) {
1203 1236
    delay_us(1); // wait 3us
1204 1237
  }
1205 1238
  if (i < 1000 && xbee_command[0] == 'M' && xbee_command[1] == 'Y')
1206 1239
    i = (xbee_command[2]<<8)+xbee_command[3]; // get address
1207 1240
  else
1208 1241
    i = WL_ERROR_XBEE_COMMAND_16BIT; // set error code
1209
  xbee_status = xbee_status&0x3F; // reset status
1242
  setStatus(XBEE_COMMAND_MASK,XBEE_COMMAND_NONE); // reset status
1210 1243
	return i; // return
1211 1244
}
1212 1245

  

Also available in: Unified diff