espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.7k stars 7.29k forks source link

OpenThread. Can't assign the UART pins 17 and 18 for OT HOST device in ot_br example. (IDFGH-9825) #11156

Closed mkonnov closed 1 year ago

mkonnov commented 1 year ago

Answers checklist.

IDF version.

v5.0.1-397-g3050ea656f

Operating System used.

Linux

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-S3-WROOM-1 & ESP32-H2-WROOM-1

Power Supply used.

USB

What is the expected behavior?

Communicate via UART and correspondingly initialize the Thread RCP Just like it's going in ot_br after the following OpenThread Host board UART pins reassignments:

.rx_pin = 4 -> .rx_pin = 18
.tx_pin = 5 -> .tx_pin = 17

What is the actual behavior?

The error in communication between the OT Host board and RCP during initialization. The logs looks the same as like there's no RCP connected on the other end.

Steps to reproduce.

OT_RCP

Build examples/openthread/ot_rcp

OT_BR

  1. In examples/openthread/ot_br/main/esp_ot_config.h change the definition of ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() so that it looks the following:

    #define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG()                        \
    {                                                                \
        .radio_mode = RADIO_MODE_UART_RCP,                           \
        .radio_uart_config = {                                       \
            .port = 2,                                               \
            .uart_config =                                           \
                {                                                    \
                    .baud_rate = 115200,                             \
                    .data_bits = UART_DATA_8_BITS,                   \
                    .parity = UART_PARITY_DISABLE,                   \
                    .stop_bits = UART_STOP_BITS_1,                   \
                    .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,           \
                    .rx_flow_ctrl_thresh = 0,                        \
                    .source_clk = UART_SCLK_DEFAULT,                 \
                },                                                   \
            .rx_pin = 18,                                             \
            .tx_pin = 17,                                             \
        },                                                           \
    }
  2. . Build and flash the codes. Nothing different from the example instructions.

Debug Logs.

I (5265) esp_netif_handlers: example_netif_sta ip: 192.168.1.40, mask: 255.255.255.0, gw: 192.168.1.1
I (5265) example_connect: Got IPv4 event: Interface "example_netif_sta" address: 192.168.1.40
I (5535) example_connect: Got IPv6 event: Interface "example_netif_sta" address: fe80:0000:0000:0000:7edf:a1ff:fef3:b790, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (5535) example_common: Connected to example_netif_sta
I (5545) example_common: - IPv4 address: 192.168.1.40,
I (5545) wifi:<ba-add>idx:0 (ifx:0, e0:1c:fc:5c:69:29), tid:0, ssn:0, winSize:64
I (5555) example_common: - IPv6 address: fe80:0000:0000:0000:7edf:a1ff:fef3:b790, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (5565) example_common: - IPv6 address: fd01:0000:0000:0000:7e*�I (7535) example_connect: Got IPv6 event: Interface "example_netif_sta" address: fd01:0000:0000:0000:7edf:a1ff:fef3:b790, type: ESP_IP6_ADDR_IS_UNIQUE_LOCAL
W(7595) OPENTHREAD:[W] Platform------: Wait for response timeout
W(7595) OPENTHREAD:[W] Platform------: RCP failure detected
W(7595) OPENTHREAD:[W] Platform------: Trying to recover (1/1)
W(9615) OPENTHREAD:[W] Platform------: Wait for response timeout
W(9615) OPENTHREAD:[W] Platform------: RCP failure detected
E(9615) OPENTHREAD:[C] Platform------: Too many rcp failures, exiting
E(9625) OPENTHREAD:[C] Platform------: RecoverFromRcpFailure() at radio_spinel_impl.hpp:2267: Failure

abort() was called at PC 0x42007db6 on core 1
0x42007db6: syscall_not_implemented_aborts at /home/f77e/projects/esp-idf-v5.0/components/newlib/syscalls.c:27

