Merge branch 'feature/add_mcpwm_rc_fast_clk_source_v6.1' into 'release/v6.1'

feat(mcpwm): support RC_FAST group clock source (backport v6.1)

See merge request espressif/esp-idf!51322
This commit is contained in:
morris
2026-07-31 10:05:25 +08:00
9 changed files with 105 additions and 13 deletions

View File

@@ -25,4 +25,5 @@ endif()
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES unity esp_driver_mcpwm esp_driver_gpio esp_driver_gptimer esp_psram
esp_timer esp_rom
WHOLE_ARCHIVE)

View File

@@ -7,6 +7,8 @@
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "unity.h"
#include "esp_timer.h"
#include "esp_rom_sys.h"
#include "hal/mcpwm_ll.h"
#include "driver/mcpwm_timer.h"
#include "esp_private/mcpwm.h"
@@ -88,6 +90,77 @@ TEST_CASE("mcpwm_timer_start_stop", "[mcpwm]")
}
}
TEST_CASE("mcpwm_timer_various_clk_src", "[mcpwm]")
{
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 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++) {
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;
mcpwm_timer_config_t config = {
.clk_src = clk_src,
.resolution_hz = 1000000, // 1MHz
.period_ticks = 12000,
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
};
printf("create MCPWM timers with clock source: %d\r\n", clk_src);
mcpwm_timer_handle_t timers[num_timers];
for (int group_id = 0; group_id < MCPWM_LL_GET(GROUP_NUM); group_id++) {
config.group_id = group_id;
for (int timer_id = 0; timer_id < MCPWM_LL_GET(TIMERS_PER_GROUP); timer_id++) {
int timer_index = group_id * MCPWM_LL_GET(TIMERS_PER_GROUP) + timer_id;
TEST_ESP_OK(mcpwm_new_timer(&config, &timers[timer_index]));
}
}
printf("enable timers\r\n");
for (int i = 0; i < num_timers; i++) {
TEST_ESP_OK(mcpwm_timer_enable(timers[i]));
}
printf("check timer resolution\r\n");
for (int i = 0; i < num_timers; i++) {
TEST_ESP_OK(mcpwm_timer_start_stop(timers[i], MCPWM_TIMER_START_NO_STOP));
uint32_t start_count = 0;
uint32_t end_count = 0;
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], &end_count, &direction));
int64_t elapsed_time_us = esp_timer_get_time() - start_time_us;
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;
TEST_ASSERT_EQUAL(MCPWM_TIMER_DIRECTION_UP, direction);
TEST_ASSERT_UINT32_WITHIN(tolerance_ticks, expected_ticks, actual_ticks);
// make sure the timer has stopped
TEST_ESP_OK(mcpwm_timer_start_stop(timers[i], MCPWM_TIMER_STOP_EMPTY));
vTaskDelay(pdMS_TO_TICKS(20));
check_mcpwm_timer_phase(&timers[i], 1, 0, MCPWM_TIMER_DIRECTION_UP);
}
printf("disable and delete timers\r\n");
for (int i = 0; i < num_timers; i++) {
TEST_ESP_OK(mcpwm_timer_disable(timers[i]));
TEST_ESP_OK(mcpwm_del_timer(timers[i]));
}
}
}
#define TEST_MCPWM_TIMER_EVENT_BIT_FULL (1 << 0)
#define TEST_MCPWM_TIMER_EVENT_BIT_EMPTY (1 << 1)
#define TEST_MCPWM_TIMER_EVENT_BIT_STOP (1 << 2)

View File

@@ -145,6 +145,9 @@ static inline void mcpwm_ll_group_set_clock_source(int group_id, soc_module_clk_
case SOC_MOD_CLK_XTAL:
PCR.pwm_clk_conf.pwm_clkm_sel = 2;
break;
case SOC_MOD_CLK_RC_FAST:
PCR.pwm_clk_conf.pwm_clkm_sel = 3;
break;
default:
HAL_ASSERT(false);
break;

View File

@@ -140,6 +140,9 @@ static inline void mcpwm_ll_group_set_clock_source(int group_id, soc_module_clk_
case SOC_MOD_CLK_XTAL:
PCR.pwm_clk_conf.pwm_clkm_sel = 0;
break;
case SOC_MOD_CLK_RC_FAST:
PCR.pwm_clk_conf.pwm_clkm_sel = 1;
break;
case SOC_MOD_CLK_PLL_F96M:
PCR.pwm_clk_conf.pwm_clkm_sel = 2;
break;

View File

@@ -181,7 +181,7 @@ static inline void mcpwm_ll_group_set_clock_source(int group_id, soc_module_clk_
case SOC_MOD_CLK_XTAL:
clk_id = 0;
break;
case SOC_MOD_CLK_PLL_F20M:
case SOC_MOD_CLK_RC_FAST:
clk_id = 1;
break;
case SOC_MOD_CLK_PLL_F160M:

View File

@@ -284,13 +284,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Timer
*/
#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM timer clock source
*/
typedef enum {
MCPWM_TIMER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_TIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
} soc_periph_mcpwm_timer_clk_src_t;
@@ -298,13 +299,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Capture Timer
*/
#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM capture clock source
*/
typedef enum {
MCPWM_CAPTURE_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_CAPTURE_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
} soc_periph_mcpwm_capture_clk_src_t;
@@ -312,13 +314,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Carrier
*/
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM carrier clock source
*/
typedef enum {
MCPWM_CARRIER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_CARRIER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_CARRIER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_CARRIER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
} soc_periph_mcpwm_carrier_clk_src_t;

View File

@@ -281,13 +281,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Timer
*/
#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM timer clock source
*/
typedef enum {
MCPWM_TIMER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_TIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
} soc_periph_mcpwm_timer_clk_src_t;
@@ -295,13 +296,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Capture Timer
*/
#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM capture clock source
*/
typedef enum {
MCPWM_CAPTURE_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_CAPTURE_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
} soc_periph_mcpwm_capture_clk_src_t;
@@ -309,13 +311,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Carrier
*/
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM carrier clock source
*/
typedef enum {
MCPWM_CARRIER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_CARRIER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_CARRIER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_CARRIER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
} soc_periph_mcpwm_carrier_clk_src_t;

View File

@@ -275,13 +275,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Timer
*/
#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F96M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F96M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM timer clock source
*/
typedef enum {
MCPWM_TIMER_CLK_SRC_PLL96M = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M as the source clock */
MCPWM_TIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M as the default clock choice */
} soc_periph_mcpwm_timer_clk_src_t;
@@ -289,13 +290,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Capture Timer
*/
#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F96M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F96M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM capture clock source
*/
typedef enum {
MCPWM_CAPTURE_CLK_SRC_PLL96M = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M as the source clock */
MCPWM_CAPTURE_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M as the default clock choice */
} soc_periph_mcpwm_capture_clk_src_t;
@@ -303,13 +305,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Carrier
*/
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F96M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F96M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM carrier clock source
*/
typedef enum {
MCPWM_CARRIER_CLK_SRC_PLL96M = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M as the source clock */
MCPWM_CARRIER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_CARRIER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_CARRIER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M as the default clock choice */
} soc_periph_mcpwm_carrier_clk_src_t;

View File

@@ -308,13 +308,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Timer
*/
#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_TIMER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM timer clock source
*/
typedef enum {
MCPWM_TIMER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_TIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default choice */
} soc_periph_mcpwm_timer_clk_src_t;
@@ -322,13 +323,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Capture Timer
*/
#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_CAPTURE_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM capture clock source
*/
typedef enum {
MCPWM_CAPTURE_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_CAPTURE_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default choice */
} soc_periph_mcpwm_capture_clk_src_t;
@@ -336,13 +338,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MCPWM Carrier
*/
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
/**
* @brief Type of MCPWM carrier clock source
*/
typedef enum {
MCPWM_CARRIER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_CARRIER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
MCPWM_CARRIER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MCPWM_CARRIER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default choice */
} soc_periph_mcpwm_carrier_clk_src_t;