54 #include <util/delay_basic.h>
55 #define delay_us( us ) ( _delay_loop_2(1+((unsigned long long)us*F_CPU)/4000000UL) )
57 #include <avr/pgmspace.h>
58 #elif defined(__MSP430__)
70 #define WITH_SEND_CCA 0
73 #if RF230_CONF_TIMESTAMPS
75 #define TIMESTAMP_LEN 3
77 #define TIMESTAMP_LEN 0
83 #ifndef RF230_CONF_CHECKSUM
84 #define RF230_CONF_CHECKSUM 0
88 #ifndef RF230_CONF_AUTOACK
89 #define RF230_CONF_AUTOACK 1
93 #if RF230_CONF_AUTOACK
94 static bool is_promiscuous;
99 #ifndef RF230_CONF_FRAME_RETRIES
100 #ifdef RF230_CONF_AUTORETRIES
101 #define RF230_CONF_FRAME_RETRIES RF230_CONF_AUTORETRIES
103 #define RF230_CONF_FRAME_RETRIES 0
119 #if RF320_CONF_INSERTACK && RF230_CONF_FRAME_RETRIES
120 #define RF230_INSERTACK 1
121 uint8_t ack_pending,ack_seqnum;
130 #ifndef RF230_CONF_CSMA_RETRIES
131 #define RF230_CONF_CSMA_RETRIES 5
135 #if RF230_CONF_CHECKSUM || defined(RF230BB_HOOK_TX_PACKET)
138 #define CHECKSUM_LEN 2
141 #define AUX_LEN (CHECKSUM_LEN + TIMESTAMP_LEN + FOOTER_LEN)
142 #if AUX_LEN != CHECKSUM_LEN
143 #warning RF230 Untested Configuration!
148 uint8_t authority_level;
151 #define FOOTER1_CRC_OK 0x80
152 #define FOOTER1_CORRELATION 0x7f
157 #define RADIOALWAYSON 1
159 #define RADIOALWAYSON 0
160 #define RADIOSLEEPSWHENOFF 1
166 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
167 #define PRINTSHORT(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
170 #define PRINTSHORT(...)
186 uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
189 #if RADIO_CONF_CALIBRATE_INTERVAL
192 uint8_t rf230_calibrate;
193 uint8_t rf230_calibrated;
198 extern uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE];
199 #define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
205 #if RF230_CONF_TIMESTAMPS
206 rtimer_clock_t rf230_time_of_arrival, rf230_time_of_departure;
208 int rf230_authority_level_of_sender;
210 static rtimer_clock_t setup_time_for_transmission;
211 static unsigned long total_time_for_transmission, total_transmission_len;
212 static int num_transmissions;
215 #if defined(__AVR_ATmega128RFA1__)
216 volatile uint8_t rf230_wakewait, rf230_txendwait, rf230_ccawait;
219 uint8_t
volatile rf230_pending;
221 uint8_t ack_pending=0;
222 uint8_t ack_seqnum=0;
240 PROCESS(rf230_process,
"RF230 driver");
243 static int rf230_on(
void);
244 static int rf230_off(
void);
246 static int rf230_read(
void *buf,
unsigned short bufsize);
247 static int rf230_read_fakeack(
void *buf,
unsigned short bufsize);
249 static int rf230_prepare(
const void *data,
unsigned short len);
250 static int rf230_transmit(
unsigned short len);
251 static int rf230_send(
const void *data,
unsigned short len);
253 static int rf230_receiving_packet(
void);
254 static int rf230_pending_packet(
void);
255 static int rf230_cca(
void);
257 uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
267 rf230_receiving_packet,
268 rf230_pending_packet,
273 uint8_t RF230_receive_on;
274 static uint8_t channel;
277 uint8_t rxframe_head,rxframe_tail;
340 bool sleeping =
false;
381 if (RF230_receive_on) DEBUGFLOW(
'-');
405 if (rf230_isidle())
break;
431 uint8_t current_state;
434 if (!((new_state ==
TRX_OFF) ||
435 (new_state ==
RX_ON) ||
451 if (new_state == current_state){
493 if (current_state != new_state) {
494 if (((new_state ==
RX_ON) && (current_state ==
BUSY_RX)) ||
498 DEBUGFLOW(
'N');DEBUGFLOW(
'A'+new_state);DEBUGFLOW(
'A'+
radio_get_trx_state());DEBUGFLOW(
'N');
507 rf230_set_promiscuous_mode(
bool isPromiscuous) {
508 #if RF230_CONF_AUTOACK
509 is_promiscuous = isPromiscuous;
516 rf230_is_ready_to_send() {
530 rxframe[rxframe_head].
length=0;
537 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
538 RF230_receive_on = 1;
539 #ifdef RF230BB_HOOK_RADIO_ON
540 RF230BB_HOOK_RADIO_ON();
545 ENERGEST_ON(ENERGEST_TYPE_LED_RED);
546 #if RF230BB_CONF_LEDONPORTE1
549 #if defined(__AVR_ATmega128RFA1__)
559 for (i=0;i<10000;i++) {
560 if (!rf230_wakewait)
break;
578 #if RF230_CONF_AUTOACK
589 RF230_receive_on = 0;
595 #if RF230BB_CONF_LEDONPORTE1
598 #ifdef RF230BB_HOOK_RADIO_OFF
599 RF230BB_HOOK_RADIO_OFF();
616 #if RADIOSLEEPSWHENOFF
619 ENERGEST_OFF(ENERGEST_TYPE_LED_RED);
623 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
627 set_txpower(uint8_t power)
629 if (power > TX_PWR_17_2DBM){
630 power=TX_PWR_17_2DBM;
634 PRINTF(
"rf230_set_txpower:Sleeping");
640 void rf230_setpendingbit(uint8_t value)
654 #define AVR_ENTER_CRITICAL_REGION( ) {uint8_t volatile saved_sreg = SREG; cli( )
655 #define AVR_LEAVE_CRITICAL_REGION( ) SREG = saved_sreg;}
656 uint8_t osccal_original,osccal_calibrated;
668 uint8_t osccal_original = OSCCAL;
669 volatile uint16_t temp;
688 uint8_t counter = 128;
694 while (ASSR & ((1 << TCN2UB)|(1 << OCR2AUB)|(1 << TCR2AUB)|(1 << TCR2BUB))) { ; }
705 while (!(TIFR2 & (1 << TOV2))){
713 #define cal_upper 32812 //(31250*1.05) // 32812 = 0x802c
714 #define cal_lower 29687 //(31250*0.95) // 29687 = 0x73f7
716 if (temp < cal_lower) {
718 if (OSCCAL==0x7e)
break;
719 if (OSCCAL==0xff)
break;
721 }
else if (temp > cal_upper) {
723 if (OSCCAL==0x81)
break;
724 if (OSCCAL==0x00)
break;
732 }
while ((counter != 0) && (
false == cal_ok));
734 osccal_calibrated=OSCCAL;
735 if (
true != cal_ok) {
737 OSCCAL = osccal_original;
740 OSCCAL = osccal_original;
768 for (i=0;i<RF230_CONF_RX_BUFFERS;i++) {
771 rxframe_head=0;rxframe_tail=0;
797 if ((tvers != RF230_REVA) && (tvers != RF230_REVB))
798 PRINTF(
"rf230: Unsupported version %u\n",tvers);
799 if (tmanu != SUPPORTED_MANUFACTURER_ID)
800 PRINTF(
"rf230: Unsupported manufacturer ID %u\n",tmanu);
802 PRINTF(
"rf230: Version %u, ID %u\n",tvers,tmanu);
816 void rf230_warm_reset(
void) {
817 #if RF230_CONF_SNEEZER && JACKDAW
819 #warning Manipulating PORTB pins for RF230 Sneezer mode!
829 (RF230_CONF_FRAME_RETRIES > 0) ? (RF230_CONF_FRAME_RETRIES - 1) : 0 );
845 #ifdef RF230_MIN_RX_POWER
846 #if RF230_MIN_RX_POWER > 84
847 #warning rf231 power threshold clipped to -48dBm by hardware register
849 #elif RF230_MIN_RX_POWER < 0
850 #error RF230_MIN_RX_POWER can not be negative!
857 #ifdef RF230_CONF_CCA_THRES
858 #if RF230_CONF_CCA_THRES < -91
860 #warning RF230_CONF_CCA_THRES below hardware limit, setting to -91dBm
863 #elif RF230_CONF_CCA_THRES > -61
865 #warning RF230_CONF_CCA_THRES above hardware limit, setting to -61dBm
874 #if RF230_CONF_CHECKSUM
881 #ifdef RF230_MAX_TX_POWER
882 set_txpower(RF230_MAX_TX_POWER);
889 rf230_transmit(
unsigned short payload_len)
894 #if RF230_CONF_TIMESTAMPS
895 struct timestamp timestamp;
901 #if defined(__AVR_ATmega128RFA1__)
902 ENERGEST_ON(ENERGEST_TYPE_LED_RED);
903 #if RF230BB_CONF_LEDONPORTE1
910 for (i=0;i<10000;i++) {
911 if (!rf230_wakewait)
break;
922 #if RADIO_CONF_CALIBRATE_INTERVAL
924 if (rf230_calibrate) {
937 if(RF230_receive_on) {
938 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
941 #if RF230_CONF_FRAME_RETRIES
951 if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
953 txpower = rf230_get_txpower();
955 set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1);
958 total_len = payload_len + AUX_LEN;
960 #if RF230_CONF_TIMESTAMPS
964 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
977 PRINTF(
"rf230_transmit: %d\n", (
int)total_len);
986 for (i=0;i<total_len;i++) PRINTF(
" %02x",buffer[i]);
1000 #if RF230_CONF_FRAME_RETRIES
1003 tx_result=RADIO_TX_OK;
1006 #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS
1007 ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,rf230_get_txpower());
1011 if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
1012 set_txpower(txpower & 0xff);
1015 #if RF230_CONF_TIMESTAMPS
1016 setup_time_for_transmission = txtime - timestamp.time;
1018 if(num_transmissions < 10000) {
1020 total_transmission_len += total_len;
1021 num_transmissions++;
1026 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
1027 if(RF230_receive_on) {
1029 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
1037 PRINTF(
"rf230_transmit: turning radio off\n");
1046 tx_result=RADIO_TX_OK;
1049 if (tx_result==RADIO_TX_OK) {
1050 RIMESTATS_ADD(lltx);
1051 if(packetbuf_attr(PACKETBUF_ATTR_RELIABLE))
1052 RIMESTATS_ADD(ackrx);
1055 if (!((buffer[5]==0xff) && (buffer[6]==0xff)) && (buffer[0]&(1<<6)))
1059 }
else if (tx_result==3) {
1062 RIMESTATS_ADD(contentiondrop);
1063 PRINTF(
"rf230_transmit: Transmission never started\n");
1064 tx_result = RADIO_TX_COLLISION;
1065 }
else if (tx_result==5) {
1068 tx_result = RADIO_TX_NOACK;
1069 PRINTF(
"rf230_transmit: ACK not received\n");
1070 RIMESTATS_ADD(badackrx);
1071 }
else if (tx_result==7) {
1074 tx_result = RADIO_TX_ERR;
1081 rf230_prepare(
const void *payload,
unsigned short payload_len)
1084 printf(
"rf230_send():");
1085 for(idx = 0; idx < payload_len; idx++) {
1089 printf(
"%02x ", ((
char*)payload)[idx] & 0xFF);
1094 uint8_t total_len,*pbuf;
1095 #if RF230_CONF_TIMESTAMPS
1096 struct timestamp timestamp;
1098 #if RF230_CONF_CHECKSUM
1103 ack_seqnum=*(((uint8_t *)payload)+2);
1113 #if RF230_CONF_CHECKSUM
1114 checksum =
crc16_data(payload, payload_len, 0);
1118 total_len = payload_len + AUX_LEN;
1128 memcpy(pbuf,payload,payload_len);
1131 #if RF230_CONF_CHECKSUM
1132 memcpy(pbuf,&checksum,CHECKSUM_LEN);
1136 #if RF230_CONF_TIMESTAMPS
1139 memcpy(pbuf,×tamp,TIMESTAMP_LEN);
1140 pbuf+=TIMESTAMP_LEN;
1144 #ifdef RF230BB_HOOK_TX_PACKET
1145 #if !RF230_CONF_CHECKSUM
1148 checksum =
crc16_data(payload, payload_len, 0);
1149 memcpy(buffer+total_len-CHECKSUM_LEN,&checksum,CHECKSUM_LEN);
1152 RF230BB_HOOK_TX_PACKET(buffer,total_len);
1161 rf230_send(
const void *payload,
unsigned short payload_len)
1165 #ifdef RF230BB_HOOK_IS_SEND_ENABLED
1166 if(!RF230BB_HOOK_IS_SEND_ENABLED()) {
1171 if((ret=rf230_prepare(payload, payload_len))) {
1172 PRINTF(
"rf230_send: Unable to send, prep failed (%d)\n",ret);
1176 ret = rf230_transmit(payload_len);
1180 if (ret) RF230_sendfail++;
1189 if(RF230_receive_on == 0) {
1199 if (!rf230_isidle()) {
1201 PRINTF(
"rf230_off: busy receiving\r\n");
1212 if(RF230_receive_on) {
1222 rf230_get_channel(
void)
1230 rf230_set_channel(uint8_t c)
1233 PRINTF(
"rf230: Set Channel %u\n",c);
1240 rf230_listen_channel(uint8_t c)
1244 rf230_set_channel(c);
1249 rf230_set_pan_addr(
unsigned pan,
1251 const uint8_t ieee_addr[8])
1254 PRINTF(
"rf230: PAN=0x%02x Short Addr=0x%04x\n",pan,addr);
1259 abyte = (pan >> 8) & 0xFF;
1262 abyte = addr & 0xFF;
1264 abyte = (addr >> 8) & 0xFF;
1267 if (ieee_addr !=
NULL) {
1268 PRINTF(
"MAC=%02x",*ieee_addr);
1270 PRINTF(
":%02x",*ieee_addr);
1272 PRINTF(
":%02x",*ieee_addr);
1274 PRINTF(
":%02x",*ieee_addr);
1276 PRINTF(
":%02x",*ieee_addr);
1278 PRINTF(
":%02x",*ieee_addr);
1280 PRINTF(
":%02x",*ieee_addr);
1282 PRINTF(
":%02x",*ieee_addr);
1291 #if RF230_CONF_TIMESTAMPS
1292 static volatile rtimer_clock_t interrupt_time;
1293 static volatile int interrupt_time_set;
1296 rf230_interrupt(
void)
1300 if (RF230_receive_on) {
1303 #if RF230_CONF_TIMESTAMPS
1305 interrupt_time_set = 1;
1312 #if RADIOSTATS //TODO:This will double count buffered packets
1313 RF230_receivepackets++;
1315 RIMESTATS_ADD(llrx);
1320 rxframe[rxframe_head].
length=0;
1332 uint8_t rf230processflag;
1333 #define RF230PROCESSFLAG(arg) rf230processflag=arg
1335 #define RF230PROCESSFLAG(arg)
1342 RF230PROCESSFLAG(99);
1346 RF230PROCESSFLAG(42);
1357 PRINTF(
"rf230_read: %u bytes lqi %u\n",len,rf230_last_correlation);
1363 for (i=0;i<len+AUX_LEN;i++) PRINTF(
" %02x",rxdata[i]);
1369 RF230PROCESSFLAG(1);
1372 RF230PROCESSFLAG(2);
1373 NETSTACK_RDC.input();
1376 RF230_receivefail++;
1388 rf230_read_fakeack(
void *buf,
unsigned short bufsize)
1390 if(ack_pending && bufsize == 3){
1392 uint8_t *buff=(uint8_t *)buf;
1398 return rf230_read(buf,bufsize);
1411 rf230_read(
void *buf,
unsigned short bufsize)
1413 uint8_t len,*framep;
1415 uint8_t footer[FOOTER_LEN];
1417 #if RF230_CONF_CHECKSUM
1420 #if RF230_CONF_TIMESTAMPS
1425 if(ack_pending && bufsize == 3){
1427 uint8_t *buff=(uint8_t *)buf;
1436 len=rxframe[rxframe_head].
length;
1438 #if RADIOALWAYSON && DEBUGFLOWSIZE
1439 if (RF230_receive_on==0) {
if (debugflow[debugflowsize-1]!=
'z') DEBUGFLOW(
'z');}
1444 #if RF230_CONF_TIMESTAMPS
1445 if(interrupt_time_set) {
1446 rf230_time_of_arrival = interrupt_time;
1447 interrupt_time_set = 0;
1449 rf230_time_of_arrival = 0;
1451 rf230_time_of_departure = 0;
1458 RIMESTATS_ADD(badsynch);
1462 if(len <= AUX_LEN) {
1466 RIMESTATS_ADD(tooshort);
1470 if(len - AUX_LEN > bufsize) {
1474 RIMESTATS_ADD(toolong);
1479 framep=&(rxframe[rxframe_head].
data[0]);
1480 memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN);
1481 rf230_last_correlation = rxframe[rxframe_head].
lqi;
1484 rxframe[rxframe_head].
length=0;
1486 if (rxframe_head >= RF230_CONF_RX_BUFFERS) {
1490 if (rxframe[rxframe_head].length) {
1498 framep+=len-AUX_LEN;
1499 #if RF230_CONF_CHECKSUM
1500 memcpy(&checksum,framep,CHECKSUM_LEN);
1502 framep+=CHECKSUM_LEN;
1503 #if RF230_CONF_TIMESTAMPS
1504 memcpy(&t,framep,TIMESTAMP_LEN);
1506 framep+=TIMESTAMP_LEN;
1508 memcpy(footer,framep,FOOTER_LEN);
1510 #if RF230_CONF_CHECKSUM
1511 if(checksum !=
crc16_data(buf, len - AUX_LEN, 0)) {
1517 if(footer[1] & FOOTER1_CRC_OK &&
1518 checksum ==
crc16_data(buf, len - AUX_LEN, 0)) {
1523 #if 0 //more general
1524 rf230_last_rssi = rf230_get_raw_rssi();
1526 #if RF230_CONF_AUTOACK
1536 if ((rf230_smallest_rssi==0) || (rf230_last_rssi<rf230_smallest_rssi))
1537 rf230_smallest_rssi=rf230_last_rssi;
1540 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf230_last_rssi);
1541 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf230_last_correlation);
1545 #if RF230_CONF_TIMESTAMPS
1546 rf230_time_of_departure =
1548 setup_time_for_transmission +
1549 (total_time_for_transmission * (len - 2)) / total_transmission_len;
1551 rf230_authority_level_of_sender = t.authority_level;
1553 packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, t.time);
1556 #if RF230_CONF_CHECKSUM
1561 RIMESTATS_ADD(badcrc);
1567 #ifdef RF230BB_HOOK_RX_PACKET
1568 RF230BB_HOOK_RX_PACKET(buf,len);
1572 return len - AUX_LEN;
1582 rf230_get_txpower(
void)
1584 uint8_t power = TX_PWR_UNDEFINED;
1586 PRINTF(
"rf230_get_txpower:Sleeping");
1595 rf230_get_raw_rssi(
void)
1598 bool radio_was_off = 0;
1601 if(!RF230_receive_on) {
1613 #if 0 // 3-clock shift and add is faster on machines with no hardware multiply
1616 rssi = (rssi << 1) + rssi;
1617 #else // 1 or 2 clock multiply, or compiler with correct optimization
1634 uint8_t radio_was_off = 0;
1639 if(RF230_receive_on) {
1644 if (!rf230_isidle()) {
1654 ENERGEST_ON(ENERGEST_TYPE_LED_YELLOW);
1661 #if defined(__AVR_ATmega128RFA1__)
1662 #if 1 //interrupt method
1665 #ifdef RF230_MIN_RX_POWER
1679 uint8_t
volatile saved_sreg = SREG;
1682 while (rf230_ccawait) {}
1687 #ifdef RF230_CONF_CCA_THRES
1694 #if RF230_CONF_AUTOACK
1699 #ifdef RF230_MIN_RX_POWER
1709 #ifdef RF230_CONF_CCA_THRES
1721 { uint8_t
volatile saved_sreg = SREG;
1726 while ((cca & 0x80) == 0 ) {
1736 ENERGEST_OFF(ENERGEST_TYPE_LED_YELLOW);
1752 rf230_receiving_packet(
void)
1754 uint8_t radio_state;
1768 rf230_pending_packet(
void)
1771 if(ack_pending == 1)
return 1;
1773 return rf230_pending;
1776 #if RF230_CONF_SNEEZER && JACKDAW
1782 void rf230_start_sneeze(
void) {