mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 13:09:38 +00:00 
			
		
		
		
	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.
This commit is contained in:
		| @@ -212,6 +212,8 @@ int duty_val, ledc_duty_direction_t duty_direction, uint32_t duty_num, uint32_t | |||||||
| #if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED | #if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED | ||||||
|     ledc_hal_set_duty_range_wr_addr(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 0); |     ledc_hal_set_duty_range_wr_addr(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 0); | ||||||
|     ledc_hal_set_range_number(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 1); |     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 | #endif | ||||||
|     return ESP_OK; |     return ESP_OK; | ||||||
| } | } | ||||||
| @@ -1274,6 +1276,8 @@ static esp_err_t _ledc_set_multi_fade(ledc_mode_t speed_mode, ledc_channel_t cha | |||||||
|         ledc_hal_set_duty_range_wr_addr(&(p_ledc_obj[speed_mode]->ledc_hal), channel, i); |         ledc_hal_set_duty_range_wr_addr(&(p_ledc_obj[speed_mode]->ledc_hal), channel, i); | ||||||
|     } |     } | ||||||
|     ledc_hal_set_range_number(&(p_ledc_obj[speed_mode]->ledc_hal), channel, list_len); |     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); |     portEXIT_CRITICAL(&ledc_spinlock); | ||||||
|     // Calculate target duty, and take account for overflow |     // Calculate target duty, and take account for overflow | ||||||
|     uint32_t target_duty = start_duty; |     uint32_t target_duty = start_duty; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD |  * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier: Apache-2.0 |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  */ |  */ | ||||||
| @@ -386,6 +386,15 @@ void ledc_hal_get_range_number(ledc_hal_context_t *hal, ledc_channel_t channel_n | |||||||
|  * @return None |  * @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); | 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 | #endif //SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| /* | /* | ||||||
|  * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD |  * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier: Apache-2.0 |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| // The HAL layer for LEDC (common part, in iram) | // 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 "esp_attr.h" | #include "esp_attr.h" | ||||||
| #include "hal/ledc_hal.h" | #include "hal/ledc_hal.h" | ||||||
| @@ -70,6 +70,17 @@ 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); |     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_duty_direction(hal->dev, hal->speed_mode, channel_num, 0); | ||||||
|  |         ledc_ll_set_duty_cycle(hal->dev, hal->speed_mode, channel_num, 0); | ||||||
|  |         ledc_ll_set_duty_scale(hal->dev, hal->speed_mode, channel_num, 0); | ||||||
|  |         ledc_ll_set_duty_num(hal->dev, hal->speed_mode, channel_num, 0); | ||||||
|  |         ledc_ll_set_duty_range_wr_addr(hal->dev, hal->speed_mode, channel_num, i); | ||||||
|  |     } | ||||||
|  | } | ||||||
| #endif //SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED | #endif //SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED | ||||||
|  |  | ||||||
| void ledc_hal_get_fade_end_intr_status(ledc_hal_context_t *hal, uint32_t *intr_status) | void ledc_hal_get_fade_end_intr_status(ledc_hal_context_t *hal, uint32_t *intr_status) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Song Ruo Jing
					Song Ruo Jing