feat(ledc): support ledc on esp32p4

This commit is contained in:
wanlei
2023-10-17 16:40:04 +08:00
parent db4598e305
commit 57614bbad2
33 changed files with 4556 additions and 869 deletions
+25 -6
View File
@@ -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