fix(ledc): duty_start bit should wait for its self-clear before next set on esp32

This commit is contained in:
Song Ruo Jing
2025-08-14 19:07:06 +08:00
parent 5d20d91dac
commit a194b02246
14 changed files with 38 additions and 41 deletions
+2 -3
View File
@@ -977,7 +977,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)
static void _ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
{
ledc_hal_set_sig_out_en(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true);
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true);
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel);
ledc_ls_channel_update(speed_mode, channel);
}
@@ -1000,7 +1000,6 @@ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idl
portENTER_CRITICAL_SAFE(&ledc_spinlock);
ledc_hal_set_idle_level(&(p_ledc_obj[speed_mode]->ledc_hal), channel, idle_level);
ledc_hal_set_sig_out_en(&(p_ledc_obj[speed_mode]->ledc_hal), channel, false);
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, false);
ledc_ls_channel_update(speed_mode, channel);
portEXIT_CRITICAL_SAFE(&ledc_spinlock);
return ESP_OK;
@@ -1263,7 +1262,7 @@ static void IRAM_ATTR ledc_fade_isr(void *arg)
cycle,
scale);
s_ledc_fade_rec[speed_mode][channel]->fsm = LEDC_FSM_HW_FADE;
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true);
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel);
ledc_ls_channel_update(speed_mode, channel);
}
portEXIT_CRITICAL_ISR(&ledc_spinlock);
@@ -151,6 +151,12 @@ TEST_CASE("LEDC output idle level test", "[ledc]")
TEST_ESP_OK(ledc_stop(test_speed_mode, LEDC_CHANNEL_0, !current_level));
vTaskDelay(1000 / portTICK_PERIOD_MS);
TEST_ASSERT_EQUAL_INT32(!current_level, LEDC.channel_group[test_speed_mode].channel[LEDC_CHANNEL_0].conf0.idle_lv);
// check real output level over some period
gpio_input_enable(PULSE_IO);
for (int i = 0; i < 40; i++) {
TEST_ASSERT_EQUAL_INT32(!current_level, gpio_get_level(PULSE_IO));
esp_rom_delay_us(50);
}
}
TEST_CASE("LEDC iterate over all channel and timer configs", "[ledc]")