Is BLE + raw IEEE 802.15.4 TX (PHY only, no Thread/Zigbee) officially supported on nRF52840 with MPSL?

Hello Nordic team,

I am working on an nRF52840 project using nRF Connect SDK (Zephyr-based, v2.x / v3.x) and I would like to clarify the official support status of a specific multiprotocol use case.

I have intentionally limited this question to two focused points to avoid ambiguity.

1. Target Use Case

  • Device: nRF52840

  • SDK: nRF Connect SDK (Zephyr)

  • Protocols:

    • Bluetooth LE (SoftDevice Controller)

    • IEEE 802.15.4 PHY only (raw TX)

      • No Thread

      • No Zigbee

      • No MAC / NET stack usage

  • Radio sharing via MPSL (dynamic multiprotocol)

The 802.15.4 side is used only for custom raw frame transmission (driver-level TX), not for any standardized 802.15.4-based stack.


2. Observations So Far

  • BLE and IEEE 802.15.4 TX can both be enabled and initialized.

  • A single 802.15.4 TX call works while BLE is active.

  • However, periodic or continuous TX loops do not behave reliably:

    • TX returns success (0)

    • But repeated transmissions do not appear on a sniffer

    • No explicit runtime error is reported

  • All development was done using the nRF IEEE 802.15.4 radio driver + MPSL, not the legacy raw radio HAL.


3. Documentation Gap

From available documentation and samples, I understand that:

  • nRF52840 officially supports BLE + Thread/Zigbee concurrency via MPSL.

  • Multiprotocol support is clearly documented for full 802.15.4 stacks.

  • However, I cannot find an explicit statement or reference confirming:

    BLE + custom raw IEEE 802.15.4 TX (PHY only) is officially supported and validated


4. Questions (Primary Scope)

  1. Is BLE + raw IEEE 802.15.4 TX (PHY only, no Thread/Zigbee) an officially supported use case on nRF52840 when using MPSL?

  2. If supported in principle, are there any known limitations or design constraints (e.g. scheduling, TX frequency, timeslot behavior) that would explain why periodic TX may silently stop or not appear on a sniffer?

I am intentionally not asking for code review or full implementation guidance yet.
I would like to first understand the official support boundary and expectations.


5. Next Steps

Depending on the answers to the two questions above, I plan to:

  • Adjust the architecture (e.g. move to Thread/Zigbee, or dedicated timeslot handling), or

  • Continue debugging within the supported configuration and ask follow-up implementation questions.

Thank you for your time and clarification.

Best regards,

Ryan

Parents
  • Hello,

    You should be able to use 802154_phy_test together with MPSL+BLE. It is only BLE that has hard timing requirements, while the rest of the time can be spent on 802154. We don't have any samples showing exactly how to do this, but I imagine that you can take any of the ble+Zigbee/Thread samples, strip out the zigbee/thread, and replace it with what you find in NCS\nrf\samples\peripheral\802154_phy_test, and go from there.

    For follow up questions, please don't use chatGPT or other AI tools to format your questions. It makes it difficult to know what you are really asking for, and what the AI made up.

    Best regards,

    Edvin

  • Hello.

    I understand that there is no official reference code available for this specific use case.
    As a first step, I am trying to implement periodic TX using IEEE 802.15.4 only, but even this basic periodic transmission is not working yet.

    If I upload the source code I have been working on, would it be possible to receive support or feedback on it?

    Best regards,

    Ryan

  • Edvin said:
    If you stop sending packet after the first nrf_802154_transmit_raw(), do you see any of the interrupts then? You should see either nrf_802154_transmitted() or nrf_802154_transmit_failed() occur once. As far as I know, this is the way openthread and Zigbee uses it.

    Did you test queuing up only one packet, and see if you get any of the callbacks?

    Best regards,

    Edvin

  • Yes. transmit_raw() returns success (err=0), but no callback is triggered at all.

    Best regards,

    Ryan

  • Can you please zip and upload the entire application folder (Not just some of the files)? This way I can try to reproduce what you are seeing. Are you only missing the replies when you use the 0xFFFF address? Or is it for all messages?

    Best regards,

    Edvin

  • Sure, I will zip the entire application folder (including all files) and upload it here shortly.

    Regarding your question, the issue happens not only with 0xFFFF, but also with unicast messages.
    In other words, I am missing replies for all messages.

    Best regards,

    Ryan

    802154_tx_test.zip

  • This is the log from the unmodified application that you sent:

    So apparently, nrf_802154_transmitted() is being triggered.

    However, I do see in your main loop:

            if (!nrf_802154_transmit_raw(tx_frame, &metadata)) {
                LOG_ERR("TX rejected! Attempting driver reset...");                
            }

    But if nrf_802154_transmit_raw returns NRF_802154_TX_ERROR_NONE (=0), then it is a success. I did some changes, but mostly in error checking and logging. Try the attached project, and let me know the log output:

    802154_tx_test2.zip

    Note that I enabled UART logging in prj.conf. Disable it if you don't need it.

    Best regards,

    Edvin

