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,

     

    My apologies for the long wait, and thank you so much for sharing such an in-depth explanation and detailed bug report!

    This is highly appreciated.

    Remi.G said:
    Start with wifi/ble_coex example on nRF7002-DK and NCS 2.8.0, no modifications.

    I build it with this command, to enable the interface (as outlined in the readme for the sample):

    west build -p -b nrf7002dk/nrf5340/cpuapp -- -DCONFIG_MPSL_CX=y -Dipc_radio_CONFIG_MPSL_CX=y

    I can confirm that I see similar behavior on my end:

    When running the routine that you posted:

    Remi.G said:

    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

    First suspicion is that it looks to be charge in the voltage net that is discharged, but I will report this back to the wifi-team for further investigation.

    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.

    I will try to reproduce this within a couple of business days and get back to you.

    Remi.G said:

    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?

    I will check up on this. There's other places where this is inverted as well, but the PS does not specify an active level for the GRANT pin.

     

    Kind regards,

    Håkon

Reply
  • Hi,

     

    My apologies for the long wait, and thank you so much for sharing such an in-depth explanation and detailed bug report!

    This is highly appreciated.

    Remi.G said:
    Start with wifi/ble_coex example on nRF7002-DK and NCS 2.8.0, no modifications.

    I build it with this command, to enable the interface (as outlined in the readme for the sample):

    west build -p -b nrf7002dk/nrf5340/cpuapp -- -DCONFIG_MPSL_CX=y -Dipc_radio_CONFIG_MPSL_CX=y

    I can confirm that I see similar behavior on my end:

    When running the routine that you posted:

    Remi.G said:

    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

    First suspicion is that it looks to be charge in the voltage net that is discharged, but I will report this back to the wifi-team for further investigation.

    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.

    I will try to reproduce this within a couple of business days and get back to you.

    Remi.G said:

    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?

    I will check up on this. There's other places where this is inverted as well, but the PS does not specify an active level for the GRANT pin.

     

    Kind regards,

    Håkon

Children
No Data
Related