BLE+Wifi coexistence

I am trying BLE+WiFi coexistence on NCS 2.8.0 with nRF7002DK and finding some issues.

First is that it's non-functional. Running the wifi/ble_coex example, there is no activity on the COEX_REQUEST and COEX_STATUS0 pins.

Tracked that down to the GPIOs not being assigned to cpunet, and the cause of that is MPSL_CX_ANY_SUPPORT not set.

That is auto-configured based on nrf_radio_coex node existing in the DTS, which was removed from nrf5340_cpuapp_common.dtsi (relative to NCS 2.6.1).

Copying the nrf_radio_coex section from cpunet to cpuapp DTS, I see the coex pins toggling as expected. The proper fix is probably different, to avoid duplication.

Second issue is that coex appears to be limiting BLE + 5GHz Wifi, which I wouldn't expect because there is no interference.

The wifi/ble_coex README provides some results for 2.4 and 5GHz Wifi, and the BLE throughput for 5GHz wifi is shown to be the same with and without coex enabled.

I am seeing a difference - BLE throughput without coex is ~1.2Mbps, with coex it's ~700kbps.

Tried setting CONFIG_NRF70_SR_COEX_RF_SWITCH=n, same reduced throughput.

Here's a logic analyzer capture of BLE + 5GHz wifi coexistence with CONFIG_NRF70_SR_COEX_RF_SWITCH=n. Note the long pulse on COEX_GRANT, which appears to preempt the COEX_REQUEST (its rising edge is before the falling edge of COEX_REQUEST), indicating that BLE is yielding to WiFi, which shouldn't be necessary because there's no dependency.

Can you try the 5GHz benchmarks again for this scenario to see if the results in the README are still valid? 

Finally, there appears to be some long periods where WiFi is scanning where it holds the COEX_GRANT signal high, preventing BLE from transmitting.

To reproduce that, hack the wifi/ble_coex example:

  • Enable the coex signals, fix from first issue above.
  • Set CONFIG_WIFI_CREDENTIALS_STATIC_SSID to an invalid SSID, so it will only scan but not connect.
  • In main.c, move the BLE setup "if (test_ble)" section (line 417-425) to before the "if (test_wlan)" section (before line 380), so BLE starts first.
  • Edit ble_throughput_test.c, and change line 600 from select_role(true) to "select_role(false); return 0;". That will change BLE to peripheral role.
  • Build with coexistence enabled.
  • Don't need another DK to connect to over BLE, just let the board advertise indefinitely.

Those changes will run the test with BLE advertising concurrent with WiFi scanning. The effects of coexistence can be seen by missing BLE advertisements (a throughput test with missing packet detection would be better, but this is simpler/quicker).

Here's a logic analyzer trace of that setup:

Note the ~1 second intervals where COEX_GRANT stays high. This is part of the WiFi scanning, and BLE transmissions are not allowed during those periods. Here's a screenshot from the nRF Connect app monitoring those advertisements:

 

It's easier to see live, because the graph connects between missing advertisements, but each of those scanning periods shows missing advertisements.

Our application connects to BLE continuously but to WiFi only when needed, so a 1 second outage will result in a glitch to BLE real-time activity (e.g. audio or HID).

