esp_common: add "USB CDC" option for console output

This commit is contained in:
Ivan Grokhotkov 2020-04-30 15:29:23 +02:00
parent 4f8c42ca73
commit 5ee75165f2
5 changed files with 156 additions and 123 deletions

View File

@ -0,0 +1,104 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "bootloader_console.h"
#include "soc/uart_periph.h"
#include "soc/uart_channel.h"
#include "soc/io_mux_reg.h"
#include "soc/gpio_periph.h"
#include "soc/gpio_sig_map.h"
#include "soc/rtc.h"
#include "hal/clk_gate_ll.h"
#ifdef CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h"
#include "esp32/rom/uart.h"
#include "esp32/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#include "esp32s2/rom/uart.h"
#include "esp32s2/rom/gpio.h"
#include "esp32s2/rom/usb/cdc_acm.h"
#include "esp32s2/rom/usb/usb_common.h"
#endif
#ifdef CONFIG_ESP_CONSOLE_UART_NONE
void bootloader_console_init(void)
{
ets_install_putc1(NULL);
ets_install_putc2(NULL);
}
#endif // CONFIG_ESP_CONSOLE_UART_NONE
#ifdef CONFIG_ESP_CONSOLE_UART
void bootloader_console_init(void)
{
const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM;
ets_install_uart_printf();
// Wait for UART FIFO to be empty.
uart_tx_wait_idle(0);
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
// Some constants to make the following code less upper-case
const int uart_tx_gpio = CONFIG_ESP_CONSOLE_UART_TX_GPIO;
const int uart_rx_gpio = CONFIG_ESP_CONSOLE_UART_RX_GPIO;
// Switch to the new UART (this just changes UART number used for
// ets_printf in ROM code).
uart_tx_switch(uart_num);
// 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 != UART_NUM_0_TXD_DIRECT_GPIO_NUM ||
uart_rx_gpio != UART_NUM_0_RXD_DIRECT_GPIO_NUM) {
// Change default UART pins back to GPIOs
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, PIN_FUNC_GPIO);
// Route GPIO signals to/from pins
const uint32_t tx_idx = uart_periph_signal[uart_num].tx_sig;
const uint32_t rx_idx = uart_periph_signal[uart_num].rx_sig;
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
gpio_pad_pullup(uart_rx_gpio);
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
// Enable the peripheral
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + uart_num);
}
#endif // CONFIG_ESP_CONSOLE_UART_CUSTOM
// Set configured UART console baud rate
const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
}
#endif // CONFIG_ESP_CONSOLE_UART
#ifdef CONFIG_ESP_CONSOLE_USB_CDC
/* Buffer for CDC data structures. No RX buffer allocated. */
static char s_usb_cdc_buf[CDC_ACM_WORK_BUF_MIN];
void bootloader_console_init(void)
{
#ifdef CONFIG_IDF_TARGET_ESP32S2
/* ESP32-S2 specific patch to set the correct serial number in the descriptor.
* Later chips don't need this.
*/
rom_usb_cdc_set_descriptor_patch();
#endif
Uart_Init_USB(s_usb_cdc_buf, sizeof(s_usb_cdc_buf));
uart_tx_switch(ROM_UART_USB);
ets_install_putc1(bootloader_console_write_char_usb);
}
#endif //CONFIG_ESP_CONSOLE_USB_CDC

View File

