Skyworks FEM control with 802.15.4 with NCS/Zephyr 2.0.0

Hi,

I'm having trouble getting the FEM in my Fanstel BT840X module working (the module with the nRF52840 processor and Skyworks 66112 amplifier).

I'm using nRF Connect version 2.0.0, though I can upgrade if it helps.

The first issue I've had is conflicting documentation on how to do this. I found that the recommended path of adding CONFIG_MPSL and CONFIG_MPSL_FEM does not build if you have CONFIG_NRF_802154_SOURCE_HAL_NORDIC in the project. I started this project from radio_test originally, and that sample uses the _NORDIC version.

The radio_test sample puts references to fem.c and generic_fem.c from the /nrf/samples/bluetooth/direct_test_mode/src/fem/ directory into CMakeLists.txt and Kconfig and it seems to expect you to use CONFIG_FEM and CONFIG_GENERIC_FEM in prj.conf. That scheme will at least build along with CONFIG_NRF_802154_SOURCE_HAL_NORDIC so I've been trying to use that.

Based on other support tickets I found, and information at this link,: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.0/nrf/ug_radio_fem.html#ug-radio-fem-skyworks

I modified my .dts file to add this code in the / { section:

nrf_radio_fem: skyworks_fem {
compatible = "skyworks,sky66112-11", "generic-fem-two-ctrl-pins";
ctx-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
crx-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
cps-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
chl-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
};

and this code outside of that section: 

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

For my testing, I turned down the transmit power to -20dBm, and with the amplifier off my two boards can see each other at about -59dBm across my desk. At this level my boards can communicate but I'd definitely see a jump in RSSI if the amplifier were working.

If I put in the modified .dts file, my two devices can no longer talk to each other - regardless of the presence or absence of any CONFIG values in the prj.conf. So it seems like the .dts changes are making a difference, but not in the direction I expected.

Please help! This is urgent!

Thanks,

Glen

Parents
  • Hi,

    Can you try setting cps-gpios to GPIO_ACTIVE_LOW? According to the SKY66112-11 datasheet, setting CPS high will put the FEM in "Receive/Transmit bypass mode", which will give you approximately -2 dB gain.

    Best regards,
    Jørgen

  • I just had a thought - maybe the devicetree stuff is working fine and the reason I'm not seeing packets through is that I'm not initializing or using the generic FEM driver code correctly. Am I supposed to call some functions in my code to set up/use that driver?

    My code is using nrf_802154_transmit_raw() to send packets and nrf_802154_transmitted_raw() and nrf_802154_transmit_failed() to know when the attempt to send it is complete.

    I'm assuming that somewhere along the way, nrf_802154_transmit_raw somehow calls the FEM code to switch the GPIO to TX mode, then off to listen for the 802.15.4 ack as soon as it's been sent. is that how this works and will the driver I'm trying to use do what I want?

    To receive packets I defined my own instance of rf_process_rx_packets where I call my own little ISR function to save off the info etc and then nrf_802154_buffer_free_raw.

  • Hi Jørgen,

    I've been working on the MPSL stuff today - I removed CONFIG_NRF_802154_SOURCE_HAL_NORDIC=y and I added the following configs (not sure if all of them are necessary):

    CONFIG_MPSL=y
    CONFIG_MPSL_FEM=y
    CONFIG_MPSL_FEM_SIMPLE_GPIO=y
    CONFIG_MPSL_FEM_DEVICE_CONFIG_254=y
    As I mentioned above, I'm manually controlling the CPS and CHL lines, so all I have added to the dts file at this point is this: 
    /{ nrf_radio_fem: skyworks_fem {
    compatible = "skyworks,sky66112-11", "generic-fem-two-ctrl-pins";
    ctx-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
    crx-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
    };
    };
    I've found that with those .dts changes, the signal level is lower than it is without. So "turning on" the amplifier is apparently making things worse.
    I stumbled on some documentation for the MPSL code and related files here: /nRF_Connect/v2.0.0/nrfxlib/mpsl/doc/fem.rst
    /nRF_Connect/v2.0.0/nrfxlib/mpsl/doc/pic/FEM_sequence_simple.svg
    /nRF_Connect/v2.0.0/nrfxlib/mpsl/include/protocol/mpsl_fem_protocol_api.h
    From looking at those files, it looks like I'm supposed to figure out the exact timing of my radio exchange and feed the MPSL library a timer and the compare/capture timings where I want all the  RX/TX switching to occur. Am I interpreting that correctly? I'd imagined that the driver would take care of all of that for me and I'll I'd have to do to use the FEM code would be to get the .dts and .conf information correct.
     
    If I do need to manually configure the driver to carry out its operations, is there any example code or assistance for figuring all of that out for 802.15.4? I searched devzone for the mpsl_fem_pa_configuration_set function and apparently nobody has ever asked about that before.
     
    Thanks
    Glen
  • A bit more information - It looks like the transmit function I'm using ultimately does call the FEM functions via this long string of calls:

    nrf_802154_transmit_raw() calls nrf_802154_request_transmit() which calls nrf_802154_core_transmit() which calls tx_init() which calls nrf_802154_trx_transmit_frame() which calls fem_for_tx_set() which calls mpsl_fem_pa_configuration_set().

    So it seems like the code is there to do what I want. I wish I had access to these GPIO pins where I could hook up an oscilloscope and see them toggling, but they are buried, and I think they are no-connects to the balls on this Fanstel module anyway.

    I guess I'll just keep experimenting, and advice would be appreciated.

    On another topic - I finally figured out how to reply to the exact comment I want on a DevZone post - the "reply" buttons just don't appear under most comments so my conversations in the past have been a mess of replying to the wrong comment because it's all I can find a reply button for. I figured out if I zoom way out so that I can see all the posts on one page then the reply buttons appear under all of the posts.

  • Do you have a nRF52840 DK that you can flash the application to and verify if the GPIOs are toggling on that one? Unless you have done some major modifications to the target board files, or interfaces with some external sensors, the application might be able to run on the DK without any changes.

  • Good idea - I do have a devkit. I'll give that a try

  • I think I got it working! I need to do more testing to make sure I don't still have a problem, but redefining the GPIO to be on pins I could get to with an oscilloscope helped immensely.

    The big thing that made it start working was that in order for the MPSL FEM code to work, MPSL_FEM_GENERIC_TWO_CTRL_PINS_SUPPORT has to be defined. I had tried to define that previously in my kconfig.board file but maybe I did it wrong. I ended up putting the following code in the Kconfig in my main project:

    config BOARD_ENABLE_FEM
    bool "FEM enabled"
    default y
    select MPSL_FEM_GENERIC_TWO_CTRL_PINS_SUPPORT

    I had previously tried adding that to my kconfig.board in my board directory but it gave me an error about the default y, saying something about defaults not applying to choices, so I'd removed the default and I think that made it not do anything. Maybe there's some difference between Kconfig and kconfig.board that I don't understand... maybe you can suggest the 'right' way to do this, but for now what I have works.

    ----------------------

    So, for anyone else trying to do this, you need the Kconfig modification, you need these two lines in your prj.conf:

    CONFIG_MPSL=y
    CONFIG_MPSL_FEM=y
    and you need  to add this to your .dts file:
    / {
    nrf_radio_fem: skyFem {
    compatible = "skyworks,sky66112-11", "generic-fem-two-ctrl-pins";
    ctx-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
    crx-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
    };
    I also have this line in my .dts file which may or may not be necessary... I'll do more experimenting later to see if I can remove it:
    &radio {
    fem = <&nrf_radio_fem>;
    };
    A final piece of information I just got answered in a different support request: The MPSL FEM library takes into account the 22dB amplification you get from the PA, so when you set the power level, either through the metadata or through a call to nrf_802154_tx_power_set, don't set it to 2dBm like the Skyworks/Fanstel documentation says to - set it to the final output power you want. For my project I'm now setting it to 22dBm.
    Somewhere along the way I found a thing you can add to the dts file to tell it what the PA gain is, but I'm leaving it at the default because it should be correct for my amplifier.
Reply
  • I think I got it working! I need to do more testing to make sure I don't still have a problem, but redefining the GPIO to be on pins I could get to with an oscilloscope helped immensely.

    The big thing that made it start working was that in order for the MPSL FEM code to work, MPSL_FEM_GENERIC_TWO_CTRL_PINS_SUPPORT has to be defined. I had tried to define that previously in my kconfig.board file but maybe I did it wrong. I ended up putting the following code in the Kconfig in my main project:

    config BOARD_ENABLE_FEM
    bool "FEM enabled"
    default y
    select MPSL_FEM_GENERIC_TWO_CTRL_PINS_SUPPORT

    I had previously tried adding that to my kconfig.board in my board directory but it gave me an error about the default y, saying something about defaults not applying to choices, so I'd removed the default and I think that made it not do anything. Maybe there's some difference between Kconfig and kconfig.board that I don't understand... maybe you can suggest the 'right' way to do this, but for now what I have works.

    ----------------------

    So, for anyone else trying to do this, you need the Kconfig modification, you need these two lines in your prj.conf:

    CONFIG_MPSL=y
    CONFIG_MPSL_FEM=y
    and you need  to add this to your .dts file:
    / {
    nrf_radio_fem: skyFem {
    compatible = "skyworks,sky66112-11", "generic-fem-two-ctrl-pins";
    ctx-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
    crx-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
    };
    I also have this line in my .dts file which may or may not be necessary... I'll do more experimenting later to see if I can remove it:
    &radio {
    fem = <&nrf_radio_fem>;
    };
    A final piece of information I just got answered in a different support request: The MPSL FEM library takes into account the 22dB amplification you get from the PA, so when you set the power level, either through the metadata or through a call to nrf_802154_tx_power_set, don't set it to 2dBm like the Skyworks/Fanstel documentation says to - set it to the final output power you want. For my project I'm now setting it to 22dBm.
    Somewhere along the way I found a thing you can add to the dts file to tell it what the PA gain is, but I'm leaving it at the default because it should be correct for my amplifier.
Children
  • Hi, do you by any chance have a working demo project I could have a look at? This is really doing my head in, I followed your directions and also checked the final settings in the generated '.config' file. However, comparing RSSI (using the 'nRF Connect' app on my phone) from the BT840X module against a 'normal' nRF52840 (with no amplifier front-end), the BT840X actually shows worse RSSI levels. I think the GPIOs are working correctly because if I change any, then the RF module doesn't work at all.

  • Unfortunately my code is set up for a custom board and full of customer IP so I don't have a nice package I could send you.

    I suggest you try the trick to edit the .dts to tell it the CTX and CRX pins are on different GPIO that you have access to. If you can put an oscilloscope or logic analyzer on them you'll be able to see if the module is toggling those pins when it's time to transmit (obviously your RSSI *really* won't be good since the FEM definitely won't be getting turned on and off in this state).

    If they are toggling you're almost there - just make sure you're setting CPS low and CHL high (I'm using 

    gpio_pin_configure for those) and make sure you're setting the output power level correctly - also maybe experiment with different power levels from -40 to as high as it will go to see what your RSSI does.  I found my signal stopped getting better after +22 or maybe +24.
    If they aren't toggling, it's probably something related to the configuration. Try looking in the autoconf.h file in the build directory to see what's getting included in the final build. Here's what the CONFIG_MPSL section of mine looks like (I've just got CONFIG_MPSL and CONFIG_MPSL_FEM in my prj.conf, and that stuff in my kconfig pulls in the GENERIC_TWO_CTRL_PINS thing):
    #define CONFIG_MPSL_FEM_GENERIC_TWO_CTRL_PINS_SUPPORT 1
    #define CONFIG_MPSL_FEM 1
    #define CONFIG_MPSL_FEM_SIMPLE_GPIO 1
    #define CONFIG_MPSL_FEM_DEVICE_CONFIG_254 1
    #define CONFIG_MPSL_THREAD_COOP_PRIO 8
    #define CONFIG_MPSL_WORK_STACK_SIZE 1024
    #define CONFIG_MPSL_TIMESLOT_SESSION_COUNT 0
    Good luck,
    Glen
  • Thank you for the info and suggestions. Yes, I was going to try and look at CTX/CRX to see if they're being toggled correctly (autoconfig.h looks good).
    May I ask what version of the SDK you're using? I'm using v2.2.0

  • Actually, it started working for me after I set 

    tx-gain-db = < 2 >; (instead of 22)

    Thanks for all your help!

  • Interesting - I wonder if that's a difference in the nCS version (since I used 2.0.0 and you're at 2.2.0) or if it's because you're setting it in the dts file instead of through a function call. I really miss the days of thorough software documentation where there would be a section describing everything about how each module works instead of the Doxygen self-documenting junk everyone pretends is documentation now.

Related