esp-idf: IEEE 802.15.4 doesn't receive packets after calling esp_ieee802154_receive() (IDFGH-10286)

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.2-dev-823-g903af13e84

Operating System used.

macOS

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

ESP32-C6-DevKitC-1

Power Supply used.

USB

What is the expected behavior?

I expected the call to esp_ieee802154_receive() to enable the driver to receive all packets on the network on a particular channel. This should trigger the corresponding hooks like esp_ieee802154_receive_done and esp_ieee802154_receive_failed but neither are called.

What is the actual behavior?

The expected behaviour is a continuous stream of packets passed to the esp_ieee802154_receive_done handler.

It’s important to note here that this does work if the esp_ieee802154_transmit(…) is called before calling esp_ieee802154_receive().

Steps to reproduce.

Use the following main.c

#include <string.h>
#include <nvs.h>
#include <nvs_flash.h>
#include <esp_ieee802154.h>
#include <esp_log.h>
#include <esp_phy_init.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"

#define TAG "main"
#define RADIO_TAG "ieee802154"

#define PANID 0x4242
#define CHANNEL 15

#define SHORT_NOT_CONFIGURED 0xFFFE

void esp_ieee802154_receive_done(uint8_t* frame, esp_ieee802154_frame_info_t* frame_info) {
    ESP_EARLY_LOGI(RADIO_TAG, "rx OK, received %d bytes", frame[0]);
}

void esp_ieee802154_receive_failed(uint16_t error) {
    ESP_EARLY_LOGI(RADIO_TAG, "rx failed, error %d", error);
}

void esp_ieee802154_receive_sfd_done(void) {
    ESP_EARLY_LOGI(RADIO_TAG, "rx sfd done, Radio state: %d", esp_ieee802154_get_state());
}

void app_main() {
    ESP_LOGI(TAG, "Initializing NVS from flash...");
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);

    ESP_ERROR_CHECK(esp_ieee802154_enable());
    ESP_ERROR_CHECK(esp_ieee802154_set_promiscuous(true));
    ESP_ERROR_CHECK(esp_ieee802154_set_rx_when_idle(true));

    ESP_ERROR_CHECK(esp_ieee802154_set_panid(PANID));
    ESP_ERROR_CHECK(esp_ieee802154_set_coordinator(false));

    ESP_ERROR_CHECK(esp_ieee802154_set_channel(CHANNEL));

    esp_phy_calibration_data_t cal_data;
    ESP_ERROR_CHECK(esp_phy_load_cal_data_from_nvs(&cal_data));

    // Set long address to the mac address (with 0xff padding at the end)
    // Set short address to unconfigured
    uint8_t long_address[8];
    memcpy(&long_address, cal_data.mac, 6);
    long_address[6] = 0xff;
    long_address[7] = 0xfe;
    esp_ieee802154_set_extended_address(long_address);
    esp_ieee802154_set_short_address(SHORT_NOT_CONFIGURED);

//#define MAKE_IT_WORK
#ifdef MAKE_IT_WORK
    // basically bogus data
    long_address[0] = 8;
    esp_ieee802154_transmit(long_address, false);
#endif

    uint8_t radio_long_address[8];
    esp_ieee802154_get_extended_address(radio_long_address);
    ESP_LOGI(TAG, "Receiver ready, panId=0x%04x, channel=%d, long=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, short=%04x",
             esp_ieee802154_get_panid(), esp_ieee802154_get_channel(),
             radio_long_address[0], radio_long_address[1], radio_long_address[2], radio_long_address[3],
             radio_long_address[4], radio_long_address[5], radio_long_address[6], radio_long_address[7],
             esp_ieee802154_get_short_address());


    ESP_ERROR_CHECK(esp_ieee802154_receive());

    // All done, the rest is up to handlers
    while (true) {
        vTaskDelay(10 / portTICK_PERIOD_MS);
    }
}

On an active Zigbee network the output with the MAKE_IT_WORK define enabled is:

I (293) main_task: Calling app_main()
I (293) main: Initializing NVS from flash...
I (303) phy_init: phy_version 202,b4b3263,May 17 2023,20:14:14
I (353) main: Receiver ready, panId=0x4242, channel=15, long=40:4c:ca:40:28:dc:ff:fe, short=fffe
I (1143) ieee802154: rx sfd done, Radio state: 2
I (1143) ieee802154: rx OK, received 50 bytes
I (1203) ieee802154: rx sfd done, Radio state: 2
I (1203) ieee802154: rx OK, received 53 bytes
I (1203) ieee802154: rx sfd done, Radio state: 2
I (1233) ieee802154: rx sfd done, Radio state: 2
I (1233) ieee802154: rx OK, received 50 bytes
I (1243) ieee802154: rx sfd done, Radio state: 2
I (1243) ieee802154: rx OK, received 53 bytes

On the same Zigbee network without the MAKE_IT_WORK define

I (293) main_task: Calling app_main()
I (293) main: Initializing NVS from flash...
I (303) phy_init: phy_version 202,b4b3263,May 17 2023,20:14:14
I (353) main: Receiver ready, panId=0x4242, channel=15, long=40:4c:ca:40:28:dc:ff:fe, short=fffe
I (9943) ieee802154: rx sfd done, Radio state: 2

Debug Logs.

No response

More Information.

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 16

Most upvoted comments

I’ve tried the demo projects I’ve created with the latest version of esp-idf and everything seems to be working. I verified by removing the workarounds in some other code an no issues anymore.

I (192) cpu_start: Application information:
I (195) cpu_start: Project name:     ieee802154-receiver
I (201) cpu_start: App version:      0.1.0
I (205) cpu_start: Compile time:     Jan  6 2024 21:38:50
I (211) cpu_start: ELF file SHA256:  0ab02c395...
I (217) cpu_start: ESP-IDF:          v5.3-dev-1288-g5524b692ee
I (223) cpu_start: Min chip rev:     v0.0
I (228) cpu_start: Max chip rev:     v0.99
I (233) cpu_start: Chip rev:         v0.0

Many thanks for all the support on this!

@spark404

Your code was able to communicate with the Digi Xbee S2C 802.15.4 firmware.

wonderful!

digi-xbee-s2c

digi-xbee-s2c-20

And could you please push your idf branch to your remote repository and give me a link? I want to try to reproduce with your code base. Also I can leave some commits for debugging on your repository directly.