feat(ledc): add ETM support for LEDC peripheral

Closes https://github.com/espressif/esp-idf/issues/11855
This commit is contained in:
Song Ruo Jing
2025-11-14 20:58:17 +08:00
parent ca9b6b9607
commit 68f9d729cf
49 changed files with 2070 additions and 21 deletions
@@ -6,6 +6,10 @@ if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED)
list(APPEND srcs "test_ledc_sleep.cpp")
endif()
if(CONFIG_SOC_ETM_SUPPORTED AND CONFIG_SOC_LEDC_SUPPORT_ETM)
list(APPEND srcs "test_ledc_etm.cpp")
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(
@@ -0,0 +1,72 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "test_utils.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
#include "test_ledc_utils.h"
#include "esp_etm.h"
#include "esp_attr.h"
#include "driver/uart.h"
TEST_CASE("ledc etm event and task", "[ledc]")
{
// Generate a PWM signal with certain number of pulses
ledc_timer_config_t ledc_time_config = create_default_timer_config();
TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
ledc_channel_config_t ledc_ch_config = initialize_channel_config();
TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
vTaskDelay(pdMS_TO_TICKS(50));
ledc_timer_pause(TEST_SPEED_MODE, LEDC_TIMER_0);
TEST_ESP_OK(ledc_channel_configure_maximum_timer_ovf_cnt(TEST_SPEED_MODE, LEDC_CHANNEL_0, 500));
esp_etm_channel_config_t etm_config = {};
esp_etm_channel_handle_t etm_channel_a = NULL;
TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_a));
esp_etm_event_handle_t event_handle = NULL;
ledc_channel_etm_event_config_t event_config = {
.event_type = LEDC_CHANNEL_ETM_EVENT_REACH_MAX_OVF_CNT,
};
TEST_ESP_OK(ledc_channel_new_etm_event(TEST_SPEED_MODE, LEDC_CHANNEL_0, &event_config, &event_handle));
esp_etm_task_handle_t task_handle_a = NULL;
ledc_timer_etm_task_config_t task_config_a = {
.task_type = LEDC_TIMER_ETM_TASK_PAUSE,
};
TEST_ESP_OK(ledc_timer_new_etm_task(TEST_SPEED_MODE, LEDC_TIMER_0, &task_config_a, &task_handle_a));
TEST_ESP_OK(esp_etm_channel_connect(etm_channel_a, event_handle, task_handle_a));
TEST_ESP_OK(esp_etm_channel_enable(etm_channel_a));
// use UART auto baud rate detection feature to count the PWM pulse count
uart_bitrate_detect_config_t conf = {
.rx_io_num = PULSE_IO,
.source_clk = UART_SCLK_DEFAULT,
};
uart_bitrate_res_t res = {};
uart_detect_bitrate_start(UART_NUM_1, &conf);
TEST_ESP_OK(ledc_timer_rst(TEST_SPEED_MODE, LEDC_TIMER_0));
TEST_ESP_OK(ledc_timer_resume(TEST_SPEED_MODE, LEDC_TIMER_0));
vTaskDelay(pdMS_TO_TICKS(500));
uart_detect_bitrate_stop(UART_NUM_1, true, &res);
uint32_t pulse_count = (res.edge_cnt + 1) / 2;
TEST_ASSERT_INT32_WITHIN(1, 500, pulse_count);
TEST_ESP_OK(esp_etm_channel_disable(etm_channel_a));
TEST_ESP_OK(esp_etm_del_event(event_handle));
TEST_ESP_OK(esp_etm_del_task(task_handle_a));
TEST_ESP_OK(esp_etm_del_channel(etm_channel_a));
}