Unable to enable gain control on nRF21540 FEM with nRF5340

Hello,

I’m trying to get an nRF21540 FEM working with a chip-down nRF5340 design under NCS v2.4.2. I’m able to enable the FEM at its default gain setting, but I hit a wall trying to get gain control either via the mode-gpios property and associated KConfig settings, or dynamic control via SPI0 on the network core.

I have a pin forwarder defined in the application core's DTS:

gpio_fwd: nrf-gpio-forwarder {
        compatible = "nordic,nrf-gpio-forwarder";
		status = "okay";
		nrf21540-gpio-if {
			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>, /* rx-en-gpios */
					<&gpio1 6 GPIO_ACTIVE_HIGH>, /* tx-en-gpios */
					<&gpio0 29 GPIO_ACTIVE_HIGH>, /* pdn-gpios */
					<&gpio1 8 GPIO_ACTIVE_HIGH>;
		};
		nrf21540-spi-if {
			gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>, /* clk */
					<&gpio0 27 GPIO_ACTIVE_HIGH>, /* mosi */
					<&gpio0 24 GPIO_ACTIVE_HIGH>, /* csn */
					<&gpio0 26 GPIO_ACTIVE_HIGH>; /* miso */
		};	
    };
 

Here's my hci_rpmsg.overlay:

/ {
   nrf_radio_fem: nrf21540_fem {
		compatible  = "nordic,nrf21540-fem";
		tx-en-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
		rx-en-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
		pdn-gpios   = <&gpio0 29 GPIO_ACTIVE_HIGH>;
		// mode-gpios  = <&gpio1 8 GPIO_ACTIVE_HIGH>;
		spi-if = <&nrf_radio_fem_spi>;
		supply-voltage-mv = <1800>;
  	};
};

&radio {
	fem = <&nrf_radio_fem>;
};

&uart0 {
   status = "disabled";
};

fem_spi: &spi0 {
	status = "okay";
	pinctrl-0 = <&spi0_default_alt>;
	pinctrl-1 = <&spi0_sleep_alt>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;

	nrf_radio_fem_spi: nrf21540_fem_spi@0 {
		compatible = "nordic,nrf21540-fem-spi";
		status = "okay";
		reg = <0>;
		spi-max-frequency = <8000000>;
	};
};

&pinctrl {

	spi0_default_alt: spi0_default_alt {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK,  0, 28)>,
					<NRF_PSEL(SPIM_MISO, 0, 26)>,
					<NRF_PSEL(SPIM_MOSI, 0, 27)>;
		};
	};
	spi0_sleep_alt: spi0_sleep_alt {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK,  0, 28)>,
					<NRF_PSEL(SPIM_MISO, 0, 26)>,
					<NRF_PSEL(SPIM_MOSI, 0, 27)>;
			low-power-enable;
		};
	};
};

And here's the relevant settings from my hci_rpmsg.conf:

CONFIG_FEM=y
CONFIG_FEM_AL_LIB=y
CONFIG_MPSL_FEM=y
CONFIG_MPSL_FEM_ONLY=y

CONFIG_GPIO=y
CONFIG_MPSL_FEM_NRF21540_GPIO=y

# CONFIG_SPI=y
# CONFIG_SPI_NRFX=y
# CONFIG_NRFX_SPIM0=y
# CONFIG_MPSL_FEM_NRF21540_GPIO_SPI=y
# CONFIG_MPSL_FEM_NRF21540_RUNTIME_PA_GAIN_CONTROL=y

CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTA=20
CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTB=10
CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB=20

It builds successfully and has a much higher RSSI than with the FEM configs disabled, as expected.

When I uncomment the nrf_radio_fem's mode-gpios definition to allow switching between 10dB and 20dB, I get an undeclared device error originating from:

/opt/nordic/ncs/v2.4.2/nrf/subsys/mpsl/fem/nrf21540_gpio/mpsl_fem_nrf21540_gpio.c:174:25: note: in expansion of macro 'DEVICE_DT_GET'
174 | DEVICE_DT_GET(MPSL_FEM_GPIO_PORT(mode_gpios)),

