feat(system): support choosing xtal as rtc-fast clock src on P4 and C5

With xtal as rtc-fast clock source the LP-Core can run at twice the default
clock frequency. 40 MHz as opposed to 20 MHz.
This commit is contained in:
Marius Vikhammer 2024-07-31 09:39:22 +08:00
parent 4b77ecdb45
commit 00eb97725b
13 changed files with 115 additions and 4 deletions

View File

@ -35,3 +35,24 @@ config RTC_CLK_CAL_CYCLES
- 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more.
In case more value will help improve the definition of the launch of the crystal.
If the crystal could not start, it will be switched to internal RC.
choice RTC_FAST_CLK_SRC
depends on SOC_CLK_LP_FAST_SUPPORT_XTAL
prompt "RTC fast clock source"
default RTC_FAST_CLK_SRC_RC_FAST
help
Choose which clock is used as RTC fast clock source.
Choosing the faster 48 MHz external crystal clock (XTAL) can allow modules which depend on RTC_FAST
to work at a higher clock frequency. With this the ULP LP-Core will run with a
CPU frequency of 48 Mhz instead of the default 20 Mhz.
The drawback is that the XTAL is usually powered down during sleep, as
it draw a lot of power. Choosing this option will cause the XTAL to stay
powered on, increasing sleep power consumption.
config RTC_FAST_CLK_SRC_RC_FAST
bool "20 Mhz RC Fast Clock"
config RTC_FAST_CLK_SRC_XTAL
bool "48 Mhz crystal (increased power consumption during sleep)"
endchoice

View File

@ -34,3 +34,24 @@ config RTC_CLK_CAL_CYCLES
- 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more.
In case more value will help improve the definition of the launch of the crystal.
If the crystal could not start, it will be switched to internal RC.
choice RTC_FAST_CLK_SRC
depends on SOC_CLK_LP_FAST_SUPPORT_XTAL
prompt "RTC fast clock source"
default RTC_FAST_CLK_SRC_RC_FAST
help
Choose which clock is used as RTC fast clock source.
Choosing the faster 40 MHz XTAL can allow modules which depend on RTC_FAST
to work at a higher clock frequency. With this the ULP LP-Core will run with a
CPU frequency of 40 Mhz instead of the default 20 Mhz.
The drawback is that the XTAL is usually powered down during sleep, as
it draw a lot of power. Choosing this option will cause the XTAL to stay
powered on, increasing sleep power consumption.
config RTC_FAST_CLK_SRC_RC_FAST
bool "20 Mhz RC Fast Clock"
config RTC_FAST_CLK_SRC_XTAL
bool "40 Mhz crystal (increased power consumption during sleep)"
endchoice

View File

@ -191,7 +191,7 @@ uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t prec
case SOC_RTC_FAST_CLK_SRC_LP_PLL:
return clk_ll_lp_pll_get_freq_mhz() * MHZ;
#endif
#if SOC_CLK_LP_FAST_SUPPORT_XTAL
#if SOC_CLK_LP_FAST_SUPPORT_XTAL && !CONFIG_IDF_TARGET_ESP32P4 // On P4 SOC_RTC_FAST_CLK_SRC_XTAL is an alias for SOC_RTC_FAST_CLK_SRC_XTAL_DIV
case SOC_RTC_FAST_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz() * MHZ;
#endif

View File

@ -56,8 +56,14 @@ __attribute__((weak)) void esp_clk_init(void)
assert((rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_48M) || (rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M));
rtc_clk_8m_enable(true);
#if CONFIG_RTC_FAST_CLK_SRC_RC_FAST
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
#elif CONFIG_RTC_FAST_CLK_SRC_XTAL
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_XTAL);
#else
#error "No RTC fast clock source configured"
#endif
#endif //!CONFIG_IDF_ENV_FPGA
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.

View File

@ -53,7 +53,13 @@ __attribute__((weak)) void esp_clk_init(void)
assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M);
rtc_clk_8m_enable(true);
#if CONFIG_RTC_FAST_CLK_SRC_RC_FAST
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
#elif CONFIG_RTC_FAST_CLK_SRC_XTAL
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_XTAL);
#else
#error "No RTC fast clock source configured"
#endif
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.

View File

@ -1751,6 +1751,10 @@ config SOC_CLK_LP_FAST_SUPPORT_LP_PLL
bool
default y
config SOC_CLK_LP_FAST_SUPPORT_XTAL
bool
default y
config SOC_PERIPH_CLK_CTRL_SHARED
bool
default y

View File

@ -682,6 +682,8 @@
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
#define SOC_CLK_LP_FAST_SUPPORT_LP_PLL (1) /*!< Support LP_PLL clock as the LP_FAST clock source */
#define SOC_CLK_LP_FAST_SUPPORT_XTAL (1) /*!< Support XTAL clock as the LP_FAST clock source */
#define SOC_PERIPH_CLK_CTRL_SHARED (1) /*!< Peripheral clock control (e.g. set clock source) is shared between various peripherals */

View File

