cc1200: Make it more suitable for contikimac + bugfix in rx_rx()

This commit is contained in:
Ulf Knoblich 2015-11-25 14:56:04 +01:00
parent 6d08597d14
commit 5d1045d002
2 changed files with 64 additions and 47 deletions

View file

@ -73,15 +73,15 @@
#define CC1200_MAX_PAYLOAD_LEN 127 #define CC1200_MAX_PAYLOAD_LEN 127
#endif #endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* /*
* The RX watchdog is used to check whether the radio is in RX mode at regular * 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 * 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 #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 #else
#define CC1200_USE_RX_WATCHDOG 0 #define CC1200_USE_RX_WATCHDOG 0
#endif #endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* /*
@ -159,9 +159,7 @@
#define CC1200_DEFAULT_CHANNEL CC1200_CONF_DEFAULT_CHANNEL #define CC1200_DEFAULT_CHANNEL CC1200_CONF_DEFAULT_CHANNEL
#else #else
/* 868.325 MHz */ /* 868.325 MHz */
//#define CC1200_DEFAULT_CHANNEL 26 #define CC1200_DEFAULT_CHANNEL 26
/* 865.725 MHz */
#define CC1200_DEFAULT_CHANNEL 13
#endif #endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* /*
@ -182,11 +180,19 @@
#endif #endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* /*
* If CC1200_AUTOCAL is 0, a timeout is used to decide when to calibrate when * If CC1200_AUTOCAL is not set, we use this parameter to defer
* going to TX. * calibration until a certain amount of time has expired.
* *
* Therefore, we don't calibrate every time we transmit. Set this parameter * This is what happens in detail:
* to 0 when this feature is not used. *
* - 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 #ifdef CC1200_CONF_CAL_TIMEOUT_SECONDS
#define CC1200_CAL_TIMEOUT_SECONDS CC1200_CONF_CAL_TIMEOUT_SECONDS #define CC1200_CAL_TIMEOUT_SECONDS CC1200_CONF_CAL_TIMEOUT_SECONDS

View file