Parents
  • Found another issue, related to the state of COEX_GRANT when nRF7002 is in standby mode.

    Start with wifi/ble_coex example on nRF7002-DK and NCS 2.8.0, no modifications. This means that the COEX_REQUEST and COEX_STATUS0 will not be driven, as per the first issue above. That's fine as we're only looking at the nRF7002 signals.

    Probe the BUCKEN and COEX_GRANT pins.

    Edit main.c and modify wifi_connect with the following:

    static int wifi_connect(void)

    {
        struct net_if *iface = net_if_get_first_wifi();

        LOG_INF("Net interface is up");
        k_msleep(3000);
        LOG_INF("Setting net_if_down");
        net_if_down(iface);
        k_msleep(3000);
        LOG_INF("Setting net_if_up");
        net_if_up(iface);
        k_msleep(3000);

        if (net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0)) {

        ... remainder the same

    So at startup, the net interface, including the nRF7002 driver, will be toggled off then on again.

    Here's the trace (digital and analog capture of COEX_GRANT):

    That's good, the COEX_GRANT signal goes low (always granted) when the interface is down. 

    Zooming in on the falling edge of BUCKEN:

    The COEX_GRANT signal is actually driven high briefly before BUCKEN is set low, then it decays to 0. By stepping through the code, the high setting corresponds to the call to nrf_wifi_fmac_set_power_save(), then BUCKEN goes low in rpu_pwroff(), then COEX_GRANT decays when IOVDD is switched off.

    First concern is why power save would drive COEX_GRANT high, and it's actively driven because the pulldown (on nRF5340) has no effect. I would expect IOs to be set low, corresponding to "always granted". Some of the nRF7002 coexistence documentation shows COEX_GRANT as being active high, for example this: https://docs.nordicsemi.com/bundle/ncs-2.6.2/page/nrf/device_guides/wifi_coex.html

    Maybe this was the old "granted" state and it wasn't updated?

    Our board doesn't have a separate control for IOVDD, it's tied to the same power rail as the MCU. And I can claim that's more correct than the nRF7002-DK+driver, where it's turned off when the wifi interface is down - the BLE coex signals (COEX_REQUEST, COEX_STATUS0) can't be disabled dynamically, so they will continue to be driven and violate the IOVDD+0.3V spec on those IOs if BLE remains on with nRF7002 off.

    Without IOVDD turning off, the COEX_GRANT signal won't decay, and stays asserted while nRF7002 is in standby. Hacked the rpu_hw_if.c and disabled the iovdd control in both rpu_pwroff() and rpu_gpio_remove() to confirm:

    As expected, COEX_GRANT remains high when BUCKEN is low.

    That means that on a BLE+nRF7002 device, if the nRF7002 is put into standby mode and coex is enabled, the BLE can't be used unless IOVDD is also disabled - but if it is, then the BLE COEX_REQUEST/COEX_STATUS0 signals will violate the nRF7002 IO spec.

    If COEX_GRANT was set low in the power save command, things should be fine in all cases. In other words, whenever WiFi isn't active, the state of COEX_GRANT should be low/granted. Hopefully that can be done in the nRF7002 firmware, and it isn't a hardware dependency.

    A related issue - when nRF7002 is first started up with BUCKEN, and before the image is downloaded, it is also driving COEX_GRANT high. That drops low quickly, after the download, so shouldn't have much of an impact on BLE, but would also be more correct to default low.

  • Hi,

     

    We have been analyzing the reported behavior, and this symbol shall be set regardless of COEX enabled or not, as it is an indication that the feature is supported on a board-level:

    Tracked that down to the GPIOs not being assigned to cpunet, and the cause of that is MPSL_CX_ANY_SUPPORT not set.

    ie. MPSL_CX_ANY_SUPPORT will be set regardless of these symbols being appended to the build:

    -DCONFIG_MPSL_CX=y -Dipc_radio_CONFIG_MPSL_CX=y

    Meaning that if we explicitly set these to 'n':

    -DCONFIG_MPSL_CX=n -Dipc_radio_CONFIG_MPSL_CX=n

    The MPSL_CX_ANY_SUPPORT is still set, as the node itself is declared in device tree.

     

    If MPSL_CX_ANY_SUPPORT is not set by default, it indicates that the "nrf_radio_coex" node isn't declared in device tree:

    https://github.com/nrfconnect/sdk-nrf/blob/v2.8-branch/subsys/mpsl/cx/Kconfig#L12

    Note the ~1 second intervals where COEX_GRANT stays high. This is part of the WiFi scanning, and BLE transmissions are not allowed during those periods. Here's a screenshot from the nRF Connect app monitoring those advertisements:

    I assume a valid SSID is set for this test case.

    During scanning, it is expected to see intervals up to 0.5 second:

    However, 1 second is not expected, which we will look into.

    Q1: Are you seeing this consistently?

    Q2: Which wifi-channel are you connecting on?

    Related to the power-off of the module and COEX GRANT pin behavior:

    Remi.G said:
    The COEX_GRANT signal is actually driven high briefly before BUCKEN is set low, then it decays to 0. By stepping through the code, the high setting corresponds to the call to nrf_wifi_fmac_set_power_save(), then BUCKEN goes low in rpu_pwroff(), then COEX_GRANT decays when IOVDD is switched off.

    We are actively looking into this.

     

    I am seeing a difference - BLE throughput without coex is ~1.2Mbps, with coex it's ~700kbps.

    Q3: Is this measurement consistent across each measurement?

    Keep in mind that range has a great impact on the throughput, so if the devices are long apart, it will yield different results.

     

    • Enable the coex signals, fix from first issue above.
    • Set CONFIG_WIFI_CREDENTIALS_STATIC_SSID to an invalid SSID, so it will only scan but not connect.
    • In main.c, move the BLE setup "if (test_ble)" section (line 417-425) to before the "if (test_wlan)" section (before line 380), so BLE starts first.
    • Edit ble_throughput_test.c, and change line 600 from select_role(true) to "select_role(false); return 0;". That will change BLE to peripheral role.
    • Build with coexistence enabled.
    • Don't need another DK to connect to over BLE, just let the board advertise indefinitely.

    Those changes will run the test with BLE advertising concurrent with WiFi scanning. The effects of coexistence can be seen by missing BLE advertisements (a throughput test with missing packet detection would be better, but this is simpler/quicker).

    I have recreated this scenario, with no other changes than to set WIFI_CREDENTIALS_STATIC_SSID="Invalid SSID", and see that the GRANT pin is blocking continuously for 5 seconds. I will report this internally.

     

    Kind regards,

    Håkon

  • For MPSL_CX_ANY_SUPPORT, I understand it's set based on devicetree setting. But in NCS 2.8.0, that setting is only in nrf7002dk_nrf5340_cpunet.dts, not in nrf7002dk_nrf5340_cpuapp.dts, so it is only being set for cpunet. It would be reasonable to assume that only cpunet needs it as that's where the signals are driven, but just the initialization step on cpuapp for the IOs are missing when that setting is not present. Older NCS versions had it in both.

    For the ~1 second COEX_GRANT high test, it was not with a valid SSID. The intent was to reproduce a scenario where a device was periodically scanning and connecting to AP, which may not be available, while remaining connected to BLE. Even 0.5 seconds with no grant should cause a glitch on BLE real-time traffic, so that is undesirable.

    Q1: Those results are consistent, every time the WiFi scan runs. There are minor differences in the exact timing, but the magnitude of the intervals are the same.

    Q2: That grant test was for an invalid SSID so no relevant channel, but for other tests which did connect to AP (like the throughput test), it was 5GHz usually channel 44, sometimes channel 48 (the AP switches infrequently, but never switches mid-test).

    Q3: There is maybe ~50-100kbps variation from run to run, but the difference from coex enabled to disabled is consistent. I did several runs and switched back and forth several times, and the location of the dev board and AP were consistent. And the coex signals are clearly toggling even with 5GHz.

  • Hi,

     

    Remi.G said:
    For MPSL_CX_ANY_SUPPORT, I understand it's set based on devicetree setting. But in NCS 2.8.0, that setting is only in nrf7002dk_nrf5340_cpunet.dts, not in nrf7002dk_nrf5340_cpuapp.dts, so it is only being set for cpunet. It would be reasonable to assume that only cpunet needs it as that's where the signals are driven, but just the initialization step on cpuapp for the IOs are missing when that setting is not present. Older NCS versions had it in both.

    Yes, you are 100% correct here. My deepest apologies for totally misunderstanding your initial point. This is a clear bug from our side.

    The nRF5340 NRF_GPIO->PIN_CNF[] field MCUSEL (bits 28-30) are default set to the app core, which requires the application core to know about which pins to forward to either peripherals or the network core.

    I have reported this as a separate issue with high priority.

    Remi.G said:
    For the ~1 second COEX_GRANT high test, it was not with a valid SSID. The intent was to reproduce a scenario where a device was periodically scanning and connecting to AP, which may not be available, while remaining connected to BLE. Even 0.5 seconds with no grant should cause a glitch on BLE real-time traffic, so that is undesirable.

    I see up to 5 seconds of blocking in this scenario. I have made the wi-fi coex team aware of this.

    I have also reported that 0.5 seconds is too high in a working scenario. A task as been generated to look into improving this scenario.

    With a successful wifi-connection: 

    I am seeing a throughput reduction (and high variation) when connected to 5 GHz (ch 36), with CONFIG_NRF70_SR_COEX_RF_SWITCH=n and running the tests:

    [local] received 2433420 bytes (2376 KB) in 4916 GATT writes at 977544 bps
    [local] received 2631420 bytes (2569 KB) in 5316 GATT writes at 1057160 bps
    [local] received 2739330 bytes (2675 KB) in 5534 GATT writes at 1100512 bps
    [local] received 2713590 bytes (2649 KB) in 5482 GATT writes at 1090170 bps
    [local] received 2771505 bytes (2706 KB) in 5599 GATT writes at 1113360 bps

    Reduced with approx. 15-20% throughput in my test case.

    And as you mention, I see some "slots" of between 50 and 100 ms:

     

     With CONFIG_NRF70_SR_COEX_RF_SWITCH=y, I see around 1.0-1.1 Mbit/s throughput with bluetooth.

    Iperf is steadily reporting 9 MBit/s.

      

    Which version of the nRF7002-DK are you testing with? I am using v1.0.3 and also tested with an older revision v0.7.4, both of these have the same results as above.

     

    Kind regards,

    Håkon 

  • I am currently out of town, but will check the nRF7002-DK version when I get back at the end of this week.

  • My nRF7002 DK is v1.0.2. I have two boards with that version, they behave similar to each other.

Reply Children
Related