nRF21540(FEM) not working on custom nRF52840 board

Hello,
I'm testing the nRF21540 FEM on a custom nRF52840-based board using the nRF Connect SDK.

I’ve enabled
CONFIG_MPSL_FEM
CONFIG_MPSL_FEM_NRF21540_GPIO_SPI
CONFIG_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_sol from 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)>;
        };
    };
};


Parents Reply Children
No Data
Related