And when I uncomment the SPI-related configs, I get another undeclared device error originating from:

/opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_nrfx_spim.c:625:1: note: in expansion of macro 'SPI_NRFX_SPIM_DEFINE'
625 | SPI_NRFX_SPIM_DEFINE(0);

In my experience, these types of error are usually due to some missing KConfig flag, but I'm all out of guesses as to which I may be missing that's not covered in the official docs. Or am I missing something else?

Thanks

Parents
  • Are you using GPIO mode, or SPI+GPIO mode?

    As per this page (FEM GPIO SPI), I see mode-gpios configures in the gpio_fwd node, but not in your overlay.

    Also, in the spi pins I see that first it is CSN, then CLK and then MISO and MOSI but in your overlay the order is changed.

    Can you check .config from the ./build/zephyr/ folder to check the configs are set in the compilation.

  • Sorry, I think I've been unclear. I have two issues with the two ways of controlling the FEM gain, and I'm not sure whether they're variations on the same issue.

    Note this time I've taken care to keep pin orders consistent, but I'm seeing the same issues.

    Issue 1 (GPIO mode):

    My pin forwarder:

    gpio_fwd: nrf-gpio-forwarder {
        compatible = "nordic,nrf-gpio-forwarder";
    	status = "okay";
    	nrf21540-gpio-if {
    		gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>, 	// tx-en-gpios
    				<&gpio1 6 GPIO_ACTIVE_HIGH>, 	// rx-en-gpios
    				<&gpio1 8 GPIO_ACTIVE_HIGH>,	// mode-gpios
    				<&gpio0 29 GPIO_ACTIVE_HIGH>; 	// pdn-gpios
    	};
    };

    My hci_rpmsg.overlay:

    / {
        nrf_radio_fem: nrf21540_fem {
          compatible  = "nordic,nrf21540-fem";
          tx-en-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
          rx-en-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
          mode-gpios  = <&gpio1 8 GPIO_ACTIVE_HIGH>;
          pdn-gpios   = <&gpio0 29 GPIO_ACTIVE_HIGH>;
          supply-voltage-mv = <1800>;
     };
    };
    
    &radio {
    	fem = <&nrf_radio_fem>;
    };

    Relevant hci_rpmsg.conf flags:

    CONFIG_FEM=y
    CONFIG_FEM_AL_LIB=y
    CONFIG_MPSL_FEM=y
    CONFIG_MPSL_FEM_ONLY=y
    
    CONFIG_MPSL_FEM_NRF21540_GPIO=y
    CONFIG_MPSL_FEM_NRF21540_RUNTIME_PA_GAIN_CONTROL=y
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTA=20
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTB=10
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB=10

    The full build error:

    /opt/nordic/ncs/v2.4.2/nrf/subsys/mpsl/fem/nrf21540_gpio/mpsl_fem_nrf21540_gpio.c: In function 'fem_nrf21540_gpio_configure':
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:41: error: '__device_dts_ord_55' undeclared (first use in this function); did you mean '__device_dts_ord_56'?
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                         ^~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/toolchain/common.h:132:26: note: in definition of macro '_DO_CONCAT'
      132 | #define _DO_CONCAT(x, y) x ## y
          |                          ^
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:33: note: in expansion of macro '_CONCAT'
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                 ^~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:210:37: note: in expansion of macro 'DEVICE_NAME_GET'
      210 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
          |                                     ^~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:227:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      227 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
          |                                  ^~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/nrf/subsys/mpsl/fem/nrf21540_gpio/mpsl_fem_nrf21540_gpio.c:174:25: note: in expansion of macro 'DEVICE_DT_GET'
      174 |                         DEVICE_DT_GET(MPSL_FEM_GPIO_PORT(mode_gpios)),
          |                         ^~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:41: note: each undeclared identifier is reported only once for each function it appears in
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                         ^~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/toolchain/common.h:132:26: note: in definition of macro '_DO_CONCAT'
      132 | #define _DO_CONCAT(x, y) x ## y
          |                          ^
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:33: note: in expansion of macro '_CONCAT'
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                 ^~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:210:37: note: in expansion of macro 'DEVICE_NAME_GET'
      210 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
          |                                     ^~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:227:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      227 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
          |                                  ^~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/nrf/subsys/mpsl/fem/nrf21540_gpio/mpsl_fem_nrf21540_gpio.c:174:25: note: in expansion of macro 'DEVICE_DT_GET'
      174 |                         DEVICE_DT_GET(MPSL_FEM_GPIO_PORT(mode_gpios)),

    Issue 2 (GPIO+SPI mode):

    My pin forwarder:

    gpio_fwd: nrf-gpio-forwarder {
        compatible = "nordic,nrf-gpio-forwarder";
    	status = "okay";
    	nrf21540-gpio-if {
    		gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>, 	// tx-en-gpios
    				<&gpio1 6 GPIO_ACTIVE_HIGH>, 	// rx-en-gpios
    				<&gpio1 8 GPIO_ACTIVE_HIGH>,	// mode-gpios
    				<&gpio0 29 GPIO_ACTIVE_HIGH>; 	// pdn-gpios
    	};
    	nrf21540-spi-if {
    		gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>, 	// clk
    				<&gpio0 26 GPIO_ACTIVE_HIGH>, 	// miso
    				<&gpio0 27 GPIO_ACTIVE_HIGH>, 	// mosi
    				<&gpio0 24 GPIO_ACTIVE_HIGH>; 	// csn
    	};	
    };

    My hci_rpmsg.overlay:

    / {
        nrf_radio_fem: nrf21540_fem {
          compatible  = "nordic,nrf21540-fem";
          tx-en-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
          rx-en-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
          mode-gpios  = <&gpio1 8 GPIO_ACTIVE_HIGH>;
          pdn-gpios   = <&gpio0 29 GPIO_ACTIVE_HIGH>;
          spi-if = <&nrf_radio_fem_spi>;
          supply-voltage-mv = <1800>;
     };
    };
    
    &radio {
    	fem = <&nrf_radio_fem>;
    };
    
    &uart0 {
       status = "disabled";
    };
    
    fem_spi: &spi0 {
    	status = "okay";
    	pinctrl-0 = <&spi0_default_alt>;
    	pinctrl-1 = <&spi0_sleep_alt>;
    	pinctrl-names = "default", "sleep";
    	cs-gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
    
    	nrf_radio_fem_spi: nrf21540_fem_spi@0 {
    		compatible = "nordic,nrf21540-fem-spi";
    		status = "okay";
    		reg = <0>;
    		spi-max-frequency = <8000000>;
    	};
    };
    
    &pinctrl {
    
    	spi0_default_alt: spi0_default_alt {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK,  0, 28)>,
    					<NRF_PSEL(SPIM_MISO, 0, 26)>,
    					<NRF_PSEL(SPIM_MOSI, 0, 27)>;
    		};
    	};
    	spi0_sleep_alt: spi0_sleep_alt {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK,  0, 28)>,
    					<NRF_PSEL(SPIM_MISO, 0, 26)>,
    					<NRF_PSEL(SPIM_MOSI, 0, 27)>;
    			low-power-enable;
    		};
    	};
    };

    And the relevant hci_rpmsg.conf settings:

    CONFIG_FEM=y
    CONFIG_FEM_AL_LIB=y
    CONFIG_MPSL_FEM=y
    CONFIG_MPSL_FEM_ONLY=y
    
    CONFIG_SPI=y
    CONFIG_SPI_NRFX=y
    CONFIG_NRFX_SPIM0=y
    
    CONFIG_MPSL_FEM_NRF21540_GPIO_SPI=y
    CONFIG_MPSL_FEM_NRF21540_RUNTIME_PA_GAIN_CONTROL=y
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTA=20
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTB=10
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB=10

    Here's the full build error:

    In file included from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_macro.h:34,
                     from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util.h:17,
                     from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/devicetree.h:21,
                     from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:12,
                     from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/drivers/spi.h:24,
                     from /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_nrfx_spim.c:7:
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:41: error: '__device_dts_ord_57' undeclared here (not in a function); did you mean '__device_dts_ord_7'?
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                         ^~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_internal.h:72:26: note: in definition of macro '__DEBRACKET'
       72 | #define __DEBRACKET(...) __VA_ARGS__
          |                          ^~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_internal.h:64:9: note: in expansion of macro '__GET_ARG2_DEBRACKET'
       64 |         __GET_ARG2_DEBRACKET(one_or_two_args _if_code, _else_code)
          |         ^~~~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_internal.h:59:9: note: in expansion of macro '__COND_CODE'
       59 |         __COND_CODE(_XXXX##_flag, _if_1_code, _else_code)
          |         ^~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_macro.h:180:9: note: in expansion of macro 'Z_COND_CODE_1'
      180 |         Z_COND_CODE_1(_flag, _if_1_code, _else_code)
          |         ^~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_context.h:73:17: note: in expansion of macro 'COND_CODE_1'
       73 |                 COND_CODE_1(DT_SPI_HAS_CS_GPIOS(_node_id),                              \
          |                 ^~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/toolchain/common.h:133:23: note: in expansion of macro '_DO_CONCAT'
      133 | #define _CONCAT(x, y) _DO_CONCAT(x, y)
          |                       ^~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:33: note: in expansion of macro '_CONCAT'
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                 ^~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:210:37: note: in expansion of macro 'DEVICE_NAME_GET'
      210 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
          |                                     ^~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:227:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      227 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
          |                                  ^~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/drivers/gpio.h:331:25: note: in expansion of macro 'DEVICE_DT_GET'
      331 |                 .port = DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(node_id, prop, idx)),\
          |                         ^~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_context.h:65:9: note: in expansion of macro 'GPIO_DT_SPEC_GET_BY_IDX'
       65 |         GPIO_DT_SPEC_GET_BY_IDX(_node_id, _prop, _idx),
          |         ^~~~~~~~~~~~~~~~~~~~~~~
    zephyr/include/generated/devicetree_generated.h:7391:68: note: in expansion of macro 'SPI_CONTEXT_CS_GPIO_SPEC_ELEM'
     7391 | #define DT_N_S_soc_S_spi_41013000_P_cs_gpios_FOREACH_PROP_ELEM(fn) fn(DT_N_S_soc_S_spi_41013000, cs_gpios, 0)
          |                                                                    ^~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/devicetree.h:4053:33: note: in expansion of macro 'DT_N_S_soc_S_spi_41013000_P_cs_gpios_FOREACH_PROP_ELEM'
     4053 | #define DT_CAT4(a1, a2, a3, a4) a1 ## a2 ## a3 ## a4
          |                                 ^~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_context.h:68:9: note: in expansion of macro 'DT_FOREACH_PROP_ELEM'
       68 |         DT_FOREACH_PROP_ELEM(_node_id, cs_gpios,                                \
          |         ^~~~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_context.h:74:30: note: in expansion of macro 'SPI_CONTEXT_CS_GPIOS_FOREACH_ELEM'
       74 |                             (SPI_CONTEXT_CS_GPIOS_FOREACH_ELEM(_node_id)), ({0}))       \
          |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_nrfx_spim.c:581:17: note: in expansion of macro 'SPI_CONTEXT_CS_GPIOS_INITIALIZE'
      581 |                 SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPIM(idx), ctx)                \
          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_nrfx_spim.c:625:1: note: in expansion of macro 'SPI_NRFX_SPIM_DEFINE'
      625 | SPI_NRFX_SPIM_DEFINE(0);

    I've noticed that I can get rid of this build error by commenting out the three SPI/NRFX configs in hci_rpmsg.conf, but I'm still unsure how to set the gain, other than setting CONFIG_MPSL_FEM_NRF21540 to 10 or 20, which doesn't appear to have any effect on RSSI in my test rig.

    I have seen what looks like the fem_al API in the radio_test sample, but I only see gain being set for specific BLE channels rather than a global setting.

    I have seen this forum post related to granular FEM gain control: nRF21540 SPI Gain Dynamic Control , which is checking FEM gain with mpsl_fem_pa_is_configured(), but I'm struggling to find the right includes for incorporating this API, if it's the way to go.

