mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 04:43:33 +00:00
ledc: Fix FADE_NO_WAIT mode concurrency problem.
Add test cases for fade concurrency issue and fade timing check. Closes https://github.com/espressif/esp-idf/issues/6710
This commit is contained in:
@@ -216,7 +216,7 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_
|
||||
static IRAM_ATTR esp_err_t ledc_duty_config(ledc_mode_t speed_mode, ledc_channel_t channel, int hpoint_val, int duty_val,
|
||||
ledc_duty_direction_t duty_direction, uint32_t duty_num, uint32_t duty_cycle, uint32_t duty_scale)
|
||||
{
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
portENTER_CRITICAL_SAFE(&ledc_spinlock);
|
||||
if (hpoint_val >= 0) {
|
||||
ledc_hal_set_hpoint(&(p_ledc_obj[speed_mode]->ledc_hal), channel, hpoint_val);
|
||||
}
|
||||
@@ -228,7 +228,7 @@ static IRAM_ATTR esp_err_t ledc_duty_config(ledc_mode_t speed_mode, ledc_channel
|
||||
ledc_hal_set_duty_cycle(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_cycle);
|
||||
ledc_hal_set_duty_scale(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_scale);
|
||||
ledc_ls_channel_update(speed_mode, channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
portEXIT_CRITICAL_SAFE(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -802,9 +802,9 @@ void IRAM_ATTR ledc_fade_isr(void *arg)
|
||||
ledc_calc_fade_end_channel(&intr_status, &channel);
|
||||
|
||||
// clear interrupt
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
portENTER_CRITICAL_ISR(&ledc_spinlock);
|
||||
ledc_hal_clear_fade_end_intr_status(&(p_ledc_obj[speed_mode]->ledc_hal), channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
portEXIT_CRITICAL_ISR(&ledc_spinlock);
|
||||
|
||||
if (s_ledc_fade_rec[speed_mode][channel] == NULL) {
|
||||
//fade object not initialized yet.
|
||||
@@ -854,9 +854,9 @@ void IRAM_ATTR ledc_fade_isr(void *arg)
|
||||
1,
|
||||
0);
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
portENTER_CRITICAL_ISR(&ledc_spinlock);
|
||||
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
portEXIT_CRITICAL_ISR(&ledc_spinlock);
|
||||
}
|
||||
}
|
||||
if (HPTaskAwoken == pdTRUE || cb_yield) {
|
||||
@@ -999,7 +999,10 @@ static void _ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, led
|
||||
ledc_enable_intr_type(speed_mode, channel, LEDC_INTR_FADE_END);
|
||||
ledc_update_duty(speed_mode, channel);
|
||||
if (fade_mode == LEDC_FADE_WAIT_DONE) {
|
||||
xSemaphoreTake(s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem, portMAX_DELAY);
|
||||
// Waiting for fade done
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
// Release hardware to support next time fade configure
|
||||
_ledc_fade_hw_release(speed_mode, channel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,7 +1044,6 @@ esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_f
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
_ledc_fade_start(speed_mode, channel, fade_mode);
|
||||
_ledc_fade_hw_release(speed_mode, channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -1089,12 +1091,10 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe
|
||||
LEDC_ARG_CHECK(hpoint <= LEDC_HPOINT_VAL_MAX, "hpoint");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK, LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
|
||||
_ledc_op_lock_acquire(speed_mode, channel);
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
ledc_duty_config(speed_mode, channel, hpoint, duty, 1, 0, 0, 0);
|
||||
ledc_update_duty(speed_mode, channel);
|
||||
_ledc_fade_hw_release(speed_mode, channel);
|
||||
_ledc_op_lock_release(speed_mode, channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -1110,9 +1110,6 @@ esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t ch
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
_ledc_set_fade_with_time(speed_mode, channel, target_duty, max_fade_time_ms);
|
||||
_ledc_fade_start(speed_mode, channel, fade_mode);
|
||||
if (fade_mode == LEDC_FADE_WAIT_DONE) {
|
||||
_ledc_fade_hw_release(speed_mode, channel);
|
||||
}
|
||||
_ledc_op_lock_release(speed_mode, channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -1131,9 +1128,6 @@ esp_err_t ledc_set_fade_step_and_start(ledc_mode_t speed_mode, ledc_channel_t ch
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
_ledc_set_fade_with_step(speed_mode, channel, target_duty, scale, cycle_num);
|
||||
_ledc_fade_start(speed_mode, channel, fade_mode);
|
||||
if (fade_mode == LEDC_FADE_WAIT_DONE) {
|
||||
_ledc_fade_hw_release(speed_mode, channel);
|
||||
}
|
||||
_ledc_op_lock_release(speed_mode, channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
Reference in New Issue
Block a user