mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(ledc): support ledc on esp32p4
This commit is contained in:
@@ -44,6 +44,18 @@ static __attribute__((unused)) const char *LEDC_TAG = "ledc";
|
||||
#define LEDC_CLK_SRC_FREQ_PRECISION ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX
|
||||
#endif
|
||||
|
||||
#if !SOC_RCC_IS_INDEPENDENT
|
||||
#define LEDC_BUS_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC()
|
||||
#else
|
||||
#define LEDC_BUS_CLOCK_ATOMIC()
|
||||
#endif
|
||||
|
||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
||||
#define LEDC_FUNC_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC()
|
||||
#else
|
||||
#define LEDC_FUNC_CLOCK_ATOMIC()
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
LEDC_FSM_IDLE,
|
||||
LEDC_FSM_HW_FADE,
|
||||
@@ -297,8 +309,10 @@ static bool ledc_speed_mode_ctx_create(ledc_mode_t speed_mode)
|
||||
memset(ledc_new_mode_obj->timer_specific_clk, LEDC_TIMER_SPECIFIC_CLK_UNINIT, sizeof(ledc_clk_src_t) * LEDC_TIMER_MAX);
|
||||
#endif
|
||||
p_ledc_obj[speed_mode] = ledc_new_mode_obj;
|
||||
// Enable APB access to LEDC registers
|
||||
periph_module_enable(PERIPH_LEDC_MODULE);
|
||||
LEDC_BUS_CLOCK_ATOMIC() {
|
||||
ledc_ll_enable_bus_clock(true);
|
||||
ledc_ll_enable_reset_reg(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
_lock_release(&s_ledc_mutex[speed_mode]);
|
||||
@@ -439,7 +453,6 @@ static uint32_t ledc_auto_clk_divisor(ledc_mode_t speed_mode, int freq_hz, uint3
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern void esp_sleep_periph_use_8m(bool use_or_not);
|
||||
|
||||
/**
|
||||
* @brief Function setting the LEDC timer divisor with the given source clock,
|
||||
@@ -549,14 +562,20 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
|
||||
if (p_ledc_obj[speed_mode]->glb_clk != glb_clk) {
|
||||
// TODO: release old glb_clk (if not UNINIT), and acquire new glb_clk [clk_tree]
|
||||
p_ledc_obj[speed_mode]->glb_clk = glb_clk;
|
||||
ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), glb_clk);
|
||||
LEDC_FUNC_CLOCK_ATOMIC() {
|
||||
ledc_ll_enable_clock(p_ledc_obj[speed_mode]->ledc_hal.dev, true);
|
||||
ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), glb_clk);
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
|
||||
ESP_LOGD(LEDC_TAG, "In slow speed mode, global clk set: %d", glb_clk);
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32P4 //depend on sleep support IDF-7528 and IDF-7529
|
||||
/* keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
|
||||
extern void esp_sleep_periph_use_8m(bool use_or_not);
|
||||
esp_sleep_periph_use_8m(glb_clk == LEDC_SLOW_CLK_RC_FAST);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The divisor is correct, we can write in the hardware. */
|
||||
@@ -564,7 +583,7 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
|
||||
return ESP_OK;
|
||||
|
||||
error:
|
||||
ESP_LOGE(LEDC_TAG, "requested frequency and duty resolution can not be achieved, try reducing freq_hz or duty_resolution. div_param=%"PRIu32, div_param);
|
||||
ESP_LOGE(LEDC_TAG, "requested frequency %d and duty resolution %d can not be achieved, try reducing freq_hz or duty_resolution. div_param=%"PRIu32, freq_hz, duty_resolution, div_param);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -655,7 +674,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)
|
||||
if (!new_speed_mode_ctx_created && !p_ledc_obj[speed_mode]) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
#if !(CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32H2)
|
||||
#if !(CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4)
|
||||
// On such targets, the default ledc core(global) clock does not connect to any clock source
|
||||
// Set channel configurations and update bits before core clock is on could lead to error
|
||||
// Therefore, we should connect the core clock to a real clock source to make it on before any ledc register operation
|
||||
|
||||
Reference in New Issue
Block a user