diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index d0be01aabb..da6fc41ab4 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -70,4 +70,19 @@ menu "Hardware Settings" pull-up, you do not need to select this option, otherwise, you should enable this option. endmenu + + menu "RTC Clock Config" + # This is used for configure the RTC clock. + config RTC_CLOCK_BBPLL_POWER_ON_WITH_USB + bool "Keep BBPLL clock always work" + depends on ESP_CONSOLE_USB_SERIAL_JTAG || ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG + default y + help + When the chip goes sleep or software reset, the clock source would change to XTAL + and switch off the BBPLL clock for saving power. However, this might make the + USB_SERIAL_JTAG down which depends on BBPLL as its unique clock source. + Therefore, this is used for keeping bbpll clock always on when USB_SERIAL_JTAG PORT is using. + If you want to use USB_SERIAL_JTAG under sw_reset case or sleep-wakeup case, you shoule select + this option. But be aware that this might increase the power consumption. + endmenu endmenu diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk.c b/components/esp_hw_support/port/esp32c3/rtc_clk.c index 8816a0e935..d568b45400 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c3/rtc_clk.c @@ -23,6 +23,7 @@ #include "soc_log.h" #include "rtc_clk_common.h" #include "esp_rom_sys.h" +#include "hal/usb_serial_jtag_ll.h" static const char *TAG = "rtc_clk"; @@ -34,6 +35,7 @@ static const char *TAG = "rtc_clk"; static int s_cur_pll_freq; static void rtc_clk_cpu_freq_to_8m(void); +static bool rtc_clk_set_bbpll_always_on(void); void rtc_clk_32k_enable_internal(x32k_config_t cfg) { @@ -334,7 +336,8 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL); if (config->source == RTC_CPU_FREQ_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); - if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) { + if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) { + // We don't turn off the bbpll if some consumers only depends on bbpll rtc_clk_bbpll_disable(); } } else if (config->source == RTC_CPU_FREQ_SRC_PLL) { @@ -345,7 +348,8 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); } else if (config->source == RTC_CPU_FREQ_SRC_8M) { rtc_clk_cpu_freq_to_8m(); - if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) { + if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) { + // We don't turn off the bbpll if some consumers only depends on bbpll rtc_clk_bbpll_disable(); } } @@ -420,7 +424,10 @@ void rtc_clk_cpu_freq_set_xtal(void) int freq_mhz = (int) rtc_clk_xtal_freq_get(); rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); - rtc_clk_bbpll_disable(); + // We don't turn off the bbpll if some consumers only depends on bbpll + if (!rtc_clk_set_bbpll_always_on()) { + rtc_clk_bbpll_disable(); + } } /** @@ -501,6 +508,21 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +static bool rtc_clk_set_bbpll_always_on(void) +{ + /* We just keep the rtc bbpll clock on just under the case that + user selects the `RTC_CLOCK_BBPLL_POWER_ON_WITH_USB` as well as + the USB_SERIAL_JTAG is connected with PC. + */ + bool is_bbpll_on = false; +#if CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB + if (usb_serial_jtag_ll_txfifo_writable() == 1) { + is_bbpll_on = true; + } +#endif + return is_bbpll_on; +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32s3/rtc_clk.c b/components/esp_hw_support/port/esp32s3/rtc_clk.c index d1e5956eb1..2d3f1d3139 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s3/rtc_clk.c @@ -24,6 +24,7 @@ #include "regi2c_ctrl.h" #include "soc_log.h" #include "rtc_clk_common.h" +#include "hal/usb_serial_jtag_ll.h" #include "sdkconfig.h" static const char *TAG = "rtc_clk"; @@ -38,6 +39,7 @@ static uint32_t s_cur_pll_freq; static uint32_t s_apb_freq; static void rtc_clk_cpu_freq_to_8m(void); +static bool rtc_clk_set_bbpll_always_on(void); void rtc_clk_32k_enable_internal(x32k_config_t cfg) { @@ -364,7 +366,8 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL); if (config->source == RTC_CPU_FREQ_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); - if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) { + if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) { + // We don't turn off the bbpll if some consumers only depends on bbpll rtc_clk_bbpll_disable(); } } else if (config->source == RTC_CPU_FREQ_SRC_PLL) { @@ -375,7 +378,8 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); } else if (config->source == RTC_CPU_FREQ_SRC_8M) { rtc_clk_cpu_freq_to_8m(); - if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) { + if ((soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) && !rtc_clk_set_bbpll_always_on()) { + // We don't turn off the bbpll if some consumers only depends on bbpll rtc_clk_bbpll_disable(); } } @@ -453,7 +457,11 @@ void rtc_clk_cpu_freq_set_xtal(void) int freq_mhz = (int) rtc_clk_xtal_freq_get(); rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); - rtc_clk_bbpll_disable(); + + // We don't turn off the bbpll if some consumers only depends on bbpll + if (!rtc_clk_set_bbpll_always_on()) { + rtc_clk_bbpll_disable(); + } } /** @@ -539,6 +547,21 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +static bool rtc_clk_set_bbpll_always_on(void) +{ + /* We just keep the rtc bbpll clock on just under the case that + user selects the `RTC_CLOCK_BBPLL_POWER_ON_WITH_USB` as well as + the USB_SERIAL_JTAG is connected with PC. + */ + bool is_bbpll_on = false; +#if CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB + if (usb_serial_jtag_ll_txfifo_writable() == 1) { + is_bbpll_on = true; + } +#endif + return is_bbpll_on; +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/soc/esp32c3/include/soc/rtc.h b/components/soc/esp32c3/include/soc/rtc.h index db67d3ac51..dccd7a0778 100644 --- a/components/soc/esp32c3/include/soc/rtc.h +++ b/components/soc/esp32c3/include/soc/rtc.h @@ -1,16 +1,8 @@ -// 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. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include diff --git a/docs/en/api-guides/usb-serial-jtag-console.rst b/docs/en/api-guides/usb-serial-jtag-console.rst index 0bdfeec4fd..e3b7b2b592 100644 --- a/docs/en/api-guides/usb-serial-jtag-console.rst +++ b/docs/en/api-guides/usb-serial-jtag-console.rst @@ -46,11 +46,12 @@ Limitations There are several limitations to the USB console feature. These may or may not be significant, depending on the type of application being developed, and the development workflow. -{IDF_TARGET_BOOT_PIN:default = "GPIO0", esp32c3 = "GPIO9"} +{IDF_TARGET_BOOT_PIN:default = "Not Updated!", esp32c3 = "GPIO9", esp32s3 = "GPIO0"} 1. If the application accidentally reconfigures the USB peripheral pins, or disables the USB Serial/JTAG Controller, the device will disappear from the system. After fixing the issue in the application, you will need to manually put the {IDF_TARGET_NAME} into download mode by pulling low {IDF_TARGET_BOOT_PIN} and resetting the chip. -2. If the application enters light sleep (including automatic light sleep) or deep sleep mode, USB CDC device will disappear from the system. +2. If the application enters deep sleep mode, USB CDC device will disappear from the system. 3. The behaviour between an actual USB-to-serial bridge chip and the USB Serial/JTAG Controller is slightly different if the ESP-IDF application does not listen for incoming bytes. An USB-to-serial bridge chip will just send the bytes to a (not listening) chip, while the USB Serial/JTAG Controller will block until the application reads the bytes. This can lead to a non-responsive looking terminal program. +4. If the application enters light-sleep (including automatic light-sleep) or software reset, etc. The USB CDC device will still work on the system. But be aware that this might increase the power consumption, if you don't need USB CDC in sleep and want to keep low power consumption, please disable the menuconfig ``CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB``. Moreover, the power consumption will only increase when your USB CDC port is really in use (like data transaction), therefore, if your USB CDC just connects with power bank or battery, rather than something like computer, you don't need to care about the increasing power consumption mentioned above.