mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/add_mcpwm_carrier_clk_source_v5.1' into 'release/v5.1'
feat(MCPWM): Add mcpwm carrier clk source(v5.1) See merge request espressif/esp-idf!25572
This commit is contained in:
commit
2a80451b24
@ -135,6 +135,7 @@ esp_err_t mcpwm_operator_register_event_callbacks(mcpwm_oper_handle_t oper, cons
|
||||
* @brief MCPWM carrier configuration structure
|
||||
*/
|
||||
typedef struct {
|
||||
mcpwm_carrier_clock_source_t clk_src; /*!< MCPWM carrier clock source */
|
||||
uint32_t frequency_hz; /*!< Carrier frequency in Hz */
|
||||
uint32_t first_pulse_duration_us; /*!< The duration of the first PWM pulse, in us */
|
||||
float duty_cycle; /*!< Carrier duty cycle */
|
||||
|
@ -182,9 +182,14 @@ esp_err_t mcpwm_operator_apply_carrier(mcpwm_oper_handle_t oper, const mcpwm_car
|
||||
float real_duty = 0.0;
|
||||
|
||||
if (config && config->frequency_hz) {
|
||||
uint8_t pre_scale = group->resolution_hz / 8 / config->frequency_hz;
|
||||
mcpwm_ll_carrier_set_prescale(hal->dev, oper_id, pre_scale);
|
||||
real_frequency = group->resolution_hz / 8 / pre_scale;
|
||||
// select the clock source
|
||||
mcpwm_carrier_clock_source_t clk_src = config->clk_src ? config->clk_src : MCPWM_CARRIER_CLK_SRC_DEFAULT;
|
||||
ESP_RETURN_ON_ERROR(mcpwm_select_periph_clock(group, (soc_module_clk_t)clk_src), TAG, "set group clock failed");
|
||||
|
||||
uint8_t prescale = group->resolution_hz / 8 / config->frequency_hz;
|
||||
ESP_RETURN_ON_FALSE(prescale > 0 && prescale <= MCPWM_LL_MAX_CARRIER_PRESCALE, ESP_ERR_INVALID_STATE, TAG, "group clock cannot match the frequency");
|
||||
mcpwm_ll_carrier_set_prescale(hal->dev, oper_id, prescale);
|
||||
real_frequency = group->resolution_hz / 8 / prescale;
|
||||
|
||||
uint8_t duty = (uint8_t)(config->duty_cycle * 8);
|
||||
mcpwm_ll_carrier_set_duty(hal->dev, oper_id, duty);
|
||||
|
@ -107,6 +107,7 @@ esp_err_t mcpwm_new_timer(const mcpwm_timer_config_t *config, mcpwm_timer_handle
|
||||
mcpwm_hal_timer_reset(hal, timer_id);
|
||||
// set timer resolution
|
||||
uint32_t prescale = group->resolution_hz / config->resolution_hz;
|
||||
ESP_RETURN_ON_FALSE(prescale > 0 && prescale <= MCPWM_LL_MAX_TIMER_PRESCALE, ESP_ERR_INVALID_STATE, TAG, "group clock cannot match the resolution");
|
||||
mcpwm_ll_timer_set_clock_prescale(hal->dev, timer_id, prescale);
|
||||
timer->resolution_hz = group->resolution_hz / prescale;
|
||||
if (timer->resolution_hz != config->resolution_hz) {
|
||||
|
@ -64,22 +64,11 @@ TEST_CASE("mcpwm_operator_install_uninstall", "[mcpwm]")
|
||||
|
||||
TEST_CASE("mcpwm_operator_carrier", "[mcpwm]")
|
||||
{
|
||||
mcpwm_timer_config_t timer_config = {
|
||||
.group_id = 0,
|
||||
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
|
||||
.resolution_hz = 1000000, // 1MHz, 1us per tick
|
||||
.period_ticks = 20000,
|
||||
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
|
||||
};
|
||||
mcpwm_timer_handle_t timer = NULL;
|
||||
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timer));
|
||||
|
||||
mcpwm_operator_config_t operator_config = {
|
||||
.group_id = 0,
|
||||
};
|
||||
mcpwm_oper_handle_t oper = NULL;
|
||||
TEST_ESP_OK(mcpwm_new_operator(&operator_config, &oper));
|
||||
TEST_ESP_OK(mcpwm_operator_connect_timer(oper, timer));
|
||||
|
||||
mcpwm_generator_config_t generator_config = {
|
||||
.gen_gpio_num = 0,
|
||||
@ -87,36 +76,34 @@ TEST_CASE("mcpwm_operator_carrier", "[mcpwm]")
|
||||
mcpwm_gen_handle_t generator = NULL;
|
||||
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &generator));
|
||||
|
||||
TEST_ESP_OK(mcpwm_generator_set_action_on_timer_event(generator,
|
||||
MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_TOGGLE)));
|
||||
|
||||
printf("add carrier to PWM wave\r\n");
|
||||
mcpwm_carrier_config_t carrier_config = {
|
||||
.clk_src = MCPWM_CARRIER_CLK_SRC_DEFAULT,
|
||||
.frequency_hz = 1000000, // 1MHz carrier
|
||||
.duty_cycle = 0.5,
|
||||
.first_pulse_duration_us = 10,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(mcpwm_operator_apply_carrier(oper, &carrier_config));
|
||||
|
||||
TEST_ESP_OK(mcpwm_timer_enable(timer));
|
||||
|
||||
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_START_NO_STOP));
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_STOP_EMPTY));
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
TEST_ESP_OK(mcpwm_generator_set_force_level(generator, 1, true));
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
TEST_ESP_OK(mcpwm_generator_set_force_level(generator, 0, true));
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
TEST_ESP_OK(mcpwm_generator_set_force_level(generator, 1, true));
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
|
||||
printf("remove carrier from PWM wave\r\n");
|
||||
carrier_config.frequency_hz = 0;
|
||||
TEST_ESP_OK(mcpwm_operator_apply_carrier(oper, &carrier_config));
|
||||
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_START_NO_STOP));
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_STOP_EMPTY));
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
TEST_ESP_OK(mcpwm_generator_set_force_level(generator, 1, true));
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
TEST_ESP_OK(mcpwm_generator_set_force_level(generator, 0, true));
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
TEST_ESP_OK(mcpwm_generator_set_force_level(generator, 1, true));
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
|
||||
TEST_ESP_OK(mcpwm_timer_disable(timer));
|
||||
TEST_ESP_OK(mcpwm_del_generator(generator));
|
||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||
}
|
||||
|
||||
static bool IRAM_ATTR test_cbc_brake_on_gpio_fault_callback(mcpwm_oper_handle_t oper, const mcpwm_brake_event_data_t *edata, void *user_data)
|
||||
|
@ -43,6 +43,8 @@ extern "C" {
|
||||
#define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27))
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define MCPWM_LL_MAX_TIMER_PRESCALE 256
|
||||
#define MCPWM_LL_MAX_CARRIER_PRESCALE 16
|
||||
#define MCPWM_LL_MAX_CARRIER_ONESHOT 16
|
||||
#define MCPWM_LL_MAX_CAPTURE_PRESCALE 256
|
||||
#define MCPWM_LL_MAX_DEAD_DELAY 65536
|
||||
|
@ -45,6 +45,8 @@ extern "C" {
|
||||
#define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27))
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define MCPWM_LL_MAX_TIMER_PRESCALE 256
|
||||
#define MCPWM_LL_MAX_CARRIER_PRESCALE 16
|
||||
#define MCPWM_LL_MAX_CARRIER_ONESHOT 16
|
||||
#define MCPWM_LL_MAX_CAPTURE_PRESCALE 256
|
||||
#define MCPWM_LL_MAX_DEAD_DELAY 65536
|
||||
|
@ -43,6 +43,8 @@ extern "C" {
|
||||
#define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27))
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define MCPWM_LL_MAX_TIMER_PRESCALE 256
|
||||
#define MCPWM_LL_MAX_CARRIER_PRESCALE 16
|
||||
#define MCPWM_LL_MAX_CARRIER_ONESHOT 16
|
||||
#define MCPWM_LL_MAX_CAPTURE_PRESCALE 256
|
||||
#define MCPWM_LL_MAX_DEAD_DELAY 65536
|
||||
|
@ -43,6 +43,8 @@ extern "C" {
|
||||
#define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27))
|
||||
|
||||
// Maximum values due to limited register bit width
|
||||
#define MCPWM_LL_MAX_TIMER_PRESCALE 256
|
||||
#define MCPWM_LL_MAX_CARRIER_PRESCALE 16
|
||||
#define MCPWM_LL_MAX_CARRIER_ONESHOT 16
|
||||
#define MCPWM_LL_MAX_CAPTURE_PRESCALE 256
|
||||
#define MCPWM_LL_MAX_DEAD_DELAY 65536
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -31,6 +31,15 @@ typedef soc_periph_mcpwm_capture_clk_src_t mcpwm_capture_clock_source_t;
|
||||
typedef int mcpwm_capture_clock_source_t;
|
||||
#endif // SOC_MCPWM_SUPPORTED
|
||||
|
||||
/**
|
||||
* @brief MCPWM carrier clock source
|
||||
*/
|
||||
#if SOC_MCPWM_SUPPORTED
|
||||
typedef soc_periph_mcpwm_carrier_clk_src_t mcpwm_carrier_clock_source_t;
|
||||
#else
|
||||
typedef int mcpwm_carrier_clock_source_t;
|
||||
#endif // SOC_MCPWM_SUPPORTED
|
||||
|
||||
/**
|
||||
* @brief MCPWM timer count direction
|
||||
*/
|
||||
|
@ -239,6 +239,19 @@ typedef enum {
|
||||
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
|
||||
} soc_periph_mcpwm_capture_clk_src_t;
|
||||
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of MCPWM Carrier
|
||||
*/
|
||||
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M}
|
||||
|
||||
/**
|
||||
* @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_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
|
||||
} soc_periph_mcpwm_carrier_clk_src_t;
|
||||
|
||||
///////////////////////////////////////////////////I2S//////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of I2S
|
||||
|
@ -255,6 +255,20 @@ typedef enum {
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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}
|
||||
|
||||
/**
|
||||
* @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_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;
|
||||
|
||||
///////////////////////////////////////////////////// I2S //////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
@ -264,6 +264,20 @@ typedef enum {
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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}
|
||||
|
||||
/**
|
||||
* @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_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;
|
||||
|
||||
///////////////////////////////////////////////////// I2S //////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
@ -257,6 +257,19 @@ typedef enum {
|
||||
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
|
||||
} soc_periph_mcpwm_capture_clk_src_t;
|
||||
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of MCPWM Carrier
|
||||
*/
|
||||
#define SOC_MCPWM_CARRIER_CLKS {SOC_MOD_CLK_PLL_F160M}
|
||||
|
||||
/**
|
||||
* @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_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
|
||||
} soc_periph_mcpwm_carrier_clk_src_t;
|
||||
|
||||
///////////////////////////////////////////////////// I2S //////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
@ -658,10 +658,11 @@ The MCPWM operator has a carrier submodule that can be used if galvanic isolatio
|
||||
|
||||
To configure the carrier submodule, you can call :cpp:func:`mcpwm_operator_apply_carrier`, and provide configuration structure :cpp:type:`mcpwm_carrier_config_t`:
|
||||
|
||||
- :cpp:member:`mcpwm_carrier_config_t::frequency_hz`: The carrier frequency in Hz.
|
||||
- :cpp:member:`mcpwm_carrier_config_t::duty_cycle`: The duty cycle of the carrier. Note that, the supported choices of duty cycle are discrete, the driver will search the nearest one based the user configuration.
|
||||
- :cpp:member:`mcpwm_carrier_config_t::first_pulse_duration_us`: The duration of the first pulse in microseconds. The resolution of the first pulse duration is determined by the carrier frequency you set in the :cpp:member:`mcpwm_carrier_config_t::frequency_hz`. The first pulse duration can't be zero, and it has to be at least one period of the carrier. A longer pulse width can help conduct the inductance quicker.
|
||||
- :cpp:member:`mcpwm_carrier_config_t::invert_before_modulate` and :cpp:member:`mcpwm_carrier_config_t::invert_after_modulate`: Set whether to invert the carrier output before and after modulation.
|
||||
- :cpp:member:`mcpwm_carrier_config_t::clk_src` sets the clock source of the carrier.
|
||||
- :cpp:member:`mcpwm_carrier_config_t::frequency_hz` indicates carrier frequency in Hz.
|
||||
- :cpp:member:`mcpwm_carrier_config_t::duty_cycle` indicates the duty cycle of the carrier. Note that, the supported choices of the duty cycle are discrete, the driver will search for the nearest one based on your configuration.
|
||||
- :cpp:member:`mcpwm_carrier_config_t::first_pulse_duration_us` indicates the duration of the first pulse in microseconds. The resolution of the first pulse duration is determined by the carrier frequency you set in the :cpp:member:`mcpwm_carrier_config_t::frequency_hz`. The first pulse duration can't be zero, and it has to be at least one period of the carrier. A longer pulse width can help conduct the inductance quicker.
|
||||
- :cpp:member:`mcpwm_carrier_config_t::invert_before_modulate` and :cpp:member:`mcpwm_carrier_config_t::invert_after_modulate` set whether to invert the carrier output before and after modulation.
|
||||
|
||||
Specifically, the carrier submodule can be disabled by calling :cpp:func:`mcpwm_operator_apply_carrier` with a ``NULL`` configuration.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user