From 4ba58cd22b84c50da063f6b98f71543c03242015 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 20 Dec 2024 19:17:08 +0800 Subject: [PATCH 1/4] fix(ledc): updated docs for esp32h2 eco5 bugfix --- components/driver/ledc/ledc.c | 2 +- docs/en/api-reference/peripherals/ledc.rst | 4 ++++ docs/zh_CN/api-reference/peripherals/ledc.rst | 4 ++++ .../ledc/ledc_basic/main/ledc_basic_example_main.c | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/components/driver/ledc/ledc.c b/components/driver/ledc/ledc.c index e3b9f5bc90..25604010e6 100644 --- a/components/driver/ledc/ledc.c +++ b/components/driver/ledc/ledc.c @@ -692,7 +692,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf) /*set channel parameters*/ /* channel parameters decide how the waveform looks like in one period */ /* set channel duty and hpoint value, duty range is [0, (2**duty_res)], hpoint range is [0, (2**duty_res)-1] */ - /* Note: On ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2, ESP32P4, due to a hardware bug, + /* Note: On ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2 (rev < 1.2), ESP32P4, due to a hardware bug, * 100% duty cycle (i.e. 2**duty_res) is not reachable when the binded timer selects the maximum duty * resolution. For example, the max duty resolution on ESP32C3 is 14-bit width, then set duty to (2**14) * will mess up the duty calculation in hardware. diff --git a/docs/en/api-reference/peripherals/ledc.rst b/docs/en/api-reference/peripherals/ledc.rst index 3a19afbcef..13fdad2228 100644 --- a/docs/en/api-reference/peripherals/ledc.rst +++ b/docs/en/api-reference/peripherals/ledc.rst @@ -256,6 +256,10 @@ The range of the duty cycle values passed to functions depends on selected ``dut On {IDF_TARGET_NAME}, when channel's binded timer selects its maximum duty resolution, the duty cycle value cannot be set to ``(2 ** duty_resolution)``. Otherwise, the internal duty counter in the hardware will overflow and be messed up. + .. only:: esp32h2 + + The hardware limitation above only applies to chip revision before v1.2. + Change PWM Duty Cycle Using Hardware """""""""""""""""""""""""""""""""""" diff --git a/docs/zh_CN/api-reference/peripherals/ledc.rst b/docs/zh_CN/api-reference/peripherals/ledc.rst index 8cfb8209b7..7da9033cb1 100644 --- a/docs/zh_CN/api-reference/peripherals/ledc.rst +++ b/docs/zh_CN/api-reference/peripherals/ledc.rst @@ -256,6 +256,10 @@ LEDC 驱动提供了一个辅助函数 :cpp:func:`ledc_find_suitable_duty_resolu 在 {IDF_TARGET_NAME} 上,当通道绑定的定时器配置了其最大 PWM 占空比分辨率( ``MAX_DUTY_RES`` ),通道的占空比不能被设置到 ``(2 ** MAX_DUTY_RES)`` 。否则,硬件内部占空比计数器会溢出,并导致占空比计算错误。 + .. only:: esp32h2 + + 以上硬件限制仅在芯片版本低于 v1.2 的 ESP32H2 上存在。 + 使用硬件改变 PWM 占空比 """""""""""""""""""""""""""""""""""" diff --git a/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c b/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c index 840c5bcd87..0f45c87b77 100644 --- a/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c +++ b/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c @@ -19,7 +19,7 @@ #define LEDC_FREQUENCY (4000) // Frequency in Hertz. Set frequency at 4 kHz /* Warning: - * For ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2, ESP32P4 targets, + * For ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2 (rev < 1.2), ESP32P4 targets, * when LEDC_DUTY_RES selects the maximum duty resolution (i.e. value equal to SOC_LEDC_TIMER_BIT_WIDTH), * 100% duty cycle is not reachable (duty cannot be set to (2 ** SOC_LEDC_TIMER_BIT_WIDTH)). */ From 2c9fa3771e99a53b428e02742462aef09d76917e Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Tue, 31 Dec 2024 21:28:20 +0800 Subject: [PATCH 2/4] fix(ledc): left-off gamma ram registers should be cleared Hardware reads in (range_number+1) fade parameter registers, which could cause output waveform error. --- components/driver/ledc/ledc.c | 17 ++++++++++++----- components/hal/include/hal/ledc_hal.h | 11 ++++++++++- components/hal/ledc_hal_iram.c | 11 +++++++++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/components/driver/ledc/ledc.c b/components/driver/ledc/ledc.c index 25604010e6..62d84b2d06 100644 --- a/components/driver/ledc/ledc.c +++ b/components/driver/ledc/ledc.c @@ -232,6 +232,8 @@ int duty_val, ledc_duty_direction_t duty_direction, uint32_t duty_num, uint32_t ledc_hal_set_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 0, duty_direction, duty_cycle, duty_scale, duty_num); #if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED ledc_hal_set_range_number(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 1); + // Clear left-off LEDC gamma ram registers, random data in ram could cause output waveform error + ledc_hal_clear_left_off_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 1); #endif return ESP_OK; } @@ -303,16 +305,20 @@ static bool ledc_speed_mode_ctx_create(ledc_mode_t speed_mode) 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; + LEDC_BUS_CLOCK_ATOMIC() { + ledc_ll_enable_bus_clock(true); + ledc_ll_enable_reset_reg(false); + } + // Enable core clock gating at early stage, some LEDC registers and gamma RAM rely on the LEDC core clock existence + LEDC_FUNC_CLOCK_ATOMIC() { + ledc_ll_enable_clock(LEDC_LL_GET_HW(), true); + } ledc_hal_init(&(ledc_new_mode_obj->ledc_hal), speed_mode); 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 p_ledc_obj[speed_mode] = ledc_new_mode_obj; - LEDC_BUS_CLOCK_ATOMIC() { - ledc_ll_enable_bus_clock(true); - ledc_ll_enable_reset_reg(false); - } } } _lock_release(&s_ledc_mutex[speed_mode]); @@ -563,7 +569,6 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n // 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_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); } } @@ -1378,6 +1383,8 @@ static esp_err_t _ledc_set_multi_fade(ledc_mode_t speed_mode, ledc_channel_t cha ledc_hal_set_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, i, fade_param.dir, fade_param.cycle_num, fade_param.scale, fade_param.step_num); } ledc_hal_set_range_number(&(p_ledc_obj[speed_mode]->ledc_hal), channel, list_len); + // Clear left-off LEDC gamma ram registers, random data in ram could cause output waveform error + ledc_hal_clear_left_off_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, list_len); portEXIT_CRITICAL(&ledc_spinlock); // Calculate target duty, and take account for overflow uint32_t target_duty = start_duty; diff --git a/components/hal/include/hal/ledc_hal.h b/components/hal/include/hal/ledc_hal.h index b914cb5778..fe9275ee9b 100644 --- a/components/hal/include/hal/ledc_hal.h +++ b/components/hal/include/hal/ledc_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -365,6 +365,15 @@ void ledc_hal_get_range_number(ledc_hal_context_t *hal, ledc_channel_t channel_n * @return None */ void ledc_hal_get_fade_param(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t range, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step); + +/** + * @brief Clear left-off range fade parameters in LEDC gamma ram + * + * @param hal Context of the HAL layer + * @param channel_num LEDC channel index, select from ledc_channel_t + * @param start_range Start of the range to clear + */ +void ledc_hal_clear_left_off_fade_param(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t start_range); #endif //SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED /** diff --git a/components/hal/ledc_hal_iram.c b/components/hal/ledc_hal_iram.c index 4cff5cfcd7..be3e876567 100644 --- a/components/hal/ledc_hal_iram.c +++ b/components/hal/ledc_hal_iram.c @@ -1,11 +1,11 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ // The HAL layer for LEDC (common part, in iram) -// make these functions in a seperate file to make sure all LL functions are in the IRAM. +// make these functions in a separate file to make sure all LL functions are in the IRAM. #include "hal/ledc_hal.h" #include "hal/assert.h" @@ -58,6 +58,13 @@ void ledc_hal_get_range_number(ledc_hal_context_t *hal, ledc_channel_t channel_n { ledc_ll_get_range_number(hal->dev, hal->speed_mode, channel_num, range_num); } + +void ledc_hal_clear_left_off_fade_param(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t start_range) +{ + for (int i = start_range; i < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX; i++) { + ledc_ll_set_fade_param_range(hal->dev, hal->speed_mode, channel_num, i, 0, 0, 0, 0); + } +} #endif //SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED void ledc_hal_get_fade_end_intr_status(ledc_hal_context_t *hal, uint32_t *intr_status) From c1c62cb16e09996e87d952954025a50b6584cbd0 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 7 Feb 2025 20:41:17 +0800 Subject: [PATCH 3/4] docs(ledc): add notes for ledc_set_fade_with_time API reference Closes https://github.com/espressif/esp-idf/issues/15085 --- components/driver/ledc/include/driver/ledc.h | 32 +++++++++++++++++--- components/driver/ledc/ledc.c | 14 ++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/components/driver/ledc/include/driver/ledc.h b/components/driver/ledc/include/driver/ledc.h index d4a149c9bf..424900ea62 100644 --- a/components/driver/ledc/include/driver/ledc.h +++ b/components/driver/ledc/include/driver/ledc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -439,7 +439,18 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param target_duty Target duty of fading [0, (2**duty_resolution)] - * @param max_fade_time_ms The maximum time of the fading ( ms ). + * @param desired_fade_time_ms The intended time of the fading ( ms ). + * Note that the actual time it takes to complete the fade could vary by a factor of up to 2x shorter + * or longer than the expected time due to internal rounding errors in calculations. + * Specifically: + * * The total number of cycles (total_cycle_num = desired_fade_time_ms * freq / 1000) + * * The difference in duty cycle (duty_delta = |target_duty - current_duty|) + * The fade may complete faster than expected if total_cycle_num larger than duty_delta. Conversely, + * it may take longer than expected if total_cycle_num is less than duty_delta. + * The closer the ratio of total_cycle_num/duty_delta (or its inverse) is to a whole number (the floor value), + * the more accurately the actual fade duration will match the intended time. + * If an exact fade time is expected, please consider to split the entire fade into several smaller linear fades. + * The split should make each fade step has a divisible total_cycle_num/duty_delta (or its inverse) ratio. * * @return * - ESP_OK Success @@ -447,7 +458,7 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ -esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int max_fade_time_ms); +esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int desired_fade_time_ms); /** * @brief Install LEDC fade function. This function will occupy interrupt of LEDC module. @@ -538,7 +549,18 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. * @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t * @param target_duty Target duty of fading [0, (2**duty_resolution)] - * @param max_fade_time_ms The maximum time of the fading ( ms ). + * @param desired_fade_time_ms The intended time of the fading ( ms ). + * Note that the actual time it takes to complete the fade could vary by a factor of up to 2x shorter + * or longer than the expected time due to internal rounding errors in calculations. + * Specifically: + * * The total number of cycles (total_cycle_num = desired_fade_time_ms * freq / 1000) + * * The difference in duty cycle (duty_delta = |target_duty - current_duty|) + * The fade may complete faster than expected if total_cycle_num larger than duty_delta. Conversely, + * it may take longer than expected if total_cycle_num is less than duty_delta. + * The closer the ratio of total_cycle_num/duty_delta (or its inverse) is to a whole number (the floor value), + * the more accurately the actual fade duration will match the intended time. + * If an exact fade time is expected, please consider to split the entire fade into several smaller linear fades. + * The split should make each fade step has a divisible total_cycle_num/duty_delta (or its inverse) ratio. * @param fade_mode choose blocking or non-blocking mode * * @return @@ -547,7 +569,7 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe * - ESP_ERR_INVALID_STATE Channel not initialized * - ESP_FAIL Fade function init error */ -esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t max_fade_time_ms, ledc_fade_mode_t fade_mode); +esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t desired_fade_time_ms, ledc_fade_mode_t fade_mode); /** * @brief A thread-safe API to set and start LEDC fade function. diff --git a/components/driver/ledc/ledc.c b/components/driver/ledc/ledc.c index 62d84b2d06..b5e4e21932 100644 --- a/components/driver/ledc/ledc.c +++ b/components/driver/ledc/ledc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1125,7 +1125,7 @@ static esp_err_t _ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t return ESP_OK; } -static esp_err_t _ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int max_fade_time_ms) +static esp_err_t _ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int desired_fade_time_ms) { ledc_timer_t timer_sel; uint32_t duty_cur = 0; @@ -1137,7 +1137,7 @@ static esp_err_t _ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t if (duty_delta == 0) { return _ledc_set_fade_with_step(speed_mode, channel, target_duty, 0, 0); } - uint32_t total_cycles = max_fade_time_ms * freq / 1000; + uint32_t total_cycles = desired_fade_time_ms * freq / 1000; if (total_cycles == 0) { ESP_LOGW(LEDC_TAG, LEDC_FADE_TOO_FAST_STR); return _ledc_set_fade_with_step(speed_mode, channel, target_duty, 0, 0); @@ -1184,7 +1184,7 @@ static void _ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, led } } -esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int max_fade_time_ms) +esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int desired_fade_time_ms) { LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode"); LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel"); @@ -1193,7 +1193,7 @@ esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK, LEDC_FADE_INIT_ERROR_STR, ESP_FAIL); _ledc_fade_hw_acquire(speed_mode, channel); - _ledc_set_fade_with_time(speed_mode, channel, target_duty, max_fade_time_ms); + _ledc_set_fade_with_time(speed_mode, channel, target_duty, desired_fade_time_ms); _ledc_fade_hw_release(speed_mode, channel); return ESP_OK; } @@ -1337,7 +1337,7 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe return ESP_OK; } -esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t max_fade_time_ms, ledc_fade_mode_t fade_mode) +esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t desired_fade_time_ms, ledc_fade_mode_t fade_mode) { LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode"); LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel"); @@ -1347,7 +1347,7 @@ esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t ch LEDC_ARG_CHECK(target_duty <= ledc_get_max_duty(speed_mode, channel), "target_duty"); _ledc_op_lock_acquire(speed_mode, channel); _ledc_fade_hw_acquire(speed_mode, channel); - _ledc_set_fade_with_time(speed_mode, channel, target_duty, max_fade_time_ms); + _ledc_set_fade_with_time(speed_mode, channel, target_duty, desired_fade_time_ms); _ledc_fade_start(speed_mode, channel, fade_mode); _ledc_op_lock_release(speed_mode, channel); return ESP_OK; From ab4ec0aa5e3abdf930957c28e45b0f37bdc0b1df Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 14 Feb 2025 16:42:36 +0800 Subject: [PATCH 4/4] fix(ledc): overflowed integer argument in ledc_hal_clear_left_off_fade_param --- components/hal/esp32c6/include/hal/ledc_ll.h | 2 ++ components/hal/esp32h2/include/hal/ledc_ll.h | 2 ++ components/hal/esp32p4/include/hal/ledc_ll.h | 2 ++ components/hal/ledc_hal_iram.c | 1 - 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/components/hal/esp32c6/include/hal/ledc_ll.h b/components/hal/esp32c6/include/hal/ledc_ll.h index cc858d4dee..32a0234936 100644 --- a/components/hal/esp32c6/include/hal/ledc_ll.h +++ b/components/hal/esp32c6/include/hal/ledc_ll.h @@ -16,6 +16,7 @@ #include "soc/clk_tree_defs.h" #include "hal/assert.h" #include "esp_rom_sys.h" //for sync issue workaround +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { @@ -442,6 +443,7 @@ static inline void ledc_ll_set_duty_range_wr_addr(ledc_dev_t *hw, ledc_mode_t sp */ static inline void ledc_ll_set_fade_param_range(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint8_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step) { + HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX); // To workaround sync issue // This is to ensure the fade param write to the gamma_wr register would not mess up the last wr_addr ledc_ll_set_duty_range_wr_addr(hw, speed_mode, channel_num, range); diff --git a/components/hal/esp32h2/include/hal/ledc_ll.h b/components/hal/esp32h2/include/hal/ledc_ll.h index 81e8177b7b..c6439d4c72 100644 --- a/components/hal/esp32h2/include/hal/ledc_ll.h +++ b/components/hal/esp32h2/include/hal/ledc_ll.h @@ -16,6 +16,7 @@ #include "soc/clk_tree_defs.h" #include "hal/assert.h" #include "esp_rom_sys.h" //for sync issue workaround +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { @@ -440,6 +441,7 @@ static inline void ledc_ll_set_duty_range_wr_addr(ledc_dev_t *hw, ledc_mode_t sp */ static inline void ledc_ll_set_fade_param_range(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint8_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step) { + HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX); // To workaround sync issue // This is to ensure the fade param write to the gamma_wr register would not mess up the last wr_addr ledc_ll_set_duty_range_wr_addr(hw, speed_mode, channel_num, range); diff --git a/components/hal/esp32p4/include/hal/ledc_ll.h b/components/hal/esp32p4/include/hal/ledc_ll.h index ca655dabb5..f7b759e12b 100644 --- a/components/hal/esp32p4/include/hal/ledc_ll.h +++ b/components/hal/esp32p4/include/hal/ledc_ll.h @@ -15,6 +15,7 @@ #include "soc/ledc_reg.h" #include "soc/clk_tree_defs.h" #include "soc/hp_sys_clkrst_struct.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { @@ -372,6 +373,7 @@ static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc */ static inline void ledc_ll_set_fade_param_range(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint8_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step) { + HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX); ledc_channel_gamma_fade_param_t range_param = { .duty_inc = dir, .duty_cycle = cycle, diff --git a/components/hal/ledc_hal_iram.c b/components/hal/ledc_hal_iram.c index be3e876567..ac3112caa8 100644 --- a/components/hal/ledc_hal_iram.c +++ b/components/hal/ledc_hal_iram.c @@ -39,7 +39,6 @@ void ledc_hal_get_duty(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint void ledc_hal_set_fade_param(const ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step) { #if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED - HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX); ledc_ll_set_fade_param_range(hal->dev, hal->speed_mode, channel_num, range, dir, cycle, scale, step); #else // !SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED HAL_ASSERT(range == 0);