This change adds a set of menuconfig options to set custom UART#, baud rate, and pins, for console output.
Setting happens in bootloader startup code for PRO CPU, and in application startup code for APP CPU.
Ref. TW8146
#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"
#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"
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()
{
void bootloader_main()
{
+ uart_console_configure();
ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION);
esp_image_header_t fhdr;
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
+}
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"
// 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;
// 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);
#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
"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 */
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();
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
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();