Contiki 2.6
|
00001 /** 00002 * \file 00003 * CC2430 RF driver 00004 * \author 00005 * Zach Shelby <zach@sensinode.com> (Original) 00006 * George Oikonomou - <oikonomou@users.sourceforge.net> 00007 * (port to the netstack API, hexdump output, RX FIFO overflow fixes 00008 * code cleanup, ...) 00009 * 00010 * bankable code for cc2430 rf driver. this code can be placed in any bank. 00011 * 00012 */ 00013 00014 #include <stdio.h> 00015 00016 #include "contiki.h" 00017 #include "dev/radio.h" 00018 #include "dev/cc2430_rf.h" 00019 #include "cc2430_sfr.h" 00020 #include "sys/clock.h" 00021 #include "sys/rtimer.h" 00022 00023 #include "net/packetbuf.h" 00024 #include "net/rime/rimestats.h" 00025 #include "net/netstack.h" 00026 00027 #define CC2430_RF_TX_POWER_RECOMMENDED 0x5F 00028 #ifdef CC2430_RF_CONF_TX_POWER 00029 #define CC2430_RF_TX_POWER CC2430_RF_CONF_TX_POWER 00030 #else 00031 #define CC2430_RF_TX_POWER CC2430_RF_TX_POWER_RECOMMENDED 00032 #endif 00033 00034 #ifdef CC2430_RF_CONF_CHANNEL 00035 #define CC2430_RF_CHANNEL CC2430_RF_CONF_CHANNEL 00036 #else 00037 #define CC2430_RF_CHANNEL 18 00038 #endif /* CC2430_RF_CONF_CHANNEL */ 00039 #define CC2430_CHANNEL_MIN 11 00040 #define CC2430_CHANNEL_MAX 26 00041 00042 #ifdef CC2430_RF_CONF_AUTOACK 00043 #define CC2430_RF_AUTOACK CC2430_RF_CONF_AUTOACK 00044 #else 00045 #define CC2430_RF_AUTOACK 1 00046 #endif 00047 00048 #ifndef CC2430_CONF_CHECKSUM 00049 #define CC2430_CONF_CHECKSUM 0 00050 #endif /* CC2420_CONF_CHECKSUM */ 00051 00052 #if CC2430_CONF_CHECKSUM 00053 #include "lib/crc16.h" 00054 #define CHECKSUM_LEN 2 00055 #else 00056 #define CHECKSUM_LEN 2 00057 #endif /* CC2430_CONF_CHECKSUM */ 00058 #if DEBUG_LEDS 00059 /* moved leds code to BANK1 to make space for cc2430_rf_process in HOME */ 00060 /* can't call code in BANK1 from alternate banks unless it is marked with __banked */ 00061 #include "dev/leds.h" 00062 #define RF_RX_LED_ON() leds_on(LEDS_RED); 00063 #define RF_RX_LED_OFF() leds_off(LEDS_RED); 00064 #define RF_TX_LED_ON() leds_on(LEDS_GREEN); 00065 #define RF_TX_LED_OFF() leds_off(LEDS_GREEN); 00066 #else 00067 #define RF_RX_LED_ON() 00068 #define RF_RX_LED_OFF() 00069 #define RF_TX_LED_ON() 00070 #define RF_TX_LED_OFF() 00071 #endif 00072 #define DEBUG 0 00073 #if DEBUG 00074 #define PRINTF(...) printf(__VA_ARGS__) 00075 #else 00076 #define PRINTF(...) do {} while (0) 00077 #endif 00078 00079 /* rf_flags bits */ 00080 #define RX_ACTIVE 0x80 00081 #define TX_ACK 0x40 00082 #define TX_ON_AIR 0x20 00083 #define WAS_OFF 0x10 00084 #define INITIALISED 0x01 00085 00086 #define RX_NO_DMA 00087 /* Bits of the last byte in the RX FIFO */ 00088 #define CRC_BIT_MASK 0x80 00089 #define LQI_BIT_MASK 0x7F 00090 00091 /* 192 ms, radio off -> on interval */ 00092 #define ONOFF_TIME ((RTIMER_ARCH_SECOND / 3125) + 4) 00093 00094 #if CC2430_RF_CONF_HEXDUMP 00095 #include "uart1.h" 00096 static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */ 00097 #endif 00098 00099 #ifdef HAVE_RF_ERROR 00100 uint8_t rf_error = 0; 00101 #endif 00102 00103 /*---------------------------------------------------------------------------*/ 00104 #if !NETSTACK_CONF_SHORTCUTS 00105 PROCESS(cc2430_rf_process, "CC2430 RF driver"); 00106 #endif 00107 /*---------------------------------------------------------------------------*/ 00108 static uint8_t __data rf_flags; 00109 static uint8_t rf_channel; 00110 00111 static int on(void); /* prepare() needs our prototype */ 00112 static int off(void); /* transmit() needs our prototype */ 00113 static int channel_clear(void); /* transmit() needs our prototype */ 00114 /*---------------------------------------------------------------------------*/ 00115 /** 00116 * Execute a single CSP command. 00117 * 00118 * \param command command to execute 00119 * 00120 */ 00121 void 00122 cc2430_rf_command(uint8_t command) 00123 { 00124 if(command >= 0xE0) { /*immediate strobe*/ 00125 uint8_t fifo_count; 00126 switch (command) { /*hardware bug workaround*/ 00127 case ISRFOFF: 00128 case ISRXON: 00129 case ISTXON: 00130 fifo_count = RXFIFOCNT; 00131 RFST = command; 00132 clock_delay_usec(2); 00133 if(fifo_count != RXFIFOCNT) { 00134 RFST = ISFLUSHRX; 00135 RFST = ISFLUSHRX; 00136 } 00137 break; 00138 00139 default: 00140 RFST = command; 00141 } 00142 } else if(command == SSTART) { 00143 RFIF &= ~IRQ_CSP_STOP; /*clear IRQ flag*/ 00144 RFST = SSTOP; /*make sure there is a stop in the end*/ 00145 RFST = ISSTART; /*start execution*/ 00146 while((RFIF & IRQ_CSP_STOP) == 0); 00147 } else { 00148 RFST = command; /*write command*/ 00149 } 00150 } 00151 /*---------------------------------------------------------------------------*/ 00152 static void 00153 flush_rx() 00154 { 00155 cc2430_rf_command(ISFLUSHRX); 00156 cc2430_rf_command(ISFLUSHRX); 00157 00158 #if !NETSTACK_CONF_SHORTCUTS 00159 IEN2 |= RFIE; 00160 #endif 00161 #if CC2430_RFERR_INTERRUPT 00162 IEN0 |= RFERRIE; 00163 #endif 00164 00165 RFIF &= ~IRQ_FIFOP; 00166 } 00167 /*---------------------------------------------------------------------------*/ 00168 /** 00169 * Select RF channel. 00170 * 00171 * \param channel channel number to select 00172 * 00173 * \return channel value or negative (invalid channel number) 00174 */ 00175 00176 /* channel freqdiv = (2048 + FSCTRL(9:0)) / 4 00177 freq = (2048 + FSCTRL(9:0)) MHz */ 00178 00179 int8_t 00180 cc2430_rf_channel_set(uint8_t channel) 00181 { 00182 uint16_t freq; 00183 00184 if((channel < 11) || (channel > 26)) { 00185 return -1; 00186 } 00187 00188 cc2430_rf_command(ISSTOP); /*make sure CSP is not running*/ 00189 cc2430_rf_command(ISRFOFF); 00190 /* Channel values: 11-26 */ 00191 freq = (uint16_t) channel - 11; 00192 freq *= 5; /*channel spacing*/ 00193 freq += 357; /*correct channel range*/ 00194 freq |= 0x4000; /*LOCK_THR = 1*/ 00195 FSCTRLH = (freq >> 8); 00196 FSCTRLL = (uint8_t)freq; 00197 00198 cc2430_rf_command(ISRXON); 00199 00200 rf_channel = channel; 00201 00202 return (int8_t) channel; 00203 } 00204 /*---------------------------------------------------------------------------*/ 00205 uint8_t 00206 cc2430_rf_channel_get() 00207 { 00208 return rf_channel; 00209 } 00210 /*---------------------------------------------------------------------------*/ 00211 /** 00212 * Select RF transmit power. 00213 * 00214 * \param new_power new power level 00215 * 00216 * \return new level 00217 */ 00218 uint8_t 00219 cc2430_rf_power_set(uint8_t new_power) 00220 { 00221 /* Set transmitter power */ 00222 TXCTRLL = new_power; 00223 00224 return TXCTRLL; 00225 } 00226 /*---------------------------------------------------------------------------*/ 00227 #if 0 /* unused */ 00228 /** 00229 * Enable RF transmitter. 00230 * 00231 * 00232 * \return pdTRUE 00233 * \return pdFALSE bus not free 00234 */ 00235 int 00236 cc2430_rf_tx_enable(void) 00237 { 00238 DMAARM = 0x80 + (1 << 0); /*ABORT + channel bit*/ 00239 00240 return 1; 00241 } 00242 #endif 00243 /*---------------------------------------------------------------------------*/ 00244 /** 00245 * Set MAC addresses 00246 * 00247 * \param pan The PAN address to set 00248 * \param addr The short address to set 00249 * \param ieee_addr The 64-bit IEEE address to set 00250 */ 00251 void 00252 cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr) 00253 { 00254 uint8_t f; 00255 __xdata unsigned char *ptr; 00256 00257 PANIDH = pan >> 8; 00258 PANIDL = pan & 0xff; 00259 00260 SHORTADDRH = addr >> 8; 00261 SHORTADDRL = addr & 0xff; 00262 00263 if(ieee_addr != NULL) { 00264 ptr = &IEEE_ADDR7; 00265 /* LSB first, MSB last for 802.15.4 addresses in CC2420 */ 00266 for (f = 0; f < 8; f++) { 00267 *ptr-- = ieee_addr[f]; 00268 } 00269 } 00270 } 00271 #if 0 /* currently unused */ 00272 /*---------------------------------------------------------------------------*/ 00273 /** 00274 * Channel energy detect. 00275 * 00276 * Coordinator use this function detect best channel for PAN-network. 00277 * \return RSSI-energy level dBm. 00278 * \return 0 operation failed. 00279 */ 00280 00281 int8_t 00282 cc2430_rf_analyze_rssi(void) 00283 { 00284 int8_t retval = -128; 00285 /*pause_us(128);*/ 00286 00287 retval = (int8_t)RSSIL; 00288 retval -= 45; 00289 return retval; 00290 } 00291 #endif /* currently unused */ 00292 /*---------------------------------------------------------------------------*/ 00293 /** 00294 * Send ACK. 00295 * 00296 *\param pending set up pending flag if pending > 0. 00297 */ 00298 void 00299 cc2430_rf_send_ack(uint8_t pending) 00300 { 00301 if(pending) { 00302 cc2430_rf_command(ISACKPEND); 00303 } else { 00304 cc2430_rf_command(ISACK); 00305 } 00306 } 00307 /*---------------------------------------------------------------------------*/ 00308 /* Netstack API radio driver functions */ 00309 /*---------------------------------------------------------------------------*/ 00310 static int 00311 init(void) 00312 { 00313 if(rf_flags & INITIALISED) { 00314 return 0; 00315 } 00316 00317 PRINTF("cc2430_rf_init called\n"); 00318 00319 RFPWR &= ~RREG_RADIO_PD; /*make sure it's powered*/ 00320 while((RFPWR & ADI_RADIO_PD) == 1); 00321 while((RFIF & IRQ_RREG_ON) == 0); /*wait for power up*/ 00322 SLEEP &= ~OSC_PD; /*Osc on*/ 00323 while((SLEEP & XOSC_STB) == 0); /*wait for power up*/ 00324 00325 rf_flags = 0; 00326 00327 FSMTC1 = 1; /*don't abort reception, if enable called, accept ack, auto rx after tx*/ 00328 00329 MDMCTRL0H = 0x0A; /* Generic client, standard hysteresis, decoder on 0x0a */ 00330 MDMCTRL0L = 0xE2; /* automatic CRC, standard CCA and preamble 0xE2 */ 00331 #if CC2430_RF_AUTOACK 00332 MDMCTRL0L |= 0x10; 00333 #endif 00334 00335 MDMCTRL1H = 0x30; /* Defaults */ 00336 MDMCTRL1L = 0x0; 00337 00338 RXCTRL0H = 0x32; /* RX tuning optimized */ 00339 RXCTRL0L = 0xf5; 00340 00341 cc2430_rf_channel_set(CC2430_RF_CHANNEL); 00342 cc2430_rf_command(ISFLUSHTX); 00343 cc2430_rf_command(ISFLUSHRX); 00344 00345 /* Temporary values, main() will sort this out later on */ 00346 cc2430_rf_set_addr(0xffff, 0x0000, NULL); 00347 00348 RFIM = IRQ_FIFOP; 00349 RFIF &= ~(IRQ_FIFOP); 00350 00351 S1CON &= ~(RFIF_0 | RFIF_1); 00352 #if !NETSTACK_CONF_SHORTCUTS 00353 IEN2 |= RFIE; 00354 #endif 00355 00356 /* If contiki-conf.h turns on the RFERR interrupt, enable it here */ 00357 #if CC2430_RFERR_INTERRUPT 00358 IEN0 |= RFERRIE; 00359 #endif 00360 00361 RF_TX_LED_OFF(); 00362 RF_RX_LED_OFF(); 00363 00364 rf_flags |= INITIALISED; 00365 00366 #if !NETSTACK_CONF_SHORTCUTS 00367 process_start(&cc2430_rf_process, NULL); 00368 #endif 00369 00370 cc2430_rf_power_set(CC2430_RF_TX_POWER); 00371 00372 return 1; 00373 } 00374 /*---------------------------------------------------------------------------*/ 00375 static int 00376 prepare(const void *payload, unsigned short payload_len) 00377 { 00378 uint8_t i; 00379 /* 00380 * When we transmit in very quick bursts, make sure previous transmission 00381 * is not still in progress before re-writing in the TX FIFO 00382 */ 00383 while(RFSTATUS & TX_ACTIVE); 00384 00385 if(rf_flags & TX_ACK) { 00386 return -1; 00387 } 00388 00389 if((rf_flags & RX_ACTIVE) == 0) { 00390 on(); 00391 } 00392 00393 PRINTF("cc2430_rf: sending %u byte payload\n", payload_len); 00394 00395 cc2430_rf_command(ISFLUSHTX); 00396 PRINTF("cc2430_rf: data = "); 00397 /* Send the phy length byte first */ 00398 RFD = payload_len + CHECKSUM_LEN; /* Payload plus FCS */ 00399 PRINTF("(%d)", payload_len+CHECKSUM_LEN); 00400 for(i = 0; i < payload_len; i++) { 00401 RFD = ((unsigned char*) (payload))[i]; 00402 PRINTF("%02X", ((unsigned char*)(payload))[i]); 00403 } 00404 PRINTF("\n"); 00405 00406 /* Leave space for the FCS */ 00407 RFD = 0; 00408 RFD = 0; 00409 00410 return 0; 00411 } 00412 /*---------------------------------------------------------------------------*/ 00413 static int 00414 transmit(unsigned short transmit_len) 00415 { 00416 uint8_t counter; 00417 int ret = RADIO_TX_ERR; 00418 00419 if(!(rf_flags & RX_ACTIVE)) { 00420 on(); 00421 rf_flags |= WAS_OFF; 00422 } 00423 00424 if(channel_clear() == CC2430_CCA_BUSY) { 00425 RIMESTATS_ADD(contentiondrop); 00426 return RADIO_TX_COLLISION; 00427 } 00428 00429 /* 00430 * prepare() double checked that TX_ACTIVE is low. If SFD is high we are 00431 * receiving. Abort transmission and bail out with RADIO_TX_COLLISION 00432 */ 00433 if(RFSTATUS & SFD) { 00434 RIMESTATS_ADD(contentiondrop); 00435 return RADIO_TX_COLLISION; 00436 } 00437 00438 /* Start the transmission */ 00439 ENERGEST_OFF(ENERGEST_TYPE_LISTEN); 00440 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); 00441 00442 cc2430_rf_command(ISTXON); 00443 counter = 0; 00444 while(!(RFSTATUS & TX_ACTIVE) && (counter++ < 3)) { 00445 clock_delay_usec(6); 00446 } 00447 00448 if(!(RFSTATUS & TX_ACTIVE)) { 00449 PRINTF("cc2430_rf: TX never active.\n"); 00450 cc2430_rf_command(ISFLUSHTX); 00451 ret = RADIO_TX_ERR; 00452 } else { 00453 /* Wait for the transmission to finish */ 00454 while(RFSTATUS & TX_ACTIVE); 00455 RF_RX_LED_OFF(); 00456 RF_TX_LED_ON(); 00457 ret = RADIO_TX_OK; 00458 // rf_flags |= TX_ON_AIR; 00459 } 00460 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); 00461 ENERGEST_ON(ENERGEST_TYPE_LISTEN); 00462 00463 if(rf_flags & WAS_OFF){ 00464 off(); 00465 } 00466 00467 RIMESTATS_ADD(lltx); 00468 /* OK, sent. We are now ready to send more */ 00469 return ret; 00470 } 00471 /*---------------------------------------------------------------------------*/ 00472 static int 00473 send(void *payload, unsigned short payload_len) 00474 { 00475 prepare(payload, payload_len); 00476 return transmit(payload_len); 00477 } 00478 /*---------------------------------------------------------------------------*/ 00479 static int 00480 read(void *buf, unsigned short bufsize) 00481 { 00482 uint8_t i; 00483 uint8_t len; 00484 uint8_t crc_corr; 00485 int8_t rssi; 00486 #if CC2420_CONF_CHECKSUM 00487 uint16_t checksum; 00488 #endif /* CC2420_CONF_CHECKSUM */ 00489 00490 /* Don't interrupt us while emptying the FIFO */ 00491 #if !NETSTACK_CONF_SHORTCUTS 00492 IEN2 &= ~RFIE; 00493 #endif 00494 #if CC2430_RFERR_INTERRUPT 00495 IEN0 &= ~RFERRIE; 00496 #endif 00497 00498 /* RX interrupt polled the cc2430_rf_process, now read the RX FIFO */ 00499 /* Check the length */ 00500 len = RFD; 00501 00502 /* Check for validity */ 00503 if(len > CC2430_MAX_PACKET_LEN) { 00504 /* Oops, we must be out of sync. */ 00505 PRINTF("error: bad sync\n"); 00506 00507 RIMESTATS_ADD(badsynch); 00508 flush_rx(); 00509 return 0; 00510 } 00511 00512 if(len <= CC2430_MIN_PACKET_LEN) { 00513 PRINTF("error: too short\n"); 00514 00515 RIMESTATS_ADD(tooshort); 00516 flush_rx(); 00517 return 0; 00518 } 00519 00520 if(len - CHECKSUM_LEN > bufsize) { 00521 PRINTF("error: too long\n"); 00522 00523 RIMESTATS_ADD(toolong); 00524 flush_rx(); 00525 return 0; 00526 } 00527 00528 #if CC2430_RF_CONF_HEXDUMP 00529 /* If we reach here, chances are the FIFO is holding a valid frame */ 00530 uart1_writeb(magic[0]); 00531 uart1_writeb(magic[1]); 00532 uart1_writeb(magic[2]); 00533 uart1_writeb(magic[3]); 00534 uart1_writeb(len); 00535 #endif 00536 00537 PRINTF("cc2430_rf: read = "); 00538 PRINTF("(%d)", len); 00539 len -= CHECKSUM_LEN; 00540 for(i = 0; i < len; ++i) { 00541 ((unsigned char*)(buf))[i] = RFD; 00542 #if CC2430_RF_CONF_HEXDUMP 00543 uart1_writeb(((unsigned char*)(buf))[i]); 00544 #endif 00545 PRINTF("%02X", ((unsigned char*)(buf))[i]); 00546 } 00547 PRINTF("\n"); 00548 00549 #if CC2430_CONF_CHECKSUM 00550 /* Deal with the checksum */ 00551 checksum = RFD * 256; 00552 checksum += RFD; 00553 #endif /* CC2430_CONF_CHECKSUM */ 00554 00555 /* Read the RSSI and CRC/Corr bytes */ 00556 rssi = ((int8_t) RFD) - 45; 00557 crc_corr = RFD; 00558 00559 #if CC2430_RF_CONF_HEXDUMP 00560 uart1_writeb(rssi); 00561 uart1_writeb(crc_corr); 00562 #endif 00563 00564 /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */ 00565 if(crc_corr & CRC_BIT_MASK) { 00566 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); 00567 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK); 00568 RIMESTATS_ADD(llrx); 00569 } else { 00570 RIMESTATS_ADD(badcrc); 00571 flush_rx(); 00572 return 0; 00573 } 00574 00575 /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */ 00576 if((RFSTATUS & (FIFO | FIFOP)) == FIFOP) { 00577 /* 00578 * If we reach here means that there might be more intact packets in the 00579 * FIFO despite the overflow. This can happen with bursts of small packets. 00580 * 00581 * Only flush if the FIFO is actually empty. If not, then next pass we will 00582 * pick up one more packet or flush due to an error. 00583 */ 00584 if(!RXFIFOCNT) { 00585 flush_rx(); 00586 } 00587 } 00588 00589 RF_RX_LED_OFF(); 00590 00591 #if !NETSTACK_CONF_SHORTCUTS 00592 IEN2 |= RFIE; 00593 #endif 00594 #if CC2430_RFERR_INTERRUPT 00595 IEN0 |= RFERRIE; 00596 #endif 00597 00598 RFIF &= ~IRQ_FIFOP; 00599 00600 return (len); 00601 } 00602 /*---------------------------------------------------------------------------*/ 00603 static int 00604 channel_clear(void) 00605 { 00606 if(!(RFSTATUS & CCA)) { 00607 return CC2430_CCA_BUSY; 00608 } 00609 return CC2430_CCA_CLEAR; 00610 } 00611 /*---------------------------------------------------------------------------*/ 00612 static int 00613 receiving_packet(void) 00614 { 00615 /* 00616 * SFD high while transmitting and receiving. 00617 * TX_ACTIVE high only when transmitting 00618 * 00619 * RFSTATUS & (TX_ACTIVE | SFD) == SFD <=> receiving 00620 */ 00621 return (RFSTATUS & (TX_ACTIVE | SFD) == SFD); 00622 } 00623 /*---------------------------------------------------------------------------*/ 00624 static int 00625 pending_packet(void) 00626 { 00627 return (RFSTATUS & FIFOP); 00628 } 00629 /*---------------------------------------------------------------------------*/ 00630 /** 00631 * Enable RF receiver. 00632 * 00633 * 00634 * \return pdTRUE 00635 * \return pdFALSE bus not free 00636 */ 00637 static int 00638 on(void) 00639 { 00640 rtimer_clock_t t0; 00641 PRINTF("cc2430_rf_rx_enable called\n"); 00642 if(!(rf_flags & RX_ACTIVE)) { 00643 t0 = RTIMER_NOW(); 00644 rf_flags |= RX_ACTIVE; 00645 IOCFG0 = 0x7f; /* Set the FIFOP threshold 127 */ 00646 RSSIH = 0xd2; /* -84dbm = 0xd2 default, 0xe0 -70 dbm */ 00647 00648 RFPWR &= ~RREG_RADIO_PD; /* make sure it's powered */ 00649 while ((RFIF & IRQ_RREG_ON) == 0); /* wait for power up */ 00650 00651 /* Make sure the RREG On Interrupt Flag is 0 next time we get called */ 00652 RFIF &= ~IRQ_RREG_ON; 00653 00654 cc2430_rf_command(ISRXON); 00655 cc2430_rf_command(ISFLUSHRX); 00656 while (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME)); 00657 00658 } 00659 PRINTF("cc2430_rf_rx_enable done\n"); 00660 ENERGEST_ON(ENERGEST_TYPE_LISTEN); 00661 return 1; 00662 } 00663 /*---------------------------------------------------------------------------*/ 00664 /** 00665 * Disable RF receiver. 00666 * 00667 * 00668 * \return pdTRUE 00669 * \return pdFALSE bus not free 00670 */ 00671 00672 static int 00673 off(void) 00674 { 00675 cc2430_rf_command(ISSTOP); /* make sure CSP is not running */ 00676 cc2430_rf_command(ISRFOFF); 00677 00678 RFPWR |= RREG_RADIO_PD; /* RF powerdown */ 00679 00680 /* Clear the RREG On Interrupt Flag */ 00681 RFIF &= ~IRQ_RREG_ON; 00682 00683 rf_flags &= ~RX_ACTIVE; 00684 rf_flags &= ~WAS_OFF; 00685 ENERGEST_OFF(ENERGEST_TYPE_LISTEN); 00686 return 1; 00687 } 00688 /*---------------------------------------------------------------------------*/ 00689 const struct radio_driver cc2430_rf_driver = 00690 { 00691 init, 00692 prepare, 00693 transmit, 00694 send, 00695 read, 00696 channel_clear, 00697 receiving_packet, 00698 pending_packet, 00699 on, 00700 off, 00701 }; 00702 /*---------------------------------------------------------------------------*/ 00703 #if !NETSTACK_CONF_SHORTCUTS 00704 /*---------------------------------------------------------------------------*/ 00705 PROCESS_THREAD(cc2430_rf_process, ev, data) 00706 { 00707 int len; 00708 PROCESS_BEGIN(); 00709 while(1) { 00710 PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); 00711 00712 packetbuf_clear(); 00713 len = read(packetbuf_dataptr(), PACKETBUF_SIZE); 00714 if(len > 0) { 00715 packetbuf_set_datalen(len); 00716 NETSTACK_RDC.input(); 00717 } 00718 } 00719 00720 PROCESS_END(); 00721 } 00722 #endif 00723 /*---------------------------------------------------------------------------*/