From 30b2e020881057698db23e99ee2e37297ad0fb15 Mon Sep 17 00:00:00 2001 From: houwenxiang Date: Tue, 22 Oct 2019 16:34:13 +0800 Subject: [PATCH] bugfix(LEDC):fix ledc CI issue for esp32s2beta. --- components/driver/ledc.c | 61 ++++-- .../driver/test/{esp32 => }/test_ledc.c | 186 +++++++++++------- tools/ci/config/target-test.yml | 21 ++ 3 files changed, 173 insertions(+), 95 deletions(-) rename components/driver/test/{esp32 => }/test_ledc.c (70%) diff --git a/components/driver/ledc.c b/components/driver/ledc.c index f44625217e..352c76257c 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -168,6 +168,27 @@ static int ledc_get_max_duty(ledc_mode_t speed_mode, ledc_channel_t channel) return max_duty; } +static ledc_clk_cfg_t ledc_timer_get_source_clk(ledc_mode_t speed_mode, ledc_timer_t timer_sel) +{ + ledc_clk_cfg_t clk_cfg = LEDC_USE_APB_CLK; +#ifdef CONFIG_IDF_TARGET_ESP32 + if (speed_mode == LEDC_LOW_SPEED_MODE && LEDC.conf.slow_clk_sel == 0) { + clk_cfg = LEDC_USE_RTC8M_CLK; + } else if( LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 0) { + clk_cfg = LEDC_USE_REF_TICK; + } +#elif defined CONFIG_IDF_TARGET_ESP32S2BETA + if (LEDC.conf.apb_clk_sel == 2) { + clk_cfg = LEDC_USE_RTC8M_CLK; + } else if (LEDC.conf.apb_clk_sel == 1) { + if (LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel) { + clk_cfg = LEDC_USE_REF_TICK; + } + } +#endif + return clk_cfg; +} + esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider, uint32_t duty_resolution, ledc_clk_src_t clk_src) { @@ -176,7 +197,7 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_ portENTER_CRITICAL(&ledc_spinlock); LEDC.timer_group[speed_mode].timer[timer_sel].conf.clock_divider = clock_divider; #ifdef CONFIG_IDF_TARGET_ESP32 - LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = clk_src; + LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = clk_src; #elif defined CONFIG_IDF_TARGET_ESP32S2BETA if(clk_src == LEDC_REF_TICK) { //REF_TICK can only be used when APB is selected. @@ -184,7 +205,6 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_ LEDC.conf.apb_clk_sel = 1; } else { LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 0; - LEDC.conf.apb_clk_sel = clk_src; } #endif LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution = duty_resolution; @@ -308,12 +328,21 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n if (div_param < 256 || div_param > LEDC_TIMER_DIV_NUM_MAX) { goto error; } + portENTER_CRITICAL(&ledc_spinlock); #ifdef CONFIG_IDF_TARGET_ESP32 // For low speed channels, if RTC_8MCLK is used as the source clock, the `slow_clk_sel` register should be cleared, otherwise it should be set. if (speed_mode == LEDC_LOW_SPEED_MODE) { LEDC.conf.slow_clk_sel = (clk_cfg == LEDC_USE_RTC8M_CLK) ? 0 : 1; } +#elif defined CONFIG_IDF_TARGET_ESP32S2BETA + if (clk_cfg == LEDC_USE_RTC8M_CLK) { + LEDC.conf.apb_clk_sel = 2; + } else { + LEDC.conf.apb_clk_sel = 1; + } + //TODO:Support XTAL_CLK #endif + portEXIT_CRITICAL(&ledc_spinlock); //Set the divisor ledc_timer_set(speed_mode, timer_num, div_param, duty_resolution, timer_clk_src); // reset the timer @@ -499,23 +528,11 @@ int ledc_get_hpoint(ledc_mode_t speed_mode, ledc_channel_t channel) esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz) { LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode"); - portENTER_CRITICAL(&ledc_spinlock); esp_err_t ret = ESP_OK; - uint32_t clock_divider = 0; + ledc_clk_cfg_t clk_cfg = LEDC_AUTO_CLK; + portENTER_CRITICAL(&ledc_spinlock); uint32_t duty_resolution = LEDC.timer_group[speed_mode].timer[timer_num].conf.duty_resolution; - uint32_t timer_source_clk = LEDC.timer_group[speed_mode].timer[timer_num].conf.tick_sel; - uint32_t precision = (0x1 << duty_resolution); - if (timer_source_clk == LEDC_APB_CLK) { - clock_divider = ((uint64_t) LEDC_APB_CLK_HZ << 8) / freq_hz / precision; - } else { - clock_divider = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision; - } - if (clock_divider <= 256 || clock_divider > LEDC_TIMER_DIV_NUM_MAX) { - ESP_LOGE(LEDC_TAG, "div param err,div_param=%u", clock_divider); - ret = ESP_FAIL; - } - LEDC.timer_group[speed_mode].timer[timer_num].conf.clock_divider = clock_divider; - ledc_ls_timer_update(speed_mode, timer_num); + ledc_set_timer_div(speed_mode, timer_num, clk_cfg, freq_hz, duty_resolution); portEXIT_CRITICAL(&ledc_spinlock); return ret; } @@ -523,18 +540,20 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num) { LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode"); - portENTER_CRITICAL(&ledc_spinlock); uint32_t freq = 0; - uint32_t timer_source_clk = LEDC.timer_group[speed_mode].timer[timer_num].conf.tick_sel; + portENTER_CRITICAL(&ledc_spinlock); + ledc_clk_cfg_t timer_source_clk = ledc_timer_get_source_clk(speed_mode, timer_num); uint32_t duty_resolution = LEDC.timer_group[speed_mode].timer[timer_num].conf.duty_resolution; uint32_t clock_divider = LEDC.timer_group[speed_mode].timer[timer_num].conf.clock_divider; uint32_t precision = (0x1 << duty_resolution); - if (timer_source_clk == LEDC_APB_CLK) { + portEXIT_CRITICAL(&ledc_spinlock); + if (timer_source_clk == LEDC_USE_APB_CLK) { freq = ((uint64_t) LEDC_APB_CLK_HZ << 8) / precision / clock_divider; + } else if(timer_source_clk == LEDC_USE_RTC8M_CLK) { + freq = ((uint64_t) s_ledc_slow_clk_8M << 8) / precision / clock_divider; } else { freq = ((uint64_t) LEDC_REF_CLK_HZ << 8) / precision / clock_divider; } - portEXIT_CRITICAL(&ledc_spinlock); return freq; } diff --git a/components/driver/test/esp32/test_ledc.c b/components/driver/test/test_ledc.c similarity index 70% rename from components/driver/test/esp32/test_ledc.c rename to components/driver/test/test_ledc.c index b5e9441e00..4624d03aac 100644 --- a/components/driver/test/esp32/test_ledc.c +++ b/components/driver/test/test_ledc.c @@ -52,6 +52,7 @@ static int16_t wave_count(int last_time) // initialize first TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); + vTaskDelay(100 / portTICK_RATE_MS); TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter)); @@ -79,27 +80,20 @@ static void timer_frequency_test(ledc_channel_t channel, ledc_timer_bit_t timer_ .intr_type = LEDC_INTR_DISABLE, .timer_sel = timer, .duty = 4000, + .hpoint = 0, }; ledc_timer_config_t ledc_time_config = { .speed_mode = speed_mode, .duty_resolution = timer_bit, .timer_num = timer, .freq_hz = 5000, - .clk_cfg = LEDC_AUTO_CLK, + .clk_cfg = LEDC_USE_APB_CLK, }; TEST_ESP_OK(ledc_channel_config(&ledc_ch_config)); TEST_ESP_OK(ledc_timer_config(&ledc_time_config)); - - if(ledc_ch_config.speed_mode == LEDC_HIGH_SPEED_MODE) { - frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 100, 100, 2); - frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 5000, 5000, 5); - frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 9000, 9025, 5); - } else { - frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 10, 10, 1); -// comment it because this is a bug that when ledc in low speed mode, its frequency can't be changed -// frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 50, 50, 2); -// frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 100, 100, 2); - } + frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 100, 100, 2); + frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 5000, 5000, 5); + frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 9000, 9025, 5); } static void timer_duty_set_get(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty) @@ -120,13 +114,14 @@ static void timer_duty_test(ledc_channel_t channel, ledc_timer_bit_t timer_bit, .intr_type = LEDC_INTR_DISABLE, .timer_sel = timer, .duty = 4000, + .hpoint = 0, }; ledc_timer_config_t ledc_time_config = { .speed_mode = speed_mode, .duty_resolution = timer_bit, .timer_num = timer, .freq_hz = 5000, - .clk_cfg = LEDC_AUTO_CLK, + .clk_cfg = LEDC_USE_APB_CLK, }; TEST_ESP_OK(ledc_channel_config(&ledc_ch_config)); TEST_ESP_OK(ledc_timer_config(&ledc_time_config)); @@ -141,14 +136,20 @@ static void timer_duty_test(ledc_channel_t channel, ledc_timer_bit_t timer_bit, TEST_CASE("LEDC error log channel and timer config", "[ledc][test_env=UT_T1_LEDC]") { +#ifdef CONFIG_IDF_TARGET_ESP32 + const ledc_mode_t test_speed_mode = LEDC_HIGH_SPEED_MODE; +#elif defined CONFIG_IDF_TARGET_ESP32S2BETA + const ledc_mode_t test_speed_mode = LEDC_LOW_SPEED_MODE; +#endif //channel configuration test ledc_channel_config_t ledc_ch_config = { .gpio_num = PULSE_IO, - .speed_mode = LEDC_HIGH_SPEED_MODE, + .speed_mode = test_speed_mode, .channel = LEDC_CHANNEL_0, .intr_type = LEDC_INTR_DISABLE, .timer_sel = LEDC_TIMER_0, .duty = 4000, + .hpoint = 0, }; // basic right parameter test @@ -156,9 +157,8 @@ TEST_CASE("LEDC error log channel and timer config", "[ledc][test_env=UT_T1_LEDC TEST_ESP_OK(ledc_channel_config(&ledc_ch_config)); // with wrong GPIO using - ledc_ch_config.gpio_num = 41; + ledc_ch_config.gpio_num = GPIO_NUM_MAX; TEST_ASSERT(ledc_channel_config(&ledc_ch_config) == ESP_ERR_INVALID_ARG); - // with wrong speed ledc_ch_config = temp_ch_config; ledc_ch_config.speed_mode = LEDC_SPEED_MODE_MAX; @@ -185,11 +185,11 @@ TEST_CASE("LEDC error log channel and timer config", "[ledc][test_env=UT_T1_LEDC // timer configuration test ledc_timer_config_t ledc_time_config; - ledc_time_config.speed_mode = LEDC_HIGH_SPEED_MODE; + ledc_time_config.speed_mode = test_speed_mode; ledc_time_config.duty_resolution = LEDC_TIMER_13_BIT; ledc_time_config.timer_num = LEDC_TIMER_0; ledc_time_config.freq_hz = 5000; - ledc_time_config.clk_cfg = LEDC_AUTO_CLK; + ledc_time_config.clk_cfg = LEDC_USE_APB_CLK; ledc_timer_config_t temp_timer_config = ledc_time_config; TEST_ESP_OK(ledc_timer_config(&ledc_time_config)); @@ -207,39 +207,42 @@ TEST_CASE("LEDC error log channel and timer config", "[ledc][test_env=UT_T1_LEDC ledc_time_config.timer_num = 4; TEST_ASSERT(ledc_timer_config(&ledc_time_config) == ESP_ERR_INVALID_ARG); - uint32_t current_level = LEDC.channel_group[LEDC_HIGH_SPEED_MODE].channel[LEDC_CHANNEL_0].conf0.idle_lv; - TEST_ESP_OK(ledc_stop(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, !current_level)); + uint32_t current_level = LEDC.channel_group[test_speed_mode].channel[LEDC_CHANNEL_0].conf0.idle_lv; + TEST_ESP_OK(ledc_stop(test_speed_mode, LEDC_CHANNEL_0, !current_level)); vTaskDelay(1000 / portTICK_RATE_MS); - TEST_ASSERT_EQUAL_INT32( LEDC.channel_group[LEDC_HIGH_SPEED_MODE].channel[LEDC_CHANNEL_0].conf0.idle_lv, !current_level); + TEST_ASSERT_EQUAL_INT32( LEDC.channel_group[test_speed_mode].channel[LEDC_CHANNEL_0].conf0.idle_lv, !current_level); } TEST_CASE("LEDC normal channel and timer config", "[ledc][test_env=UT_T1_LEDC]") { ledc_channel_config_t ledc_ch_config = { .gpio_num = PULSE_IO, - .speed_mode = LEDC_HIGH_SPEED_MODE, .channel = LEDC_CHANNEL_0, .intr_type = LEDC_INTR_DISABLE, .timer_sel = LEDC_TIMER_0, .duty = 4000, + .hpoint = 0, }; ledc_channel_config_t temp_ch_config = ledc_ch_config; ledc_timer_config_t ledc_time_config = { - .speed_mode = LEDC_HIGH_SPEED_MODE, .duty_resolution = LEDC_TIMER_13_BIT, .timer_num = LEDC_TIMER_0, .freq_hz = 5000, - .clk_cfg = LEDC_AUTO_CLK, + .clk_cfg = LEDC_USE_APB_CLK, }; ledc_timer_config_t temp_time_config = ledc_time_config; // use all kinds of speed mode, channel, timer combination to test all of possible configuration - ledc_mode_t speed_mode[2] = {LEDC_HIGH_SPEED_MODE, LEDC_LOW_SPEED_MODE}; +#ifdef CONFIG_IDF_TARGET_ESP32 + ledc_mode_t speed_mode[LEDC_SPEED_MODE_MAX] = {LEDC_HIGH_SPEED_MODE, LEDC_LOW_SPEED_MODE}; +#elif defined CONFIG_IDF_TARGET_ESP32S2BETA + ledc_mode_t speed_mode[LEDC_SPEED_MODE_MAX] = {LEDC_LOW_SPEED_MODE}; +#endif ledc_channel_t channel_type[8] = {LEDC_CHANNEL_0, LEDC_CHANNEL_1, LEDC_CHANNEL_2, LEDC_CHANNEL_3, LEDC_CHANNEL_4, LEDC_CHANNEL_5, LEDC_CHANNEL_6, LEDC_CHANNEL_7}; ledc_timer_t timer_select[4] = {LEDC_TIMER_0, LEDC_TIMER_1, LEDC_TIMER_2, LEDC_TIMER_3}; - for (int i = 0; i < 2; i++) { + for (int i = 0; i < LEDC_SPEED_MODE_MAX; i++) { ledc_ch_config.speed_mode = speed_mode[i]; ledc_time_config.speed_mode = speed_mode[i]; for (int j = 0; j < 8; j++) { @@ -259,11 +262,12 @@ TEST_CASE("LEDC normal channel and timer config", "[ledc][test_env=UT_T1_LEDC]") // set it ignore: need to debug TEST_CASE("LEDC set and get frequency", "[ledc][test_env=UT_T1_LEDC][timeout=60][ignore]") { +#ifdef CONFIG_IDF_TARGET_ESP32 timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_0, LEDC_HIGH_SPEED_MODE); timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_1, LEDC_HIGH_SPEED_MODE); timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_2, LEDC_HIGH_SPEED_MODE); timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_3, LEDC_HIGH_SPEED_MODE); - +#endif timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_0, LEDC_LOW_SPEED_MODE); timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_1, LEDC_LOW_SPEED_MODE); timer_frequency_test(LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, LEDC_TIMER_2, LEDC_LOW_SPEED_MODE); @@ -275,9 +279,13 @@ TEST_CASE("LEDC set and get frequency", "[ledc][test_env=UT_T1_LEDC][timeout=60] TEST_CASE("LEDC set and get dut(with logic analyzer)", "[ledc][ignore]") { ledc_timer_t timer_list[4] = {LEDC_TIMER_0, LEDC_TIMER_1, LEDC_TIMER_2, LEDC_TIMER_3}; - ledc_mode_t speed_mode_list[2] = {LEDC_HIGH_SPEED_MODE, LEDC_LOW_SPEED_MODE}; +#ifdef CONFIG_IDF_TARGET_ESP32 + ledc_mode_t speed_mode_list[LEDC_SPEED_MODE_MAX] = {LEDC_HIGH_SPEED_MODE, LEDC_LOW_SPEED_MODE}; +#elif defined CONFIG_IDF_TARGET_ESP32S2BETA + ledc_mode_t speed_mode_list[LEDC_SPEED_MODE_MAX] = {LEDC_LOW_SPEED_MODE}; +#endif for(int i=0; i