mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(esp_hw_support): support set clock divider for esp32p4 clock output
This commit is contained in:
parent
309725fcd0
commit
ffd5d1fd66
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -88,7 +88,6 @@ static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig
|
||||
allocated_channel->mapped_io_bmap |= BIT(gpio_num);
|
||||
allocated_channel->mapped_clock = clk_sig;
|
||||
allocated_channel->ref_cnt++;
|
||||
|
||||
if (allocated_channel->ref_cnt == 1) {
|
||||
portENTER_CRITICAL(&s_clkout_lock);
|
||||
#if SOC_CLOCKOUT_HAS_SOURCE_GATE
|
||||
@ -219,6 +218,18 @@ esp_err_t esp_clock_output_stop(esp_clock_output_mapping_handle_t clkout_mapping
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_CLOCKOUT_SUPPORT_CHANNEL_DIVIDER
|
||||
esp_err_t esp_clock_output_set_divider(esp_clock_output_mapping_handle_t clkout_mapping_hdl, uint32_t div_num)
|
||||
{
|
||||
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");
|
||||
portENTER_CRITICAL(&clkout_mapping_hdl->clkout_mapping_lock);
|
||||
clk_hal_clock_output_set_divider(clkout_mapping_hdl->clkout_channel_hdl->channel_id, div_num);
|
||||
portEXIT_CRITICAL(&clkout_mapping_hdl->clkout_mapping_lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
// Due to a hardware bug, PIN_CTRL cannot select 0xf output, whereas 0xf is the default value.
|
||||
__attribute__((constructor))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -25,7 +25,7 @@ typedef struct esp_clock_output_mapping *esp_clock_output_mapping_handle_t;
|
||||
*
|
||||
* @param[in] clk_src The clock signal source to be mapped to GPIOs
|
||||
* @param[in] gpio_num GPIO number to be mapped soc_root_clk signal source
|
||||
* @param[out] clkout_mapping_ret_hdl Clock output controll handler
|
||||
* @param[out] clkout_mapping_ret_hdl Clock output control handler
|
||||
* @return
|
||||
* - ESP_OK: Output specified clock signal to specified GPIO successfully
|
||||
* - ESP_ERR_INVALID_ARG: Specified GPIO not supported to output internal clock
|
||||
@ -36,12 +36,26 @@ esp_err_t esp_clock_output_start(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_nu
|
||||
|
||||
/**
|
||||
* @brief Stop clock signal to GPIO outputting
|
||||
* @param[in] clkout_mapping_hdl Clock output mapping controll handle
|
||||
* @param[in] clkout_mapping_hdl Clock output mapping control handle
|
||||
* @return
|
||||
* - ESP_OK: Disable the clock output on GPIO successfully
|
||||
* - ESP_ERR_INVALID_STATE The clock in handle is already in the disabled state
|
||||
* - ESP_ERR_INVALID_ARG The clock mapping handle is not initialized yet
|
||||
* - ESP_ERR_INVALID_STATE The clock mapping handle is already in the disabled state
|
||||
*/
|
||||
esp_err_t esp_clock_output_stop(esp_clock_output_mapping_handle_t clkout_mapping_hdl);
|
||||
|
||||
#if SOC_CLOCKOUT_SUPPORT_CHANNEL_DIVIDER
|
||||
/**
|
||||
* @brief Output the mapped clock after frequency division
|
||||
* @param clkout_mapping_hdl clkout_mapping_hdl Clock output mapping control handle
|
||||
* @param div_num clock frequency division value, should be in the range of 1 ~ 256
|
||||
* @return
|
||||
* - ESP_OK: Disable the clock output on GPIO successfully
|
||||
* - ESP_ERR_INVALID_ARG The clock mapping handle is not initialized yet or the div_num is in bad range
|
||||
*/
|
||||
esp_err_t esp_clock_output_set_divider(esp_clock_output_mapping_handle_t clkout_mapping_hdl, uint32_t div_num);
|
||||
#endif
|
||||
|
||||
#endif // SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX || SOC_GPIO_CLOCKOUT_BY_IO_MUX
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -35,6 +35,9 @@ void output_clock_1(void *pvParameter)
|
||||
esp_clock_output_mapping_handle_t clkout_mapping_hdl;
|
||||
for (int i = 0; i < TEST_LOOPS; ++i) {
|
||||
TEST_ESP_OK(esp_clock_output_start(test_clk_out_sig[0], test_clk_out_io[0], &clkout_mapping_hdl));
|
||||
#if SOC_CLOCKOUT_SUPPORT_CHANNEL_DIVIDER
|
||||
TEST_ESP_OK(esp_clock_output_set_divider(clkout_mapping_hdl, 8));
|
||||
#endif
|
||||
vTaskDelay(3);
|
||||
TEST_ESP_OK(esp_clock_output_stop(clkout_mapping_hdl));
|
||||
vTaskDelay(7);
|
||||
|
@ -83,9 +83,15 @@ 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)
|
||||
{
|
||||
clk_ll_set_dbg_clk_ctrl(clk_sig, channel_id);
|
||||
clk_ll_set_dbg_clk_channel_divider(channel_id, 1);
|
||||
clk_ll_enable_dbg_clk_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)
|
||||
{
|
||||
clk_ll_enable_dbg_clk_channel(channel_id, false);
|
||||
|
@ -833,15 +833,17 @@ static inline __attribute__((always_inline)) void clk_ll_set_dbg_clk_ctrl(soc_cl
|
||||
{
|
||||
if (channel_id == CLKOUT_CHANNEL_1) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_sel, clk_sig);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl0, reg_dbg_ch0_div_num, 0);
|
||||
} 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);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.dbg_clk_ctrl1, reg_dbg_ch1_div_num, 0);
|
||||
} 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) {
|
||||
@ -853,6 +855,22 @@ static inline __attribute__((always_inline)) void clk_ll_enable_dbg_clk_channel(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -68,6 +68,15 @@ 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);
|
||||
|
||||
#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
|
||||
* @param channel_id The clock output channel to teardown
|
||||
|
@ -199,10 +199,6 @@ config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_CLOCKOUT_CHANNEL_NUM
|
||||
int
|
||||
default 3
|
||||
|
@ -213,7 +213,7 @@
|
||||
#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
|
||||
|
||||
// The Clock Out signal is route to the pin by GPIO matrix
|
||||
#define SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX (1)
|
||||
// #define SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX (1)
|
||||
#define SOC_GPIO_CLOCKOUT_CHANNEL_NUM (3)
|
||||
|
||||
/*-------------------------- RTCIO CAPS --------------------------------------*/
|
||||
|
@ -563,6 +563,10 @@ config SOC_GPIO_CLOCKOUT_CHANNEL_NUM
|
||||
int
|
||||
default 2
|
||||
|
||||
config SOC_CLOCKOUT_SUPPORT_CHANNEL_DIVIDER
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_SUPPORT_FORCE_HOLD
|
||||
bool
|
||||
default y
|
||||
|
@ -234,6 +234,7 @@
|
||||
// The Clock Out signal is route to the pin by GPIO matrix
|
||||
#define SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX (1)
|
||||
#define SOC_GPIO_CLOCKOUT_CHANNEL_NUM (2)
|
||||
#define SOC_CLOCKOUT_SUPPORT_CHANNEL_DIVIDER (1)
|
||||
|
||||
// Support to force hold all IOs
|
||||
#define SOC_GPIO_SUPPORT_FORCE_HOLD (1)
|
||||
|
Loading…
Reference in New Issue
Block a user