Backtrace: 0x40376036:0x3fcc1670 0x4037e1f1:0x3fcc1690 0x40384b12:0x3fcc16b0 0x42007db6:0x3fcc1720 0x420dd8da:0x3fcc1740 0x420bf1d8:0x3fcc1760 0x420bf0d1:0x3fcc1780 0x420bf2c8:0x3fcc17e0 0x420c0738:0x3fcc1800 0x420c08e1:0x3fcc1840 0x420be7a0:0x3fcc1870 0x420bd515:0x3fcc18a0 0x4200af4c:0x3fcc18d0 0x40381725:0x3fcc1960
0x40376036: panic_abort at /home/f77e/projects/esp-idf-v5.0/components/esp_system/panic.c:423

0x4037e1f1: esp_system_abort at /home/f77e/projects/esp-idf-v5.0/components/esp_system/esp_system.c:153

0x40384b12: abort at /home/f77e/projects/esp-idf-v5.0/components/newlib/abort.c:38

0x42007db6: syscall_not_implemented_aborts at /home/f77e/projects/esp-idf-v5.0/components/newlib/syscalls.c:27

0x420dd8da: exit at /builds/idf/crosstool-NG/.build/xtensa-esp32s3-elf/src/newlib/newlib/libc/stdlib/exit.c:64

0x420bf1d8: ot::Spinel::RadioSpinel<esp::openthread::UartSpinelInterface, esp_openthread_mainloop_context_t>::RecoverFromRcpFailure() at ??:?

0x420bf0d1: ot::Spinel::RadioSpinel<esp::openthread::UartSpinelInterface, esp_openthread_mainloop_context_t>::Set(unsigned long, char const*, ...) at ??:?

0x420bf2c8: ot::Spinel::RadioSpinel<esp::openthread::UartSpinelInterface, esp_openthread_mainloop_context_t>::RecoverFromRcpFailure() at ??:?

0x420c0738: ot::Spinel::RadioSpinel<esp::openthread::UartSpinelInterface, esp_openthread_mainloop_context_t>::Init(bool, bool, bool) at ??:?

0x420c08e1: esp_openthread_radio_init at ??:?

0x420be7a0: esp_openthread_platform_init at ??:?

0x420bd515: esp_openthread_init at ??:?

0x4200af4c: ot_task_worker at /home/f77e/projects/ot_br/build/../main/esp_ot_br.c:174

0x40381725: vPortTaskWrapper at /home/f77e/esp-idf-v5.0/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:154

More Information.

Tried to produce more logs by changing Component config -> OpenThread -> OpenThread -> OpenThread log verbosity to Debug logs and slightly changing main not to call LoggingSetLevel(...) but logs were the same.

During my experiments I managed to successfully communicate with RCP with the following pin assignments:

            .rx_pin = 18,                                             \
            .tx_pin = 5,                                             \

what makes me think that the problem is in pin18.

In order to narrow down the problem I tried the uart example with all of aforementioned definitions and all works:

From the above, the only conclude I can make is that OpenThread library not correctly initializes pin18. Maybe this is the one of "problematic" pins, but I haven't checked the others.

fenilGhoghari commented 1 year ago

As you are using ESP32S3 and they have 3 UART so if you are not able to assign 17-18 you have another option as 33 and 34 before implement this pin make sure check once in datasheet. also we can use any number of pin as uart pin.

as your code change the UART port 2 -> 0


