Skip to content

Commit

Permalink
Merge branch 'feature/lp_core_40_mhz' into 'master'
Browse files Browse the repository at this point in the history
feat(system): support choosing xtal as rtc-fast clock src on P4 and C5

Closes IDF-10203

See merge request espressif/esp-idf!32450
  • Loading branch information
ESP-Marius committed Sep 20, 2024
2 parents 8320e42 + 00eb977 commit 564d777
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 4 deletions.
21 changes: 21 additions & 0 deletions components/esp_hw_support/port/esp32c5/Kconfig.rtc
Original file line number Diff line number Diff line change
Expand Up @@ -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
21 changes: 21 additions & 0 deletions components/esp_hw_support/port/esp32p4/Kconfig.rtc
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,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
2 changes: 1 addition & 1 deletion components/esp_hw_support/port/esp_clk_tree_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions components/esp_system/port/soc/esp32c5/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions components/esp_system/port/soc/esp32p4/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,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.
Expand Down
4 changes: 4 additions & 0 deletions components/soc/esp32p4/include/soc/Kconfig.soc_caps.in
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,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
Expand Down
2 changes: 2 additions & 0 deletions components/soc/esp32p4/include/soc/soc_caps.h
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,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 */

Expand Down
10 changes: 10 additions & 0 deletions components/ulp/lp_core/lp_core/lp_core_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,17 @@
#include "esp_cpu.h"

/* 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;

Expand Down
7 changes: 6 additions & 1 deletion components/ulp/test_apps/.build-test-rules.yml
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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]")
{
Expand Down Expand Up @@ -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

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,31 @@
@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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_RTC_FAST_CLK_SRC_XTAL=y
13 changes: 13 additions & 0 deletions docs/en/api-reference/system/ulp-lp-core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
----------------------------------

Expand Down

0 comments on commit 564d777

Please sign in to comment.