feat(esp_hw_support): support esp_perip_clk_init for esp32c5

This commit is contained in:
wuzhenghui
2025-01-20 15:49:03 +08:00
parent 904d9526d3
commit 34f249a28b
14 changed files with 402 additions and 110 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -11,6 +11,7 @@
#include "soc/rtc.h"
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "hal/clk_gate_ll.h"
#include "esp_private/esp_clk_tree_common.h"
static const char *TAG = "esp_clk_tree";
@@ -69,6 +70,38 @@ uint32_t *freq_value)
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
{
(void)clk_src; (void)enable;
PERIPH_RCC_ATOMIC() {
switch (clk_src) {
case SOC_MOD_CLK_PLL_F12M:
clk_gate_ll_ref_12m_clk_en(enable);
break;
case SOC_MOD_CLK_PLL_F20M:
clk_gate_ll_ref_20m_clk_en(enable);
break;
case SOC_MOD_CLK_PLL_F40M:
clk_gate_ll_ref_40m_clk_en(enable);
break;
case SOC_MOD_CLK_PLL_F48M:
clk_gate_ll_ref_48m_clk_en(enable);
break;
case SOC_MOD_CLK_PLL_F60M:
clk_gate_ll_ref_60m_clk_en(enable);
break;
case SOC_MOD_CLK_PLL_F80M:
clk_gate_ll_ref_80m_clk_en(enable);
break;
case SOC_MOD_CLK_PLL_F120M:
clk_gate_ll_ref_120m_clk_en(enable);
break;
case SOC_MOD_CLK_PLL_F160M:
clk_gate_ll_ref_160m_clk_en(enable);
break;
case SOC_MOD_CLK_PLL_F240M:
clk_gate_ll_ref_240m_clk_en(enable);
break;
default:
break;
}
}
return ESP_OK;
}

View File

@@ -6,6 +6,7 @@
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h"
#include "hal/gpio_ll.h"
@@ -40,6 +41,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
return ESP_ERR_INVALID_STATE;
}
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
gpio_ll_iomux_set_clk_src(clk_src);
return ESP_OK;

View File

@@ -64,7 +64,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
rtc_dig_clk8m_enable();
}
}
clk_ll_enable_timergroup_rtc_calibration_clock(true);
/* There may be another calibration process already running during we call this function,
* so we should wait the last process is done.
*/
@@ -123,6 +123,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
}
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
clk_ll_enable_timergroup_rtc_calibration_clock(false);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable();

View File