@ -23,6 +23,7 @@
#include "bootloader_common.h" #include "bootloader_common.h"
#include "bootloader_flash_config.h" #include "bootloader_flash_config.h"
#include "bootloader_mem.h" #include "bootloader_mem.h"
#include "bootloader_console.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
@ -277,59 +278,6 @@ static esp_err_t bootloader_init_spi_flash(void)
return ESP_OK; return ESP_OK;
} }
static void bootloader_init_uart_console(void)
{
#if CONFIG_ESP_CONSOLE_UART_NONE
ets_install_putc1(NULL);
ets_install_putc2(NULL);
#else // CONFIG_ESP_CONSOLE_UART_NONE
const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM;
uartAttach();
ets_install_uart_printf();
// Wait for UART FIFO to be empty.
uart_tx_wait_idle(0);
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
// Some constants to make the following code less upper-case
const int uart_tx_gpio = CONFIG_ESP_CONSOLE_UART_TX_GPIO;
const int uart_rx_gpio = CONFIG_ESP_CONSOLE_UART_RX_GPIO;
// Switch to the new UART (this just changes UART number used for
// ets_printf in ROM code).
uart_tx_switch(uart_num);
// 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 uart_reset[3] = {DPORT_UART_RST, DPORT_UART1_RST, DPORT_UART2_RST};
const uint32_t tx_idx = tx_idx_list[uart_num];
const uint32_t rx_idx = rx_idx_list[uart_num];
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
gpio_pad_pullup(uart_rx_gpio);
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
}
#endif // CONFIG_ESP_CONSOLE_UART_CUSTOM
// Set configured UART console baud rate
const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
#endif // CONFIG_ESP_CONSOLE_UART_NONE
}
static void wdt_reset_cpu0_info_enable(void) static void wdt_reset_cpu0_info_enable(void)
{ {
//We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1. //We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
@ -452,7 +400,7 @@ esp_err_t bootloader_init(void)
// config clock // config clock
bootloader_clock_configure(); bootloader_clock_configure();
// initialize uart console, from now on, we can use esp_log // initialize uart console, from now on, we can use esp_log
bootloader_init_uart_console(); bootloader_console_init();
/* print 2nd bootloader banner */ /* print 2nd bootloader banner */
bootloader_print_banner(); bootloader_print_banner();
// update flash ID // update flash ID

View File

@ -26,12 +26,13 @@
#include "bootloader_clock.h" #include "bootloader_clock.h"
#include "bootloader_flash_config.h" #include "bootloader_flash_config.h"
#include "bootloader_mem.h" #include "bootloader_mem.h"
#include "bootloader_console.h"
#include "esp32s2/rom/cache.h" #include "esp32s2/rom/cache.h"
#include "esp32s2/rom/ets_sys.h" #include "esp32s2/rom/ets_sys.h"
#include "esp32s2/rom/spi_flash.h" #include "esp32s2/rom/spi_flash.h"
#include "esp32s2/rom/rtc.h" #include "esp32s2/rom/rtc.h"
#include "esp32s2/rom/uart.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_image_format.h" #include "esp_image_format.h"
@ -216,59 +217,6 @@ static esp_err_t bootloader_init_spi_flash(void)
return ESP_OK; return ESP_OK;
} }
static void bootloader_init_uart_console(void)
{
#if CONFIG_ESP_CONSOLE_UART_NONE
ets_install_putc1(NULL);
ets_install_putc2(NULL);
#else // CONFIG_ESP_CONSOLE_UART_NONE
const int uart_num = CONFIG_ESP_CONSOLE_UART_NUM;
uartAttach(NULL);
ets_install_uart_printf();
// Wait for UART FIFO to be empty.
uart_tx_wait_idle(0);
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
// Some constants to make the following code less upper-case
const int uart_tx_gpio = CONFIG_ESP_CONSOLE_UART_TX_GPIO;
const int uart_rx_gpio = CONFIG_ESP_CONSOLE_UART_RX_GPIO;
// Switch to the new UART (this just changes UART number used for
// ets_printf in ROM code).
uart_tx_switch(uart_num);
// 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 != 43 || uart_rx_gpio != 44) {
// Change pin mode UART to GPIO
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO44);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO43);
// Route GPIO signals to/from pins
// (arrays should be optimized away by the compiler)
const uint32_t tx_idx_list[2] = {U0TXD_OUT_IDX, U1TXD_OUT_IDX};
const uint32_t rx_idx_list[2] = {U0RXD_IN_IDX, U1RXD_IN_IDX};
const uint32_t uart_reset[2] = {DPORT_UART_RST, DPORT_UART1_RST};
const uint32_t tx_idx = tx_idx_list[uart_num];
const uint32_t rx_idx = rx_idx_list[uart_num];
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
gpio_pad_pullup(uart_rx_gpio);
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
}
#endif // CONFIG_ESP_CONSOLE_UART_CUSTOM
// Set configured UART console baud rate
const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
#endif // CONFIG_ESP_CONSOLE_UART_NONE
}
static void wdt_reset_cpu0_info_enable(void) static void wdt_reset_cpu0_info_enable(void)
{ {
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG); DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
@ -366,8 +314,8 @@ esp_err_t bootloader_init(void)
bootloader_reset_mmu(); bootloader_reset_mmu();
// config clock // config clock
bootloader_clock_configure(); bootloader_clock_configure();
// initialize uart console, from now on, we can use esp_log // initialize console, from now on, we can use esp_log
bootloader_init_uart_console(); bootloader_console_init();
/* print 2nd bootloader banner */ /* print 2nd bootloader banner */
bootloader_print_banner(); bootloader_print_banner();
// update flash ID // update flash ID

View File

@ -62,33 +62,45 @@ menu "Common ESP-related"
with shared stack. with shared stack.
choice ESP_CONSOLE_UART choice ESP_CONSOLE_UART
prompt "UART for console output" prompt "Channel for console output"
default ESP_CONSOLE_UART_DEFAULT default ESP_CONSOLE_UART_DEFAULT
help help
Select whether to use UART for console output (through stdout and stderr). Select where to send console output (through stdout and stderr).
- Default is to use UART0 on pre-defined GPIOs. - Default is to use UART0 on pre-defined GPIOs.
- If "Custom" is selected, UART0 or UART1 can be chosen, - If "Custom" is selected, UART0 or UART1 can be chosen,
and any pins can be selected. and any pins can be selected.
- If "None" is selected, there will be no console output on any UART, except - 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 for initial output from ROM bootloader. This ROM output can be suppressed by
bootstrapping GPIO13 pin to low logic level. GPIO strapping or EFUSE, refer to chip datasheet for details.
- On chips with USB peripheral, "USB CDC" option redirects output to the
CDC port. This option uses the CDC driver in the chip ROM.
This option is incompatible with TinyUSB stack.
config ESP_CONSOLE_UART_DEFAULT config ESP_CONSOLE_UART_DEFAULT
bool "Default: UART0" bool "Default: UART0"
config ESP_CONSOLE_USB_CDC
bool "USB CDC"
# The naming is confusing: USB_ENABLED means that TinyUSB driver is enabled, not USB in general.
# && !USB_ENABLED is because the ROM CDC driver is currently incompatible with TinyUSB.
depends on IDF_TARGET_ESP32S2 && !USB_ENABLED
config ESP_CONSOLE_UART_CUSTOM config ESP_CONSOLE_UART_CUSTOM
bool "Custom" bool "Custom UART"
config ESP_CONSOLE_UART_NONE config ESP_CONSOLE_NONE
bool "None" bool "None"
endchoice endchoice
# Internal option, indicates that console UART is used (and not USB, for example)
config ESP_CONSOLE_UART
bool
default y if ESP_CONSOLE_UART_DEFAULT || ESP_CONSOLE_UART_CUSTOM
choice ESP_CONSOLE_UART_NUM choice ESP_CONSOLE_UART_NUM
prompt "UART peripheral to use for console output (0-1)" prompt "UART peripheral to use for console output (0-1)"
depends on ESP_CONSOLE_UART_CUSTOM depends on ESP_CONSOLE_UART_CUSTOM
default ESP_CONSOLE_UART_CUSTOM_NUM_0 default ESP_CONSOLE_UART_CUSTOM_NUM_0
help help
Due of a ROM bug, UART2 is not supported for console output Select which UART peripheral to use for console output.
via ets_printf. On ESP32, UART2 is not supported for console output via ets_printf.
config ESP_CONSOLE_UART_CUSTOM_NUM_0 config ESP_CONSOLE_UART_CUSTOM_NUM_0
bool "UART0" bool "UART0"
@ -98,28 +110,48 @@ menu "Common ESP-related"
config ESP_CONSOLE_UART_NUM config ESP_CONSOLE_UART_NUM
int int
default 0 if ESP_CONSOLE_UART_DEFAULT || ESP_CONSOLE_UART_NONE default 0 if ESP_CONSOLE_UART_DEFAULT
default 0 if ESP_CONSOLE_UART_CUSTOM_NUM_0 default 0 if ESP_CONSOLE_UART_CUSTOM_NUM_0
default 1 if ESP_CONSOLE_UART_CUSTOM_NUM_1 default 1 if ESP_CONSOLE_UART_CUSTOM_NUM_1
default -1 if !ESP_CONSOLE_UART
config ESP_CONSOLE_UART_TX_GPIO config ESP_CONSOLE_UART_TX_GPIO
int "UART TX on GPIO#" int "UART TX on GPIO#"
depends on ESP_CONSOLE_UART_CUSTOM
range 0 46 range 0 46
default 1 if IDF_TARGET_ESP32 default 1 if IDF_TARGET_ESP32
default 43 if IDF_TARGET_ESP32S2 default 43 if IDF_TARGET_ESP32S2
config ESP_CONSOLE_UART_RX_GPIO config ESP_CONSOLE_UART_RX_GPIO
int "UART RX on GPIO#" int "UART RX on GPIO#"
depends on ESP_CONSOLE_UART_CUSTOM
range 0 46 range 0 46
default 3 if IDF_TARGET_ESP32 default 3 if IDF_TARGET_ESP32
default 44 if IDF_TARGET_ESP32S2 default 44 if IDF_TARGET_ESP32S2
config ESP_CONSOLE_UART_BAUDRATE config ESP_CONSOLE_UART_BAUDRATE
int "UART console baud rate" int
depends on !ESP_CONSOLE_UART_NONE prompt "UART console baud rate" if ESP_CONSOLE_UART_CUSTOM
depends on ESP_CONSOLE_UART
default 115200 default 115200
range 1200 4000000 range 1200 4000000
config ESP_CONSOLE_USB_CDC_RX_BUF_SIZE
int "Size of USB CDC RX buffer"
depends on ESP_CONSOLE_USB_CDC
default 64
range 4 16384
help
Set the size of USB CDC RX buffer. Increase the buffer size if your application
is often receiving data over USB CDC.
config ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF
bool "Enable ets_printf / ESP_EARLY_LOG via USB CDC"
depends on ESP_CONSOLE_USB_CDC
default n
help
If enabled, ets_printf and ESP_EARLY_LOG output will also be sent over USB CDC.
Disabling this option saves about 1kB or RAM.
config ESP_INT_WDT config ESP_INT_WDT
bool "Interrupt watchdog" bool "Interrupt watchdog"

View File

@ -8,7 +8,8 @@ CONFIG_IPC_TASK_STACK_SIZE CONFIG_ESP_IPC_TASK_STAC
CONFIG_CONSOLE_UART CONFIG_ESP_CONSOLE_UART CONFIG_CONSOLE_UART CONFIG_ESP_CONSOLE_UART
CONFIG_CONSOLE_UART_DEFAULT CONFIG_ESP_CONSOLE_UART_DEFAULT CONFIG_CONSOLE_UART_DEFAULT CONFIG_ESP_CONSOLE_UART_DEFAULT
CONFIG_CONSOLE_UART_CUSTOM CONFIG_ESP_CONSOLE_UART_CUSTOM CONFIG_CONSOLE_UART_CUSTOM CONFIG_ESP_CONSOLE_UART_CUSTOM
CONFIG_CONSOLE_UART_NONE CONFIG_ESP_CONSOLE_UART_NONE CONFIG_CONSOLE_UART_NONE CONFIG_ESP_CONSOLE_NONE
CONFIG_ESP_CONSOLE_UART_NONE CONFIG_ESP_CONSOLE_NONE
CONFIG_CONSOLE_UART_NUM CONFIG_ESP_CONSOLE_UART_NUM CONFIG_CONSOLE_UART_NUM CONFIG_ESP_CONSOLE_UART_NUM
CONFIG_CONSOLE_UART_CUSTOM_NUM_0 CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0 CONFIG_CONSOLE_UART_CUSTOM_NUM_0 CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0
CONFIG_CONSOLE_UART_CUSTOM_NUM_1 CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 CONFIG_CONSOLE_UART_CUSTOM_NUM_1 CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1