Skip to content

Commit

Permalink
Merge branch 'feature/add_ledc_output_in_sleep_test_v5.4' into 'relea…
Browse files Browse the repository at this point in the history
…se/v5.4'

feat(ledc): added a multi device test for testing ledc output in sleep (v5.4)

See merge request espressif/esp-idf!34522
  • Loading branch information
Jiang Jiang Jian committed Nov 4, 2024
2 parents 131609c + 3310330 commit b21b729
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
set(srcs "test_app_main.c"
"test_ledc.c"
"test_ledc_sleep.c"
"test_ledc_utils.c")

if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED)
list(APPEND srcs "test_ledc_sleep.c")
endif()

# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies:
test_utils:
path: ${IDF_PATH}/tools/unit-test-app/components/test_utils
64 changes: 62 additions & 2 deletions components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

#include "unity.h"
#include "test_utils.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
Expand All @@ -15,6 +16,7 @@
#include "esp_private/esp_pmu.h"
#include "soc/ledc_periph.h"
#include "esp_private/sleep_retention.h"
#include "esp_rom_uart.h"

// Note. Test cases in this file cannot run one after another without reset

Expand Down Expand Up @@ -51,15 +53,15 @@ static void test_ledc_sleep_retention(bool allow_pd)
#endif
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(2 * 1000 * 1000));

printf("go to light sleep for 2 seconds\n");
printf("Go to light sleep for 2 seconds\n");
TEST_ESP_OK(esp_light_sleep_start());
printf("Waked up! Let's see if LEDC peripheral can still work...\n");

#if ESP_SLEEP_POWER_DOWN_CPU
TEST_ESP_OK(sleep_cpu_configure(false));
#endif

printf("check if the sleep happened as expected\r\n");
printf("Check if the sleep happened as expected\r\n");
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
#if SOC_PMU_SUPPORTED
// check if the TOP power domain on/off as desired
Expand Down Expand Up @@ -97,3 +99,61 @@ TEST_CASE("ledc can output after light sleep (LEDC power domain pd)", "[ledc]")
sleep_retention_module_deinit(module);
}
#endif

#if SOC_PCNT_SUPPORTED
static const ledc_clk_src_t test_ledc_clk_in_slp[] = {
LEDC_USE_RC_FAST_CLK,
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
LEDC_USE_XTAL_CLK,
#endif
};

static const int test_clks_num = sizeof(test_ledc_clk_in_slp) / sizeof(test_ledc_clk_in_slp[0]);

static void ledc_output_monitor(void)
{
setup_testbench();

for (int i = 0; i < test_clks_num; i++) {
unity_wait_for_signal("Go to light sleep for 3 seconds");
vTaskDelay(500 / portTICK_PERIOD_MS);
int pulse_count = wave_count(1000);
uint32_t acceptable_delta = (test_ledc_clk_in_slp[i] == (ledc_clk_src_t)LEDC_USE_RC_FAST_CLK) ? 20 : 5; // RC_FAST as the clk src has a bigger error range is reasonable
TEST_ASSERT_UINT32_WITHIN(acceptable_delta, TEST_PWM_LOW_FREQ, pulse_count);
unity_wait_for_signal("Waked up!");
}

tear_testbench();
}

static void ledc_output_in_sleep(void)
{
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(3 * 1000 * 1000));

ledc_channel_config_t ledc_ch_config = initialize_channel_config();
ledc_ch_config.speed_mode = LEDC_LOW_SPEED_MODE;
ledc_ch_config.sleep_mode = LEDC_SLEEP_MODE_KEEP_ALIVE;
TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));

for (int i = 0; i < test_clks_num; i++) {
ledc_timer_config_t ledc_time_config = create_default_timer_config();
ledc_time_config.speed_mode = LEDC_LOW_SPEED_MODE;
ledc_time_config.clk_cfg = test_ledc_clk_in_slp[i];
ledc_time_config.freq_hz = TEST_PWM_LOW_FREQ;
TEST_ESP_OK(ledc_timer_config(&ledc_time_config));

TEST_ESP_OK(ledc_update_duty(ledc_ch_config.speed_mode, ledc_ch_config.channel));

unity_send_signal("Go to light sleep for 3 seconds");
esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM); // wait until the signal sent
TEST_ESP_OK(esp_light_sleep_start());
unity_send_signal("Waked up!");

TEST_ESP_OK(ledc_timer_pause(ledc_time_config.speed_mode, ledc_time_config.timer_num));
ledc_time_config.deconfigure = 1;
TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
}
}

TEST_CASE_MULTIPLE_DEVICES("ledc can output during light sleep", "[ledc][test_env=generic_multi_device]", ledc_output_in_sleep, ledc_output_monitor);
#endif // SOC_PCNT_SUPPORTED
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

#define PULSE_IO 5

#define TEST_PWM_FREQ 2000
#define TEST_PWM_FREQ 2000
#define TEST_PWM_LOW_FREQ 200

#if SOC_LEDC_SUPPORT_HS_MODE
#define TEST_SPEED_MODE LEDC_HIGH_SPEED_MODE
Expand Down
16 changes: 16 additions & 0 deletions components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,19 @@ def test_ledc(dut: IdfDut) -> None:
)
def test_ledc_psram(dut: IdfDut) -> None:
dut.run_all_single_board_cases(reset=True)


@pytest.mark.supported_targets
@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32c61'],
reason='s3 multi device runner has no psram, c61 lack of runner IDF-10949')
@pytest.mark.generic_multi_device
@pytest.mark.parametrize(
'count, config',
[
(2, 'iram_safe',),
(2, 'release',),
],
indirect=True
)
def test_ledc_multi_device(case_tester) -> None: # type: ignore
case_tester.run_all_multi_dev_cases(reset=True)

0 comments on commit b21b729

Please sign in to comment.