Merge branch 'refactor/esp_hal_clock' into 'master'

refactor(clk): split clock HAL into separate component

Closes IDF-14108

See merge request espressif/esp-idf!44768
This commit is contained in:
Song Ruo Jing
2026-01-19 11:33:35 +08:00
83 changed files with 980 additions and 889 deletions
+2 -2
View File
@@ -74,7 +74,7 @@ if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_RAM)
"private_include") "private_include")
set(priv_requires micro-ecc spi_flash efuse esp_bootloader_format esp_app_format esptool_py) set(priv_requires micro-ecc spi_flash efuse esp_bootloader_format esp_app_format esptool_py)
# `esp_hal_ana_conv` is required by bootloader_random_esp32xx.c # `esp_hal_ana_conv` is required by bootloader_random_esp32xx.c
list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer) list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer esp_hal_clock)
list(APPEND srcs list(APPEND srcs
"src/bootloader_init.c" "src/bootloader_init.c"
"src/bootloader_clock_loader.c" "src/bootloader_clock_loader.c"
@@ -92,7 +92,7 @@ else()
# heap is required for `heap_memory_layout.h` header # heap is required for `heap_memory_layout.h` header
set(priv_requires spi_flash mbedtls efuse heap esp_bootloader_format esp_app_format esptool_py) set(priv_requires spi_flash mbedtls efuse heap esp_bootloader_format esp_app_format esptool_py)
# `esp_hal_ana_conv` is required by bootloader_random_esp32xx.c # `esp_hal_ana_conv` is required by bootloader_random_esp32xx.c
list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer) list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer esp_hal_clock)
endif() endif()
if(BOOTLOADER_BUILD) if(BOOTLOADER_BUILD)
+1 -1
View File
@@ -1,7 +1,7 @@
idf_build_get_property(target IDF_TARGET) idf_build_get_property(target IDF_TARGET)
set(srcs) set(srcs)
set(priv_req esp_pm esp_driver_gpio) set(priv_req esp_pm esp_driver_gpio esp_hal_clock)
if(${target} STREQUAL "linux") if(${target} STREQUAL "linux")
return() # This component is not supported by the POSIX/Linux simulator return() # This component is not supported by the POSIX/Linux simulator
+1 -1
View File
@@ -6,7 +6,7 @@ endif()
set(srcs) set(srcs)
set(include "include") set(include "include")
set(priv_requires esp_driver_gpio esp_pm esp_mm) set(priv_requires esp_driver_gpio esp_pm esp_mm esp_hal_clock)
if(${target} STREQUAL "esp32") if(${target} STREQUAL "esp32")
# ADC on esp32 is routed to I2S0, I2S driver needs to operate ADC to ensure the I2S function. # ADC on esp32 is routed to I2S0, I2S driver needs to operate ADC to ensure the I2S function.
@@ -984,7 +984,7 @@ static void sd_host_set_clk_div(sd_host_sdmmc_ctlr_t *ctlr, soc_periph_sdmmc_clk
sdmmc_ll_set_clock_div(ctlr->hal.dev, div); sdmmc_ll_set_clock_div(ctlr->hal.dev, div);
sdmmc_ll_select_clk_source(ctlr->hal.dev, src); sdmmc_ll_select_clk_source(ctlr->hal.dev, src);
sdmmc_ll_init_phase_delay(ctlr->hal.dev); sdmmc_ll_init_phase_delay(ctlr->hal.dev);
#if SOC_CLK_SDIO_PLL_SUPPORTED #if SDMMC_LL_SDIO_PLL_SUPPORTED
if (src == SDMMC_CLK_SRC_SDIO_200M) { if (src == SDMMC_CLK_SRC_SDIO_200M) {
sdmmc_ll_enable_sdio_pll(ctlr->hal.dev, true); sdmmc_ll_enable_sdio_pll(ctlr->hal.dev, true);
} }
+1 -1
View File
@@ -10,7 +10,7 @@ set(ld_fragments linker.lf)
# As CONFIG_ETH_ENABLED comes from Kconfig, it is not evaluated yet # As CONFIG_ETH_ENABLED comes from Kconfig, it is not evaluated yet
# when components are being registered. # when components are being registered.
# Thus, always add the (private) requirements, regardless of Kconfig # Thus, always add the (private) requirements, regardless of Kconfig
set(priv_requires log esp_timer esp_driver_spi esp_driver_gpio) set(priv_requires log esp_timer esp_driver_spi esp_driver_gpio esp_hal_clock)
# If Ethernet disabled in Kconfig, this is a config-only component # If Ethernet disabled in Kconfig, this is a config-only component
if(CONFIG_ETH_ENABLED) if(CONFIG_ETH_ENABLED)
+15
View File
@@ -0,0 +1,15 @@
idf_build_get_property(target IDF_TARGET)
set(srcs)
set(includes "include")
# Target-specific include directory if present
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${target}/include")
list(APPEND includes "${target}/include")
endif()
list(APPEND srcs "${target}/clk_tree_hal.c")
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${includes}
REQUIRES soc hal)
+42
View File
@@ -0,0 +1,42 @@
# ESP Hardware Abstraction Layer for Clock Tree
> [!NOTE]
> This component is currently in beta. Its API, behavior, and compatibility may change at any time and without notice; backward compatibility is not guaranteed. Use caution when integrating into production systems.
## Overview
The `esp_hal_clock` component provides the **Hardware Abstraction Layer** for the SoC clock tree across ESP-IDF supported targets. It exposes helpers to query and configure clock sources, select roots, and manage clock gates in a target-agnostic way while delegating register details to per-target Low-Level (LL) implementations.
## Architecture
The Clock HAL is organized in two layers:
1. **HAL Layer (Upper)**: Target-independent logic and APIs to interact with the clock tree (e.g., querying frequencies, switching roots, enabling/disabling gates).
2. **Low-Level Layer (Bottom)**: Per-target register accessors defined by:
- `clk_tree_ll.h` — clock source/root select, muxes, dividers, and frequency helpers.
- `clk_gate_ll.h` — clock gate enable/disable, reset, and configuration of default clock gate status for peripherals.
- `clkout_channel.h` — clock output channel IDs and related helpers used to route internal clocks to GPIOs.
Per-target HAL sources implement SoC-specific behavior in `clk_tree_hal.c`, using the LL accessors above.
## Features
- Query effective frequencies of common clock domains.
- Select and switch clock roots (when supported).
- Configure dividers/multipliers per domain (target-dependent).
- Gate/ungate peripheral clocks via unified helpers.
- Apply default peripheral clock gate configuration during early boot (target-dependent).
- Configure and map on-chip clocks to GPIOs via clock-out channels (`clkout_channel.h`) on supported targets.
## Usage
This HAL is consumed by ESP-IDF internal components (e.g., `esp_hw_support`, drivers, bootloader code) to perform clock configuration and queries.
Advanced users may interact with the HAL directly when implementing custom bring-up or performance-sensitive flows. API stability is not guaranteed during beta.
## Dependencies
- `soc`: SoC register definitions and clock tree constants
- `hal`: Common HAL utilities and macros
@@ -4,11 +4,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/log.h" #include "hal/log.h"
HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal"); HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal");
@@ -111,10 +109,10 @@ uint32_t clk_hal_apll_get_freq_hz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -6,17 +6,16 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph)
{ {
@@ -143,7 +142,7 @@ static inline void periph_ll_reset(shared_periph_module_t periph)
static inline bool IRAM_ATTR periph_ll_periph_enabled(shared_periph_module_t periph) static inline bool IRAM_ATTR periph_ll_periph_enabled(shared_periph_module_t periph)
{ {
return DPORT_REG_GET_BIT(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)) == 0 && return DPORT_REG_GET_BIT(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)) == 0 &&
DPORT_REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0; DPORT_REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0;
} }
static inline void periph_ll_wifi_module_enable_clk_clear_rst(void) static inline void periph_ll_wifi_module_enable_clk_clear_rst(void)
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -14,16 +14,14 @@
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "soc/io_mux_reg.h"
#include "hal/clkout_channel.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/regi2c_apll.h" #include "soc/regi2c_apll.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "esp32/rom/rtc.h" #include "esp32/rom/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80) #define CLK_LL_PLL_80M_FREQ_MHZ (80)
@@ -86,6 +84,10 @@ extern "C" {
#define CLK_LL_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation #define CLK_LL_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
#define CLK_LL_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation #define CLK_LL_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -117,8 +119,8 @@ static inline __attribute__((always_inline)) void clk_ll_i2c_pd(void)
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void) static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
{ {
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD |
RTC_CNTL_BBPLL_I2C_FORCE_PD); RTC_CNTL_BBPLL_I2C_FORCE_PD);
// Reset BBPLL configuration // Reset BBPLL configuration
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_IR_CAL_DELAY, CLK_LL_BBPLL_IR_CAL_DELAY_VAL); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_IR_CAL_DELAY, CLK_LL_BBPLL_IR_CAL_DELAY_VAL);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, CLK_LL_BBPLL_IR_CAL_EXT_CAP_VAL); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, CLK_LL_BBPLL_IR_CAL_EXT_CAP_VAL);
@@ -133,8 +135,8 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void) static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
{ {
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD |
RTC_CNTL_BBPLL_I2C_FORCE_PD); RTC_CNTL_BBPLL_I2C_FORCE_PD);
} }
/** /**
@@ -829,6 +831,43 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider
return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 1; return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL) + 1;
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(PIN_CTRL, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/ /************************* RTC STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store XTAL_CLK frequency in RTC storage register * @brief Store XTAL_CLK frequency in RTC storage register
@@ -864,7 +903,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(
// Read from RTC storage register // Read from RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
} }
// If the format in reg is invalid or haven't written XTAL value into RTC_XTAL_FREQ_REG // If the format in reg is invalid or haven't written XTAL value into RTC_XTAL_FREQ_REG
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -4,12 +4,10 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/config.h" #include "hal/config.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/log.h" #include "hal/log.h"
HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal"); HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal");
@@ -86,10 +84,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -6,10 +6,6 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "hal/assert.h" #include "hal/assert.h"
@@ -17,9 +13,12 @@ extern "C" {
#include "soc/system_reg.h" #include "soc/system_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#include "soc/dport_access.h" #include "soc/dport_access.h"
#include "soc/soc_caps.h"
#include "esp_attr.h" #include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph)
{ {
switch (periph) { switch (periph) {
@@ -64,7 +63,7 @@ static inline uint32_t periph_ll_get_clk_en_reg(shared_periph_module_t periph)
case PERIPH_WIFI_MODULE: case PERIPH_WIFI_MODULE:
case PERIPH_BT_MODULE: case PERIPH_BT_MODULE:
case PERIPH_WIFI_BT_COMMON_MODULE: case PERIPH_WIFI_BT_COMMON_MODULE:
return SYSTEM_WIFI_CLK_EN_REG; return SYSTEM_WIFI_CLK_EN_REG;
default: default:
return SYSTEM_PERIP_CLK_EN0_REG; return SYSTEM_PERIP_CLK_EN0_REG;
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -14,14 +14,12 @@
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "soc/io_mux_reg.h"
#include "hal/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32c2/rom/rtc.h" #include "esp32c2/rom/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_40M_FREQ_MHZ (40) #define CLK_LL_PLL_40M_FREQ_MHZ (40)
@@ -37,6 +35,10 @@ extern "C" {
#define CLK_LL_RC_FAST_WAIT_DEFAULT 20 #define CLK_LL_RC_FAST_WAIT_DEFAULT 20
#define CLK_LL_RC_FAST_ENABLE_WAIT_DEFAULT 5 #define CLK_LL_RC_FAST_ENABLE_WAIT_DEFAULT 5
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -44,7 +46,6 @@ typedef enum {
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK (i.e. EXT_OSC_CLK) CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK (i.e. EXT_OSC_CLK)
} clk_ll_xtal32k_enable_mode_t; } clk_ll_xtal32k_enable_mode_t;
/** /**
* @brief Power up BBPLL circuit * @brief Power up BBPLL circuit
*/ */
@@ -274,7 +275,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_bbpll_div_7_0 = div7_0; uint8_t i2c_bbpll_div_7_0 = div7_0;
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
@@ -528,6 +529,43 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD); SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(PIN_CTRL, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/ /************************* RTC STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store XTAL_CLK frequency in RTC storage register * @brief Store XTAL_CLK frequency in RTC storage register
@@ -563,7 +601,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(
// Read from RTC storage register // Read from RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
} }
// If the format in reg is invalid // If the format in reg is invalid
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -4,11 +4,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/log.h" #include "hal/log.h"
HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal"); HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal");
@@ -85,10 +83,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -6,10 +6,6 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "hal/assert.h" #include "hal/assert.h"
@@ -17,9 +13,12 @@ extern "C" {
#include "soc/system_reg.h" #include "soc/system_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#include "soc/dport_access.h" #include "soc/dport_access.h"
#include "soc/soc_caps.h"
#include "esp_attr.h" #include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph)
{ {
switch (periph) { switch (periph) {
@@ -55,7 +54,7 @@ static inline uint32_t periph_ll_get_rst_en_mask(shared_periph_module_t periph,
case PERIPH_WIFI_MODULE: case PERIPH_WIFI_MODULE:
return SYSTEM_WIFIMAC_RST; return SYSTEM_WIFIMAC_RST;
case PERIPH_BT_MODULE: case PERIPH_BT_MODULE:
return (SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST); return (SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST);
case PERIPH_UART1_MODULE: case PERIPH_UART1_MODULE:
return SYSTEM_UART1_RST; return SYSTEM_UART1_RST;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG0_MODULE:
@@ -78,7 +77,7 @@ static inline uint32_t periph_ll_get_clk_en_reg(shared_periph_module_t periph)
case PERIPH_WIFI_MODULE: case PERIPH_WIFI_MODULE:
case PERIPH_BT_MODULE: case PERIPH_BT_MODULE:
case PERIPH_WIFI_BT_COMMON_MODULE: case PERIPH_WIFI_BT_COMMON_MODULE:
return SYSTEM_WIFI_CLK_EN_REG; return SYSTEM_WIFI_CLK_EN_REG;
default: default:
return SYSTEM_PERIP_CLK_EN0_REG; return SYSTEM_PERIP_CLK_EN0_REG;
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -14,14 +14,12 @@
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "soc/io_mux_reg.h"
#include "hal/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32c3/rom/rtc.h" #include "esp32c3/rom/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80) #define CLK_LL_PLL_80M_FREQ_MHZ (80)
@@ -43,6 +41,10 @@ extern "C" {
.dbuf = 1, \ .dbuf = 1, \
} }
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -380,7 +382,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32
} }
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_bbpll_div_7_0 = div7_0; uint8_t i2c_bbpll_div_7_0 = div7_0;
uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
@@ -636,6 +638,43 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD); SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(PIN_CTRL, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/ /************************* RTC STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store XTAL_CLK frequency in RTC storage register * @brief Store XTAL_CLK frequency in RTC storage register
@@ -671,7 +710,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(
// Read from RTC storage register // Read from RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
} }
// If the format in reg is invalid // If the format in reg is invalid
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -4,11 +4,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{ {
@@ -72,10 +70,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -6,10 +6,6 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
@@ -28,6 +24,10 @@ extern "C" {
#include "soc/usb_serial_jtag_struct.h" #include "soc/usb_serial_jtag_struct.h"
#include "soc/lp_clkrst_struct.h" #include "soc/lp_clkrst_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* Enable or disable the clock gate for ref_12m. * Enable or disable the clock gate for ref_12m.
* @param enable Enable / disable * @param enable Enable / disable
@@ -220,12 +220,12 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason,
LPPERI.clk_en.val = 0; LPPERI.clk_en.val = 0;
LPPERI.clk_en.efuse_ck_en = 1; // keep efuse clock enabled LPPERI.clk_en.efuse_ck_en = 1; // keep efuse clock enabled
if (config->disable_crypto_periph_clk) { if (config->disable_crypto_periph_clk) {
LP_APM.clock_gate.clk_en = 0; LP_APM.clock_gate.clk_en = 0;
LP_APM0.clock_gate.clk_en = 0; LP_APM0.clock_gate.clk_en = 0;
} }
LP_CLKRST.lp_clk_po_en.val = 0; LP_CLKRST.lp_clk_po_en.val = 0;
} }
} }
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -15,6 +15,8 @@
#include "soc/pmu_reg.h" #include "soc/pmu_reg.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
#include "soc/chip_revision.h" #include "soc/chip_revision.h"
#include "soc/gpio_ext_reg.h"
#include "hal/clkout_channel.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "hal/assert.h" #include "hal/assert.h"
@@ -23,10 +25,6 @@
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/efuse_hal.h" #include "hal/efuse_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80) #define CLK_LL_PLL_80M_FREQ_MHZ (80)
@@ -46,6 +44,10 @@ extern "C" {
// Fix default division factor for the RC_FAST clock for calibration to be 32 // Fix default division factor for the RC_FAST clock for calibration to be 32
#define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5 #define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -609,6 +611,78 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1); HAL_ASSERT(divider == 1);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(GPIO_EXT_PIN_CTRL_REG, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/**
* @brief Enable/Disable the clock gate for clock output signal source
*
* @param clk_src The clock output signal source
* @param en Enable or disable the clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
switch (clk_src) {
case CLKOUT_SIG_PLL_F22M:
PCR.ctrl_clk_out_en.clk22_oen = en;
break;
case CLKOUT_SIG_PLL_F44M:
PCR.ctrl_clk_out_en.clk44_oen = en;
break;
case CLKOUT_SIG_PLL_F40M:
PCR.ctrl_clk_out_en.clk_bb_oen = en;
break;
case CLKOUT_SIG_PLL_F80M:
PCR.ctrl_clk_out_en.clk80_oen = en;
break;
case CLKOUT_SIG_PLL_F160M:
PCR.ctrl_clk_out_en.clk160_oen = en;
break;
case CLKOUT_SIG_PLL_F480M:
PCR.ctrl_clk_out_en.clk_480m_oen = en;
break;
case CLKOUT_SIG_XTAL:
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
break;
default:
break;
}
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register * @brief Store RTC_SLOW_CLK calibration value in RTC storage register
@@ -635,39 +709,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
return REG_READ(RTC_SLOW_CLK_CAL_REG); return REG_READ(RTC_SLOW_CLK_CAL_REG);
} }
/*
* Enable/Disable the clock gate for clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
switch (clk_src)
{
case CLKOUT_SIG_PLL_F22M:
PCR.ctrl_clk_out_en.clk22_oen = en;
break;
case CLKOUT_SIG_PLL_F44M:
PCR.ctrl_clk_out_en.clk44_oen = en;
break;
case CLKOUT_SIG_PLL_F40M:
PCR.ctrl_clk_out_en.clk_bb_oen = en;
break;
case CLKOUT_SIG_PLL_F80M:
PCR.ctrl_clk_out_en.clk80_oen = en;
break;
case CLKOUT_SIG_PLL_F160M:
PCR.ctrl_clk_out_en.clk160_oen = en;
break;
case CLKOUT_SIG_PLL_F480M:
PCR.ctrl_clk_out_en.clk_480m_oen = en;
break;
case CLKOUT_SIG_XTAL:
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
break;
default:
break;
}
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -4,11 +4,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/log.h" #include "hal/log.h"
HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal"); HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal");
@@ -78,10 +76,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -10,7 +10,6 @@
#include <stdbool.h> #include <stdbool.h>
#include "hal/assert.h" #include "hal/assert.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/soc_caps.h"
#include "soc/reset_reasons.h" #include "soc/reset_reasons.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "soc/pcr_reg.h" #include "soc/pcr_reg.h"
@@ -30,34 +29,16 @@ extern "C" {
static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph)
{ {
switch (periph) { switch (periph) {
case PERIPH_SARADC_MODULE: case PERIPH_TIMG0_MODULE:
return PCR_SARADC_CLK_EN; return PCR_TG0_CLK_EN;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG1_MODULE:
return PCR_TG0_CLK_EN; return PCR_TG1_CLK_EN;
case PERIPH_TIMG1_MODULE: case PERIPH_UHCI0_MODULE:
return PCR_TG1_CLK_EN; return PCR_UHCI_CLK_EN;
case PERIPH_UHCI0_MODULE: case PERIPH_SYSTIMER_MODULE:
return PCR_UHCI_CLK_EN; return PCR_SYSTIMER_CLK_EN;
case PERIPH_SYSTIMER_MODULE: default:
return PCR_SYSTIMER_CLK_EN; return 0;
case PERIPH_AES_MODULE:
return PCR_AES_CLK_EN;
case PERIPH_SHA_MODULE:
return PCR_SHA_CLK_EN;
case PERIPH_ECC_MODULE:
return PCR_ECC_CLK_EN;
case PERIPH_RSA_MODULE:
return PCR_RSA_CLK_EN;
case PERIPH_HMAC_MODULE:
return PCR_HMAC_CLK_EN;
case PERIPH_DS_MODULE:
return PCR_DS_CLK_EN;
case PERIPH_SDIO_SLAVE_MODULE:
return PCR_SDIO_SLAVE_CLK_EN;
case PERIPH_ASSIST_DEBUG_MODULE:
return PCR_ASSIST_CLK_EN;
default:
return 0;
} }
} }
@@ -66,79 +47,30 @@ static inline uint32_t periph_ll_get_rst_en_mask(shared_periph_module_t periph,
(void)enable; // unused (void)enable; // unused
switch (periph) { switch (periph) {
case PERIPH_SARADC_MODULE: case PERIPH_TIMG0_MODULE:
return PCR_SARADC_REG_RST_EN; return PCR_TG0_RST_EN;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG1_MODULE:
return PCR_TG0_RST_EN; return PCR_TG1_RST_EN;
case PERIPH_TIMG1_MODULE: case PERIPH_UHCI0_MODULE:
return PCR_TG1_RST_EN; return PCR_UHCI_RST_EN;
case PERIPH_UHCI0_MODULE: case PERIPH_SYSTIMER_MODULE:
return PCR_UHCI_RST_EN; return PCR_SYSTIMER_RST_EN;
case PERIPH_SYSTIMER_MODULE: default:
return PCR_SYSTIMER_RST_EN; return 0;
case PERIPH_ECC_MODULE:
return PCR_ECC_RST_EN;
case PERIPH_AES_MODULE:
if (enable == true) {
// Clear reset on digital signature, otherwise AES unit is held in reset
PCR.ds_conf.ds_rst_en = 0;
}
return PCR_AES_RST_EN;
case PERIPH_SHA_MODULE:
if (enable == true) {
// Clear reset on digital signature and HMAC, otherwise SHA is held in reset
PCR.ds_conf.ds_rst_en = 0;
PCR.hmac_conf.hmac_rst_en = 0;
}
return PCR_SHA_RST_EN;
case PERIPH_RSA_MODULE:
if (enable == true) {
// Clear reset on digital signature, otherwise RSA is held in reset
PCR.ds_conf.ds_rst_en = 0;
}
return PCR_RSA_RST_EN;
case PERIPH_HMAC_MODULE:
return PCR_HMAC_RST_EN;
case PERIPH_DS_MODULE:
return PCR_DS_RST_EN;
case PERIPH_SDIO_SLAVE_MODULE:
return PCR_SDIO_SLAVE_RST_EN;
case PERIPH_ASSIST_DEBUG_MODULE:
return PCR_ASSIST_RST_EN;
default:
return 0;
} }
} }
static inline uint32_t periph_ll_get_clk_en_reg(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_reg(shared_periph_module_t periph)
{ {
switch (periph) { switch (periph) {
case PERIPH_SARADC_MODULE: case PERIPH_TIMG0_MODULE:
return PCR_SARADC_CONF_REG; return PCR_TIMERGROUP0_CONF_REG;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG1_MODULE:
return PCR_TIMERGROUP0_CONF_REG; return PCR_TIMERGROUP1_CONF_REG;
case PERIPH_TIMG1_MODULE: case PERIPH_UHCI0_MODULE:
return PCR_TIMERGROUP1_CONF_REG; return PCR_UHCI_CONF_REG;
case PERIPH_UHCI0_MODULE: case PERIPH_SYSTIMER_MODULE:
return PCR_UHCI_CONF_REG; return PCR_SYSTIMER_CONF_REG;
case PERIPH_SYSTIMER_MODULE:
return PCR_SYSTIMER_CONF_REG;
case PERIPH_AES_MODULE:
return PCR_AES_CONF_REG;
case PERIPH_SHA_MODULE:
return PCR_SHA_CONF_REG;
case PERIPH_ECC_MODULE:
return PCR_ECC_CONF_REG;
case PERIPH_RSA_MODULE:
return PCR_RSA_CONF_REG;
case PERIPH_HMAC_MODULE:
return PCR_HMAC_CONF_REG;
case PERIPH_DS_MODULE:
return PCR_DS_CONF_REG;
case PERIPH_SDIO_SLAVE_MODULE:
return PCR_SDIO_SLAVE_CONF_REG;
case PERIPH_ASSIST_DEBUG_MODULE:
return PCR_ASSIST_CONF_REG;
default: default:
return 0; return 0;
} }
@@ -147,32 +79,14 @@ static inline uint32_t periph_ll_get_clk_en_reg(shared_periph_module_t periph)
static inline uint32_t periph_ll_get_rst_en_reg(shared_periph_module_t periph) static inline uint32_t periph_ll_get_rst_en_reg(shared_periph_module_t periph)
{ {
switch (periph) { switch (periph) {
case PERIPH_SARADC_MODULE: case PERIPH_TIMG0_MODULE:
return PCR_SARADC_CONF_REG; return PCR_TIMERGROUP0_CONF_REG;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG1_MODULE:
return PCR_TIMERGROUP0_CONF_REG; return PCR_TIMERGROUP1_CONF_REG;
case PERIPH_TIMG1_MODULE: case PERIPH_UHCI0_MODULE:
return PCR_TIMERGROUP1_CONF_REG; return PCR_UHCI_CONF_REG;
case PERIPH_UHCI0_MODULE: case PERIPH_SYSTIMER_MODULE:
return PCR_UHCI_CONF_REG; return PCR_SYSTIMER_CONF_REG;
case PERIPH_SYSTIMER_MODULE:
return PCR_SYSTIMER_CONF_REG;
case PERIPH_AES_MODULE:
return PCR_AES_CONF_REG;
case PERIPH_SHA_MODULE:
return PCR_SHA_CONF_REG;
case PERIPH_ECC_MODULE:
return PCR_ECC_CONF_REG;
case PERIPH_RSA_MODULE:
return PCR_RSA_CONF_REG;
case PERIPH_HMAC_MODULE:
return PCR_HMAC_CONF_REG;
case PERIPH_DS_MODULE:
return PCR_DS_CONF_REG;
case PERIPH_SDIO_SLAVE_MODULE:
return PCR_SDIO_SLAVE_CONF_REG;
case PERIPH_ASSIST_DEBUG_MODULE:
return PCR_ASSIST_CONF_REG;
default: default:
return 0; return 0;
} }
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -15,15 +15,13 @@
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "soc/io_mux_reg.h"
#include "hal/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32c6/rom/rtc.h" #include "esp32c6/rom/rtc.h"
#include "hal/misc.h" #include "hal/misc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80) #define CLK_LL_PLL_80M_FREQ_MHZ (80)
@@ -48,6 +46,10 @@ So the frequency division factor of ref_tick must be greater than or equal to 32
#define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5 #define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5
#define REG_FOSC_TICK_NUM 255 #define REG_FOSC_TICK_NUM 255
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -321,7 +323,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32
} }
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_bbpll_div_7_0 = div7_0; uint8_t i2c_bbpll_div_7_0 = div7_0;
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
@@ -535,7 +537,7 @@ static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divide
uint32_t div_num = 0; uint32_t div_num = 0;
switch (divider) { switch (divider) {
case 4: case 4:
div_num = 3; div_num = 3;
break; break;
case 5: case 5:
div_num = 4; div_num = 4;
@@ -746,6 +748,66 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1); HAL_ASSERT(divider == 1);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(PIN_CTRL, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/**
* @brief Enable/Disable the clock gate for clock output signal source
*
* @param clk_src The clock output signal source
* @param en Enable or disable the clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
switch (clk_src) {
case CLKOUT_SIG_PLL:
PCR.ctrl_clk_out_en.clk160_oen = en;
break;
case CLKOUT_SIG_PLL_F80M:
PCR.ctrl_clk_out_en.clk80_oen = en;
break;
case CLKOUT_SIG_XTAL:
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
break;
default:
break;
}
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store XTAL_CLK frequency in RTC storage register * @brief Store XTAL_CLK frequency in RTC storage register
@@ -781,7 +843,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(
// Read from RTC storage register // Read from RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
} }
// If the format in reg is invalid // If the format in reg is invalid
@@ -813,28 +875,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
return REG_READ(RTC_SLOW_CLK_CAL_REG); return REG_READ(RTC_SLOW_CLK_CAL_REG);
} }
/*
* Enable/Disable the clock gate for clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
switch (clk_src)
{
case CLKOUT_SIG_PLL:
PCR.ctrl_clk_out_en.clk160_oen = en;
break;
case CLKOUT_SIG_PLL_F80M:
PCR.ctrl_clk_out_en.clk80_oen = en;
break;
case CLKOUT_SIG_XTAL:
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
break;
default:
break;
}
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -6,7 +6,6 @@
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/assert.h" #include "hal/assert.h"
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
@@ -69,10 +68,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,8 @@
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/lp_clkrst_struct.h" #include "soc/lp_clkrst_struct.h"
#include "soc/pmu_reg.h" #include "soc/pmu_reg.h"
#include "soc/gpio_ext_reg.h"
#include "hal/clkout_channel.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "hal/assert.h" #include "hal/assert.h"
@@ -19,10 +21,6 @@
#include "esp32c61/rom/rtc.h" #include "esp32c61/rom/rtc.h"
#include "hal/misc.h" #include "hal/misc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80) #define CLK_LL_PLL_80M_FREQ_MHZ (80)
@@ -41,6 +39,10 @@ extern "C" {
// Fix default division factor for the RC_FAST clock for calibration to be 32 // Fix default division factor for the RC_FAST clock for calibration to be 32
#define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5 #define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -555,6 +557,75 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1); HAL_ASSERT(divider == 1);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(GPIO_EXT_PIN_CTRL_REG, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/**
* @brief Enable/Disable the clock gate for clock output signal source
*
* @param clk_src The clock output signal source
* @param en Enable or disable the clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
switch (clk_src) {
case CLKOUT_SIG_PLL_F22M:
PCR.ctrl_clk_out_en.clk22_oen = en;
break;
case CLKOUT_SIG_PLL_F44M:
PCR.ctrl_clk_out_en.clk44_oen = en;
break;
case CLKOUT_SIG_PLL_F40M:
PCR.ctrl_clk_out_en.clk_bb_oen = en;
break;
case CLKOUT_SIG_PLL_F80M:
PCR.ctrl_clk_out_en.clk80_oen = en;
break;
case CLKOUT_SIG_PLL_F160M:
PCR.ctrl_clk_out_en.clk160_oen = en;
break;
case CLKOUT_SIG_XTAL:
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
break;
default:
break;
}
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register * @brief Store RTC_SLOW_CLK calibration value in RTC storage register
@@ -602,36 +673,6 @@ static inline __attribute__((always_inline)) uint64_t clk_ll_rtc_slow_load_rtc_f
return REG_READ(RTC_FIX_US_LOW_REG) | ((uint64_t)REG_READ(RTC_FIX_US_HIGH_REG) << 32); return REG_READ(RTC_FIX_US_LOW_REG) | ((uint64_t)REG_READ(RTC_FIX_US_HIGH_REG) << 32);
} }
/*
* Enable/Disable the clock gate for clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
switch (clk_src)
{
case CLKOUT_SIG_PLL_F22M:
PCR.ctrl_clk_out_en.clk22_oen = en;
break;
case CLKOUT_SIG_PLL_F44M:
PCR.ctrl_clk_out_en.clk44_oen = en;
break;
case CLKOUT_SIG_PLL_F40M:
PCR.ctrl_clk_out_en.clk_bb_oen = en;
break;
case CLKOUT_SIG_PLL_F80M:
PCR.ctrl_clk_out_en.clk80_oen = en;
break;
case CLKOUT_SIG_PLL_F160M:
PCR.ctrl_clk_out_en.clk160_oen = en;
break;
case CLKOUT_SIG_XTAL:
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
break;
default:
break;
}
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -4,11 +4,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/log.h" #include "hal/log.h"
HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal"); HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal");
@@ -34,7 +32,7 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
uint32_t clk_hal_cpu_get_freq_hz(void) uint32_t clk_hal_cpu_get_freq_hz(void)
{ {
soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider(); return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
} }
static uint32_t clk_hal_ahb_get_freq_hz(void) static uint32_t clk_hal_ahb_get_freq_hz(void)
@@ -78,10 +76,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -13,7 +13,6 @@
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "soc/pcr_reg.h" #include "soc/pcr_reg.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/soc_caps.h"
#include "soc/reset_reasons.h" #include "soc/reset_reasons.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/gdma_struct.h" #include "soc/gdma_struct.h"
@@ -27,124 +26,50 @@ extern "C" {
#endif #endif
static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph)
{// ESP32H2-TODO: IDF-6400 {
switch (periph) { switch (periph) {
case PERIPH_SARADC_MODULE: case PERIPH_TIMG0_MODULE:
return PCR_SARADC_CLK_EN; return PCR_TG0_CLK_EN;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG1_MODULE:
return PCR_TG0_CLK_EN; return PCR_TG1_CLK_EN;
case PERIPH_TIMG1_MODULE: case PERIPH_UHCI0_MODULE:
return PCR_TG1_CLK_EN; return PCR_UHCI_CLK_EN;
case PERIPH_UHCI0_MODULE: case PERIPH_SYSTIMER_MODULE:
return PCR_UHCI_CLK_EN; return PCR_SYSTIMER_CLK_EN;
case PERIPH_SYSTIMER_MODULE: default:
return PCR_SYSTIMER_CLK_EN; return 0;
case PERIPH_AES_MODULE:
return PCR_AES_CLK_EN;
case PERIPH_SHA_MODULE:
return PCR_SHA_CLK_EN;
case PERIPH_ECC_MODULE:
return PCR_ECC_CLK_EN;
case PERIPH_RSA_MODULE:
return PCR_RSA_CLK_EN;
case PERIPH_HMAC_MODULE:
return PCR_HMAC_CLK_EN;
case PERIPH_DS_MODULE:
return PCR_DS_CLK_EN;
case PERIPH_ECDSA_MODULE:
return PCR_ECDSA_CLK_EN;
case PERIPH_ASSIST_DEBUG_MODULE:
return PCR_ASSIST_CLK_EN;
default:
return 0;
} }
} }
static inline uint32_t periph_ll_get_rst_en_mask(shared_periph_module_t periph, bool enable) static inline uint32_t periph_ll_get_rst_en_mask(shared_periph_module_t periph, bool enable)
{ {
// ESP32H2-TODO: IDF-6400
(void)enable; // unused (void)enable; // unused
switch (periph) { switch (periph) {
case PERIPH_SARADC_MODULE: case PERIPH_TIMG0_MODULE:
return PCR_SARADC_REG_RST_EN; return PCR_TG0_RST_EN;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG1_MODULE:
return PCR_TG0_RST_EN; return PCR_TG1_RST_EN;
case PERIPH_TIMG1_MODULE: case PERIPH_UHCI0_MODULE:
return PCR_TG1_RST_EN; return PCR_UHCI_RST_EN;
case PERIPH_UHCI0_MODULE: case PERIPH_SYSTIMER_MODULE:
return PCR_UHCI_RST_EN; return PCR_SYSTIMER_RST_EN;
case PERIPH_SYSTIMER_MODULE: default:
return PCR_SYSTIMER_RST_EN; return 0;
case PERIPH_ECC_MODULE:
if (enable == true) {
// Clear reset on ECDSA, otherwise ECC is held in reset
CLEAR_PERI_REG_MASK(PCR_ECDSA_CONF_REG, PCR_ECDSA_RST_EN);
}
return PCR_ECC_RST_EN;
case PERIPH_AES_MODULE:
if (enable == true) {
// Clear reset on digital signature, otherwise AES unit is held in reset
CLEAR_PERI_REG_MASK(PCR_DS_CONF_REG, PCR_DS_RST_EN);
}
return PCR_AES_RST_EN;
case PERIPH_SHA_MODULE:
if (enable == true) {
// Clear reset on digital signature, HMAC, and ECDSA, otherwise SHA is held in reset
CLEAR_PERI_REG_MASK(PCR_DS_CONF_REG, PCR_DS_RST_EN);
CLEAR_PERI_REG_MASK(PCR_HMAC_CONF_REG, PCR_HMAC_RST_EN);
CLEAR_PERI_REG_MASK(PCR_ECDSA_CONF_REG, PCR_ECDSA_RST_EN);
}
return PCR_SHA_RST_EN;
case PERIPH_RSA_MODULE:
if (enable == true) {
// Clear reset on digital signature, and ECDSA, otherwise RSA is held in reset
CLEAR_PERI_REG_MASK(PCR_DS_CONF_REG, PCR_DS_RST_EN);
CLEAR_PERI_REG_MASK(PCR_ECDSA_CONF_REG, PCR_ECDSA_RST_EN);
}
return PCR_RSA_RST_EN;
case PERIPH_HMAC_MODULE:
return PCR_HMAC_RST_EN;
case PERIPH_DS_MODULE:
return PCR_DS_RST_EN;
case PERIPH_ECDSA_MODULE:
return PCR_ECDSA_RST_EN;
case PERIPH_ASSIST_DEBUG_MODULE:
return PCR_ASSIST_RST_EN;
default:
return 0;
} }
} }
static inline uint32_t periph_ll_get_clk_en_reg(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_reg(shared_periph_module_t periph)
{// ESP32H2-TODO: IDF-6400 {
switch (periph) { switch (periph) {
case PERIPH_SARADC_MODULE: case PERIPH_TIMG0_MODULE:
return PCR_SARADC_CONF_REG; return PCR_TIMERGROUP0_CONF_REG;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG1_MODULE:
return PCR_TIMERGROUP0_CONF_REG; return PCR_TIMERGROUP1_CONF_REG;
case PERIPH_TIMG1_MODULE: case PERIPH_UHCI0_MODULE:
return PCR_TIMERGROUP1_CONF_REG; return PCR_UHCI_CONF_REG;
case PERIPH_UHCI0_MODULE: case PERIPH_SYSTIMER_MODULE:
return PCR_UHCI_CONF_REG; return PCR_SYSTIMER_CONF_REG;
case PERIPH_SYSTIMER_MODULE:
return PCR_SYSTIMER_CONF_REG;
case PERIPH_AES_MODULE:
return PCR_AES_CONF_REG;
case PERIPH_SHA_MODULE:
return PCR_SHA_CONF_REG;
case PERIPH_ECC_MODULE:
return PCR_ECC_CONF_REG;
case PERIPH_RSA_MODULE:
return PCR_RSA_CONF_REG;
case PERIPH_HMAC_MODULE:
return PCR_HMAC_CONF_REG;
case PERIPH_DS_MODULE:
return PCR_DS_CONF_REG;
case PERIPH_ECDSA_MODULE:
return PCR_ECDSA_CONF_REG;
case PERIPH_ASSIST_DEBUG_MODULE:
return PCR_ASSIST_CONF_REG;
default: default:
return 0; return 0;
} }
@@ -152,34 +77,15 @@ static inline uint32_t periph_ll_get_clk_en_reg(shared_periph_module_t periph)
static inline uint32_t periph_ll_get_rst_en_reg(shared_periph_module_t periph) static inline uint32_t periph_ll_get_rst_en_reg(shared_periph_module_t periph)
{ {
// ESP32H2-TODO: IDF-6400
switch (periph) { switch (periph) {
case PERIPH_SARADC_MODULE: case PERIPH_TIMG0_MODULE:
return PCR_SARADC_CONF_REG; return PCR_TIMERGROUP0_CONF_REG;
case PERIPH_TIMG0_MODULE: case PERIPH_TIMG1_MODULE:
return PCR_TIMERGROUP0_CONF_REG; return PCR_TIMERGROUP1_CONF_REG;
case PERIPH_TIMG1_MODULE: case PERIPH_UHCI0_MODULE:
return PCR_TIMERGROUP1_CONF_REG; return PCR_UHCI_CONF_REG;
case PERIPH_UHCI0_MODULE: case PERIPH_SYSTIMER_MODULE:
return PCR_UHCI_CONF_REG; return PCR_SYSTIMER_CONF_REG;
case PERIPH_SYSTIMER_MODULE:
return PCR_SYSTIMER_CONF_REG;
case PERIPH_AES_MODULE:
return PCR_AES_CONF_REG;
case PERIPH_SHA_MODULE:
return PCR_SHA_CONF_REG;
case PERIPH_ECC_MODULE:
return PCR_ECC_CONF_REG;
case PERIPH_RSA_MODULE:
return PCR_RSA_CONF_REG;
case PERIPH_HMAC_MODULE:
return PCR_HMAC_CONF_REG;
case PERIPH_DS_MODULE:
return PCR_DS_CONF_REG;
case PERIPH_ECDSA_MODULE:
return PCR_ECDSA_CONF_REG;
case PERIPH_ASSIST_DEBUG_MODULE:
return PCR_ASSIST_CONF_REG;
default: default:
return 0; return 0;
} }
@@ -197,16 +103,6 @@ static inline void periph_ll_disable_clk_set_rst(shared_periph_module_t periph)
SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
} }
static inline void periph_ll_wifi_bt_module_enable_clk(void)
{
// DPORT_SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M);// ESP32H2-TODO: IDF-6400
}
static inline void periph_ll_wifi_bt_module_disable_clk(void)
{
// DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M);// ESP32H2-TODO: IDF-6400
}
static inline void periph_ll_reset(shared_periph_module_t periph) static inline void periph_ll_reset(shared_periph_module_t periph)
{ {
SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
@@ -219,18 +115,6 @@ static inline bool periph_ll_periph_enabled(shared_periph_module_t periph)
REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0; REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0;
} }
static inline void periph_ll_wifi_module_enable_clk_clear_rst(void)
{
// DPORT_SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_EN_M);// ESP32H2-TODO: IDF-6400
// DPORT_CLEAR_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0);
}
static inline void periph_ll_wifi_module_disable_clk_set_rst(void)
{
// DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_EN_M);// ESP32H2-TODO: IDF-6400
// DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0);
}
/** /**
* @brief Configuration structure for peripheral clock gate settings * @brief Configuration structure for peripheral clock gate settings
*/ */
@@ -250,8 +134,7 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason,
&& (rst_reason != RESET_REASON_CPU0_JTAG)) { && (rst_reason != RESET_REASON_CPU0_JTAG)) {
if (config->disable_uart0_clk) { if (config->disable_uart0_clk) {
PCR.uart0_conf.uart0_clk_en = 0; PCR.uart0_conf.uart0_clk_en = 0;
} } else if (config->disable_uart1_clk) {
else if (config->disable_uart1_clk) {
PCR.uart1_conf.uart1_clk_en = 0; PCR.uart1_conf.uart1_clk_en = 0;
} }
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -16,15 +16,13 @@
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/regi2c_pmu.h" #include "soc/regi2c_pmu.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "soc/io_mux_reg.h"
#include "hal/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32h2/rom/rtc.h" #include "esp32h2/rom/rtc.h"
#include "hal/misc.h" #include "hal/misc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_8M_FREQ_MHZ (8) #define CLK_LL_PLL_8M_FREQ_MHZ (8)
@@ -47,6 +45,10 @@ So the frequency division factor of ref_tick must be greater than or equal to 32
#define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5 #define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5
#define REG_FOSC_TICK_NUM 255 #define REG_FOSC_TICK_NUM 255
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -683,6 +685,56 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1); HAL_ASSERT(divider == 1);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(PIN_CTRL, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/**
* @brief Enable/Disable the clock gate for clock output signal source
*
* @param clk_src The clock output signal source
* @param en Enable or disable the clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
if (clk_src == CLKOUT_SIG_XTAL) {
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
}
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store XTAL_CLK frequency in RTC storage register * @brief Store XTAL_CLK frequency in RTC storage register
@@ -718,7 +770,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(
// Read from RTC storage register // Read from RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
} }
// If the format in reg is invalid // If the format in reg is invalid
@@ -750,16 +802,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
return REG_READ(RTC_SLOW_CLK_CAL_REG); return REG_READ(RTC_SLOW_CLK_CAL_REG);
} }
/*
* Enable/Disable the clock gate for clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
if (clk_src == CLKOUT_SIG_XTAL) {
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
}
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -20,10 +20,6 @@
#include "hal/misc.h" #include "hal/misc.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_48M_FREQ_MHZ (48) #define CLK_LL_PLL_48M_FREQ_MHZ (48)
@@ -40,6 +36,10 @@ extern "C" {
// Fix default division factor for the RC_FAST clock for calibration to be 32 // Fix default division factor for the RC_FAST clock for calibration to be 32
#define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5 #define CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS 5
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -7,7 +7,6 @@
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/gpio_ll.h"
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{ {
@@ -68,10 +67,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -6,15 +6,15 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* Enable or disable the clock gate for ref_8m. * Enable or disable the clock gate for ref_8m.
* @param enable Enable / disable * @param enable Enable / disable
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,8 @@
#include "soc/pcr_struct.h" #include "soc/pcr_struct.h"
#include "soc/lp_clkrst_struct.h" #include "soc/lp_clkrst_struct.h"
#include "soc/pmu_reg.h" #include "soc/pmu_reg.h"
#include "soc/gpio_ext_reg.h"
#include "hal/clkout_channel.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "esp32h4/rom/rtc.h" #include "esp32h4/rom/rtc.h"
@@ -19,10 +21,6 @@
#include "hal/log.h" #include "hal/log.h"
#include "hal/misc.h" #include "hal/misc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_8M_FREQ_MHZ (8) #define CLK_LL_PLL_8M_FREQ_MHZ (8)
@@ -38,6 +36,10 @@ extern "C" {
.dbuf = 1, \ .dbuf = 1, \
} }
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -624,6 +626,69 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 4); HAL_ASSERT(divider == 4);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(GPIO_EXT_PIN_CTRL_REG, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/**
* @brief Enable/Disable the clock gate for clock output signal source
*
* @param clk_src The clock output signal source
* @param en Enable or disable the clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
switch (clk_src) {
case CLKOUT_SIG_MODEM_8M:
PCR.ctrl_clk_out_en.clk8_oen = en;
break;
case CLKOUT_SIG_MODEM_16M:
PCR.ctrl_clk_out_en.clk16_oen = en;
break;
case CLKOUT_SIG_MODEM_32M:
PCR.ctrl_clk_out_en.clk32_oen = en;
break;
case CLKOUT_SIG_XTAL:
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
break;
default:
break;
}
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register * @brief Store RTC_SLOW_CLK calibration value in RTC storage register
@@ -671,30 +736,6 @@ static inline __attribute__((always_inline)) uint64_t clk_ll_rtc_slow_load_rtc_f
return REG_READ(RTC_FIX_US_LOW_REG) | ((uint64_t)REG_READ(RTC_FIX_US_HIGH_REG) << 32); return REG_READ(RTC_FIX_US_LOW_REG) | ((uint64_t)REG_READ(RTC_FIX_US_HIGH_REG) << 32);
} }
/*
* Enable/Disable the clock gate for clock output signal source
*/
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
{
switch (clk_src)
{
case CLKOUT_SIG_MODEM_8M:
PCR.ctrl_clk_out_en.clk8_oen = en;
break;
case CLKOUT_SIG_MODEM_16M:
PCR.ctrl_clk_out_en.clk16_oen = en;
break;
case CLKOUT_SIG_MODEM_32M:
PCR.ctrl_clk_out_en.clk32_oen = en;
break;
case CLKOUT_SIG_XTAL:
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
break;
default:
break;
}
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -37,7 +37,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
denominator = 1; denominator = 1;
numerator = 0; numerator = 0;
} }
return clk_hal_soc_root_get_freq_mhz(source) * MHZ * denominator / (integer * denominator + numerator); return clk_hal_soc_root_get_freq_mhz(source) * MHZ * denominator / (integer * denominator + numerator);
} }
static uint32_t clk_hal_mem_get_freq_hz(void) static uint32_t clk_hal_mem_get_freq_hz(void)
@@ -97,17 +97,12 @@ uint32_t clk_hal_apll_get_freq_hz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
clk_ll_set_dbg_clk_ctrl(clk_sig, channel_id); clk_ll_bind_output_channel(clk_sig, channel_id);
clk_ll_set_dbg_clk_channel_divider(channel_id, 1); clk_ll_set_output_channel_divider(channel_id, 1);
clk_ll_enable_dbg_clk_channel(channel_id, true); clk_ll_enable_output_channel(channel_id, true);
}
void clk_hal_clock_output_set_divider(clock_out_channel_t channel_id, uint32_t div_num)
{
clk_ll_set_dbg_clk_channel_divider(channel_id, div_num);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
clk_ll_enable_dbg_clk_channel(channel_id, false); clk_ll_enable_output_channel(channel_id, false);
} }
@@ -6,10 +6,6 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
@@ -32,6 +28,10 @@ extern "C" {
#include "soc/lpperi_reg.h" #include "soc/lpperi_reg.h"
#include "soc/uart_reg.h" #include "soc/uart_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* Enable or disable the clock gate for ref_20m. * Enable or disable the clock gate for ref_20m.
* @param enable Enable / disable * @param enable Enable / disable
@@ -167,7 +167,6 @@ FORCE_INLINE_ATTR void _clk_gate_ll_ref_50m_clk_en(bool enable)
_clk_gate_ll_ref_50m_clk_en(__VA_ARGS__); \ _clk_gate_ll_ref_50m_clk_en(__VA_ARGS__); \
} while(0) } while(0)
/** /**
* @brief Configuration structure for peripheral clock gate settings * @brief Configuration structure for peripheral clock gate settings
*/ */
@@ -191,11 +190,11 @@ typedef struct {
static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason, const periph_ll_clk_gate_config_t *config) static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason, const periph_ll_clk_gate_config_t *config)
{ {
if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CORE_PMU_PWR_DOWN) || if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CORE_PMU_PWR_DOWN) ||
(rst_reason == RESET_REASON_SYS_BROWN_OUT) || (rst_reason == RESET_REASON_SYS_RWDT) || (rst_reason == RESET_REASON_SYS_BROWN_OUT) || (rst_reason == RESET_REASON_SYS_RWDT) ||
(rst_reason == RESET_REASON_SYS_SUPER_WDT) || (rst_reason == RESET_REASON_CORE_SW) || (rst_reason == RESET_REASON_SYS_SUPER_WDT) || (rst_reason == RESET_REASON_CORE_SW) ||
(rst_reason == RESET_REASON_CORE_MWDT) || (rst_reason == RESET_REASON_CORE_RWDT) || (rst_reason == RESET_REASON_CORE_MWDT) || (rst_reason == RESET_REASON_CORE_RWDT) ||
(rst_reason == RESET_REASON_CORE_PWR_GLITCH) || (rst_reason == RESET_REASON_CORE_EFUSE_CRC) || (rst_reason == RESET_REASON_CORE_PWR_GLITCH) || (rst_reason == RESET_REASON_CORE_EFUSE_CRC) ||
(rst_reason == RESET_REASON_CORE_USB_JTAG) || (rst_reason == RESET_REASON_CORE_USB_UART) (rst_reason == RESET_REASON_CORE_USB_JTAG) || (rst_reason == RESET_REASON_CORE_USB_UART)
) { ) {
// Not gate HP_SYS_CLKRST_REG_L2MEM_MEM_CLK_FORCE_ON since the hardware will not automatically ungate when DMA accesses L2 MEM. // Not gate HP_SYS_CLKRST_REG_L2MEM_MEM_CLK_FORCE_ON since the hardware will not automatically ungate when DMA accesses L2 MEM.
REG_CLR_BIT(HP_SYS_CLKRST_CLK_FORCE_ON_CTRL0_REG, REG_CLR_BIT(HP_SYS_CLKRST_CLK_FORCE_ON_CTRL0_REG,
@@ -212,12 +211,12 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason,
// hp_sys_clkrst register gets reset only if chip reset or pmu powers down hp // hp_sys_clkrst register gets reset only if chip reset or pmu powers down hp
// but at core reset and above, we will also disable HP modules' clock gating to save power consumption // but at core reset and above, we will also disable HP modules' clock gating to save power consumption
REG_CLR_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG, REG_CLR_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG,
HP_SYS_CLKRST_REG_AHB_PDMA_SYS_CLK_EN | HP_SYS_CLKRST_REG_AHB_PDMA_SYS_CLK_EN |
HP_SYS_CLKRST_REG_AXI_PDMA_SYS_CLK_EN | HP_SYS_CLKRST_REG_AXI_PDMA_SYS_CLK_EN |
HP_SYS_CLKRST_REG_REGDMA_SYS_CLK_EN | HP_SYS_CLKRST_REG_REGDMA_SYS_CLK_EN |
HP_SYS_CLKRST_REG_BITSCRAMBLER_SYS_CLK_EN | HP_SYS_CLKRST_REG_BITSCRAMBLER_SYS_CLK_EN |
HP_SYS_CLKRST_REG_BITSCRAMBLER_RX_SYS_CLK_EN | HP_SYS_CLKRST_REG_BITSCRAMBLER_RX_SYS_CLK_EN |
HP_SYS_CLKRST_REG_BITSCRAMBLER_TX_SYS_CLK_EN); HP_SYS_CLKRST_REG_BITSCRAMBLER_TX_SYS_CLK_EN);
// HP_SYS_CLKRST_REG_PARLIO_SYS_CLK_EN, HP_SYS_CLKRST_REG_ETM_SYS_CLK_EN default to 0, removed // HP_SYS_CLKRST_REG_PARLIO_SYS_CLK_EN, HP_SYS_CLKRST_REG_ETM_SYS_CLK_EN default to 0, removed
// HP_SYS_CLKRST_REG_PARLIO_APB_CLK_EN, HP_SYS_CLKRST_REG_ETM_APB_CLK_EN default to 0, removed // HP_SYS_CLKRST_REG_PARLIO_APB_CLK_EN, HP_SYS_CLKRST_REG_ETM_APB_CLK_EN default to 0, removed
@@ -290,8 +289,8 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason,
REG_CLR_BIT(HP_SYS_CLKRST_PERI_CLK_CTRL117_REG, HP_SYS_CLKRST_REG_GPSPI3_MST_CLK_EN); REG_CLR_BIT(HP_SYS_CLKRST_PERI_CLK_CTRL117_REG, HP_SYS_CLKRST_REG_GPSPI3_MST_CLK_EN);
if (config->disable_assist_clk) { if (config->disable_assist_clk) {
/* Disable ASSIST Debug module clock if PC recoreding function is not used, /* 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 */ * if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */
REG_CLR_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_BUSMON_CPU_CLK_EN); REG_CLR_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_BUSMON_CPU_CLK_EN);
REG_CLR_BIT(ASSIST_DEBUG_CLOCK_GATE_REG, ASSIST_DEBUG_CLK_EN); REG_CLR_BIT(ASSIST_DEBUG_CLOCK_GATE_REG, ASSIST_DEBUG_CLK_EN);
} }
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -7,7 +7,6 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include "soc/clkout_channel.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/chip_revision.h" #include "soc/chip_revision.h"
#include "soc/clk_tree_defs.h" #include "soc/clk_tree_defs.h"
@@ -16,6 +15,7 @@
#include "soc/lp_clkrst_reg.h" #include "soc/lp_clkrst_reg.h"
#include "soc/lp_clkrst_struct.h" #include "soc/lp_clkrst_struct.h"
#include "soc/pmu_reg.h" #include "soc/pmu_reg.h"
#include "hal/clkout_channel.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_cpll.h" #include "soc/regi2c_cpll.h"
#include "soc/regi2c_apll.h" #include "soc/regi2c_apll.h"
@@ -28,10 +28,6 @@
#include "hal/efuse_hal.h" #include "hal/efuse_hal.h"
#include "esp_private/regi2c_ctrl.h" #include "esp_private/regi2c_ctrl.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_8M_FREQ_MHZ (8) #define CLK_LL_PLL_8M_FREQ_MHZ (8)
@@ -74,6 +70,10 @@ extern "C" {
.dbuf = 1, \ .dbuf = 1, \
} }
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -92,7 +92,6 @@ typedef struct {
uint32_t dbuf: 1; uint32_t dbuf: 1;
} clk_ll_xtal32k_config_t; } clk_ll_xtal32k_config_t;
/** /**
* @brief Power up CPLL circuit * @brief Power up CPLL circuit
*/ */
@@ -418,7 +417,7 @@ static inline __attribute__((always_inline)) void clk_ll_cpll_set_config(uint32_
uint8_t i2c_cpll_lref = (oc_enb_fcal << I2C_CPLL_OC_ENB_FCAL_LSB) | (dchgp << I2C_CPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_cpll_lref = (oc_enb_fcal << I2C_CPLL_OC_ENB_FCAL_LSB) | (dchgp << I2C_CPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_cpll_div_7_0 = div7_0; uint8_t i2c_cpll_div_7_0 = div7_0;
uint8_t i2c_cpll_dcur = (1 << I2C_CPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_CPLL_OC_DHREF_SEL_LSB) | dcur; uint8_t i2c_cpll_dcur = (1 << I2C_CPLL_OC_DLREF_SEL_LSB) | (3 << I2C_CPLL_OC_DHREF_SEL_LSB) | dcur;
// There are sequential regi2c operations in `clk_ll_cpll_set_config`, use the raw regi2c API with one lock wrapper to save time. // There are sequential regi2c operations in `clk_ll_cpll_set_config`, use the raw regi2c API with one lock wrapper to save time.
REGI2C_ENTER_CRITICAL(); REGI2C_ENTER_CRITICAL();
esp_rom_regi2c_write(I2C_CPLL, I2C_CPLL_HOSTID, I2C_CPLL_OC_REF_DIV, i2c_cpll_lref); esp_rom_regi2c_write(I2C_CPLL, I2C_CPLL_HOSTID, I2C_CPLL_OC_REF_DIV, i2c_cpll_lref);
@@ -972,6 +971,58 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1); HAL_ASSERT(divider == 1);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
if (channel_id == CLKOUT_CHANNEL_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_sel, clk_sig);
} else if (channel_id == CLKOUT_CHANNEL_2) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch1_sel, clk_sig);
} else {
abort();
}
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
if (channel_id == CLKOUT_CHANNEL_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch0_en, enable);
} else if (channel_id == CLKOUT_CHANNEL_2) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_en, enable);
} else {
abort();
}
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t div_num)
{
if (channel_id == CLKOUT_CHANNEL_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_div_num, div_num - 1);
} else if (channel_id == CLKOUT_CHANNEL_2) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_div_num, div_num - 1);
} else {
abort();
}
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store XTAL_CLK frequency in RTC storage register * @brief Store XTAL_CLK frequency in RTC storage register
@@ -1007,7 +1058,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(
// Read from RTC storage register // Read from RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
} }
// If the format in reg is invalid // If the format in reg is invalid
@@ -1039,53 +1090,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
return REG_READ(RTC_SLOW_CLK_CAL_REG); return REG_READ(RTC_SLOW_CLK_CAL_REG);
} }
/**
* @brief Clock output channel configuration
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel to setup
*/
static inline __attribute__((always_inline)) void clk_ll_set_dbg_clk_ctrl(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
if (channel_id == CLKOUT_CHANNEL_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_sel, clk_sig);
} else if (channel_id == CLKOUT_CHANNEL_2) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch1_sel, clk_sig);
} else {
abort();
}
}
/**
* @brief Enable the clock output channel
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_dbg_clk_channel(clock_out_channel_t channel_id, bool enable)
{
if (channel_id == CLKOUT_CHANNEL_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch0_en, enable);
} else if (channel_id == CLKOUT_CHANNEL_2) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_en, enable);
} else {
abort();
}
}
/**
* @brief Output the mapped clock after frequency division
* @param channel_id channel id that need to be configured with frequency division
* @param div_num clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_dbg_clk_channel_divider(clock_out_channel_t channel_id, uint32_t div_num)
{
if (channel_id == CLKOUT_CHANNEL_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_div_num, div_num - 1);
} else if (channel_id == CLKOUT_CHANNEL_2) {
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_div_num, div_num - 1);
} else {
abort();
}
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -4,11 +4,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/log.h" #include "hal/log.h"
HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal"); HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal");
@@ -116,10 +114,10 @@ uint32_t clk_hal_apll_get_freq_hz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -6,10 +6,6 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
@@ -18,7 +14,10 @@ extern "C" {
#include "soc/system_reg.h" #include "soc/system_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#include "soc/dport_access.h" #include "soc/dport_access.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph)
{ {
@@ -125,7 +124,7 @@ static inline void periph_ll_reset(shared_periph_module_t periph)
static inline bool IRAM_ATTR periph_ll_periph_enabled(shared_periph_module_t periph) static inline bool IRAM_ATTR periph_ll_periph_enabled(shared_periph_module_t periph)
{ {
return DPORT_REG_GET_BIT(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)) == 0 && return DPORT_REG_GET_BIT(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)) == 0 &&
DPORT_REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0; DPORT_REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0;
} }
static inline void periph_ll_wifi_module_enable_clk_clear_rst(void) static inline void periph_ll_wifi_module_enable_clk_clear_rst(void)
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,6 +12,8 @@
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#include "soc/io_mux_reg.h"
#include "hal/clkout_channel.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/regi2c_apll.h" #include "soc/regi2c_apll.h"
@@ -19,10 +21,6 @@
#include "hal/assert.h" #include "hal/assert.h"
#include "esp32s2/rom/rtc.h" #include "esp32s2/rom/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80) #define CLK_LL_PLL_80M_FREQ_MHZ (80)
@@ -67,6 +65,10 @@ extern "C" {
.dbuf = 1, \ .dbuf = 1, \
} }
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -429,7 +431,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32
} }
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_bbpll_div_7_0 = div7_0; uint8_t i2c_bbpll_div_7_0 = div7_0;
uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
@@ -760,6 +762,43 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD); SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(PIN_CTRL, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/ /************************* RTC STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store APB_CLK frequency in RTC storage register * @brief Store APB_CLK frequency in RTC storage register
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -4,11 +4,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/log.h" #include "hal/log.h"
HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal"); HAL_LOG_ATTR_TAG(CLK_HAL_TAG, "clk_hal");
@@ -93,10 +91,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(clk_sig, channel_id);
} }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id) void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ {
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id)); clk_ll_bind_output_channel(0, channel_id);
} }
@@ -6,10 +6,6 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_attr.h" #include "esp_attr.h"
@@ -18,7 +14,10 @@ extern "C" {
#include "soc/system_reg.h" #include "soc/system_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#include "soc/dport_access.h" #include "soc/dport_access.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph) static inline uint32_t periph_ll_get_clk_en_mask(shared_periph_module_t periph)
{ {
@@ -56,7 +55,7 @@ static inline uint32_t periph_ll_get_rst_en_mask(shared_periph_module_t periph,
case PERIPH_WIFI_MODULE: case PERIPH_WIFI_MODULE:
return SYSTEM_WIFIMAC_RST; return SYSTEM_WIFIMAC_RST;
case PERIPH_BT_MODULE: case PERIPH_BT_MODULE:
return (SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST); return (SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST);
case PERIPH_UART1_MODULE: case PERIPH_UART1_MODULE:
return SYSTEM_UART1_RST; return SYSTEM_UART1_RST;
case PERIPH_UART2_MODULE: case PERIPH_UART2_MODULE:
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -14,14 +14,12 @@
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "soc/io_mux_reg.h"
#include "hal/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32s3/rom/rtc.h" #include "esp32s3/rom/rtc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80) #define CLK_LL_PLL_80M_FREQ_MHZ (80)
@@ -44,6 +42,10 @@ extern "C" {
.dbuf = 1, \ .dbuf = 1, \
} }
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -375,7 +377,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32
} }
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_bbpll_div_7_0 = div7_0; uint8_t i2c_bbpll_div_7_0 = div7_0;
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
@@ -637,6 +639,43 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD); SET_PERI_REG_MASK(RTC_CNTL_SLOW_CLK_CONF_REG, RTC_CNTL_ANA_CLK_DIV_VLD);
} }
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs
* @param channel_id The clock output channel ID
*/
static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
SET_PERI_REG_BITS(PIN_CTRL, CLKOUT_CHANNEL_MASK(channel_id), clk_sig, CLKOUT_CHANNEL_SHIFT(channel_id));
}
/**
* @brief Enable the clock output channel
*
* @param channel_id The clock output channel ID
* @param enable Enable or disable the clock output channel
*/
static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
{
// No such gating on the target
(void)channel_id;
(void)enable;
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param divider Clock frequency division value
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
}
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/ /************************* RTC STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store XTAL_CLK frequency in RTC storage register * @brief Store XTAL_CLK frequency in RTC storage register
@@ -672,7 +711,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(
// Read from the RTC storage register // Read from the RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
} }
// If the format in reg is invalid // If the format in reg is invalid
@@ -732,7 +771,7 @@ void clk_ll_bbpll_set_frequency_for_mspi_tuning(soc_xtal_freq_t xtal_freq, int p
uint8_t i2c_bbpll_div_7_0 = oc_div; uint8_t i2c_bbpll_div_7_0 = oc_div;
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
@@ -743,7 +782,6 @@ void clk_ll_bbpll_set_frequency_for_mspi_tuning(soc_xtal_freq_t xtal_freq, int p
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1);
} }
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -1,7 +1,7 @@
/* /*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -39,7 +39,7 @@ uint32_t clk_hal_cpu_get_freq_hz(void)
denominator = 1; denominator = 1;
numerator = 0; numerator = 0;
} }
return clk_hal_soc_root_get_freq_mhz(source) * MHZ * denominator / (integer * denominator + numerator); return clk_hal_soc_root_get_freq_mhz(source) * MHZ * denominator / (integer * denominator + numerator);
} }
static uint32_t clk_hal_mem_get_freq_hz(void) static uint32_t clk_hal_mem_get_freq_hz(void)
@@ -47,7 +47,7 @@ static uint32_t clk_hal_mem_get_freq_hz(void)
return clk_hal_cpu_get_freq_hz() / clk_ll_mem_get_divider(); return clk_hal_cpu_get_freq_hz() / clk_ll_mem_get_divider();
} }
static uint32_t clk_hal_sys_get_freq_hz(void) uint32_t clk_hal_sys_get_freq_hz(void)
{ {
return clk_hal_mem_get_freq_hz() / clk_ll_sys_get_divider(); return clk_hal_mem_get_freq_hz() / clk_ll_sys_get_divider();
} }
@@ -97,19 +97,14 @@ uint32_t clk_hal_apll_get_freq_hz(void)
return apll_freq_hz; return apll_freq_hz;
} }
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id) // void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{ // {
clk_ll_set_dbg_clk_ctrl(clk_sig, channel_id); // clk_ll_bind_output_channel(clk_sig, channel_id);
clk_ll_set_dbg_clk_channel_divider(channel_id, 1); // clk_ll_set_output_channel_divider(channel_id, 1);
clk_ll_enable_dbg_clk_channel(channel_id, true); // clk_ll_enable_output_channel(channel_id, true);
} // }
void clk_hal_clock_output_set_divider(clock_out_channel_t channel_id, uint32_t div_num) // void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{ // {
clk_ll_set_dbg_clk_channel_divider(channel_id, div_num); // clk_ll_enable_output_channel(channel_id, false);
} // }
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{
clk_ll_enable_dbg_clk_channel(channel_id, false);
}
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -16,17 +16,13 @@
#include "soc/lp_clkrst_struct.h" #include "soc/lp_clkrst_struct.h"
#include "soc/hp_alive_sys_reg.h" #include "soc/hp_alive_sys_reg.h"
#include "soc/pmu_reg.h" #include "soc/pmu_reg.h"
// #include "hal/clkout_channel.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32s31/rom/rtc.h" #include "esp32s31/rom/rtc.h"
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/efuse_hal.h" #include "hal/efuse_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MHZ (1000000) #define MHZ (1000000)
#define CLK_LL_PLL_8M_FREQ_MHZ (8) #define CLK_LL_PLL_8M_FREQ_MHZ (8)
@@ -68,6 +64,10 @@ extern "C" {
.dbuf = 1, \ .dbuf = 1, \
} }
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
*/ */
@@ -86,7 +86,6 @@ typedef struct {
uint32_t dbuf: 1; uint32_t dbuf: 1;
} clk_ll_xtal32k_config_t; } clk_ll_xtal32k_config_t;
/** /**
* @brief Power up CPLL circuit * @brief Power up CPLL circuit
*/ */
@@ -755,6 +754,58 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1); HAL_ASSERT(divider == 1);
} }
/************************** CLOCK OUTPUT **************************/
// /**
// * @brief Clock output channel configuration
// *
// * @param clk_sig The clock signal source to be mapped to GPIOs
// * @param channel_id The clock output channel ID
// */
// static inline __attribute__((always_inline)) void clk_ll_bind_output_channel(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
// {
// if (channel_id == CLKOUT_CHANNEL_1) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_sel, clk_sig);
// } else if (channel_id == CLKOUT_CHANNEL_2) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch1_sel, clk_sig);
// } else {
// abort();
// }
// }
// /**
// * @brief Enable the clock output channel
// *
// * @param channel_id The clock output channel ID
// * @param enable Enable or disable the clock output channel
// */
// static inline __attribute__((always_inline)) void clk_ll_enable_output_channel(clock_out_channel_t channel_id, bool enable)
// {
// if (channel_id == CLKOUT_CHANNEL_1) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch0_en, enable);
// } else if (channel_id == CLKOUT_CHANNEL_2) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_en, enable);
// } else {
// abort();
// }
// }
// /**
// * @brief Output the mapped clock after frequency division
// *
// * @param channel_id The clock output channel ID
// * @param divider Clock frequency division value
// */
// static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t div_num)
// {
// if (channel_id == CLKOUT_CHANNEL_1) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_div_num, div_num - 1);
// } else if (channel_id == CLKOUT_CHANNEL_2) {
// HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_div_num, div_num - 1);
// } else {
// abort();
// }
// }
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store XTAL_CLK frequency in RTC storage register * @brief Store XTAL_CLK frequency in RTC storage register
@@ -817,17 +868,16 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
* *
* @return The value used to correct the time obtained from the rtc timer when the calibration value changes * @return The value used to correct the time obtained from the rtc timer when the calibration value changes
*/ */
static inline __attribute__((always_inline)) uint64_t clk_ll_rtc_slow_load_rtc_fix_us(void) static inline __attribute__((always_inline)) uint64_t clk_ll_rtc_slow_load_rtc_fix_us(void)
{ {
return 0;// TODO: [ESP32S31] IDF-14733 return 0;// TODO: [ESP32S31] IDF-14733
} }
/**
/** * @brief Store rtc_fix_us in RTC storage register
* @brief Store rtc_fix_us in RTC storage register *
* * @param rtc_fix_us The value used to correct the time obtained from the rtc timer when the calibration value changes
* @param rtc_fix_us The value used to correct the time obtained from the rtc timer when the calibration value changes */
*/
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_store_rtc_fix_us(uint64_t rtc_fix_us) static inline __attribute__((always_inline)) void clk_ll_rtc_slow_store_rtc_fix_us(uint64_t rtc_fix_us)
{ {
// TODO: [ESP32S31] IDF-14733 // TODO: [ESP32S31] IDF-14733
@@ -11,7 +11,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#if SOC_GPIO_CLOCKOUT_CHANNEL_NUM > 0 //TODO: [ESP32H21] IDF-11582 #if SOC_GPIO_CLOCKOUT_CHANNEL_NUM > 0 //TODO: [ESP32H21] IDF-11582
#include "soc/clkout_channel.h" #include "hal/clkout_channel.h"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@@ -79,15 +79,6 @@ uint32_t clk_hal_apll_get_freq_hz(void);
*/ */
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id); void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id);
#if SOC_CLOCKOUT_SUPPORT_CHANNEL_DIVIDER
/**
* @brief Output the mapped clock after frequency division
* @param channel_id channel id that need to be configured with frequency division
* @param div_num clock frequency division value
*/
void clk_hal_clock_output_set_divider(clock_out_channel_t channel_id, uint32_t div_num);
#endif
/** /**
* @brief Teardown clock output channel configuration * @brief Teardown clock output channel configuration
* @param channel_id The clock output channel to teardown * @param channel_id The clock output channel to teardown
@@ -737,19 +737,6 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -543,19 +543,6 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
}
/** /**
* @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
@@ -540,19 +540,6 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
}
/** /**
* @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
@@ -17,7 +17,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/gpio_ext_reg.h"
#include "soc/gpio_struct.h" #include "soc/gpio_struct.h"
#include "soc/lp_aon_struct.h" #include "soc/lp_aon_struct.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
@@ -719,19 +718,6 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num
IO_MUX.gpio[gpio_num].mcu_oe = 1; IO_MUX.gpio[gpio_num].mcu_oe = 1;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(GPIO_EXT_PIN_CTRL_REG, bmap, val, shift);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -501,19 +501,6 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
hw->func_out_sel_cfg[gpio_num].out_inv_sel = out_inv; hw->func_out_sel_cfg[gpio_num].out_inv_sel = out_inv;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
}
/** /**
* @brief Select a function for the pin in the IOMUX * @brief Select a function for the pin in the IOMUX
* *
@@ -17,7 +17,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/gpio_ext_reg.h"
#include "soc/gpio_struct.h" #include "soc/gpio_struct.h"
#include "soc/lp_aon_struct.h" #include "soc/lp_aon_struct.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
@@ -719,18 +718,6 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num
IO_MUX.gpion[gpio_num].gpion_mcu_oe = 1; IO_MUX.gpion[gpio_num].gpion_mcu_oe = 1;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(GPIO_EXT_PIN_CTRL_REG, bmap, val, shift);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -564,19 +564,6 @@ static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t f
PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func); PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
}
/** /**
* @brief Set clock source of IO MUX module * @brief Set clock source of IO MUX module
* *
@@ -15,7 +15,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/gpio_ext_reg.h"
#include "soc/gpio_struct.h" #include "soc/gpio_struct.h"
#include "soc/lp_aon_struct.h" #include "soc/lp_aon_struct.h"
#include "soc/pmu_struct.h" #include "soc/pmu_struct.h"
@@ -735,19 +734,6 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num
IO_MUX.gpio[gpio_num].mcu_oe = 1; IO_MUX.gpio[gpio_num].mcu_oe = 1;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(GPIO_EXT_PIN_CTRL_REG, bmap, val, shift);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -553,19 +553,6 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
}
/** /**
* @brief Force hold digital gpio pad. * @brief Force hold digital gpio pad.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
@@ -554,19 +554,6 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3
hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv;
} }
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
}
/** /**
* @brief Force hold digital gpio pad. * @brief Force hold digital gpio pad.
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
@@ -1,3 +1,3 @@
idf_component_register(SRCS "hal_i2c.c" idf_component_register(SRCS "hal_i2c.c"
PRIV_REQUIRES esp_hal_i2c PRIV_REQUIRES esp_hal_i2c esp_hal_clock
INCLUDE_DIRS ".") INCLUDE_DIRS ".")
+1 -1
View File
@@ -35,6 +35,6 @@ list(APPEND srcs "${target}/mspi_periph.c")
idf_component_register( idf_component_register(
SRCS ${srcs} SRCS ${srcs}
INCLUDE_DIRS ${includes} INCLUDE_DIRS ${includes}
REQUIRES soc hal esp_hal_gpspi REQUIRES soc hal esp_hal_gpspi esp_hal_clock # TODO: IDF-15106 remove esp_hal_clock dependency
PRIV_REQUIRES esp_hal_gpio PRIV_REQUIRES esp_hal_gpio
) )
@@ -8,8 +8,7 @@
#include "soc/soc.h" #include "soc/soc.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "hal/clk_tree_ll.h" #include "soc/rtc_cntl_reg.h"
#include "esp_rom_sys.h"
#include "hal/assert.h" #include "hal/assert.h"
#ifdef __cplusplus #ifdef __cplusplus
+1 -1
View File
@@ -11,7 +11,7 @@ endif()
set(requires esp_hal_dma esp_hal_gpio esp_hal_usb esp_hal_pmu) set(requires esp_hal_dma esp_hal_gpio esp_hal_usb esp_hal_pmu)
# only esp_hw_support/adc_share_hw_ctrl.c requires efuse component # only esp_hw_support/adc_share_hw_ctrl.c requires efuse component
set(priv_requires efuse spi_flash bootloader_support esp_hal_wdt esp_hal_rtc_timer) set(priv_requires efuse spi_flash bootloader_support esp_hal_wdt esp_hal_rtc_timer esp_hal_clock)
set(srcs "cpu.c" "port/${IDF_TARGET}/esp_cpu_intr.c" "esp_memory_utils.c" "port/${IDF_TARGET}/cpu_region_protect.c") set(srcs "cpu.c" "port/${IDF_TARGET}/esp_cpu_intr.c" "esp_memory_utils.c" "port/${IDF_TARGET}/cpu_region_protect.c")
if(NOT non_os_build) if(NOT non_os_build)
+6 -6
View File
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -12,7 +12,7 @@
#include "esp_clock_output.h" #include "esp_clock_output.h"
#include "esp_check.h" #include "esp_check.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "soc/clkout_channel.h" #include "hal/clkout_channel.h"
#include "hal/gpio_hal.h" #include "hal/gpio_hal.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
@@ -233,7 +233,7 @@ esp_err_t esp_clock_output_set_divider(esp_clock_output_mapping_handle_t clkout_
ESP_RETURN_ON_FALSE(((div_num > 0) && (div_num <= 256)), ESP_ERR_INVALID_ARG, TAG, "Divider number must be in the range of [1, 256]"); ESP_RETURN_ON_FALSE(((div_num > 0) && (div_num <= 256)), ESP_ERR_INVALID_ARG, TAG, "Divider number must be in the range of [1, 256]");
ESP_RETURN_ON_FALSE((clkout_mapping_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Clock out mapping handle passed in is invalid"); ESP_RETURN_ON_FALSE((clkout_mapping_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Clock out mapping handle passed in is invalid");
esp_os_enter_critical(&clkout_mapping_hdl->clkout_mapping_lock); esp_os_enter_critical(&clkout_mapping_hdl->clkout_mapping_lock);
clk_hal_clock_output_set_divider(clkout_mapping_hdl->clkout_channel_hdl->channel_id, div_num); clk_ll_set_output_channel_divider(clkout_mapping_hdl->clkout_channel_hdl->channel_id, div_num);
esp_os_exit_critical(&clkout_mapping_hdl->clkout_mapping_lock); esp_os_exit_critical(&clkout_mapping_hdl->clkout_mapping_lock);
return ESP_OK; return ESP_OK;
} }
@@ -244,8 +244,8 @@ esp_err_t esp_clock_output_set_divider(esp_clock_output_mapping_handle_t clkout_
__attribute__((constructor)) __attribute__((constructor))
static void esp_clock_output_pin_ctrl_init(void) static void esp_clock_output_pin_ctrl_init(void)
{ {
gpio_ll_set_pin_ctrl(0, CLK_OUT1, CLK_OUT1_S); clk_ll_bind_output_channel(0, CLKOUT_CHANNEL_1);
gpio_ll_set_pin_ctrl(0, CLK_OUT2, CLK_OUT2_S); clk_ll_bind_output_channel(0, CLKOUT_CHANNEL_2);
gpio_ll_set_pin_ctrl(0, CLK_OUT3, CLK_OUT3_S); clk_ll_bind_output_channel(0, CLKOUT_CHANNEL_3);
} }
#endif #endif
-7
View File
@@ -26,7 +26,6 @@
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "soc/rtc.h" #include "soc/rtc.h"
#include "hal/clk_tree_ll.h"
#include "hal/uart_ll.h" #include "hal/uart_ll.h"
#include "hal/uart_types.h" #include "hal/uart_types.h"
@@ -55,12 +54,6 @@
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#if SOC_PERIPH_CLK_CTRL_SHARED
#define HP_UART_SRC_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define HP_UART_SRC_CLK_ATOMIC()
#endif
#define MHZ (1000000) #define MHZ (1000000)
#ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT #ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
+1 -1
View File
@@ -75,7 +75,7 @@ else()
idf_component_register(SRCS "${srcs}" idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS include INCLUDE_DIRS include
PRIV_REQUIRES spi_flash esp_timer esp_mm esp_hal_mspi esp_hal_wdt esp_hal_uart PRIV_REQUIRES spi_flash esp_timer esp_mm esp_hal_mspi esp_hal_wdt esp_hal_uart esp_hal_clock
# [refactor-todo] requirements due to init code, # [refactor-todo] requirements due to init code,
# should be removable once using component init functions # should be removable once using component init functions
# link-time registration is used. # link-time registration is used.
-4
View File
@@ -67,10 +67,6 @@ if(esp_tee_build)
elseif(NOT BOOTLOADER_BUILD) elseif(NOT BOOTLOADER_BUILD)
list(APPEND srcs "color_hal.c") list(APPEND srcs "color_hal.c")
if(CONFIG_SOC_CLK_TREE_SUPPORTED)
list(APPEND srcs "${target}/clk_tree_hal.c")
endif()
if(CONFIG_SOC_SYSTIMER_SUPPORTED AND NOT CONFIG_HAL_SYSTIMER_USE_ROM_IMPL) if(CONFIG_SOC_SYSTIMER_SUPPORTED AND NOT CONFIG_HAL_SYSTIMER_USE_ROM_IMPL)
list(APPEND srcs "systimer_hal.c") list(APPEND srcs "systimer_hal.c")
endif() endif()
+3 -5
View File
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -9,7 +9,7 @@
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/efuse_hal.h" #include "hal/efuse_hal.h"
#include "hal/efuse_ll.h" #include "hal/efuse_ll.h"
#include "hal/clk_tree_ll.h" #include "hal/config.h"
#include "esp_attr.h" #include "esp_attr.h"
#define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x0F << (4 * (block)))) #define ESP_EFUSE_BLOCK_ERROR_BITS(error_reg, block) ((error_reg) & (0x0F << (4 * (block))))
@@ -33,11 +33,9 @@ void efuse_hal_set_timing(uint32_t apb_freq_hz)
efuse_ll_set_dac_clk_div(0x28); efuse_ll_set_dac_clk_div(0x28);
efuse_ll_set_pwr_on_num(0x3000); efuse_ll_set_pwr_on_num(0x3000);
efuse_ll_set_pwr_off_num(0x190); efuse_ll_set_pwr_off_num(0x190);
int xtal = clk_ll_xtal_load_freq_mhz();
HAL_ASSERT(xtal == 40 || xtal == 26);
// for the XTAL = 40 MHz we use the default value = 200. // for the XTAL = 40 MHz we use the default value = 200.
// XTAL = 26 MHz the value = 130. // XTAL = 26 MHz the value = 130.
efuse_ll_set_tpgm_inactive(xtal * 5); efuse_ll_set_tpgm_inactive(HAL_CONFIG(XTAL_HINT_FREQ_MHZ) * 5);
} }
void efuse_hal_read(void) void efuse_hal_read(void)
@@ -91,6 +91,7 @@ extern "C" {
#define SDMMC_LL_HOST_CTLR_NUMS 1U #define SDMMC_LL_HOST_CTLR_NUMS 1U
#define SDMMC_LL_DELAY_MAX_NUMS_LS 4 #define SDMMC_LL_DELAY_MAX_NUMS_LS 4
#define SDMMC_LL_DELAY_PHASE_SUPPORTED 1 #define SDMMC_LL_DELAY_PHASE_SUPPORTED 1
#define SDMMC_LL_SDIO_PLL_SUPPORTED 1
/** /**
* SDMMC delay phase * SDMMC delay phase
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0 OR MIT
*/ */
@@ -17,16 +17,7 @@ typedef enum {
PERIPH_TIMG0_MODULE, PERIPH_TIMG0_MODULE,
PERIPH_TIMG1_MODULE, PERIPH_TIMG1_MODULE,
PERIPH_UHCI0_MODULE, PERIPH_UHCI0_MODULE,
PERIPH_RSA_MODULE,
PERIPH_AES_MODULE,
PERIPH_SHA_MODULE,
PERIPH_ECC_MODULE,
PERIPH_HMAC_MODULE,
PERIPH_DS_MODULE,
PERIPH_SDIO_SLAVE_MODULE,
PERIPH_SYSTIMER_MODULE, PERIPH_SYSTIMER_MODULE,
PERIPH_SARADC_MODULE,
PERIPH_ASSIST_DEBUG_MODULE,
/* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */ /* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */
PERIPH_WIFI_MODULE, PERIPH_WIFI_MODULE,
PERIPH_BT_MODULE, PERIPH_BT_MODULE,
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0 OR MIT
*/ */
@@ -16,16 +16,7 @@ typedef enum {
PERIPH_TIMG0_MODULE, PERIPH_TIMG0_MODULE,
PERIPH_TIMG1_MODULE, PERIPH_TIMG1_MODULE,
PERIPH_UHCI0_MODULE, PERIPH_UHCI0_MODULE,
PERIPH_RSA_MODULE,
PERIPH_AES_MODULE,
PERIPH_SHA_MODULE,
PERIPH_ECC_MODULE,
PERIPH_HMAC_MODULE,
PERIPH_DS_MODULE,
PERIPH_ECDSA_MODULE,
PERIPH_SYSTIMER_MODULE, PERIPH_SYSTIMER_MODULE,
PERIPH_SARADC_MODULE,
PERIPH_ASSIST_DEBUG_MODULE,
/* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */ /* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */
PERIPH_BT_MODULE, PERIPH_BT_MODULE,
PERIPH_IEEE802154_MODULE, PERIPH_IEEE802154_MODULE,
@@ -1843,10 +1843,6 @@ config SOC_CLK_MPLL_SUPPORTED
bool bool
default y default y
config SOC_CLK_SDIO_PLL_SUPPORTED
bool
default y
config SOC_CLK_XTAL32K_SUPPORTED config SOC_CLK_XTAL32K_SUPPORTED
bool bool
default y default y
@@ -696,7 +696,6 @@
#define SOC_CLK_APLL_SUPPORTED (1) /*!< Support Audio PLL */ #define SOC_CLK_APLL_SUPPORTED (1) /*!< Support Audio PLL */
#define SOC_CLK_MPLL_SUPPORTED (1) /*!< Support MSPI PLL */ #define SOC_CLK_MPLL_SUPPORTED (1) /*!< Support MSPI PLL */
#define SOC_CLK_SDIO_PLL_SUPPORTED (1) /*!< Support SDIO PLL */
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */ #define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */ #define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
@@ -427,10 +427,6 @@ config SOC_CLK_APLL_SUPPORTED
bool bool
default y default y
config SOC_CLK_SDIO_PLL_SUPPORTED
bool
default y
config SOC_CLK_RC32K_SUPPORTED config SOC_CLK_RC32K_SUPPORTED
bool bool
default y default y
@@ -282,7 +282,6 @@
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (1) #define SOC_MODEM_CLOCK_IS_INDEPENDENT (1)
#define SOC_CLK_APLL_SUPPORTED (1) /*!< Support Audio PLL */ #define SOC_CLK_APLL_SUPPORTED (1) /*!< Support Audio PLL */
#define SOC_CLK_SDIO_PLL_SUPPORTED (1) /*!< Support SDIO PLL */
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */ #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_LP_PLL (1) /*!< Support LP_PLL clock as the LP_FAST clock source */
+1 -1
View File
@@ -98,5 +98,5 @@ idf_component_register(
SRCS ${srcs} SRCS ${srcs}
INCLUDE_DIRS ${includes} INCLUDE_DIRS ${includes}
REQUIRES esp_adc esp_driver_gpio esp_driver_uart esp_driver_i2s REQUIRES esp_adc esp_driver_gpio esp_driver_uart esp_driver_i2s
esp_hal_i2c esp_hal_touch_sens esp_hal_gpspi esp_hal_pmu esp_hal_rtc_timer esp_hal_i2c esp_hal_touch_sens esp_hal_gpspi esp_hal_pmu esp_hal_rtc_timer esp_hal_clock
) )
@@ -23,6 +23,7 @@ set(esp_hal_components
esp_hal_wdt esp_hal_wdt
esp_hal_pmu esp_hal_pmu
esp_hal_rtc_timer esp_hal_rtc_timer
esp_hal_clock
) )
set(COMPONENTS ${g0_components} ${g1_components} ${esp_hal_components} main) set(COMPONENTS ${g0_components} ${g1_components} ${esp_hal_components} main)