Reply
  • Sorry, I think I've been unclear. I have two issues with the two ways of controlling the FEM gain, and I'm not sure whether they're variations on the same issue.

    Note this time I've taken care to keep pin orders consistent, but I'm seeing the same issues.

    Issue 1 (GPIO mode):

    My pin forwarder:

    gpio_fwd: nrf-gpio-forwarder {
        compatible = "nordic,nrf-gpio-forwarder";
    	status = "okay";
    	nrf21540-gpio-if {
    		gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>, 	// tx-en-gpios
    				<&gpio1 6 GPIO_ACTIVE_HIGH>, 	// rx-en-gpios
    				<&gpio1 8 GPIO_ACTIVE_HIGH>,	// mode-gpios
    				<&gpio0 29 GPIO_ACTIVE_HIGH>; 	// pdn-gpios
    	};
    };

    My hci_rpmsg.overlay:

    / {
        nrf_radio_fem: nrf21540_fem {
          compatible  = "nordic,nrf21540-fem";
          tx-en-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
          rx-en-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
          mode-gpios  = <&gpio1 8 GPIO_ACTIVE_HIGH>;
          pdn-gpios   = <&gpio0 29 GPIO_ACTIVE_HIGH>;
          supply-voltage-mv = <1800>;
     };
    };
    
    &radio {
    	fem = <&nrf_radio_fem>;
    };

    Relevant hci_rpmsg.conf flags:

    CONFIG_FEM=y
    CONFIG_FEM_AL_LIB=y
    CONFIG_MPSL_FEM=y
    CONFIG_MPSL_FEM_ONLY=y
    
    CONFIG_MPSL_FEM_NRF21540_GPIO=y
    CONFIG_MPSL_FEM_NRF21540_RUNTIME_PA_GAIN_CONTROL=y
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTA=20
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTB=10
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB=10

    The full build error:

    /opt/nordic/ncs/v2.4.2/nrf/subsys/mpsl/fem/nrf21540_gpio/mpsl_fem_nrf21540_gpio.c: In function 'fem_nrf21540_gpio_configure':
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:41: error: '__device_dts_ord_55' undeclared (first use in this function); did you mean '__device_dts_ord_56'?
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                         ^~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/toolchain/common.h:132:26: note: in definition of macro '_DO_CONCAT'
      132 | #define _DO_CONCAT(x, y) x ## y
          |                          ^
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:33: note: in expansion of macro '_CONCAT'
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                 ^~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:210:37: note: in expansion of macro 'DEVICE_NAME_GET'
      210 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
          |                                     ^~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:227:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      227 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
          |                                  ^~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/nrf/subsys/mpsl/fem/nrf21540_gpio/mpsl_fem_nrf21540_gpio.c:174:25: note: in expansion of macro 'DEVICE_DT_GET'
      174 |                         DEVICE_DT_GET(MPSL_FEM_GPIO_PORT(mode_gpios)),
          |                         ^~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:41: note: each undeclared identifier is reported only once for each function it appears in
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                         ^~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/toolchain/common.h:132:26: note: in definition of macro '_DO_CONCAT'
      132 | #define _DO_CONCAT(x, y) x ## y
          |                          ^
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:33: note: in expansion of macro '_CONCAT'
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                 ^~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:210:37: note: in expansion of macro 'DEVICE_NAME_GET'
      210 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
          |                                     ^~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:227:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      227 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
          |                                  ^~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/nrf/subsys/mpsl/fem/nrf21540_gpio/mpsl_fem_nrf21540_gpio.c:174:25: note: in expansion of macro 'DEVICE_DT_GET'
      174 |                         DEVICE_DT_GET(MPSL_FEM_GPIO_PORT(mode_gpios)),

    Issue 2 (GPIO+SPI mode):

    My pin forwarder:

    gpio_fwd: nrf-gpio-forwarder {
        compatible = "nordic,nrf-gpio-forwarder";
    	status = "okay";
    	nrf21540-gpio-if {
    		gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>, 	// tx-en-gpios
    				<&gpio1 6 GPIO_ACTIVE_HIGH>, 	// rx-en-gpios
    				<&gpio1 8 GPIO_ACTIVE_HIGH>,	// mode-gpios
    				<&gpio0 29 GPIO_ACTIVE_HIGH>; 	// pdn-gpios
    	};
    	nrf21540-spi-if {
    		gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>, 	// clk
    				<&gpio0 26 GPIO_ACTIVE_HIGH>, 	// miso
    				<&gpio0 27 GPIO_ACTIVE_HIGH>, 	// mosi
    				<&gpio0 24 GPIO_ACTIVE_HIGH>; 	// csn
    	};	
    };

    My hci_rpmsg.overlay:

    / {
        nrf_radio_fem: nrf21540_fem {
          compatible  = "nordic,nrf21540-fem";
          tx-en-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
          rx-en-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
          mode-gpios  = <&gpio1 8 GPIO_ACTIVE_HIGH>;
          pdn-gpios   = <&gpio0 29 GPIO_ACTIVE_HIGH>;
          spi-if = <&nrf_radio_fem_spi>;
          supply-voltage-mv = <1800>;
     };
    };
    
    &radio {
    	fem = <&nrf_radio_fem>;
    };
    
    &uart0 {
       status = "disabled";
    };
    
    fem_spi: &spi0 {
    	status = "okay";
    	pinctrl-0 = <&spi0_default_alt>;
    	pinctrl-1 = <&spi0_sleep_alt>;
    	pinctrl-names = "default", "sleep";
    	cs-gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
    
    	nrf_radio_fem_spi: nrf21540_fem_spi@0 {
    		compatible = "nordic,nrf21540-fem-spi";
    		status = "okay";
    		reg = <0>;
    		spi-max-frequency = <8000000>;
    	};
    };
    
    &pinctrl {
    
    	spi0_default_alt: spi0_default_alt {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK,  0, 28)>,
    					<NRF_PSEL(SPIM_MISO, 0, 26)>,
    					<NRF_PSEL(SPIM_MOSI, 0, 27)>;
    		};
    	};
    	spi0_sleep_alt: spi0_sleep_alt {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK,  0, 28)>,
    					<NRF_PSEL(SPIM_MISO, 0, 26)>,
    					<NRF_PSEL(SPIM_MOSI, 0, 27)>;
    			low-power-enable;
    		};
    	};
    };

    And the relevant hci_rpmsg.conf settings:

    CONFIG_FEM=y
    CONFIG_FEM_AL_LIB=y
    CONFIG_MPSL_FEM=y
    CONFIG_MPSL_FEM_ONLY=y
    
    CONFIG_SPI=y
    CONFIG_SPI_NRFX=y
    CONFIG_NRFX_SPIM0=y
    
    CONFIG_MPSL_FEM_NRF21540_GPIO_SPI=y
    CONFIG_MPSL_FEM_NRF21540_RUNTIME_PA_GAIN_CONTROL=y
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTA=20
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB_POUTB=10
    CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB=10

    Here's the full build error:

    In file included from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_macro.h:34,
                     from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util.h:17,
                     from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/devicetree.h:21,
                     from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:12,
                     from /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/drivers/spi.h:24,
                     from /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_nrfx_spim.c:7:
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:41: error: '__device_dts_ord_57' undeclared here (not in a function); did you mean '__device_dts_ord_7'?
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                         ^~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_internal.h:72:26: note: in definition of macro '__DEBRACKET'
       72 | #define __DEBRACKET(...) __VA_ARGS__
          |                          ^~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_internal.h:64:9: note: in expansion of macro '__GET_ARG2_DEBRACKET'
       64 |         __GET_ARG2_DEBRACKET(one_or_two_args _if_code, _else_code)
          |         ^~~~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_internal.h:59:9: note: in expansion of macro '__COND_CODE'
       59 |         __COND_CODE(_XXXX##_flag, _if_1_code, _else_code)
          |         ^~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/sys/util_macro.h:180:9: note: in expansion of macro 'Z_COND_CODE_1'
      180 |         Z_COND_CODE_1(_flag, _if_1_code, _else_code)
          |         ^~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_context.h:73:17: note: in expansion of macro 'COND_CODE_1'
       73 |                 COND_CODE_1(DT_SPI_HAS_CS_GPIOS(_node_id),                              \
          |                 ^~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/toolchain/common.h:133:23: note: in expansion of macro '_DO_CONCAT'
      133 | #define _CONCAT(x, y) _DO_CONCAT(x, y)
          |                       ^~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:84:33: note: in expansion of macro '_CONCAT'
       84 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                 ^~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:210:37: note: in expansion of macro 'DEVICE_NAME_GET'
      210 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
          |                                     ^~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/device.h:227:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      227 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
          |                                  ^~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/drivers/gpio.h:331:25: note: in expansion of macro 'DEVICE_DT_GET'
      331 |                 .port = DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(node_id, prop, idx)),\
          |                         ^~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_context.h:65:9: note: in expansion of macro 'GPIO_DT_SPEC_GET_BY_IDX'
       65 |         GPIO_DT_SPEC_GET_BY_IDX(_node_id, _prop, _idx),
          |         ^~~~~~~~~~~~~~~~~~~~~~~
    zephyr/include/generated/devicetree_generated.h:7391:68: note: in expansion of macro 'SPI_CONTEXT_CS_GPIO_SPEC_ELEM'
     7391 | #define DT_N_S_soc_S_spi_41013000_P_cs_gpios_FOREACH_PROP_ELEM(fn) fn(DT_N_S_soc_S_spi_41013000, cs_gpios, 0)
          |                                                                    ^~
    /opt/nordic/ncs/v2.4.2/zephyr/include/zephyr/devicetree.h:4053:33: note: in expansion of macro 'DT_N_S_soc_S_spi_41013000_P_cs_gpios_FOREACH_PROP_ELEM'
     4053 | #define DT_CAT4(a1, a2, a3, a4) a1 ## a2 ## a3 ## a4
          |                                 ^~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_context.h:68:9: note: in expansion of macro 'DT_FOREACH_PROP_ELEM'
       68 |         DT_FOREACH_PROP_ELEM(_node_id, cs_gpios,                                \
          |         ^~~~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_context.h:74:30: note: in expansion of macro 'SPI_CONTEXT_CS_GPIOS_FOREACH_ELEM'
       74 |                             (SPI_CONTEXT_CS_GPIOS_FOREACH_ELEM(_node_id)), ({0}))       \
          |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_nrfx_spim.c:581:17: note: in expansion of macro 'SPI_CONTEXT_CS_GPIOS_INITIALIZE'
      581 |                 SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPIM(idx), ctx)                \
          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /opt/nordic/ncs/v2.4.2/zephyr/drivers/spi/spi_nrfx_spim.c:625:1: note: in expansion of macro 'SPI_NRFX_SPIM_DEFINE'
      625 | SPI_NRFX_SPIM_DEFINE(0);

    I've noticed that I can get rid of this build error by commenting out the three SPI/NRFX configs in hci_rpmsg.conf, but I'm still unsure how to set the gain, other than setting CONFIG_MPSL_FEM_NRF21540 to 10 or 20, which doesn't appear to have any effect on RSSI in my test rig.

    I have seen what looks like the fem_al API in the radio_test sample, but I only see gain being set for specific BLE channels rather than a global setting.

    I have seen this forum post related to granular FEM gain control: nRF21540 SPI Gain Dynamic Control , which is checking FEM gain with mpsl_fem_pa_is_configured(), but I'm struggling to find the right includes for incorporating this API, if it's the way to go.

Children
No Data
Related