From 79a4fe33a6d33a34a986dc18a6e3fbeba388a0bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20P=C3=A9rez=20Penichet?= Date: Thu, 25 Oct 2018 11:24:44 +0200 Subject: [PATCH] Unmodulated carrier transmission for cc2538 Modified the cc2538 driver to enable the radio test mode to emit unmodulated carriers (tones). A carrier can be enabled using the normal radio driver API: NETSTACK_CONF_RADIO.set_value( RADIO_PARAM_POWER_MODE, RADIO_POWER_MODE_CARRIER_ON); Once enabled, the carrier can be disabled like this: NETSTACK_CONF_RADIO.set_value( RADIO_PARAM_POWER_MODE, RADIO_POWER_MODE_CARRIER_OFF); --- arch/cpu/cc2538/dev/cc2538-rf.c | 59 +++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/arch/cpu/cc2538/dev/cc2538-rf.c b/arch/cpu/cc2538/dev/cc2538-rf.c index bddfcc942..32a8eef81 100644 --- a/arch/cpu/cc2538/dev/cc2538-rf.c +++ b/arch/cpu/cc2538/dev/cc2538-rf.c @@ -140,6 +140,8 @@ static const output_config_t output_power[] = { {-24, 0x00 }, }; +static radio_result_t get_value(radio_param_t param, radio_value_t *value); + #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) /* Max and Min Output Power in dBm */ @@ -394,6 +396,50 @@ get_sfd_timestamp(void) return RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd); } /*---------------------------------------------------------------------------*/ +/* Enable or disable radio test mode emmiting modulated or unmodulated + * (carrier) signal. See datasheet page XX +*/ +static uint32_t prev_FRMCTRL0, prev_MDMTEST1; +static uint8_t was_on; + +static void +set_test_mode(uint8_t enable, uint8_t modulated) +{ + radio_value_t mode; + get_value(RADIO_PARAM_POWER_MODE, &mode); + + if (enable) { + if (mode == RADIO_POWER_MODE_CARRIER_ON) { + return; + } + was_on = (mode == RADIO_POWER_MODE_ON); + off(); + prev_FRMCTRL0 = REG(RFCORE_XREG_FRMCTRL0); + // This constantly transmits random data + printf("FRMCTRL0: %08X\n", (unsigned int)prev_FRMCTRL0); + REG(RFCORE_XREG_FRMCTRL0) = 0x00000042; + if (!modulated) { + prev_MDMTEST1 = REG(RFCORE_XREG_MDMTEST1); + printf("MDMTEST1: %08X\n", (unsigned int)prev_MDMTEST1); + // ...adding this we send an unmodulated carrier instead + REG(RFCORE_XREG_MDMTEST1) = 0x00000018; + } + CC2538_RF_CSP_ISTXON(); + } else { + if (mode != RADIO_POWER_MODE_CARRIER_ON) { + return; + } + CC2538_RF_CSP_ISRFOFF(); + REG(RFCORE_XREG_FRMCTRL0) = prev_FRMCTRL0; + if (!modulated) { + REG(RFCORE_XREG_MDMTEST1) = prev_MDMTEST1; + } + if (was_on) { + on(); + } + } +} +/*---------------------------------------------------------------------------*/ /* Netstack API radio driver functions */ /*---------------------------------------------------------------------------*/ static int @@ -806,8 +852,12 @@ get_value(radio_param_t param, radio_value_t *value) switch(param) { case RADIO_PARAM_POWER_MODE: - *value = (REG(RFCORE_XREG_RXENABLE) && RFCORE_XREG_RXENABLE_RXENMASK) == 0 - ? RADIO_POWER_MODE_OFF : RADIO_POWER_MODE_ON; + if ((REG(RFCORE_XREG_RXENABLE) & RFCORE_XREG_RXENABLE_RXENMASK) == 0) { + *value = RADIO_POWER_MODE_OFF; + } else { + *value = (REG(RFCORE_XREG_FRMCTRL0) & RFCORE_XREG_FRMCTRL0_TX_MODE) == 0 + ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_CARRIER_ON; + } return RADIO_RESULT_OK; case RADIO_PARAM_CHANNEL: *value = (radio_value_t)get_channel(); @@ -895,6 +945,11 @@ set_value(radio_param_t param, radio_value_t value) if(value == RADIO_POWER_MODE_OFF) { off(); return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_CARRIER_ON || + value == RADIO_POWER_MODE_CARRIER_OFF) { + set_test_mode((value == RADIO_POWER_MODE_CARRIER_ON), 0); + return RADIO_RESULT_OK; } return RADIO_RESULT_INVALID_VALUE; case RADIO_PARAM_CHANNEL: