Contiki 2.6

cc2430_rf.c

Go to the documentation of this file.
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 /*---------------------------------------------------------------------------*/