mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/select_default_uart' into 'master'
UART console selection This change adds a set of menuconfig options to set custom UART#, baud rate, and pins, for console output. Ref. TW8146 Also includes the following changes: - `uart_tx_wait_idle`: fix issue with last character not transmitted. ROM function `uart_tx_wait_idle` may have a bug which causes the function to return before the final character is fully transmitted. This replaces `uart_tx_wait_idle` declaration with a static inline definition which fixes the issue. Also replaces the use of `uart_tx_flush` with `uart_tx_wait_idle` in `esp_restart`, to remove garbage in console output on restart. - `rtc_printf` is temporary replaced with a no-op, pending a new release of librtc.a. Current release assumes that UART0 is used for output, and switches UART0 baud rate while doing frequency changes and printing some log output. This doesn’t work if a different UART is used for output. - disable boot watchdog only after starting the main task. Boot watchdogs were disabled very early in startup code. It was possible to introduce an infinite loop anywhere in the many functions called from startup code, and this would not be detected by interrupt watchdog and task watchdog. This change postpones disabling of boot watchdogs to the point when the scheduler is running. Also replaces register expressed using integer address with a name. This change is not directly related to the previous ones, but was found while debugging UART selection features. See merge request !288
This commit is contained in:
commit
505282bab1
@ -23,6 +23,8 @@
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "rom/uart.h"
|
||||
#include "rom/gpio.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/cpu.h"
|
||||
@ -31,6 +33,8 @@
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_image_format.h"
|
||||
@ -62,7 +66,7 @@ void set_cache_and_start_app(uint32_t drom_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr);
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
static void uart_console_configure(void);
|
||||
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
{
|
||||
@ -224,6 +228,7 @@ static bool ota_select_valid(const esp_ota_select_entry_t *s)
|
||||
|
||||
void bootloader_main()
|
||||
{
|
||||
uart_console_configure();
|
||||
ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION);
|
||||
|
||||
esp_image_header_t fhdr;
|
||||
@ -616,3 +621,63 @@ void print_flash_info(const esp_image_header_t* phdr)
|
||||
ESP_LOGI(TAG, "SPI Flash Size : %s", str );
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t get_apb_freq(void)
|
||||
{
|
||||
// Get the value of APB clock from RTC memory.
|
||||
// The value is initialized in ROM code, and updated by librtc.a
|
||||
// when APB clock is changed.
|
||||
// This value is stored in RTC_CNTL_STORE5_REG as follows:
|
||||
// RTC_CNTL_STORE5_REG = (freq >> 12) | ((freq >> 12) << 16)
|
||||
uint32_t apb_freq_reg = REG_READ(RTC_CNTL_STORE5_REG);
|
||||
uint32_t apb_freq_l = apb_freq_reg & 0xffff;
|
||||
uint32_t apb_freq_h = apb_freq_reg >> 16;
|
||||
if (apb_freq_l == apb_freq_h && apb_freq_l != 0) {
|
||||
return apb_freq_l << 12;
|
||||
} else {
|
||||
// fallback value
|
||||
return APB_CLK_FREQ_ROM;
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_console_configure(void)
|
||||
{
|
||||
#if CONFIG_CONSOLE_UART_NONE
|
||||
ets_install_putc1(NULL);
|
||||
ets_install_putc2(NULL);
|
||||
#else // CONFIG_CONSOLE_UART_NONE
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
|
||||
#if CONFIG_CONSOLE_UART_CUSTOM
|
||||
// Some constants to make the following code less upper-case
|
||||
const int uart_num = CONFIG_CONSOLE_UART_NUM;
|
||||
const int uart_baud = CONFIG_CONSOLE_UART_BAUDRATE;
|
||||
const int uart_tx_gpio = CONFIG_CONSOLE_UART_TX_GPIO;
|
||||
const int uart_rx_gpio = CONFIG_CONSOLE_UART_RX_GPIO;
|
||||
// ROM bootloader may have put a lot of text into UART0 FIFO.
|
||||
// Wait for it to be printed.
|
||||
uart_tx_wait_idle(0);
|
||||
// Switch to the new UART (this just changes UART number used for
|
||||
// ets_printf in ROM code).
|
||||
uart_tx_switch(uart_num);
|
||||
// Set new baud rate
|
||||
uart_div_modify(uart_num, (((uint64_t) get_apb_freq()) << 4) / uart_baud);
|
||||
// If console is attached to UART1 or if non-default pins are used,
|
||||
// need to reconfigure pins using GPIO matrix
|
||||
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
|
||||
// Change pin mode for GPIO1/3 from UART to GPIO
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO1);
|
||||
// Route GPIO signals to/from pins
|
||||
// (arrays should be optimized away by the compiler)
|
||||
const uint32_t tx_idx_list[3] = { U0TXD_OUT_IDX, U1TXD_OUT_IDX, U2TXD_OUT_IDX };
|
||||
const uint32_t rx_idx_list[3] = { U0RXD_IN_IDX, U1RXD_IN_IDX, U2RXD_IN_IDX };
|
||||
const uint32_t tx_idx = tx_idx_list[uart_num];
|
||||
const uint32_t rx_idx = rx_idx_list[uart_num];
|
||||
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
|
||||
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
|
||||
}
|
||||
#endif // CONFIG_CONSOLE_UART_CUSTOM
|
||||
#endif // CONFIG_CONSOLE_UART_NONE
|
||||
}
|
||||
|
@ -138,6 +138,64 @@ config NEWLIB_STDOUT_ADDCR
|
||||
is usually done by an added CR character. Enabling this will make the
|
||||
standard output code automatically add a CR character before a LF.
|
||||
|
||||
choice CONSOLE_UART
|
||||
prompt "UART for console output"
|
||||
default CONSOLE_UART_DEFAULT
|
||||
help
|
||||
Select whether to use UART for console output (through stdout and stderr).
|
||||
- Default is to use UART0 on pins GPIO1(TX) and GPIO3(RX).
|
||||
- If "Custom" is selected, UART0 or UART1 can be chosen,
|
||||
and any pins can be selected.
|
||||
- If "None" is selected, there will be no console output on any UART, except
|
||||
for initial output from ROM bootloader. This output can be further suppressed by
|
||||
bootstrapping GPIO13 pin to low logic level.
|
||||
|
||||
config CONSOLE_UART_DEFAULT
|
||||
bool "Default: UART0, TX=GPIO1, RX=GPIO3"
|
||||
config CONSOLE_UART_CUSTOM
|
||||
bool "Custom"
|
||||
config CONSOLE_UART_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
|
||||
choice CONSOLE_UART_NUM
|
||||
prompt "UART peripheral to use for console output (0-1)"
|
||||
depends on CONSOLE_UART_CUSTOM
|
||||
default CONSOLE_UART_CUSTOM_NUM_0
|
||||
help
|
||||
Due of a ROM bug, UART2 is not supported for console output
|
||||
via ets_printf.
|
||||
|
||||
config CONSOLE_UART_CUSTOM_NUM_0
|
||||
bool "UART0"
|
||||
config CONSOLE_UART_CUSTOM_NUM_1
|
||||
bool "UART1"
|
||||
endchoice
|
||||
|
||||
config CONSOLE_UART_NUM
|
||||
int
|
||||
default 0 if CONSOLE_UART_DEFAULT || CONSOLE_UART_NONE
|
||||
default 0 if CONSOLE_UART_CUSTOM_NUM_0
|
||||
default 1 if CONSOLE_UART_CUSTOM_NUM_1
|
||||
|
||||
config CONSOLE_UART_TX_GPIO
|
||||
int "UART TX on GPIO#"
|
||||
depends on CONSOLE_UART_CUSTOM
|
||||
range 0 33
|
||||
default 19
|
||||
|
||||
config CONSOLE_UART_RX_GPIO
|
||||
int "UART RX on GPIO#"
|
||||
depends on CONSOLE_UART_CUSTOM
|
||||
range 0 39
|
||||
default 21
|
||||
|
||||
config CONSOLE_UART_BAUDRATE
|
||||
int "UART console baud rate"
|
||||
depends on !CONSOLE_UART_NONE
|
||||
default 115200
|
||||
range 1200 4000000
|
||||
|
||||
config ULP_COPROC_ENABLED
|
||||
bool "Enable Ultra Low Power (ULP) Coprocessor"
|
||||
default "n"
|
||||
|
@ -33,7 +33,7 @@ void esp_set_cpu_freq(void)
|
||||
|
||||
// freq will be changed to 40MHz in rtc_init_lite,
|
||||
// wait uart tx finish, otherwise some uart output will be lost
|
||||
uart_tx_wait_idle(0);
|
||||
uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM);
|
||||
|
||||
rtc_init_lite(XTAL_AUTO);
|
||||
cpu_freq_t freq = CPU_80M;
|
||||
@ -54,7 +54,7 @@ void esp_set_cpu_freq(void)
|
||||
|
||||
// freq will be changed to freq in rtc_set_cpu_freq,
|
||||
// wait uart tx finish, otherwise some uart output will be lost
|
||||
uart_tx_wait_idle(0);
|
||||
uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM);
|
||||
|
||||
rtc_set_cpu_freq(freq);
|
||||
ets_update_cpu_frequency(freq_mhz);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@ -54,6 +55,9 @@
|
||||
#include "esp_coexist.h"
|
||||
#include "trax.h"
|
||||
|
||||
#define STRINGIFY(s) STRINGIFY2(s)
|
||||
#define STRINGIFY2(s) #s
|
||||
|
||||
void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
|
||||
void start_cpu0_default(void) IRAM_ATTR;
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
@ -86,10 +90,6 @@ static const char* TAG = "cpu_start";
|
||||
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
{
|
||||
//Kill wdt
|
||||
REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN);
|
||||
REG_CLR_BIT(0x6001f048, BIT(14)); //DR_REG_BB_BASE+48
|
||||
|
||||
cpu_configure_region_protection();
|
||||
|
||||
//Move exception vectors to IRAM
|
||||
@ -97,9 +97,6 @@ void IRAM_ATTR call_start_cpu0()
|
||||
"wsr %0, vecbase\n" \
|
||||
::"r"(&_init_start));
|
||||
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
|
||||
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
|
||||
|
||||
/* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */
|
||||
@ -145,6 +142,15 @@ void IRAM_ATTR call_start_cpu1()
|
||||
|
||||
cpu_configure_region_protection();
|
||||
|
||||
#if CONFIG_CONSOLE_UART_NONE
|
||||
ets_install_putc1(NULL);
|
||||
ets_install_putc2(NULL);
|
||||
#else // CONFIG_CONSOLE_UART_NONE
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
uart_tx_switch(CONFIG_CONSOLE_UART_NUM);
|
||||
#endif
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "App cpu up.");
|
||||
app_cpu_started = 1;
|
||||
start_cpu1();
|
||||
@ -164,7 +170,7 @@ void start_cpu0_default(void)
|
||||
trax_start_trace(TRAX_DOWNCOUNT_WORDS);
|
||||
#endif
|
||||
esp_set_cpu_freq(); // set CPU frequency configured in menuconfig
|
||||
uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200);
|
||||
uart_div_modify(CONFIG_CONSOLE_UART_NUM, (APB_CLK_FREQ << 4) / CONFIG_CONSOLE_UART_BAUDRATE);
|
||||
#if CONFIG_BROWNOUT_DET
|
||||
esp_brownout_init();
|
||||
#endif
|
||||
@ -177,10 +183,16 @@ void start_cpu0_default(void)
|
||||
esp_setup_time_syscalls();
|
||||
esp_vfs_dev_uart_register();
|
||||
esp_reent_init(_GLOBAL_REENT);
|
||||
const char* default_uart_dev = "/dev/uart/0";
|
||||
#ifndef CONFIG_CONSOLE_UART_NONE
|
||||
const char* default_uart_dev = "/dev/uart/" STRINGIFY(CONFIG_CONSOLE_UART_NUM);
|
||||
_GLOBAL_REENT->_stdin = fopen(default_uart_dev, "r");
|
||||
_GLOBAL_REENT->_stdout = fopen(default_uart_dev, "w");
|
||||
_GLOBAL_REENT->_stderr = fopen(default_uart_dev, "w");
|
||||
#else
|
||||
_GLOBAL_REENT->_stdin = (FILE*) &__sf_fake_stdin;
|
||||
_GLOBAL_REENT->_stdout = (FILE*) &__sf_fake_stdout;
|
||||
_GLOBAL_REENT->_stderr = (FILE*) &__sf_fake_stderr;
|
||||
#endif
|
||||
do_global_ctors();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
esp_crosscore_int_init();
|
||||
@ -194,9 +206,9 @@ void start_cpu0_default(void)
|
||||
#endif
|
||||
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
if (coex_init() == ESP_OK) {
|
||||
if (coex_init() == ESP_OK) {
|
||||
coexist_set_enable(true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
xTaskCreatePinnedToCore(&main_task, "main",
|
||||
@ -232,6 +244,9 @@ static void do_global_ctors(void)
|
||||
|
||||
static void main_task(void* args)
|
||||
{
|
||||
// Now that the application is about to start, disable boot watchdogs
|
||||
REG_CLR_BIT(TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN_S);
|
||||
REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN);
|
||||
app_main();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "ets_sys.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/uart_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -260,11 +262,16 @@ void uart_tx_flush(uint8_t uart_no);
|
||||
/**
|
||||
* @brief Wait until uart tx full empty and the last char send ok.
|
||||
*
|
||||
* @param uint8_t uart_no : 0 for UART0, 1 for UART1.
|
||||
* @param uart_no : 0 for UART0, 1 for UART1, 2 for UART2
|
||||
*
|
||||
* @return None.
|
||||
* The function defined in ROM code has a bug, so we define the correct version
|
||||
* here for compatibility.
|
||||
*/
|
||||
void uart_tx_wait_idle(uint8_t uart_no);
|
||||
static inline void uart_tx_wait_idle(uint8_t uart_no) {
|
||||
while(REG_GET_FIELD(UART_STATUS_REG(uart_no), UART_ST_UTX_OUT)) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an input char from message channel.
|
||||
|
@ -62,11 +62,8 @@ int phy_printf(const char* format, ...)
|
||||
|
||||
int rtc_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("rtc", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
// librtc.a printf temporary disabled due to UART baud rate switching bug.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wpa_printf(const char* format, ...)
|
||||
|
@ -105,10 +105,10 @@ void IRAM_ATTR esp_restart(void)
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Read_Disable(1);
|
||||
|
||||
// Flush any data left in UART FIFO
|
||||
uart_tx_flush(0);
|
||||
uart_tx_flush(1);
|
||||
uart_tx_flush(2);
|
||||
// Flush any data left in UART FIFOs
|
||||
uart_tx_wait_idle(0);
|
||||
uart_tx_wait_idle(1);
|
||||
uart_tx_wait_idle(2);
|
||||
|
||||
// Reset wifi/bluetooth (bb/mac)
|
||||
SET_PERI_REG_MASK(DPORT_WIFI_RST_EN_REG, 0x1f);
|
||||
|
Loading…
x
Reference in New Issue
Block a user