@@ -27,6 +27,38 @@
#if SOC_MODEM_CLOCK_SUPPORTED
#include "hal/modem_lpcon_ll.h"
#endif
#include "hal/adc_ll.h"
#include "hal/aes_ll.h"
#include "hal/assist_debug_ll.h"
#include "hal/apm_ll.h"
#include "hal/clk_gate_ll.h"
#include "hal/clk_tree_ll.h"
#include "hal/ds_ll.h"
#include "hal/ecc_ll.h"
#include "hal/etm_ll.h"
#include "hal/gdma_ll.h"
#include "hal/hmac_ll.h"
#include "hal/i2c_ll.h"
#include "hal/i2s_ll.h"
#include "hal/ledc_ll.h"
#include "hal/lp_core_ll.h"
#include "hal/lp_clkrst_ll.h"
#include "hal/mcpwm_ll.h"
#include "hal/mpi_ll.h"
#include "hal/mspi_ll.h"
#include "hal/parlio_ll.h"
#include "hal/pau_ll.h"
#include "hal/pcnt_ll.h"
#include "hal/rmt_ll.h"
#include "hal/rtc_io_ll.h"
#include "hal/sha_ll.h"
#include "hal/spi_ll.h"
#include "hal/temperature_sensor_ll.h"
#include "hal/timer_ll.h"
#include "hal/twaifd_ll.h"
#include "hal/uart_ll.h"
#include "hal/uhci_ll.h"
#include "hal/usb_serial_jtag_ll.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_modem_clock.h"
#include "esp_private/periph_ctrl.h"
@@ -200,23 +232,19 @@ void rtc_clk_select_rtc_slow_clk(void)
*/
__attribute__((weak)) void esp_perip_clk_init(void)
{
// TODO: [ESP32C5] IDF-8844
#if SOC_MODEM_CLOCK_SUPPORTED
// modem_clock_domain_pmu_state_icg_map_init();
/* During system initialization, the low-power clock source of the modem
* (WiFi, BLE or Coexist) follows the configuration of the slow clock source
* of the system. If the WiFi, BLE or Coexist module needs a higher
* precision sleep clock (for example, the BLE needs to use the main XTAL
* oscillator (40 MHz) to provide the clock during the sleep process in some
* scenarios), the module needs to switch to the required clock source by
* itself. */ //TODO - WIFI-5233
* itself. */
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)(
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? MODEM_CLOCK_LPCLK_SRC_XTAL32K
: (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K
: MODEM_CLOCK_LPCLK_SRC_RC_SLOW);
modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0);
#endif
/* On ESP32-C5 ECO1, clearing BIT(31) of PCR_FPGA_DEBUG_REG is used to fix
* the issue where the modem module fails to transmit and receive packets
@@ -225,102 +253,112 @@ __attribute__((weak)) void esp_perip_clk_init(void)
* to IDF-11064. */
clk_ll_soc_root_clk_auto_gating_bypass(true);
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
#if 0 // TODO: [ESP32C5] IDF-8844
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
uint32_t common_perip_clk1 = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
/* For reason that only reset CPU, do not disable the clocks
* that have been enabled before reset.
*/
if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
} else {
common_perip_clk = SYSTEM_WDG_CLK_EN |
SYSTEM_I2S0_CLK_EN |
if ((rst_reason != RESET_REASON_CPU0_MWDT0) && (rst_reason != RESET_REASON_CPU0_MWDT1) \
&& (rst_reason != RESET_REASON_CPU0_SW) && (rst_reason != RESET_REASON_CPU0_RTC_WDT) \
&& (rst_reason != RESET_REASON_CPU0_JTAG) && (rst_reason != RESET_REASON_CPU0_LOCKUP)) {
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
SYSTEM_UART_CLK_EN |
uart_ll_enable_bus_clock(UART_NUM_0, false);
uart_ll_sclk_disable(&UART0);
#elif CONFIG_ESP_CONSOLE_UART_NUM != 1
uart_ll_sclk_disable(&UART1);
uart_ll_enable_bus_clock(UART_NUM_1, false);
#endif
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
SYSTEM_UART1_CLK_EN |
i2c_ll_enable_bus_clock(0, false);
i2c_ll_enable_controller_clock(&I2C0, false);
rmt_ll_enable_bus_clock(0, false);
rmt_ll_enable_group_clock(0, false);
ledc_ll_enable_clock(&LEDC, false);
ledc_ll_enable_bus_clock(false);
clk_ll_enable_timergroup_rtc_calibration_clock(false);
timer_ll_enable_clock(0, 0, false);
timer_ll_enable_clock(1, 0, false);
_timer_ll_enable_bus_clock(0, false);
_timer_ll_enable_bus_clock(1, false);
twaifd_ll_enable_clock(0, false);
twaifd_ll_enable_bus_clock(0, false);
twaifd_ll_enable_clock(1, false);
twaifd_ll_enable_bus_clock(1, false);
i2s_ll_enable_bus_clock(0, false);
i2s_ll_tx_disable_clock(&I2S0);
i2s_ll_rx_disable_clock(&I2S0);
adc_ll_enable_bus_clock(false);
pcnt_ll_enable_bus_clock(0, false);
etm_ll_enable_bus_clock(0, false);
mcpwm_ll_enable_bus_clock(0, false);
mcpwm_ll_group_enable_clock(0, false);
parlio_ll_rx_enable_clock(&PARL_IO, false);
parlio_ll_tx_enable_clock(&PARL_IO, false);
parlio_ll_enable_bus_clock(0, false);
ahb_dma_ll_force_enable_reg_clock(&AHB_DMA, false);
_gdma_ll_enable_bus_clock(0, false);
#if CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
mspi_timing_ll_enable_core_clock(0, false);
#endif
SYSTEM_SPI2_CLK_EN |
SYSTEM_I2C_EXT0_CLK_EN |
SYSTEM_UHCI0_CLK_EN |
SYSTEM_RMT_CLK_EN |
SYSTEM_LEDC_CLK_EN |
SYSTEM_TIMERGROUP1_CLK_EN |
SYSTEM_SPI3_CLK_EN |
SYSTEM_SPI4_CLK_EN |
SYSTEM_TWAI_CLK_EN |
SYSTEM_I2S0_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
spi_ll_enable_bus_clock(SPI2_HOST, false);
temperature_sensor_ll_bus_clk_enable(false);
pau_ll_enable_bus_clock(false);
#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD
/* Disable ASSIST Debug module clock if PC recoreding function is not used,
* if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */
assist_debug_ll_enable_bus_clock(false);
#endif
mpi_ll_enable_bus_clock(false);
aes_ll_enable_bus_clock(false);
sha_ll_enable_bus_clock(false);
ecc_ll_enable_bus_clock(false);
hmac_ll_enable_bus_clock(false);
ds_ll_enable_bus_clock(false);
apm_tee_ll_clk_gating_enable(false);
uhci_ll_enable_bus_clock(0, false);
common_perip_clk1 = 0;
hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
SYSTEM_CRYPTO_SHA_CLK_EN |
SYSTEM_CRYPTO_RSA_CLK_EN;
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
SYSTEM_WIFI_CLK_BT_EN_M |
SYSTEM_WIFI_CLK_UNUSED_BIT5 |
SYSTEM_WIFI_CLK_UNUSED_BIT12;
// TODO: Replace with hal implementation
REG_CLR_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN);
REG_CLR_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN);
REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN);
REG_CLR_BIT(PCR_TCM_MEM_MONITOR_CONF_REG, PCR_TCM_MEM_MONITOR_CLK_EN);
REG_CLR_BIT(PCR_PSRAM_MEM_MONITOR_CONF_REG, PCR_PSRAM_MEM_MONITOR_CLK_EN);
REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN);
REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN);
WRITE_PERI_REG(PCR_CTRL_CLK_OUT_EN_REG, 0);
#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
// Disable USB-Serial-JTAG clock and it's pad if not used
usb_serial_jtag_ll_phy_enable_pad(false);
usb_serial_jtag_ll_enable_bus_clock(false);
usb_serial_jtag_ll_enable_mem_clock(false);
usb_serial_jtag_ll_set_mem_pd(true);
#endif
if (clk_ll_cpu_get_src() != SOC_CPU_CLK_SRC_PLL_F240M) {
_clk_gate_ll_ref_240m_clk_en(false);
}
if (clk_ll_cpu_get_src() != SOC_CPU_CLK_SRC_PLL_F160M) {
_clk_gate_ll_ref_160m_clk_en(false);
}
_clk_gate_ll_ref_120m_clk_en(false);
_clk_gate_ll_ref_80m_clk_en(false);
_clk_gate_ll_ref_60m_clk_en(false);
_clk_gate_ll_ref_40m_clk_en(false);
_clk_gate_ll_ref_20m_clk_en(false);
_clk_gate_ll_ref_12m_clk_en(false);
}
//Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state.
common_perip_clk |= SYSTEM_I2S0_CLK_EN |
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
SYSTEM_UART_CLK_EN |
#endif
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
SYSTEM_UART1_CLK_EN |
#endif
SYSTEM_SPI2_CLK_EN |
SYSTEM_I2C_EXT0_CLK_EN |
SYSTEM_UHCI0_CLK_EN |
SYSTEM_RMT_CLK_EN |
SYSTEM_UHCI1_CLK_EN |
SYSTEM_SPI3_CLK_EN |
SYSTEM_SPI4_CLK_EN |
SYSTEM_I2C_EXT1_CLK_EN |
SYSTEM_I2S0_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
common_perip_clk1 = 0;
if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CHIP_BROWN_OUT) \
|| (rst_reason == RESET_REASON_SYS_RTC_WDT) || (rst_reason == RESET_REASON_SYS_SUPER_WDT) \
|| (rst_reason == RESET_REASON_CORE_PWR_GLITCH)) {
_lp_i2c_ll_enable_bus_clock(0, false);
lp_uart_ll_sclk_disable(0);
_lp_uart_ll_enable_bus_clock(0, false);
_lp_core_ll_enable_bus_clock(false);
_rtcio_ll_enable_io_clock(false);
_lp_clkrst_ll_enable_rng_clock(false);
_lp_clkrst_ll_enable_otp_dbg_clock(false);
_lp_clkrst_ll_enable_lp_ana_i2c_clock(false);
_lp_clkrst_ll_enable_lp_ext_i2c_clock(false);
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
* the current is not reduced when disable I2S clock.
*/
// TOCK(check replacement)
// REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
// REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
/* Disable some peripheral clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
/* Disable hardware crypto clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
/* Disable WiFi/BT/SDIO clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
/* Set WiFi light sleep clock source to RTC slow clock */
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
/* Enable RNG clock. */
periph_module_enable(PERIPH_RNG_MODULE);
#endif
REG_CLR_BIT(LP_APM_CLOCK_GATE_REG, LP_APM_CLK_EN);
REG_CLR_BIT(LP_APM0_CLOCK_GATE_REG, LP_APM0_CLK_EN);
WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0);
}
}