Reply
  • This is the log from the unmodified application that you sent:

    So apparently, nrf_802154_transmitted() is being triggered.

    However, I do see in your main loop:

            if (!nrf_802154_transmit_raw(tx_frame, &metadata)) {
                LOG_ERR("TX rejected! Attempting driver reset...");                
            }

    But if nrf_802154_transmit_raw returns NRF_802154_TX_ERROR_NONE (=0), then it is a success. I did some changes, but mostly in error checking and logging. Try the attached project, and let me know the log output:

    802154_tx_test2.zip

    Note that I enabled UART logging in prj.conf. Disable it if you don't need it.

    Best regards,

    Edvin

Children
  • It looks like the issue was related to the RF performance of the nRF52840 DK board.
    After switching to our custom board, everything is working properly and the RF behavior is stable.

    It was a bit unexpected and confusing at first, but now the root cause seems clear.
    Thank you very much for your support and guidance throughout the debugging process — it was really helpful.

    Best regards,

    Ryan

    00> *** Booting nRF Connect SDK v3.2.1-d8887f6f32df ***
    00> *** Using Zephyr OS v4.2.99-ec78104f1569 ***
    00> [00:00:00.000,305] <inf> ieee802154_tx: === Step 1: Starting ===
    00> [00:00:00.100,463] <inf> ieee802154_tx: === Step 2: Initializing Radio ===
    00> [00:00:00.200,836] <inf> ieee802154_tx: === Step 3: Setting Channel ===
    00> [00:00:00.300,964] <inf> ieee802154_tx: === Step 4: Setting TX Power ===
    00> [00:00:00.401,092] <inf> ieee802154_tx: === Step 5: Setting Promiscuous Mode ===
    00> [00:00:00.501,220] <inf> ieee802154_tx: === Step 6: Entering RX Mode ===
    00> [00:00:00.501,373] <inf> ieee802154_tx: RX mode entered successfully.
    00> [00:00:01.001,495] <inf> ieee802154_tx: === Radio Ready! Starting TX Loop ===
    00> 
    00> [00:00:01.001,586] <inf> ieee802154_tx: TX Packet #1 [Dest: 0xFFFF, Src: 0x1111, PAN: 0x2435]
    00> [00:00:01.001,678] <inf> ieee802154_tx: Transmit request accepted. (ret = 0)
    00> [00:00:01.003,601] <inf> ieee802154_tx: >>> TX Success!
    00> ]
    00> 
    00> 
    00> 
    00> [00:00:28.007,690] <inf> ieee802154_tx: TX Packet #28 [Dest: 0xFFFF, Src: 0x1111, PAN: 0x2435]
    00> [00:00:28.007,812] <inf> ieee802154_tx: Transmit request accepted. (ret = 0)
    00> [00:00:28.009,735] <inf> ieee802154_tx: >>> TX Success!
    00> [00:00:29.007,965] <inf> ieee802154_tx: TX Packet #29 [Dest: 0xFFFF, Src: 0x1111, PAN: 0x2435]
    00> [00:00:29.008,056] <inf> ieee802154_tx: Transmit request accepted. (ret = 0)
    00> [00:00:29.009,979] <inf> ieee802154_tx: >>> TX Success!
    00> [00:00:30.008,178] <inf> ieee802154_tx: TX Packet #30 [Dest: 0xFFFF, Src: 0x1111, PAN: 0x2435]
    00> [00:00:30.008,300] <inf> ieee802154_tx: Transmit request accepted. (ret = 0)
    00> [00:00:30.010,223] <inf> ieee802154_tx: >>> TX Success!
    00> [00:00:31.008,453] <inf> ieee802154_tx: TX Packet #31 [Dest: 0xFFFF, Src: 0x1111, PAN: 0x2435]
    00> [00:00:31.008,544] <inf> ieee802154_tx: Transmit request accepted. (ret = 0)

Related