From 83892aa18423278c8f0acb71fd3198da2f449860 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Thu, 28 Nov 2019 07:06:58 +0100 Subject: [PATCH 1/2] cpu/esp32/periph: workaround for UART clock problems The UART peripheral clock seems to be sporadically set to wrong value when the CPU clock is changed. In this case, the UART clock is not set to 115.200 kbps but to 96 kbps, so that the output in the console seems like garbage. This can also cause automatic tests to fail. Therefore, the CPU clock is only changed if CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ defines a different default CPU clock than the one already used at boot time. --- cpu/esp32/startup.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/cpu/esp32/startup.c b/cpu/esp32/startup.c index 4cc6849b7d..a89637be6c 100644 --- a/cpu/esp32/startup.c +++ b/cpu/esp32/startup.c @@ -197,8 +197,8 @@ static void IRAM system_clk_init (void) rtc_init_module(rtc_cfg); /* configure main crystal frequency if necessary */ - if (CONFIG_ESP32_XTAL_FREQ != RTC_XTAL_FREQ_AUTO - && CONFIG_ESP32_XTAL_FREQ != rtc_clk_xtal_freq_get()) { + if (CONFIG_ESP32_XTAL_FREQ != RTC_XTAL_FREQ_AUTO && + CONFIG_ESP32_XTAL_FREQ != rtc_clk_xtal_freq_get()) { bootloader_clock_configure(); } @@ -208,10 +208,10 @@ static void IRAM system_clk_init (void) /* set SLOW_CLK to internal low power clock of 150 kHz */ rtc_select_slow_clk(RTC_SLOW_FREQ_RTC); + ets_printf("Switching system clocks can lead to some unreadable characters\n"); + /* wait until UART is idle to avoid losing output */ uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM); - ets_printf("Switching system clocks can lead to some unreadable characters\n"); - ets_printf("This message is usually not visible at the console\n"); /* determine configured CPU clock frequency from sdk_conf.h */ rtc_cpu_freq_t freq; @@ -230,12 +230,14 @@ static void IRAM system_clk_init (void) uint32_t freq_before = rtc_clk_cpu_freq_value(rtc_clk_cpu_freq_get()) / MHZ ; - /* set configured CPU frequency */ - rtc_clk_cpu_freq_set(freq); + if (freq_before != CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) { + /* set configured CPU frequency */ + rtc_clk_cpu_freq_set(freq); - /* Recalculate the ccount to make time calculation correct. */ - uint32_t freq_after = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; - XTHAL_SET_CCOUNT( XTHAL_GET_CCOUNT() * freq_after / freq_before ); + /* Recalculate the ccount to make time calculation correct. */ + uint32_t freq_after = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; + XTHAL_SET_CCOUNT( XTHAL_GET_CCOUNT() * freq_after / freq_before ); + } } extern void IRAM_ATTR thread_yield_isr(void* arg); @@ -340,7 +342,7 @@ static NORETURN void IRAM system_init (void) esp_event_handler_init(); /* starting RIOT */ - ets_printf("Starting RIOT kernel on PRO cpu\n"); + printf("Starting RIOT kernel on PRO cpu\n"); kernel_init(); UNREACHABLE(); } From e3bb708e4d52c0445da7d293af429a39ae27fc68 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Thu, 28 Nov 2019 08:57:12 +0100 Subject: [PATCH 2/2] cpu/esp32/periph: flush UART TX FIFO before a baudrate change --- cpu/esp32/periph/uart.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpu/esp32/periph/uart.c b/cpu/esp32/periph/uart.c index 77905de63f..5e3d7c200b 100644 --- a/cpu/esp32/periph/uart.c +++ b/cpu/esp32/periph/uart.c @@ -281,6 +281,8 @@ static void _uart_config (uart_t uart) /* setup the baudrate */ if (uart == UART_DEV(0) || uart == UART_DEV(1)) { + /* wait until TX FIFO is empty */ + while (_uarts[uart].regs->status.txfifo_cnt) { } /* for UART0 and UART1, we can us the ROM function */ uart_div_modify(uart, (UART_CLK_FREQ << 4) / _uarts[uart].baudrate); }