View File

@@ -224,7 +224,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
* precision sleep clock (for example, the BLE needs to use the main XTAL
* oscillator (40 MHz) to provide the clock during the sleep process in some
* scenarios), the module needs to switch to the required clock source by
* itself. */ //TODO - WIFI-5233
* itself. */
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)(\
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW \

View File

@@ -188,7 +188,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
* precision sleep clock (for example, the BLE needs to use the main XTAL
* oscillator (40 MHz) to provide the clock during the sleep process in some
* scenarios), the module needs to switch to the required clock source by
* itself. */ //TODO - WIFI-5233
* itself. */
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)(
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW

View File

@@ -0,0 +1,128 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/pcr_struct.h"
/**
* Enable or disable the clock gate for ref_12m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_12m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_12m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_12m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_12m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for ref_20m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_20m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_20m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_20m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_20m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for ref_40m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_40m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_40m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_40m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_40m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for ref_48m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_48m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_48m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_48m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_48m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for ref_60m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_60m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_60m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_60m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_60m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for ref_80m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_80m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_80m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_80m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_80m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for ref_120m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_120m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_120m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_120m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_120m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for ref_160m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_160m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_160m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_160m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_160m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for ref_240m.
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_ref_240m_clk_en(bool enable)
{
PCR.pll_div_clk_en.pll_240m_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_240m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_240m_clk_en(__VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -568,6 +568,15 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1);
}
/**
* @brief Enable the RTC clock calibration reference XTAL source on timer group0.
* @param enable enable or disable the XTAL source.
*/
static inline __attribute__((always_inline)) void clk_ll_enable_timergroup_rtc_calibration_clock(bool enable)
{
PCR.timergroup_xtal_conf.tg0_xtal_clk_en = enable;
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/
/**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register

View File

@@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for ESP32-C5 LP_CLKRST & LP PERI register operations
#pragma once
#include <stdbool.h>
#include <stdlib.h>
#include "soc/soc.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/lpperi_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
__attribute__((always_inline))
static inline void _lp_clkrst_ll_enable_rng_clock(bool en)
{
LPPERI.clk_en.rng_ck_en = en;
}
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
#define lp_clkrst_ll_enable_rng_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_rng_clock(__VA_ARGS__)
__attribute__((always_inline))
static inline void _lp_clkrst_ll_enable_otp_dbg_clock(bool en)
{
LPPERI.clk_en.otp_dbg_ck_en = en;
}
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
#define lp_clkrst_ll_enable_otp_dbg_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_otp_dbg_clock(__VA_ARGS__)
__attribute__((always_inline))
static inline void _lp_clkrst_ll_enable_lp_ana_i2c_clock(bool en)
{
LPPERI.clk_en.lp_ana_i2c_ck_en = en;
}
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
#define lp_clkrst_ll_enable_lp_ana_i2c_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_lp_ana_i2c_clock(__VA_ARGS__)
__attribute__((always_inline))
static inline void _lp_clkrst_ll_enable_lp_ext_i2c_clock(bool en)
{
LPPERI.clk_en.lp_ext_i2c_ck_en = en;
}
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
#define lp_clkrst_ll_enable_lp_ext_i2c_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_clkrst_ll_enable_lp_ext_i2c_clock(__VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@@ -32,7 +32,7 @@ extern "C" {
*
* @param enable true to enable, false to disable
*/
static inline void lp_core_ll_enable_bus_clock(bool enable)
static inline void _lp_core_ll_enable_bus_clock(bool enable)
{
LPPERI.clk_en.lp_cpu_ck_en = enable;
}
@@ -41,7 +41,7 @@ static inline void lp_core_ll_enable_bus_clock(bool enable)
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define lp_core_ll_enable_bus_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
lp_core_ll_enable_bus_clock(__VA_ARGS__); \
_lp_core_ll_enable_bus_clock(__VA_ARGS__); \
} while(0)
/**

View File

@@ -60,7 +60,8 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
static inline void _rtcio_ll_enable_io_clock(bool enable)
{
LPPERI.clk_en.lp_io_ck_en = enable;
while (LPPERI.clk_en.lp_io_ck_en != enable) {
LP_GPIO.clock_gate.clk_en = enable;
while ((LPPERI.clk_en.lp_io_ck_en != enable) || (LP_GPIO.clock_gate.clk_en != enable)) {
;
}
}

View File

@@ -188,7 +188,7 @@ FORCE_INLINE_ATTR bool lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, ui
* @param hw_id LP UART instance ID
* @param enable True to enable, False to disable
*/
static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
static inline void _lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
{
(void)hw_id;
LPPERI.clk_en.lp_uart_ck_en = enable;
@@ -197,7 +197,7 @@ static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
#define lp_uart_ll_enable_bus_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
lp_uart_ll_enable_bus_clock(__VA_ARGS__); \
_lp_uart_ll_enable_bus_clock(__VA_ARGS__); \
} while(0)
/**

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -329,6 +329,25 @@ FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void)
return (PCR.usb_device_conf.usb_device_clk_en && !PCR.usb_device_conf.usb_device_rst_en);
}
/* ---------------------------- USB MEM Control ---------------------------- */
/**
* @brief Power down the power USJ mem.
* @param clk_en True if power down the USJ mem.
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_set_mem_pd(bool pd)
{
USB_SERIAL_JTAG.mem_conf.usb_mem_pd = pd;
}
/**
* @brief Enable the mem clock for USJ module
* @param clk_en True if enable the clock of USJ module mem.
*/
FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_mem_clock(bool clk_en)
{
USB_SERIAL_JTAG.mem_conf.usb_mem_clk_en = clk_en;
}
#ifdef __cplusplus
}
#endif

