diff --git a/dev/cc1200/cc1200-conf.h b/dev/cc1200/cc1200-conf.h index 3641e87e3..1e50cc828 100644 --- a/dev/cc1200/cc1200-conf.h +++ b/dev/cc1200/cc1200-conf.h @@ -73,15 +73,15 @@ #define CC1200_MAX_PAYLOAD_LEN 127 #endif /*---------------------------------------------------------------------------*/ -/* +/* * The RX watchdog is used to check whether the radio is in RX mode at regular * intervals (once per second). Can be used to improve reliability especially - * if NullRDC is used. Turned of by default. - */ + * if NullRDC is used. Turned of by default. + */ #ifdef CC1200_CONF_USE_RX_WATCHDOG -#define CC1200_USE_RX_WATCHDOG CC1200_CONF_USE_RX_WATCHDOG +#define CC1200_USE_RX_WATCHDOG CC1200_CONF_USE_RX_WATCHDOG #else -#define CC1200_USE_RX_WATCHDOG 0 +#define CC1200_USE_RX_WATCHDOG 0 #endif /*---------------------------------------------------------------------------*/ /* @@ -159,9 +159,7 @@ #define CC1200_DEFAULT_CHANNEL CC1200_CONF_DEFAULT_CHANNEL #else /* 868.325 MHz */ -//#define CC1200_DEFAULT_CHANNEL 26 -/* 865.725 MHz */ -#define CC1200_DEFAULT_CHANNEL 13 +#define CC1200_DEFAULT_CHANNEL 26 #endif /*---------------------------------------------------------------------------*/ /* @@ -182,11 +180,19 @@ #endif /*---------------------------------------------------------------------------*/ /* - * If CC1200_AUTOCAL is 0, a timeout is used to decide when to calibrate when - * going to TX. + * If CC1200_AUTOCAL is not set, we use this parameter to defer + * calibration until a certain amount of time has expired. * - * Therefore, we don't calibrate every time we transmit. Set this parameter - * to 0 when this feature is not used. + * This is what happens in detail: + * + * - We (manually) calibrate once after initialization + * - We (manually) calibrate every time we change the channel + * - We (manually) calibrate when the radio is turned on() only if + * the timeout has expired + * - We (manually) calibrate when transmitting only of the timeout has expired + * + * Set this parameter to 0 when this feature is not used. In this case we + * (manually) calibrate in all situations mentioned above. */ #ifdef CC1200_CONF_CAL_TIMEOUT_SECONDS #define CC1200_CAL_TIMEOUT_SECONDS CC1200_CONF_CAL_TIMEOUT_SECONDS diff --git a/dev/cc1200/cc1200.c b/dev/cc1200/cc1200.c index 0ba4eccef..1f3bfd499 100644 --- a/dev/cc1200/cc1200.c +++ b/dev/cc1200/cc1200.c @@ -57,7 +57,6 @@ * - 3: Print errors + warnings + information (what's going on...) */ #define DEBUG_LEVEL 2 - /* * RF test mode. Blocks inside "configure()". * - Set this parameter to 1 in order to produce an modulated carrier (PN9) @@ -68,6 +67,7 @@ #ifndef CC1200_RF_TESTMODE #define CC1200_RF_TESTMODE 0 #endif + #if CC1200_RF_TESTMODE #undef CC1200_RF_CFG #if CC1200_RF_TESTMODE == 1 @@ -248,6 +248,12 @@ extern const cc1200_rf_cfg_t CC1200_RF_CFG; #define RF_UPDATE_CHANNEL 0x10 /* SPI was locked when calling RX interrupt, let the pollhandler do the job */ #define RF_POLL_RX_INTERRUPT 0x20 +/* Force calibration in case we don't use CC1200 AUTOCAL + timeout */ +#if !CC1200_AUTOCAL +#if CC1200_CAL_TIMEOUT_SECONDS +#define RF_FORCE_CALIBRATION 0x40 +#endif +#endif /*---------------------------------------------------------------------------*/ /* Length of 802.15.4 ACK. We discard packets with a smaller size */ #define ACK_LEN 3 @@ -403,10 +409,10 @@ static uint8_t rf_flags = 0; /* Use a timeout to decide when to calibrate */ static unsigned long cal_timer; #endif -#if USE_RX_WATCHDOG +#if CC1200_USE_RX_WATCHDOG /* Timer used for RX watchdog */ static struct etimer et; -#endif +#endif /* #if CC1200_USE_RX_WATCHDOG */ /*---------------------------------------------------------------------------*/ /* Prototypes for Netstack API radio driver functions */ /*---------------------------------------------------------------------------*/ @@ -557,15 +563,15 @@ PROCESS_THREAD(cc1200_process, ev, data) PROCESS_BEGIN(); -#if USE_RX_WATCHDOG && !CC1200_SNIFFER +#if CC1200_USE_RX_WATCHDOG && !CC1200_SNIFFER /* RX watchdog interferes with sniffer. Reason unknown... */ while(1) { - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - etimer_reset(&et); - if((rf_flags & (RF_ON | RF_TX_ACTIVE)) == RF_ON) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + /* * We are on and not in TX. As every function of this driver * assures that we are in RX mode @@ -593,10 +599,12 @@ PROCESS_THREAD(cc1200_process, ev, data) } + } else { + PROCESS_YIELD(); } } -#endif /* #if USE_RX_WATCHDOG */ +#endif /* #if CC1200_USE_RX_WATCHDOG */ PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_EXIT); @@ -689,19 +697,18 @@ init(void) RELEASE_SPI(); - /* Set default channel */ + /* Set default channel. This will also force initial calibration! */ set_channel(CC1200_DEFAULT_CHANNEL); /* * We have to call off() before on() because on() relies on the - * configuration of the GPIO0 pin (even if we turn the radio on in - * sniffer mode afterwards) + * configuration of the GPIO0 pin */ off(); -#if CC1200_SNIFFER - on(); -#endif +/* #if CC1200_SNIFFER */ +/* on(); */ +/* #endif */ } @@ -787,14 +794,7 @@ transmit(unsigned short transmit_len) #if !CC1200_AUTOCAL /* Perform manual calibration unless just turned on */ if(!was_off) { -#if CC1200_CAL_TIMEOUT_SECONDS - /* Calibrate after a delay defined by CC1200_CAL_TIMEOUT_SECONDS */ - if((clock_seconds() - cal_timer) > CC1200_CAL_TIMEOUT_SECONDS) { - calibrate(); - } -#else calibrate(); -#endif } #endif @@ -824,6 +824,9 @@ transmit(unsigned short transmit_len) ret = RADIO_TX_ERR; if(!was_off) { +#ifdef RF_FORCE_CALIBRATION + rf_flags |= RF_FORCE_CALIBRATION; +#endif idle_calibrate_rx(); } } @@ -1059,9 +1062,11 @@ on(void) RELEASE_SPI(); -#if USE_RX_WATCHDOG +#if CC1200_USE_RX_WATCHDOG + PROCESS_CONTEXT_BEGIN(&cc1200_process); etimer_set(&et, CLOCK_SECOND); -#endif + PROCESS_CONTEXT_END(&cc1200_process); +#endif /* #if CC1200_USE_RX_WATCHDOG */ } else { INFO("RF: Already on\n"); @@ -1103,9 +1108,9 @@ off(void) RELEASE_SPI(); -#if USE_RX_WATCHDOG +#if CC1200_USE_RX_WATCHDOG etimer_stop(&et); -#endif +#endif /* #if CC1200_USE_RX_WATCHDOG */ } else { INFO("RF: Already off\n"); @@ -1664,6 +1669,15 @@ static void calibrate(void) { +#ifdef RF_FORCE_CALIBRATION + if (!(rf_flags & RF_FORCE_CALIBRATION) + && ((clock_seconds() - cal_timer) < CC1200_CAL_TIMEOUT_SECONDS)) { + /* Timeout not reached, defer calibration... */ + return; + } + rf_flags &= ~RF_FORCE_CALIBRATION; +#endif + INFO("RF: Calibrate\n"); strobe(CC1200_SCAL); @@ -1738,11 +1752,7 @@ rx_rx(void) uint8_t s = state(); - if(s == STATE_RX) { - /* Already in RX. Flush RX FIFO */ - single_write(CC1200_RXFIRST, - single_read(CC1200_RXLAST)); - } else if(s == STATE_IDLE) { + if(s == STATE_IDLE) { /* Proceed to rx */ } else if(s == STATE_RX_FIFO_ERR) { WARNING("RF: RX FIFO error!\n"); @@ -1762,11 +1772,9 @@ rx_rx(void) /* Clear pending GPIO interrupts */ ENABLE_GPIO_INTERRUPTS(); - if(s != STATE_RX) { - strobe(CC1200_SFRX); - strobe(CC1200_SRX); - BUSYWAIT_UNTIL_STATE(STATE_RX, RTIMER_SECOND / 100); - } + strobe(CC1200_SFRX); + strobe(CC1200_SRX); + BUSYWAIT_UNTIL_STATE(STATE_RX, RTIMER_SECOND / 100); } /*---------------------------------------------------------------------------*/ @@ -2083,6 +2091,9 @@ set_channel(uint8_t channel) /* Turn on RX again unless we turn off anyway */ if(!was_off) { +#ifdef RF_FORCE_CALIBRATION + rf_flags |= RF_FORCE_CALIBRATION; +#endif idle_calibrate_rx(); }