static const uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT};
    ESP_ERROR_CHECK(uart_param_config(UART_PORT_NUM, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(UART_NUM_0, GPIO_NUM_17, GPIO_NUM_18, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
    uart_driver_install(UART_PORT_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0);
mkonnov commented 1 year ago

@CC-MASTER05 Thanks for quick reply. Worth to mention so we stay on the same page - my requirement is to use pads 17 and 18.

  1. Please clarify - are GPIO_NUM_33 and GPIO_NUM_34 muxed with these pads ? I looked across the S3 datasheet and found nothing relevant.
  2. I tried UART0 as well and it doen't work either.
  3. The main problem is that we're only passing the uart_config_t into esp_openthread_init() so UART is initialized in openthread lib intrenally and out of our control. Your code shows the explicit UART configuration. Is it possible to use the explicit UART init with OpenThread ?

Thanks.

xieqinan commented 1 year ago

@mkonnov Thanks for your issue. The problem seems to be related to the existence of GPIO frequency characteristics issue. You can use gpio_set_drive_capability() to improve the drive capability of GPIO17 and GPIO18. Beside, if you need to use the ESP32S3's GPIO17 and GPIO18 as UART1 and no any change in ESP32S3, you can try changing the configuration of the ESP32H2. Enable the CONFIG_OPENTHREAD_UART_PIN_MANUAL option to modify ESP32H2's UART0, and then reconnect it with the ESP32S3. A better solution will be submitted soon.

mkonnov commented 1 year ago

@xieqinan thanks for your suggestion. gpio_set_drive_capability() works !

mkonnov commented 1 year ago

To make it work for my case, I changed the rx_pin and tx_pin in accordance with my requirements and called gpio_set_drive_capability() in ot_task_worker() task.

This way, my code looks as following: esp_ot_config.h:

#pragma once

#include "esp_openthread_types.h"

#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG()                        \
    {                                                                \
        .radio_mode = RADIO_MODE_UART_RCP,                           \
        .radio_uart_config = {                                       \
            .port = 1,                                               \
            .uart_config =                                           \
                {                                                    \
                    .baud_rate = 115200,                             \
                    .data_bits = UART_DATA_8_BITS,                   \
                    .parity = UART_PARITY_DISABLE,                   \
                    .stop_bits = UART_STOP_BITS_1,                   \
                    .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,           \
                    .rx_flow_ctrl_thresh = 0,                        \
                    .source_clk = UART_SCLK_DEFAULT,                 \
                },                                                   \
            .rx_pin = 18,                                             \
            .tx_pin = 17,                                             \
        },                                                           \
    }

#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG()                    \
    {                                                           \
        .host_connection_mode = HOST_CONNECTION_MODE_CLI_UART,  \
        .host_uart_config = {                                   \
            .port = 0,                                          \
            .uart_config =                                      \
                {                                               \
                    .baud_rate = 115200,                        \
                    .data_bits = UART_DATA_8_BITS,              \
                    .parity = UART_PARITY_DISABLE,              \
                    .stop_bits = UART_STOP_BITS_1,              \
                    .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,      \
                    .rx_flow_ctrl_thresh = 0,                   \
                    .source_clk = UART_SCLK_DEFAULT,            \
                },                                              \
            .rx_pin = UART_PIN_NO_CHANGE,                       \
            .tx_pin = UART_PIN_NO_CHANGE,                       \
        },                                                      \
    }

#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG()    \
    {                                           \
        .storage_partition_name = "ot_storage", \
        .netif_queue_size = 10,                 \
        .task_queue_size = 10,                  \
    }

esp_ot_br.c:

...
static void ot_task_worker(void *aContext)
{
    esp_openthread_platform_config_t config = {
        .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(),
        .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
        .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
    };

    esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD();
    esp_netif_t       *openthread_netif = esp_netif_new(&cfg);
    assert(openthread_netif != NULL);
    // Initialize the OpenThread stack

    ESP_ERROR_CHECK(gpio_set_drive_capability(GPIO_NUM_17, GPIO_DRIVE_CAP_3));
    ESP_ERROR_CHECK(esp_openthread_init(&config));

    // Initialize border routing features
    esp_openthread_lock_acquire(portMAX_DELAY);
    ESP_ERROR_CHECK(esp_netif_attach(openthread_netif, esp_openthread_netif_glue_init(&config)));

    //(void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL);
    esp_openthread_cli_init();
#if CONFIG_OPENTHREAD_BR_AUTO_START
    ESP_ERROR_CHECK(esp_openthread_border_router_init());
    create_config_network(esp_openthread_get_instance());
    launch_openthread_network(esp_openthread_get_instance());
#endif // CONFIG_OPENTHREAD_BR_AUTO_START
    esp_cli_custom_command_init();
    esp_openthread_lock_release();

    // Run the main loop
    esp_openthread_cli_create_task();
    esp_openthread_launch_mainloop();

    // Clean up
    esp_netif_destroy(openthread_netif);
    esp_openthread_netif_glue_deinit();
    esp_vfs_eventfd_unregister();
    vTaskDelete(NULL);
}
...