View File

@@ -124,9 +124,15 @@ typedef enum {
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */
// For digital domain: peripherals, WIFI, BLE
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL (clock gating + fixed divider of 6), it has a fixed frequency of 80MHz */
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from PLL (clock gating + fixed divider of 3), it has a fixed frequency of 160MHz */
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 240MHz */
SOC_MOD_CLK_PLL_F12M, /*!< PLL_F12M_CLK is derived from SPLL (clock gating + fixed divider of 40), it has a fixed frequency of 12MHz */
SOC_MOD_CLK_PLL_F20M, /*!< PLL_F20M_CLK is derived from SPLL (clock gating + fixed divider of 24), it has a fixed frequency of 20MHz */
SOC_MOD_CLK_PLL_F40M, /*!< PLL_F40M_CLK is derived from SPLL (clock gating + fixed divider of 12), it has a fixed frequency of 40MHz */
SOC_MOD_CLK_PLL_F48M, /*!< PLL_F48M_CLK is derived from SPLL (clock gating + fixed divider of 10), it has a fixed frequency of 48MHz */
SOC_MOD_CLK_PLL_F60M, /*!< PLL_F60M_CLK is derived from SPLL (clock gating + fixed divider of 8), it has a fixed frequency of 60MHz */
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + fixed divider of 6), it has a fixed frequency of 80MHz */
SOC_MOD_CLK_PLL_F120M, /*!< PLL_F120M_CLK is derived from SPLL (clock gating + fixed divider of 4), it has a fixed frequency of 120MHz */
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + fixed divider of 3), it has a fixed frequency of 160MHz */
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + fixed divider of 2), it has a fixed frequency of 240MHz */
SOC_MOD_CLK_SPLL, /*!< SPLL is from the main XTAL oscillator frequency multipliers, it has a "fixed" frequency of 480MHz */
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */