mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(mcpwm): account for adjusted timer resolution in test
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -61,6 +61,17 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
esp_err_t mcpwm_new_timer(const mcpwm_timer_config_t *config, mcpwm_timer_handle_t *ret_timer);
|
esp_err_t mcpwm_new_timer(const mcpwm_timer_config_t *config, mcpwm_timer_handle_t *ret_timer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get MCPWM timer resolution, in Hz
|
||||||
|
*
|
||||||
|
* @param[in] timer MCPWM timer handle, allocated by `mcpwm_new_timer()`
|
||||||
|
* @param[out] out_resolution Returned timer resolution, in Hz
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: Get timer resolution successfully
|
||||||
|
* - ESP_ERR_INVALID_ARG: Get timer resolution failed because of invalid argument
|
||||||
|
*/
|
||||||
|
esp_err_t mcpwm_timer_get_resolution(mcpwm_timer_handle_t timer, uint32_t *out_resolution);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Delete MCPWM timer
|
* @brief Delete MCPWM timer
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -145,6 +145,13 @@ err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t mcpwm_timer_get_resolution(mcpwm_timer_handle_t timer, uint32_t *out_resolution)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(timer && out_resolution, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
|
*out_resolution = timer->resolution_hz;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t mcpwm_del_timer(mcpwm_timer_handle_t timer)
|
esp_err_t mcpwm_del_timer(mcpwm_timer_handle_t timer)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
ESP_RETURN_ON_FALSE(timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/event_groups.h"
|
#include "freertos/event_groups.h"
|
||||||
@@ -90,19 +91,24 @@ TEST_CASE("mcpwm_timer_start_stop", "[mcpwm]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TOLERANCE_PERCENT_RC_FAST 10 // 10% error allowed
|
||||||
|
#define TARGET_TIMER_RESOLUTION_HZ 1000000U
|
||||||
|
#define TIMER_RESOLUTION_TEST_DELAY_US 5000U
|
||||||
|
#define TARGET_TIMER_PERIOD_TICKS \
|
||||||
|
(2ULL * TARGET_TIMER_RESOLUTION_HZ * TIMER_RESOLUTION_TEST_DELAY_US / 1000000ULL) // nominal period should be >= 2x measurement window
|
||||||
|
|
||||||
TEST_CASE("mcpwm_timer_various_clk_src", "[mcpwm]")
|
TEST_CASE("mcpwm_timer_various_clk_src", "[mcpwm]")
|
||||||
{
|
{
|
||||||
mcpwm_timer_clock_source_t clk_srcs[] = SOC_MCPWM_TIMER_CLKS;
|
mcpwm_timer_clock_source_t clk_srcs[] = SOC_MCPWM_TIMER_CLKS;
|
||||||
const int num_timers = MCPWM_LL_GET(TIMERS_PER_GROUP) * MCPWM_LL_GET(GROUP_NUM);
|
const int num_timers = MCPWM_LL_GET(TIMERS_PER_GROUP) * MCPWM_LL_GET(GROUP_NUM);
|
||||||
const uint32_t resolution_test_duration_us = 5000;
|
|
||||||
|
|
||||||
for (size_t clk_src_idx = 0; clk_src_idx < sizeof(clk_srcs) / sizeof(clk_srcs[0]); clk_src_idx++) {
|
for (size_t clk_src_idx = 0; clk_src_idx < sizeof(clk_srcs) / sizeof(clk_srcs[0]); clk_src_idx++) {
|
||||||
mcpwm_timer_clock_source_t clk_src = clk_srcs[clk_src_idx];
|
mcpwm_timer_clock_source_t clk_src = clk_srcs[clk_src_idx];
|
||||||
const uint32_t tolerance_percent = (soc_module_clk_t)clk_src == SOC_MOD_CLK_RC_FAST ? 10 : 1;
|
const uint32_t tolerance_percent = (soc_module_clk_t)clk_src == SOC_MOD_CLK_RC_FAST ? TOLERANCE_PERCENT_RC_FAST : 1;
|
||||||
mcpwm_timer_config_t config = {
|
mcpwm_timer_config_t config = {
|
||||||
.clk_src = clk_src,
|
.clk_src = clk_src,
|
||||||
.resolution_hz = 1000000, // 1MHz
|
.resolution_hz = TARGET_TIMER_RESOLUTION_HZ,
|
||||||
.period_ticks = 12000,
|
.period_ticks = TARGET_TIMER_PERIOD_TICKS,
|
||||||
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
|
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,31 +129,36 @@ TEST_CASE("mcpwm_timer_various_clk_src", "[mcpwm]")
|
|||||||
|
|
||||||
printf("check timer resolution\r\n");
|
printf("check timer resolution\r\n");
|
||||||
for (int i = 0; i < num_timers; i++) {
|
for (int i = 0; i < num_timers; i++) {
|
||||||
|
uint32_t timer_resolution_hz = 0; // determined by mcpwm_new_timer()
|
||||||
|
TEST_ESP_OK(mcpwm_timer_get_resolution(timers[i], &timer_resolution_hz));
|
||||||
|
|
||||||
TEST_ESP_OK(mcpwm_timer_start_stop(timers[i], MCPWM_TIMER_START_NO_STOP));
|
TEST_ESP_OK(mcpwm_timer_start_stop(timers[i], MCPWM_TIMER_START_NO_STOP));
|
||||||
|
|
||||||
uint32_t start_count = 0;
|
uint32_t cnt_start = 0;
|
||||||
uint32_t end_count = 0;
|
uint32_t cnt_end = 0;
|
||||||
mcpwm_timer_direction_t direction;
|
mcpwm_timer_direction_t direction;
|
||||||
TEST_ESP_OK(mcpwm_timer_get_phase(timers[i], &start_count, &direction));
|
|
||||||
int64_t start_time_us = esp_timer_get_time();
|
|
||||||
|
|
||||||
esp_rom_delay_us(resolution_test_duration_us);
|
TEST_ESP_OK(mcpwm_timer_get_phase(timers[i], &cnt_start, &direction));
|
||||||
|
int64_t time_start_us = esp_timer_get_time();
|
||||||
|
esp_rom_delay_us(TIMER_RESOLUTION_TEST_DELAY_US);
|
||||||
|
TEST_ESP_OK(mcpwm_timer_get_phase(timers[i], &cnt_end, &direction));
|
||||||
|
int64_t time_end_us = esp_timer_get_time();
|
||||||
|
|
||||||
TEST_ESP_OK(mcpwm_timer_get_phase(timers[i], &end_count, &direction));
|
int64_t time_delta_us = time_end_us - time_start_us;
|
||||||
int64_t elapsed_time_us = esp_timer_get_time() - start_time_us;
|
uint32_t expected_ticks = (uint64_t)timer_resolution_hz * time_delta_us / 1000000;
|
||||||
uint32_t expected_ticks = (uint64_t)config.resolution_hz * elapsed_time_us / 1000000;
|
|
||||||
uint32_t actual_ticks;
|
|
||||||
if (end_count >= start_count) {
|
|
||||||
actual_ticks = end_count - start_count;
|
|
||||||
} else {
|
|
||||||
actual_ticks = config.period_ticks - start_count + end_count;
|
|
||||||
}
|
|
||||||
uint32_t tolerance_ticks = expected_ticks * tolerance_percent / 100;
|
uint32_t tolerance_ticks = expected_ticks * tolerance_percent / 100;
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(MCPWM_TIMER_DIRECTION_UP, direction);
|
uint32_t measured_ticks;
|
||||||
TEST_ASSERT_UINT32_WITHIN(tolerance_ticks, expected_ticks, actual_ticks);
|
if (cnt_end >= cnt_start) {
|
||||||
|
measured_ticks = cnt_end - cnt_start;
|
||||||
|
} else {
|
||||||
|
measured_ticks = config.period_ticks - cnt_start + cnt_end;
|
||||||
|
}
|
||||||
|
|
||||||
// make sure the timer has stopped
|
TEST_ASSERT_EQUAL(MCPWM_TIMER_DIRECTION_UP, direction);
|
||||||
|
TEST_ASSERT_UINT32_WITHIN(tolerance_ticks, expected_ticks, measured_ticks);
|
||||||
|
|
||||||
|
// ensure timer has stopped
|
||||||
TEST_ESP_OK(mcpwm_timer_start_stop(timers[i], MCPWM_TIMER_STOP_EMPTY));
|
TEST_ESP_OK(mcpwm_timer_start_stop(timers[i], MCPWM_TIMER_STOP_EMPTY));
|
||||||
vTaskDelay(pdMS_TO_TICKS(20));
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
check_mcpwm_timer_phase(&timers[i], 1, 0, MCPWM_TIMER_DIRECTION_UP);
|
check_mcpwm_timer_phase(&timers[i], 1, 0, MCPWM_TIMER_DIRECTION_UP);
|
||||||
|
|||||||
Reference in New Issue
Block a user