Hello,
I'm testing the nRF21540 FEM on a custom nRF52840-based board using the nRF Connect SDK.
I’ve enabled CONFIG_MPSL_FEMCONFIG_MPSL_FEM_NRF21540_GPIO_SPICONFIG_BT_LL_SOFTDEVICE
in my configuration.
In the device tree, I’ve also added the nordic,nrf21540-fem node with correctly connected tx-en-gpios, rx-en-gpios, and pdn-gpios.
However, the FEM does not seem to operate — no control signals are observed on the output pins.
Environment:
-
nRF Connect SDK version: v3.0.1
-
SoC: nRF52840
-
FEM: nRF21540 (controlled via GPIO + SPI)
-
Example:
l4_e1_solfrom the Bluetooth Low Energy Fundamentals course.
Note that this issue is not limited to this example — the same behavior occurs when testing with other BLE samples from the SDK as well.
Notable behavior:
If I first flash a project built with the nRF5 SDK (which does not include any FEM-related code), and then flash the NCS example, the FEM starts working correctly.
I can observe increased RSSI and verify FEM control pin activity using an oscilloscope.
.dts/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "gateway_v1-pinctrl.dtsi"
/ {
model = "gateway version 1";
compatible = "kyleboard,gateway-v1";
chosen {
zephyr,sram = &sram0;
zephyr,flash = &flash0;
zephyr,code-partition = &slot0_partition;
zephyr,console = &uart0;
zephyr,shell-uart = &uart0;
zephyr,uart-mcumgr = &uart0;
};
leds {
compatible = "gpio-leds";
led0: led_0 {
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
label = "BLE LED";
};
};
aliases {
led0 = &led0;
};
nrf_radio_fem: nrf21540_fem {
compatible = "nordic,nrf21540-fem";
tx-en-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
rx-en-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
pdn-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
ant-sel-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
mode-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
spi-if = <&nrf_radio_fem_spi>;
supply-voltage-mv = <3300>;
tx-en-settle-time-us = <13>;
rx-en-settle-time-us = <13>;
pdn-settle-time-us = <18>;
trx-hold-time-us = <5>;
};
};
fem_spi: &spi1 {
status = "okay";
cs-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&spi1_default>;
pinctrl-names = "default";
nrf_radio_fem_spi: nrf21540_fem_spi@0 {
compatible = "nordic,nrf21540-fem-spi";
reg = <0>;
spi-max-frequency = <4000000>;
status = "okay";
};
};
&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 DT_SIZE_K(48)>;
};
slot0_partition: partition@c000 {
label = "image-0";
reg = <0x0000c000 DT_SIZE_K(472)>;
};
slot1_partition: partition@82000 {
label = "image-1";
reg = <0x00082000 DT_SIZE_K(472)>;
};
storage_partition: partition@f8000 {
label = "storage";
reg = <0x000f8000 DT_SIZE_K(32)>;
};
};
};
&gpio0 {
status = "okay";
};
&gpio1 {
status = "okay";
};
&gpiote {
status = "okay";
};
&uart0 {
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <115200>;
pinctrl-0 = <&uart0_default>;
pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default", "sleep";
};
&clock {
status = "okay";
lf-clk {
clock-source = "XTAL";
accuracy = <20>;
};
};
&radio {
status = "okay";
fem = <&nrf_radio_fem>;
};
prj.conf# Logger module
CONFIG_LOG=y
# Button and LED library
CONFIG_DK_LIBRARY=y
# Bluetooth LE
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="MY_LBS1"
# Increase stack size for the main thread and System Workqueue
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_BT_LL_SOFTDEVICE=y
# CONFIG_BT_LL_SOFTDEVICE_MULTIROLE=y
CONFIG_MPSL=y
CONFIG_MPSL_FEM=y
CONFIG_MPSL_FEM_NRF21540_GPIO_SPI=y
# SPI
CONFIG_SPI=y
CONFIG_SPI_NRFX=y
pinctrl.dtsi&pinctrl {
uart0_default: uart0_default {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 4)>,
<NRF_PSEL(UART_RTS, 0, 6)>;
};
group2 {
psels = <NRF_PSEL(UART_RX, 0, 26)>,
<NRF_PSEL(UART_CTS, 0, 8)>;
bias-pull-up;
};
};
uart0_sleep: uart0_sleep {
group1 {
psels =
<NRF_PSEL(UART_TX, 0, 4)>,
<NRF_PSEL(UART_RX, 0, 26)>,
<NRF_PSEL(UART_RTS, 0, 6)>,
<NRF_PSEL(UART_CTS, 0, 8)>;
low-power-enable;
};
};
spi1_default: spi1_default {
group1 {
psels =
<NRF_PSEL(SPIM_SCK, 0, 20)>,
<NRF_PSEL(SPIM_MOSI, 0, 15)>,
<NRF_PSEL(SPIM_MISO, 0, 17)>;
};
};
spi2_default: spi2_default {
group1 {
psels =
<NRF_PSEL(SPIM_SCK, 0, 24)>,
<NRF_PSEL(SPIM_MOSI, 0, 12)>,
<NRF_PSEL(SPIM_MISO, 1, 9)>;
};
};
};