From d5a28ecd026da8dad1b64aa8739a2874ba4cb6df Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 14 Jan 2023 13:40:39 +0100 Subject: [PATCH 1/5] cpu/esp32: reorder the syscalls_init If LOG_LEVEL >= 4, such as in `tests/log_printfnoformat`, the ESP-IDF config function called for the GPIO pins of the UART will output the configuration with `printf` before the `_GLOBAL_REENT` structure is initialized. This causes a crash during system startup. Therefore the initialization by `syscalls_init` must be called earlier in the startup procedure. --- cpu/esp32/startup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpu/esp32/startup.c b/cpu/esp32/startup.c index 341d24b402..e3d8ff2dc8 100644 --- a/cpu/esp32/startup.c +++ b/cpu/esp32/startup.c @@ -147,6 +147,9 @@ static NORETURN void IRAM system_startup_cpu0(void) puf_sram_init((uint8_t *)&_sheap, SEED_RAM_LEN); #endif + /* initialize system call tables of ESP32x rom and newlib */ + syscalls_init(); + /* initialize stdio */ esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); early_init(); @@ -228,9 +231,6 @@ static NORETURN void IRAM system_init (void) /* initialize the ISR stack for usage measurements */ thread_isr_stack_init(); - /* initialize system call tables of ESP32x rom and newlib */ - syscalls_init(); - /* install exception handlers */ init_exceptions(); From 9004867fe03df0309f5fc5bc544dee030df179cf Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 14 Jan 2023 13:41:12 +0100 Subject: [PATCH 2/5] cpu/esp32/bootloader: fix the UART pin configuration --- cpu/esp32/bootloader/sdkconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/esp32/bootloader/sdkconfig.h b/cpu/esp32/bootloader/sdkconfig.h index 93cab5f7f7..1e9206b638 100644 --- a/cpu/esp32/bootloader/sdkconfig.h +++ b/cpu/esp32/bootloader/sdkconfig.h @@ -91,7 +91,7 @@ extern "C" { * If custom TX and RX are defined, use custom UART configuration for 2nd stage * bootloader. */ -#if defined(CONFIG_CONSOLE_UART_RX) && defined(CONFIG_CONSOLE_UART_RX) +#if defined(CONFIG_CONSOLE_UART_TX) && defined(CONFIG_CONSOLE_UART_RX) #define CONFIG_ESP_CONSOLE_UART_CUSTOM 1 #define CONFIG_ESP_CONSOLE_UART_TX_GPIO CONFIG_CONSOLE_UART_TX #define CONFIG_ESP_CONSOLE_UART_RX_GPIO CONFIG_CONSOLE_UART_RX From fe21e82079dea2d10ecd9052c40831d4858a0aaa Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 14 Jan 2023 13:54:16 +0100 Subject: [PATCH 3/5] cpu/esp32: improve initialization of UART pins Since PR #19100 it is possible to define: - other pins for `UART_DEV(0)` than the default pins - different `UART_DEV(0)` pins for the bootloader and RIOT To allow correct reinitialization of the UART pins used by the bootloader as well as their usage for other purposes, the pin usage for the default UART0 pins and the UART pins used by the bootloader are reset to `_GPIO`. This is done in `uart_system_init` which has to be called earlier in the startup procedure. --- cpu/esp32/startup.c | 8 ++++---- cpu/esp_common/periph/uart.c | 20 +++++++++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/cpu/esp32/startup.c b/cpu/esp32/startup.c index e3d8ff2dc8..6311758f2a 100644 --- a/cpu/esp32/startup.c +++ b/cpu/esp32/startup.c @@ -150,6 +150,10 @@ static NORETURN void IRAM system_startup_cpu0(void) /* initialize system call tables of ESP32x rom and newlib */ syscalls_init(); + /* systemwide UART initialization */ + extern void uart_system_init (void); + uart_system_init(); + /* initialize stdio */ esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); early_init(); @@ -234,10 +238,6 @@ static NORETURN void IRAM system_init (void) /* install exception handlers */ init_exceptions(); - /* systemwide UART initialization */ - extern void uart_system_init (void); - uart_system_init(); - /* set log levels for SDK library outputs */ extern void esp_log_level_set(const char* tag, esp_log_level_t level); esp_log_level_set("wifi", LOG_DEBUG); diff --git a/cpu/esp_common/periph/uart.c b/cpu/esp_common/periph/uart.c index 021bf2a3d0..91771d3752 100644 --- a/cpu/esp_common/periph/uart.c +++ b/cpu/esp_common/periph/uart.c @@ -60,6 +60,7 @@ #else /* defined(MCU_ESP8266) */ #include "esp_rom_gpio.h" +#include "esp_rom_uart.h" #include "hal/interrupt_controller_types.h" #include "hal/interrupt_controller_ll.h" #include "soc/gpio_reg.h" @@ -68,6 +69,7 @@ #include "soc/periph_defs.h" #include "soc/rtc.h" #include "soc/soc_caps.h" +#include "soc/uart_pins.h" #include "soc/uart_reg.h" #include "soc/uart_struct.h" @@ -166,7 +168,10 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) assert(uart < UART_NUMOF); #ifndef MCU_ESP8266 - /* reset the pins when they were already used as UART pins */ + assert(uart_config[uart].txd != GPIO_UNDEF); + assert(uart_config[uart].rxd != GPIO_UNDEF); + + /* reset the pin usage when they were already used as UART pins */ if (gpio_get_pin_usage(uart_config[uart].txd) == _UART) { gpio_set_pin_usage(uart_config[uart].txd, _GPIO); } @@ -186,6 +191,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) gpio_set_pin_usage(uart_config[uart].txd, _UART); gpio_set_pin_usage(uart_config[uart].rxd, _UART); + esp_rom_uart_tx_wait_idle(uart); esp_rom_gpio_connect_out_signal(uart_config[uart].txd, _uarts[uart].signal_txd, false, false); esp_rom_gpio_connect_in_signal(uart_config[uart].rxd, @@ -247,6 +253,18 @@ void uart_system_init(void) /* reset all UART interrupt status registers */ _uarts[uart].regs->int_clr.val = ~0; } +#ifndef MCU_ESP8266 + /* reset the pin usage of the default UART0 pins to GPIO to allow + * reinitialization and usage for other purposes */ + gpio_set_pin_usage(U0TXD_GPIO_NUM, _GPIO); + gpio_set_pin_usage(U0RXD_GPIO_NUM, _GPIO); +#if defined(CONFIG_CONSOLE_UART_TX) && defined(CONFIG_CONSOLE_UART_TX) + /* reset the pin usage of the UART pins used by the bootloader to + * _GPIO to be able to use them later for other purposes */ + gpio_set_pin_usage(CONFIG_CONSOLE_UART_TX, _GPIO); + gpio_set_pin_usage(CONFIG_CONSOLE_UART_RX, _GPIO); +#endif +#endif } void uart_print_config(void) From 3085b92e8f1e8e82a9a3adbab3b0b01dff290241 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 14 Jan 2023 13:55:03 +0100 Subject: [PATCH 4/5] cpu/esp32: improve UART initialization The TX line is set and temporarily configured as a pull-up open-drain output before configuring it as a push-pull output to avoid a several msec long LOW pulse resulting in some garbage. --- cpu/esp_common/periph/uart.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cpu/esp_common/periph/uart.c b/cpu/esp_common/periph/uart.c index 91771d3752..94bec07533 100644 --- a/cpu/esp_common/periph/uart.c +++ b/cpu/esp_common/periph/uart.c @@ -179,11 +179,14 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) gpio_set_pin_usage(uart_config[uart].rxd, _GPIO); } - /* try to initialize the pins as GPIOs first */ - if ((uart_config[uart].txd != GPIO_UNDEF && - gpio_init(uart_config[uart].txd, GPIO_OUT)) || - (uart_config[uart].rxd != GPIO_UNDEF && - gpio_init(uart_config[uart].rxd, GPIO_IN_PU))) { + /* Try to initialize the pins where the TX line is set and temporarily + * configured as a pull-up open-drain output before configuring it as + * a push-pull output to avoid a several msec long LOW pulse resulting + * in some garbage */ + gpio_set(uart_config[uart].txd); + if (gpio_init(uart_config[uart].txd, GPIO_OD_PU) || + gpio_init(uart_config[uart].txd, GPIO_OUT) || + gpio_init(uart_config[uart].rxd, GPIO_IN_PU)) { return -1; } From f933fde60c211cf1a631aea62d31ba1541fde2ae Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 14 Jan 2023 14:23:39 +0100 Subject: [PATCH 5/5] cpu/esp32: don't initialize the UART pins if already initialized To avoid garbage on reconfiguring the UART console pins, e.g. in initialization of the `arduino` module, pins that are already configured as UART pins must not be initialized. --- cpu/esp_common/periph/uart.c | 49 +++++++++++++++++------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/cpu/esp_common/periph/uart.c b/cpu/esp_common/periph/uart.c index 94bec07533..d7459fe86a 100644 --- a/cpu/esp_common/periph/uart.c +++ b/cpu/esp_common/periph/uart.c @@ -171,34 +171,31 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) assert(uart_config[uart].txd != GPIO_UNDEF); assert(uart_config[uart].rxd != GPIO_UNDEF); - /* reset the pin usage when they were already used as UART pins */ - if (gpio_get_pin_usage(uart_config[uart].txd) == _UART) { - gpio_set_pin_usage(uart_config[uart].txd, _GPIO); - } - if (gpio_get_pin_usage(uart_config[uart].rxd) == _UART) { - gpio_set_pin_usage(uart_config[uart].rxd, _GPIO); - } + /* don't reinitialize the pins if they are already configured as UART pins */ + if ((gpio_get_pin_usage(uart_config[uart].txd) != _UART) || + (gpio_get_pin_usage(uart_config[uart].rxd) != _UART)) { - /* Try to initialize the pins where the TX line is set and temporarily - * configured as a pull-up open-drain output before configuring it as - * a push-pull output to avoid a several msec long LOW pulse resulting - * in some garbage */ - gpio_set(uart_config[uart].txd); - if (gpio_init(uart_config[uart].txd, GPIO_OD_PU) || - gpio_init(uart_config[uart].txd, GPIO_OUT) || - gpio_init(uart_config[uart].rxd, GPIO_IN_PU)) { - return -1; + /* try to initialize the pins where the TX line is set and temporarily + * configured as a pull-up open-drain output before configuring it as + * a push-pull output to avoid a several msec long LOW pulse resulting + * in some garbage */ + gpio_set(uart_config[uart].txd); + if (gpio_init(uart_config[uart].txd, GPIO_OD_PU) || + gpio_init(uart_config[uart].txd, GPIO_OUT) || + gpio_init(uart_config[uart].rxd, GPIO_IN_PU)) { + return -1; + } + + /* store the usage type in GPIO table */ + gpio_set_pin_usage(uart_config[uart].txd, _UART); + gpio_set_pin_usage(uart_config[uart].rxd, _UART); + + esp_rom_uart_tx_wait_idle(uart); + esp_rom_gpio_connect_out_signal(uart_config[uart].txd, + _uarts[uart].signal_txd, false, false); + esp_rom_gpio_connect_in_signal(uart_config[uart].rxd, + _uarts[uart].signal_rxd, false); } - - /* store the usage type in GPIO table */ - gpio_set_pin_usage(uart_config[uart].txd, _UART); - gpio_set_pin_usage(uart_config[uart].rxd, _UART); - - esp_rom_uart_tx_wait_idle(uart); - esp_rom_gpio_connect_out_signal(uart_config[uart].txd, - _uarts[uart].signal_txd, false, false); - esp_rom_gpio_connect_in_signal(uart_config[uart].rxd, - _uarts[uart].signal_rxd, false); #endif /* MCU_ESP8266 */ _uarts[uart].baudrate = baudrate;