@ -28,7 +28,17 @@
#endif
/* LP_FAST_CLK is not very accurate, for now use a rough estimate */
#if CONFIG_RTC_FAST_CLK_SRC_RC_FAST
#define LP_CORE_CPU_FREQUENCY_HZ 16000000 // For P4 TRM says 20 MHz by default, but we tune it closer to 16 MHz
#elif CONFIG_RTC_FAST_CLK_SRC_XTAL
#if SOC_XTAL_SUPPORT_48M
#define LP_CORE_CPU_FREQUENCY_HZ 48000000
#else
#define LP_CORE_CPU_FREQUENCY_HZ 40000000
#endif
#else // Default value in chip without rtc fast clock sel option
#define LP_CORE_CPU_FREQUENCY_HZ 16000000
#endif
static uint32_t lp_wakeup_cause = 0;

View File

@ -1,6 +1,11 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/ulp/test_apps/lp_core:
components/ulp/test_apps/lp_core/lp_core_basic_tests:
disable:
- if: SOC_LP_CORE_SUPPORTED != 1
- if: CONFIG_NAME == "xtal" and SOC_CLK_LP_FAST_SUPPORT_XTAL != 1
components/ulp/test_apps/lp_core/lp_core_hp_uart:
disable:
- if: SOC_LP_CORE_SUPPORTED != 1

View File

@ -132,6 +132,7 @@ TEST_CASE("Test LP core delay", "[lp_core]")
#define LP_TIMER_TEST_SLEEP_DURATION_US (20000)
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C5)
#if SOC_DEEP_SLEEP_SUPPORTED && CONFIG_RTC_FAST_CLK_SRC_RC_FAST
static void do_ulp_wakeup_deepsleep(lp_core_test_commands_t ulp_cmd)
{
@ -228,7 +229,8 @@ TEST_CASE_MULTIPLE_STAGES("LP Timer can wakeup lp core periodically during deep
do_ulp_wakeup_with_lp_timer_deepsleep,
check_reset_reason_and_sleep_duration);
#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C5)
#endif //#if SOC_DEEP_SLEEP_SUPPORTED && CONFIG_RTC_FAST_CLK_SRC_RC_FAST
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C5)
TEST_CASE("LP Timer can wakeup lp core periodically", "[lp_core]")
{
@ -382,5 +384,4 @@ TEST_CASE("LP core ISR tests", "[ulp]")
printf("ULP LP IO ISR triggered %"PRIu32" times\n", ulp_io_isr_counter);
TEST_ASSERT_EQUAL(ISR_TEST_ITERATIONS, ulp_io_isr_counter);
#endif //SOC_RTCIO_PIN_COUNT > 0
}

View File

@ -8,10 +8,31 @@ from pytest_embedded import Dut
@pytest.mark.esp32c6
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
[
'default',
],
indirect=True,
)
def test_lp_core(dut: Dut) -> None:
dut.run_all_single_board_cases()
@pytest.mark.esp32c5
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
[
'xtal',
],
indirect=True,
)
def test_lp_core_xtal(dut: Dut) -> None:
dut.run_all_single_board_cases()
@pytest.mark.esp32c6
# TODO: Enable LP I2C test for esp32p4 (IDF-9407)
@pytest.mark.generic_multi_device

View File

@ -0,0 +1 @@
CONFIG_RTC_FAST_CLK_SRC_XTAL=y

View File

@ -262,6 +262,19 @@ For example, to override the handler for the LP IO interrupt, you can define the
In addition to configuring the interrupt related registers for the interrupt source you want to handle, you also need to enable the interrupts globally in the LP-Core interrupt controller. This can be done using the :cpp:func:`ulp_lp_core_intr_enable` function.
ULP LP-Core Clock Configuration
-------------------------------
{IDF_TARGET_XTAL_FREQ:default="Not updated", esp32c5="48 MHz", esp32p4="40 MHz"}
The ULP LP-Core clock source is based on the system clock ``LP_FAST_CLK``, see `TRM <{IDF_TARGET_TRM_EN_URL}>`__ > ``Reset and Clock`` for more details.
.. only:: SOC_CLK_LP_FAST_SUPPORT_XTAL
On {IDF_TARGET_NAME} ``LP_FAST_CLK`` supports using the external {IDF_TARGET_XTAL_FREQ} crystal (XTAL) as the source for ``LP_FAST_CLK``, which allows the ULP LP-Core to run at a higher frequency than with the default ``RTC_FAST_CLOCK`` which runs at around 20 MHz. The drawback is that this clock is normally powered down during sleep to reduce power consumption, with it selected XTAL will also stay powered on during sleep, increasing power consumption. If you only plan to use the LP-Core as a co-processor while the HP-Core is active, then this option can be used to increase both the performance and the frequency stability of the LP-Core.
To enable this feature set :ref:`CONFIG_RTC_FAST_CLK_SRC` to ``CONFIG_RTC_FAST_CLK_SRC_XTAL``.
Debugging ULP LP-Core Applications
----------------------------------