From c1c62cb16e09996e87d952954025a50b6584cbd0 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 7 Feb 2025 20:41:17 +0800 Subject: [PATCH] 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;