@ -57,7 +57,6 @@
* - 3: Print errors + warnings + information (what's going on...) * - 3: Print errors + warnings + information (what's going on...)
*/ */
#define DEBUG_LEVEL 2 #define DEBUG_LEVEL 2
/* /*
* RF test mode. Blocks inside "configure()". * RF test mode. Blocks inside "configure()".
* - Set this parameter to 1 in order to produce an modulated carrier (PN9) * - Set this parameter to 1 in order to produce an modulated carrier (PN9)
@ -68,6 +67,7 @@
#ifndef CC1200_RF_TESTMODE #ifndef CC1200_RF_TESTMODE
#define CC1200_RF_TESTMODE 0 #define CC1200_RF_TESTMODE 0
#endif #endif
#if CC1200_RF_TESTMODE #if CC1200_RF_TESTMODE
#undef CC1200_RF_CFG #undef CC1200_RF_CFG
#if CC1200_RF_TESTMODE == 1 #if CC1200_RF_TESTMODE == 1
@ -248,6 +248,12 @@ extern const cc1200_rf_cfg_t CC1200_RF_CFG;
#define RF_UPDATE_CHANNEL 0x10 #define RF_UPDATE_CHANNEL 0x10
/* SPI was locked when calling RX interrupt, let the pollhandler do the job */ /* SPI was locked when calling RX interrupt, let the pollhandler do the job */
#define RF_POLL_RX_INTERRUPT 0x20 #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 */ /* Length of 802.15.4 ACK. We discard packets with a smaller size */
#define ACK_LEN 3 #define ACK_LEN 3
@ -403,10 +409,10 @@ static uint8_t rf_flags = 0;
/* Use a timeout to decide when to calibrate */ /* Use a timeout to decide when to calibrate */
static unsigned long cal_timer; static unsigned long cal_timer;
#endif #endif
#if USE_RX_WATCHDOG #if CC1200_USE_RX_WATCHDOG
/* Timer used for RX watchdog */ /* Timer used for RX watchdog */
static struct etimer et; static struct etimer et;
#endif #endif /* #if CC1200_USE_RX_WATCHDOG */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Prototypes for Netstack API radio driver functions */ /* Prototypes for Netstack API radio driver functions */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -557,15 +563,15 @@ PROCESS_THREAD(cc1200_process, ev, data)
PROCESS_BEGIN(); PROCESS_BEGIN();
#if USE_RX_WATCHDOG && !CC1200_SNIFFER #if CC1200_USE_RX_WATCHDOG && !CC1200_SNIFFER
/* RX watchdog interferes with sniffer. Reason unknown... */ /* RX watchdog interferes with sniffer. Reason unknown... */
while(1) { while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
etimer_reset(&et);
if((rf_flags & (RF_ON | RF_TX_ACTIVE)) == RF_ON) { 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 * We are on and not in TX. As every function of this driver
* assures that we are in RX mode * 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); PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_EXIT);
@ -689,19 +697,18 @@ init(void)
RELEASE_SPI(); RELEASE_SPI();
/* Set default channel */ /* Set default channel. This will also force initial calibration! */
set_channel(CC1200_DEFAULT_CHANNEL); set_channel(CC1200_DEFAULT_CHANNEL);
/* /*
* We have to call off() before on() because on() relies on the * 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 * configuration of the GPIO0 pin
* sniffer mode afterwards)
*/ */
off(); off();
#if CC1200_SNIFFER /* #if CC1200_SNIFFER */
on(); /* on(); */
#endif /* #endif */
} }
@ -787,14 +794,7 @@ transmit(unsigned short transmit_len)
#if !CC1200_AUTOCAL #if !CC1200_AUTOCAL
/* Perform manual calibration unless just turned on */ /* Perform manual calibration unless just turned on */
if(!was_off) { 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(); calibrate();
#endif
} }
#endif #endif
@ -824,6 +824,9 @@ transmit(unsigned short transmit_len)
ret = RADIO_TX_ERR; ret = RADIO_TX_ERR;
if(!was_off) { if(!was_off) {
#ifdef RF_FORCE_CALIBRATION
rf_flags |= RF_FORCE_CALIBRATION;
#endif
idle_calibrate_rx(); idle_calibrate_rx();
} }
} }
@ -1059,9 +1062,11 @@ on(void)
RELEASE_SPI(); RELEASE_SPI();
#if USE_RX_WATCHDOG #if CC1200_USE_RX_WATCHDOG
PROCESS_CONTEXT_BEGIN(&cc1200_process);
etimer_set(&et, CLOCK_SECOND); etimer_set(&et, CLOCK_SECOND);
#endif PROCESS_CONTEXT_END(&cc1200_process);
#endif /* #if CC1200_USE_RX_WATCHDOG */
} else { } else {
INFO("RF: Already on\n"); INFO("RF: Already on\n");
@ -1103,9 +1108,9 @@ off(void)
RELEASE_SPI(); RELEASE_SPI();
#if USE_RX_WATCHDOG #if CC1200_USE_RX_WATCHDOG
etimer_stop(&et); etimer_stop(&et);
#endif #endif /* #if CC1200_USE_RX_WATCHDOG */
} else { } else {
INFO("RF: Already off\n"); INFO("RF: Already off\n");
@ -1664,6 +1669,15 @@ static void
calibrate(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"); INFO("RF: Calibrate\n");
strobe(CC1200_SCAL); strobe(CC1200_SCAL);
@ -1738,11 +1752,7 @@ rx_rx(void)
uint8_t s = state(); uint8_t s = state();
if(s == STATE_RX) { if(s == STATE_IDLE) {
/* Already in RX. Flush RX FIFO */
single_write(CC1200_RXFIRST,
single_read(CC1200_RXLAST));
} else if(s == STATE_IDLE) {
/* Proceed to rx */ /* Proceed to rx */
} else if(s == STATE_RX_FIFO_ERR) { } else if(s == STATE_RX_FIFO_ERR) {
WARNING("RF: RX FIFO error!\n"); WARNING("RF: RX FIFO error!\n");
@ -1762,11 +1772,9 @@ rx_rx(void)
/* Clear pending GPIO interrupts */ /* Clear pending GPIO interrupts */
ENABLE_GPIO_INTERRUPTS(); ENABLE_GPIO_INTERRUPTS();
if(s != STATE_RX) { strobe(CC1200_SFRX);
strobe(CC1200_SFRX); strobe(CC1200_SRX);
strobe(CC1200_SRX); BUSYWAIT_UNTIL_STATE(STATE_RX, RTIMER_SECOND / 100);
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 */ /* Turn on RX again unless we turn off anyway */
if(!was_off) { if(!was_off) {
#ifdef RF_FORCE_CALIBRATION
rf_flags |= RF_FORCE_CALIBRATION;
#endif
idle_calibrate_rx(); idle_calibrate_rx();
} }