feat(esp_hw_support): support esp32s31 esp_clock_output

This commit is contained in:
wuzhenghui
2026-04-14 12:19:07 +08:00
parent 0b4e08c0a6
commit b913f147ba
6 changed files with 251 additions and 17 deletions
@@ -17,6 +17,7 @@
#include "soc/hp_alive_sys_reg.h"
#include "soc/hp_alive_sys_struct.h"
#include "soc/pmu_reg.h"
#include "hal/clkout_channel.h"
#include "hal/assert.h"
#include "hal/log.h"
#include "esp32s31/rom/rtc.h"
@@ -900,6 +901,81 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1);
}
/************************** CLOCK OUTPUT **************************/
/**
* @brief Clock output channel configuration
*
* @param clk_sig The clock signal source to be mapped to GPIOs (raw `reg_dbg_chX_sel` mux index)
* @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)
{
switch (channel_id) {
case CLKOUT_CHANNEL_1:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg0_clk_ctrl0, reg_dbg_ch0_sel, clk_sig);
break;
case CLKOUT_CHANNEL_2:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg1_clk_ctrl0, reg_dbg_ch1_sel, clk_sig);
break;
case CLKOUT_CHANNEL_3:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg2_clk_ctrl0, reg_dbg_ch2_sel, clk_sig);
break;
default:
HAL_ASSERT(false && "invalid clock output channel");
break;
}
}
/**
* @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)
{
switch (channel_id) {
case CLKOUT_CHANNEL_1:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg0_clk_ctrl0, reg_dbg_ch0_en, enable);
break;
case CLKOUT_CHANNEL_2:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg1_clk_ctrl0, reg_dbg_ch1_en, enable);
break;
case CLKOUT_CHANNEL_3:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg2_clk_ctrl0, reg_dbg_ch2_en, enable);
break;
default:
HAL_ASSERT(false && "invalid clock output channel");
break;
}
}
/**
* @brief Output the mapped clock after frequency division
*
* @param channel_id The clock output channel ID
* @param div_num Divider value N such that output frequency is (input / N). Written to hardware as (N - 1).
* Must be in [1, 256] to match the 8-bit `reg_dbg_chX_div_num` field.
*/
static inline __attribute__((always_inline)) void clk_ll_set_output_channel_divider(clock_out_channel_t channel_id, uint32_t div_num)
{
HAL_ASSERT(div_num >= 1 && div_num <= 256);
switch (channel_id) {
case CLKOUT_CHANNEL_1:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg0_clk_ctrl0, reg_dbg_ch0_div_num, div_num - 1);
break;
case CLKOUT_CHANNEL_2:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg1_clk_ctrl0, reg_dbg_ch1_div_num, div_num - 1);
break;
case CLKOUT_CHANNEL_3:
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg2_clk_ctrl0, reg_dbg_ch2_div_num, div_num - 1);
break;
default:
HAL_ASSERT(false && "invalid clock output channel");
break;
}
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/
/**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
@@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_assert.h"
#include "soc/soc_caps.h"
#include "soc/io_mux_reg.h"
#include "soc/gpio_sig_map.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum clock_out_channel {
CLKOUT_CHANNEL_1,
CLKOUT_CHANNEL_2,
CLKOUT_CHANNEL_3,
CLKOUT_CHANNEL_MAX,
} clock_out_channel_t;
#define CLKOUT_CHANNEL_TO_GPIO_SIG_ID(channel) ((channel == CLKOUT_CHANNEL_1) ? DBG_CH0_CLK_IDX : \
(channel == CLKOUT_CHANNEL_2) ? DBG_CH1_CLK_IDX : \
(channel == CLKOUT_CHANNEL_3) ? DBG_CH2_CLK_IDX : \
SIG_GPIO_OUT_IDX)
ESP_STATIC_ASSERT(CLKOUT_CHANNEL_MAX == SOC_GPIO_CLOCKOUT_CHANNEL_NUM, "clock_out_channel enumeration mismatch");
#ifdef __cplusplus
}
#endif