mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 11:03:11 +00:00
fix(ledc): fix undesired module reset when acquiring new speed mode on ESP32
Introduced in 885e32d4f0
This commit is contained in:
@@ -399,44 +399,55 @@ esp_err_t ledc_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags,
|
||||
static bool ledc_speed_mode_ctx_create(ledc_mode_t speed_mode)
|
||||
{
|
||||
bool new_ctx = false;
|
||||
bool group_acquired = false;
|
||||
|
||||
// Prevent p_ledc_obj malloc concurrently
|
||||
_lock_acquire(&s_ledc_mutex[speed_mode]);
|
||||
if (!p_ledc_obj[speed_mode]) {
|
||||
for (int i = 0; i < LEDC_SPEED_MODE_MAX; i++) {
|
||||
if (p_ledc_obj[i]) {
|
||||
group_acquired = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ledc_obj_t *ledc_new_mode_obj = (ledc_obj_t *) heap_caps_calloc(1, sizeof(ledc_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (ledc_new_mode_obj) {
|
||||
new_ctx = true;
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
ledc_ll_enable_bus_clock(0, true);
|
||||
ledc_ll_reset_register(0);
|
||||
}
|
||||
// Enable core clock gating at early stage, some LEDC registers and gamma RAM rely on the LEDC core clock existence
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
ledc_ll_enable_clock(0, true);
|
||||
}
|
||||
ledc_hal_init(&(ledc_new_mode_obj->ledc_hal), 0);
|
||||
// initialize some fields
|
||||
ledc_new_mode_obj->glb_clk = LEDC_SLOW_CLK_UNINIT;
|
||||
#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
|
||||
memset(ledc_new_mode_obj->timer_specific_clk, LEDC_TIMER_SPECIFIC_CLK_UNINIT, sizeof(ledc_clk_src_t) * LEDC_TIMER_MAX);
|
||||
#endif
|
||||
|
||||
ledc_new_mode_obj->sleep_mode = LEDC_SLEEP_MODE_INVALID;
|
||||
|
||||
// if the entire LEDC group is not acquired, do module based initialization
|
||||
if (!group_acquired) {
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
ledc_ll_enable_bus_clock(0, true);
|
||||
ledc_ll_reset_register(0);
|
||||
}
|
||||
// Enable core clock gating at early stage, some LEDC registers and gamma RAM rely on the LEDC core clock existence
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
ledc_ll_enable_clock(0, true);
|
||||
}
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // for targets that is !SOC_LEDC_SUPPORT_SLEEP_RETENTION, retention module should still be inited to avoid TOP PD
|
||||
// Initialize sleep retention module for LEDC
|
||||
sleep_retention_module_t module = ledc_reg_retention_info[0].module_id;
|
||||
sleep_retention_module_init_param_t init_param = {
|
||||
.cbs = {
|
||||
.create = {
|
||||
.handle = ledc_create_sleep_retention_link_cb,
|
||||
.arg = NULL,
|
||||
// Initialize sleep retention module for LEDC
|
||||
sleep_retention_module_t module = ledc_reg_retention_info[0].module_id;
|
||||
sleep_retention_module_init_param_t init_param = {
|
||||
.cbs = {
|
||||
.create = {
|
||||
.handle = ledc_create_sleep_retention_link_cb,
|
||||
.arg = NULL,
|
||||
},
|
||||
},
|
||||
},
|
||||
.depends = RETENTION_MODULE_BITMAP_INIT(CLOCK_SYSTEM)
|
||||
};
|
||||
if (sleep_retention_module_init(module, &init_param) != ESP_OK) {
|
||||
ESP_LOGW(LEDC_TAG, "init sleep retention failed for ledc, power domain may be turned off during sleep");
|
||||
}
|
||||
.depends = RETENTION_MODULE_BITMAP_INIT(CLOCK_SYSTEM)
|
||||
};
|
||||
if (sleep_retention_module_init(module, &init_param) != ESP_OK) {
|
||||
ESP_LOGW(LEDC_TAG, "init sleep retention failed for ledc, power domain may be turned off during sleep");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ledc_hal_init(&(ledc_new_mode_obj->ledc_hal), 0);
|
||||
p_ledc_obj[speed_mode] = ledc_new_mode_obj;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user