From feb1513b4699ea915c0024c0860c019c112c42b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20P=C3=A9rez=20Penichet?= Date: Wed, 24 Oct 2018 15:26:40 +0200 Subject: [PATCH 1/5] Unmodulated carrier transmission for cc2420 Modified the cc2420 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/dev/cc2420/cc2420.c | 41 +++++++++++++++++++++++++++++++++++++++- os/dev/radio.h | 4 +++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/arch/dev/cc2420/cc2420.c b/arch/dev/cc2420/cc2420.c index a1572b0ef..7dfa1900b 100644 --- a/arch/dev/cc2420/cc2420.c +++ b/arch/dev/cc2420/cc2420.c @@ -114,6 +114,7 @@ PROCESS(cc2420_process, "CC2420 driver"); #define CORR_THR(n) (((n) & 0x1f) << 6) #define FIFOP_THR(n) ((n) & 0x7f) #define RXBPF_LOCUR (1 << 13); +#define TX_MODE (3 << 2) int cc2420_on(void); int cc2420_off(void); @@ -135,6 +136,8 @@ static void set_poll_mode(uint8_t enable); static void set_send_on_cca(uint8_t enable); static void set_auto_ack(uint8_t enable); +static void set_test_mode(uint8_t enable, uint8_t modulated); + signed char cc2420_last_rssi; uint8_t cc2420_last_correlation; @@ -156,7 +159,11 @@ get_value(radio_param_t param, radio_value_t *value) } switch(param) { case RADIO_PARAM_POWER_MODE: - *value = receive_on ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + if ((getreg(CC2420_MDMCTRL1) & TX_MODE) & 0x08) { + *value = RADIO_POWER_MODE_CARRIER_ON; + } else { + *value = receive_on ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + } return RADIO_RESULT_OK; case RADIO_PARAM_CHANNEL: *value = cc2420_get_channel(); @@ -237,6 +244,11 @@ set_value(radio_param_t param, radio_value_t value) cc2420_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: if(value < 11 || value > 26) { @@ -1120,3 +1132,30 @@ set_send_on_cca(uint8_t enable) send_on_cca = enable; } /*---------------------------------------------------------------------------*/ +/* Enable or disable radio test mode emmiting modulated or unmodulated + * (carrier) signal. See datasheet page 55. +*/ +static uint16_t prev_MDMCTRL1, prev_DACTST; + +static void +set_test_mode(uint8_t enable, uint8_t modulated) +{ + if (enable) { + prev_MDMCTRL1 = getreg(CC2420_MDMCTRL1); + setreg(CC2420_MDMCTRL1, 0x050C); + if (!modulated) { + prev_DACTST = getreg(CC2420_DACTST); + setreg(CC2420_DACTST, 0x1800); + } + /* actually starts the test mode */ + strobe(CC2420_STXON); + } else { + if (!modulated) { + setreg(CC2420_DACTST, prev_DACTST); + } + setreg(CC2420_MDMCTRL1, prev_MDMCTRL1); + /* actually stops the carrier */ + strobe(CC2420_SRFOFF); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/os/dev/radio.h b/os/dev/radio.h index e6ca64f3d..e279e9efe 100644 --- a/os/dev/radio.h +++ b/os/dev/radio.h @@ -196,7 +196,9 @@ enum { /* Radio power modes */ enum { RADIO_POWER_MODE_OFF, - RADIO_POWER_MODE_ON + RADIO_POWER_MODE_ON, + RADIO_POWER_MODE_CARRIER_ON, + RADIO_POWER_MODE_CARRIER_OFF }; /** 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 2/5] 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: From c6770112af8663761d1f2a260224eda7c0818456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20P=C3=A9rez=20Penichet?= Date: Thu, 25 Oct 2018 11:49:20 +0200 Subject: [PATCH 3/5] Fixed code style and removed forgotten pritf's --- arch/cpu/cc2538/dev/cc2538-rf.c | 18 ++++++++---------- arch/dev/cc2420/cc2420.c | 8 ++++---- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/arch/cpu/cc2538/dev/cc2538-rf.c b/arch/cpu/cc2538/dev/cc2538-rf.c index 32a8eef81..23e3e11e0 100644 --- a/arch/cpu/cc2538/dev/cc2538-rf.c +++ b/arch/cpu/cc2538/dev/cc2538-rf.c @@ -408,33 +408,31 @@ 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) { + 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); + /* This constantly transmits random data */ REG(RFCORE_XREG_FRMCTRL0) = 0x00000042; - if (!modulated) { + if(!modulated) { prev_MDMTEST1 = REG(RFCORE_XREG_MDMTEST1); - printf("MDMTEST1: %08X\n", (unsigned int)prev_MDMTEST1); - // ...adding this we send an unmodulated carrier instead + /* ...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) { + if(mode != RADIO_POWER_MODE_CARRIER_ON) { return; } CC2538_RF_CSP_ISRFOFF(); REG(RFCORE_XREG_FRMCTRL0) = prev_FRMCTRL0; - if (!modulated) { + if(!modulated) { REG(RFCORE_XREG_MDMTEST1) = prev_MDMTEST1; } - if (was_on) { + if(was_on) { on(); } } diff --git a/arch/dev/cc2420/cc2420.c b/arch/dev/cc2420/cc2420.c index 7dfa1900b..58c77e140 100644 --- a/arch/dev/cc2420/cc2420.c +++ b/arch/dev/cc2420/cc2420.c @@ -159,7 +159,7 @@ get_value(radio_param_t param, radio_value_t *value) } switch(param) { case RADIO_PARAM_POWER_MODE: - if ((getreg(CC2420_MDMCTRL1) & TX_MODE) & 0x08) { + if((getreg(CC2420_MDMCTRL1) & TX_MODE) & 0x08) { *value = RADIO_POWER_MODE_CARRIER_ON; } else { *value = receive_on ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; @@ -1140,17 +1140,17 @@ static uint16_t prev_MDMCTRL1, prev_DACTST; static void set_test_mode(uint8_t enable, uint8_t modulated) { - if (enable) { + if(enable) { prev_MDMCTRL1 = getreg(CC2420_MDMCTRL1); setreg(CC2420_MDMCTRL1, 0x050C); - if (!modulated) { + if(!modulated) { prev_DACTST = getreg(CC2420_DACTST); setreg(CC2420_DACTST, 0x1800); } /* actually starts the test mode */ strobe(CC2420_STXON); } else { - if (!modulated) { + if(!modulated) { setreg(CC2420_DACTST, prev_DACTST); } setreg(CC2420_MDMCTRL1, prev_MDMCTRL1); From a906f03a253e906c9c9a8f37188db868a85a9b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20P=C3=A9rez=20Penichet?= Date: Fri, 26 Oct 2018 16:28:20 +0200 Subject: [PATCH 4/5] cc2420 return to last state when disabling carrier Made cc2420 follow the same logic as cc2538 when disabling the unmodulated carrier. Now they both return to the state they were in before the carrier was enabled. --- arch/cpu/cc2538/dev/cc2538-rf.c | 2 +- arch/dev/cc2420/cc2420.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/cpu/cc2538/dev/cc2538-rf.c b/arch/cpu/cc2538/dev/cc2538-rf.c index 23e3e11e0..cee2197e7 100644 --- a/arch/cpu/cc2538/dev/cc2538-rf.c +++ b/arch/cpu/cc2538/dev/cc2538-rf.c @@ -397,7 +397,7 @@ get_sfd_timestamp(void) } /*---------------------------------------------------------------------------*/ /* Enable or disable radio test mode emmiting modulated or unmodulated - * (carrier) signal. See datasheet page XX + * (carrier) signal. See User's Guide pages 719 and 741. */ static uint32_t prev_FRMCTRL0, prev_MDMTEST1; static uint8_t was_on; diff --git a/arch/dev/cc2420/cc2420.c b/arch/dev/cc2420/cc2420.c index 58c77e140..18b289c1d 100644 --- a/arch/dev/cc2420/cc2420.c +++ b/arch/dev/cc2420/cc2420.c @@ -1136,11 +1136,20 @@ set_send_on_cca(uint8_t enable) * (carrier) signal. See datasheet page 55. */ static uint16_t prev_MDMCTRL1, prev_DACTST; +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_MDMCTRL1 = getreg(CC2420_MDMCTRL1); setreg(CC2420_MDMCTRL1, 0x050C); if(!modulated) { @@ -1150,12 +1159,18 @@ set_test_mode(uint8_t enable, uint8_t modulated) /* actually starts the test mode */ strobe(CC2420_STXON); } else { + if(mode != RADIO_POWER_MODE_CARRIER_ON) { + return; + } + strobe(CC2420_SRFOFF); if(!modulated) { setreg(CC2420_DACTST, prev_DACTST); } setreg(CC2420_MDMCTRL1, prev_MDMCTRL1); /* actually stops the carrier */ - strobe(CC2420_SRFOFF); + if(was_on) { + on(); + } } } /*---------------------------------------------------------------------------*/ From 2d2d6b3ad6d9b02f228a7c95ff8fdfe164222135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20P=C3=A9rez=20Penichet?= Date: Mon, 29 Oct 2018 11:15:40 +0100 Subject: [PATCH 5/5] Fixed code style issues --- arch/cpu/cc2538/dev/cc2538-rf.c | 12 ++++++------ arch/dev/cc2420/cc2420.c | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/cpu/cc2538/dev/cc2538-rf.c b/arch/cpu/cc2538/dev/cc2538-rf.c index cee2197e7..e3a548067 100644 --- a/arch/cpu/cc2538/dev/cc2538-rf.c +++ b/arch/cpu/cc2538/dev/cc2538-rf.c @@ -396,9 +396,9 @@ get_sfd_timestamp(void) return RTIMER_NOW() - RADIO_TO_RTIMER(timer_val - sfd); } /*---------------------------------------------------------------------------*/ -/* Enable or disable radio test mode emmiting modulated or unmodulated +/* Enable or disable radio test mode emmiting modulated or unmodulated * (carrier) signal. See User's Guide pages 719 and 741. -*/ + */ static uint32_t prev_FRMCTRL0, prev_MDMTEST1; static uint8_t was_on; @@ -407,7 +407,7 @@ 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; @@ -416,7 +416,7 @@ set_test_mode(uint8_t enable, uint8_t modulated) off(); prev_FRMCTRL0 = REG(RFCORE_XREG_FRMCTRL0); /* This constantly transmits random data */ - REG(RFCORE_XREG_FRMCTRL0) = 0x00000042; + REG(RFCORE_XREG_FRMCTRL0) = 0x00000042; if(!modulated) { prev_MDMTEST1 = REG(RFCORE_XREG_MDMTEST1); /* ...adding this we send an unmodulated carrier instead */ @@ -850,7 +850,7 @@ get_value(radio_param_t param, radio_value_t *value) switch(param) { case RADIO_PARAM_POWER_MODE: - if ((REG(RFCORE_XREG_RXENABLE) & RFCORE_XREG_RXENABLE_RXENMASK) == 0) { + 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 @@ -943,7 +943,7 @@ 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); diff --git a/arch/dev/cc2420/cc2420.c b/arch/dev/cc2420/cc2420.c index 18b289c1d..545f917ac 100644 --- a/arch/dev/cc2420/cc2420.c +++ b/arch/dev/cc2420/cc2420.c @@ -1132,9 +1132,9 @@ set_send_on_cca(uint8_t enable) send_on_cca = enable; } /*---------------------------------------------------------------------------*/ -/* Enable or disable radio test mode emmiting modulated or unmodulated +/* Enable or disable radio test mode emmiting modulated or unmodulated * (carrier) signal. See datasheet page 55. -*/ + */ static uint16_t prev_MDMCTRL1, prev_DACTST; static uint8_t was_on; @@ -1151,12 +1151,12 @@ set_test_mode(uint8_t enable, uint8_t modulated) was_on = (mode == RADIO_POWER_MODE_ON); off(); prev_MDMCTRL1 = getreg(CC2420_MDMCTRL1); - setreg(CC2420_MDMCTRL1, 0x050C); + setreg(CC2420_MDMCTRL1, 0x050C); if(!modulated) { prev_DACTST = getreg(CC2420_DACTST); setreg(CC2420_DACTST, 0x1800); } - /* actually starts the test mode */ + /* actually starts the test mode */ strobe(CC2420_STXON); } else { if(mode != RADIO_POWER_MODE_CARRIER_ON) {