Skip to content

Commit

Permalink
Merge branch 'feature/modify_mcpwm_clock_pre_scale' into 'master'
Browse files Browse the repository at this point in the history
feat(mcpwm): Set group clock prescale dynamically

See merge request espressif/esp-idf!25117
  • Loading branch information
suda-morris committed Sep 9, 2023
2 parents ed2fa1d + fc80d3e commit 3e5906a
Show file tree
Hide file tree
Showing 17 changed files with 200 additions and 38 deletions.
1 change: 1 addition & 0 deletions components/driver/mcpwm/include/driver/mcpwm_cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extern "C" {
typedef struct {
int group_id; /*!< Specify from which group to allocate the capture timer */
mcpwm_capture_clock_source_t clk_src; /*!< MCPWM capture timer clock source */
uint32_t resolution_hz; /*!< Resolution of capture timer */
} mcpwm_capture_timer_config_t;

/**
Expand Down
2 changes: 1 addition & 1 deletion components/driver/mcpwm/include/driver/mcpwm_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ typedef struct {
typedef struct {
int group_id; /*!< Specify from which group to allocate the MCPWM timer */
mcpwm_timer_clock_source_t clk_src; /*!< MCPWM timer clock source */
uint32_t resolution_hz; /*!< Counter resolution in Hz, ranges from around 300KHz to 80MHz.
uint32_t resolution_hz; /*!< Counter resolution in Hz
The step size of each count tick equals to (1 / resolution_hz) seconds */
mcpwm_timer_count_mode_t count_mode; /*!< Count mode */
uint32_t period_ticks; /*!< Number of count ticks within a period */
Expand Down
14 changes: 14 additions & 0 deletions components/driver/mcpwm/mcpwm_cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "esp_attr.h"
#include "esp_check.h"
#include "esp_private/esp_clk.h"
#include "esp_clk_tree.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_memory_utils.h"
Expand Down Expand Up @@ -100,12 +101,25 @@ esp_err_t mcpwm_new_capture_timer(const mcpwm_capture_timer_config_t *config, mc
#if SOC_MCPWM_CAPTURE_CLK_FROM_GROUP
// capture timer clock source is same as the MCPWM group
ESP_GOTO_ON_ERROR(mcpwm_select_periph_clock(group, (soc_module_clk_t)clk_src), err, TAG, "set group clock failed");
uint32_t periph_src_clk_hz = 0;
ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &periph_src_clk_hz), err, TAG, "get clock source freq failed");
ESP_LOGD(TAG, "periph_src_clk_hz %"PRIu32"", periph_src_clk_hz);
// when resolution_hz set to zero, use default resolution_hz
uint32_t resolution_hz = config->resolution_hz ? config->resolution_hz : periph_src_clk_hz / MCPWM_GROUP_CLOCK_DEFAULT_PRESCALE;

ESP_GOTO_ON_ERROR(mcpwm_set_prescale(group, resolution_hz, MCPWM_LL_MAX_CAPTURE_TIMER_PRESCALE, NULL), err, TAG, "set prescale failed");
cap_timer->resolution_hz = group->resolution_hz;
if (cap_timer->resolution_hz != resolution_hz) {
ESP_LOGW(TAG, "adjust cap_timer resolution to %"PRIu32"Hz", cap_timer->resolution_hz);
}
#else
// capture timer has independent clock source selection
switch (clk_src) {
case MCPWM_CAPTURE_CLK_SRC_APB:
cap_timer->resolution_hz = esp_clk_apb_freq();
if (config->resolution_hz) {
ESP_LOGW(TAG, "cap_timer resolution is not adjustable in current target, still %"PRIu32"Hz", cap_timer->resolution_hz);
}
#if CONFIG_PM_ENABLE
ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "mcpwm_cap_timer", &cap_timer->pm_lock);
ESP_GOTO_ON_ERROR(ret, err, TAG, "create ESP_PM_APB_FREQ_MAX lock failed");
Expand Down
78 changes: 72 additions & 6 deletions components/driver/mcpwm/mcpwm_com.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,9 @@ int mcpwm_get_intr_priority_flag(mcpwm_group_t *group)
esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_src)
{
esp_err_t ret = ESP_OK;
uint32_t periph_src_clk_hz = 0;
bool clock_selection_conflict = false;
bool do_clock_init = false;
// check if we need to update the group clock source, group clock source is shared by all mcpwm objects
// check if we need to update the group clock source, group clock source is shared by all mcpwm modules
portENTER_CRITICAL(&group->spinlock);
if (group->clk_src == 0) {
group->clk_src = clk_src;
Expand All @@ -142,7 +141,6 @@ esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_s
"group clock conflict, already is %d but attempt to %d", group->clk_src, clk_src);

if (do_clock_init) {
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &periph_src_clk_hz), TAG, "get clock source freq failed");

#if CONFIG_PM_ENABLE
sprintf(group->pm_lock_name, "mcpwm_%d", group->group_id); // e.g. mcpwm_0
Expand All @@ -152,9 +150,77 @@ esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_s
#endif // CONFIG_PM_ENABLE

mcpwm_ll_group_set_clock_source(group->hal.dev, clk_src);
mcpwm_ll_group_set_clock_prescale(group->hal.dev, MCPWM_PERIPH_CLOCK_PRE_SCALE);
group->resolution_hz = periph_src_clk_hz / MCPWM_PERIPH_CLOCK_PRE_SCALE;
ESP_LOGD(TAG, "group (%d) clock resolution:%"PRIu32"Hz", group->group_id, group->resolution_hz);
}
return ret;
}

esp_err_t mcpwm_set_prescale(mcpwm_group_t *group, uint32_t expect_module_resolution_hz, uint32_t module_prescale_max, uint32_t* ret_module_prescale)
{
ESP_RETURN_ON_FALSE(group && expect_module_resolution_hz && module_prescale_max, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
uint32_t periph_src_clk_hz = 0;
int group_id = group->group_id;
uint32_t group_resolution_hz = 0;
uint32_t group_prescale = group->prescale > 0 ? group->prescale : MCPWM_GROUP_CLOCK_DEFAULT_PRESCALE; // range: 1~256, 0 means not calculated
uint32_t module_prescale = 0; // range: 1~256 (for timer) or 1~16 (for carrier) or 1 (for capture)

ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(group->clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &periph_src_clk_hz), TAG, "get clock source freq failed");

// calc the group prescale

group_resolution_hz = periph_src_clk_hz / group_prescale;
module_prescale = group_resolution_hz / expect_module_resolution_hz;

// default prescale cannot match
// try to ensure accurate division. If none of the division factors can be guaranteed to be integers, then allocate the clock frequency to the highest divisor
uint32_t fit_module_prescale = 0;
uint32_t fit_group_prescale = 0;
if (!(module_prescale >= 1 && module_prescale <= module_prescale_max)) {
group_prescale = 0;
while (++group_prescale <= MCPWM_LL_MAX_GROUP_PRESCALE) {
group_resolution_hz = periph_src_clk_hz / group_prescale;
module_prescale = group_resolution_hz / expect_module_resolution_hz;
if (module_prescale >= 1 && module_prescale <= module_prescale_max) {
// maintain the first value found during the search that satisfies the division requirement (highest frequency), applicable for cases where integer division is not possible."
fit_module_prescale = fit_module_prescale ? fit_module_prescale : module_prescale;
fit_group_prescale = fit_group_prescale ? fit_group_prescale : group_prescale;
// find accurate division
if (group_resolution_hz == expect_module_resolution_hz * module_prescale) {
fit_module_prescale = module_prescale;
fit_group_prescale = group_prescale;
break;
}
}
}
module_prescale = fit_module_prescale;
group_prescale = fit_group_prescale;
group_resolution_hz = periph_src_clk_hz / group_prescale;
}

ESP_LOGD(TAG, "group (%d) calc prescale:%"PRIu32", module calc prescale:%"PRIu32"", group_id, group_prescale, module_prescale);
ESP_RETURN_ON_FALSE(group_prescale > 0 && group_prescale <= MCPWM_LL_MAX_GROUP_PRESCALE, ESP_ERR_INVALID_STATE, TAG,
"set group prescale failed, group clock cannot match the resolution");

// check if we need to update the group prescale, group prescale is shared by all mcpwm modules
bool prescale_conflict = false;
portENTER_CRITICAL(&group->spinlock);
if (group->prescale == 0) {
group->prescale = group_prescale;
group->resolution_hz = group_resolution_hz;
mcpwm_ll_group_set_clock_prescale(group->hal.dev, group_prescale);
} else {
prescale_conflict = (group->prescale != group_prescale);
}
portEXIT_CRITICAL(&group->spinlock);

ESP_RETURN_ON_FALSE(!prescale_conflict, ESP_ERR_INVALID_STATE, TAG,
"group prescale conflict, already is %"PRIu32" but attempt to %"PRIu32"", group->prescale, group_prescale);

ESP_LOGD(TAG, "group (%d) clock resolution:%"PRIu32"Hz", group_id, group->resolution_hz);

// set module resolution
if (ret_module_prescale) {
*ret_module_prescale = module_prescale;
}

return ESP_OK;
}
5 changes: 4 additions & 1 deletion components/driver/mcpwm/mcpwm_oper.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,10 @@ esp_err_t mcpwm_operator_apply_carrier(mcpwm_oper_handle_t oper, const mcpwm_car
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;
uint32_t prescale = 0;
ESP_RETURN_ON_ERROR(mcpwm_set_prescale(group, config->frequency_hz, MCPWM_LL_MAX_CARRIER_PRESCALE * 8, &prescale), TAG, "set prescale failed");
// here div 8 because the duty has 3 register bits
prescale /= 8;
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;
Expand Down
6 changes: 4 additions & 2 deletions components/driver/mcpwm/mcpwm_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ extern "C" {

#define MCPWM_ALLOW_INTR_PRIORITY_MASK ESP_INTR_FLAG_LOWMED

#define MCPWM_PERIPH_CLOCK_PRE_SCALE (2)
#define MCPWM_GROUP_CLOCK_DEFAULT_PRESCALE 2
#define MCPWM_PM_LOCK_NAME_LEN_MAX 16

typedef struct mcpwm_group_t mcpwm_group_t;
Expand All @@ -59,7 +59,8 @@ struct mcpwm_group_t {
int intr_priority; // MCPWM interrupt priority
mcpwm_hal_context_t hal; // HAL instance is at group level
portMUX_TYPE spinlock; // group level spinlock
uint32_t resolution_hz; // MCPWM group clock resolution
uint32_t prescale; // group prescale
uint32_t resolution_hz; // MCPWM group clock resolution: clock_src_hz / clock_prescale = resolution_hz
esp_pm_lock_handle_t pm_lock; // power management lock
soc_module_clk_t clk_src; // peripheral source clock
mcpwm_cap_timer_t *cap_timer; // mcpwm capture timers
Expand Down Expand Up @@ -238,6 +239,7 @@ void mcpwm_release_group_handle(mcpwm_group_t *group);
esp_err_t mcpwm_check_intr_priority(mcpwm_group_t *group, int intr_priority);
int mcpwm_get_intr_priority_flag(mcpwm_group_t *group);
esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_src);
esp_err_t mcpwm_set_prescale(mcpwm_group_t *group, uint32_t expect_module_resolution_hz, uint32_t module_prescale_max, uint32_t* ret_module_prescale);

#ifdef __cplusplus
}
Expand Down
6 changes: 3 additions & 3 deletions components/driver/mcpwm/mcpwm_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,12 @@ esp_err_t mcpwm_new_timer(const mcpwm_timer_config_t *config, mcpwm_timer_handle

// select the clock source
mcpwm_timer_clock_source_t clk_src = config->clk_src ? config->clk_src : MCPWM_TIMER_CLK_SRC_DEFAULT;
ESP_RETURN_ON_ERROR(mcpwm_select_periph_clock(group, (soc_module_clk_t)clk_src), TAG, "set group clock failed");
ESP_GOTO_ON_ERROR(mcpwm_select_periph_clock(group, (soc_module_clk_t)clk_src), err, TAG, "set group clock failed");
// reset the timer to a determined state
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");
uint32_t prescale = 0;
ESP_GOTO_ON_ERROR(mcpwm_set_prescale(group, config->resolution_hz, MCPWM_LL_MAX_TIMER_PRESCALE, &prescale), err, TAG, "set prescale failed");
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) {
Expand Down
2 changes: 1 addition & 1 deletion components/driver/test_apps/gptimer/main/test_gptimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ TEST_CASE("gptimer_wallclock_with_various_clock_sources", "[gptimer]")
#if CONFIG_PM_ENABLE
#define GPTIMER_STOP_ON_ALARM_COUNT_DELTA 150
#else
#define GPTIMER_STOP_ON_ALARM_COUNT_DELTA 30
#define GPTIMER_STOP_ON_ALARM_COUNT_DELTA 40
#endif // CONFIG_PM_ENABLE

TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_alarm_stop_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
Expand Down
2 changes: 2 additions & 0 deletions components/driver/test_apps/mcpwm/main/test_mcpwm_cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
mcpwm_capture_timer_config_t cap_timer_config = {
.clk_src = MCPWM_CAPTURE_CLK_SRC_DEFAULT,
.group_id = 0,
.resolution_hz = 8 * 1000 * 1000,
};
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timer));

Expand Down Expand Up @@ -118,6 +119,7 @@ TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
uint32_t clk_src_res;
TEST_ESP_OK(mcpwm_capture_timer_get_resolution(cap_timer, &clk_src_res));
clk_src_res /= 1000; // convert to kHz
printf("timer resolution:%"PRIu32"KHz\r\n", clk_src_res);
TEST_ASSERT_UINT_WITHIN(1000, 10000, (cap_value[1] - cap_value[0]) * 1000 / clk_src_res);

printf("uninstall capture channel and timer\r\n");
Expand Down
45 changes: 45 additions & 0 deletions components/driver/test_apps/mcpwm/main/test_mcpwm_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,48 @@ TEST_CASE("mcpwm_set_interrupt_priority", "[mcpwm]")
TEST_ESP_OK(mcpwm_del_timer(timer));
TEST_ESP_OK(mcpwm_del_fault(fault));
}

TEST_CASE("mcpwm_group_set_prescale_dynamically", "[mcpwm]")
{
mcpwm_timer_config_t timer_config = {
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz = 100 * 1000, // 100kHz
.period_ticks = 400,
.count_mode = MCPWM_TIMER_COUNT_MODE_UP_DOWN,
.group_id = 0,
};

mcpwm_timer_handle_t timer = NULL;
printf("create mcpwm timer\r\n");
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));

mcpwm_generator_config_t generator_config = {
.gen_gpio_num = 0,
};
mcpwm_gen_handle_t generator = NULL;
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &generator));

printf("add carrier to PWM wave\r\n");
mcpwm_carrier_config_t carrier_config = {
.clk_src = MCPWM_CARRIER_CLK_SRC_DEFAULT,
.frequency_hz = 100000, // 100KHz carrier need higher group prescale
.duty_cycle = 0.5,
.first_pulse_duration_us = 10,
};

TEST_ESP_ERR(ESP_ERR_INVALID_STATE, mcpwm_operator_apply_carrier(oper, &carrier_config));
carrier_config.frequency_hz = 2000000; // 2MHz carrier
carrier_config.first_pulse_duration_us = 5;
TEST_ESP_OK(mcpwm_operator_apply_carrier(oper, &carrier_config));


TEST_ESP_OK(mcpwm_del_generator(generator));
TEST_ESP_OK(mcpwm_del_operator(oper));
TEST_ESP_OK(mcpwm_del_timer(timer));
}
11 changes: 7 additions & 4 deletions components/hal/esp32/include/hal/mcpwm_ll.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -43,10 +43,12 @@ extern "C" {
#define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27))

// Maximum values due to limited register bit width
#define MCPWM_LL_MAX_GROUP_PRESCALE 256
#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_CAPTURE_TIMER_PRESCALE 1
#define MCPWM_LL_MAX_DEAD_DELAY 65536
#define MCPWM_LL_MAX_COUNT_VALUE 65536

Expand Down Expand Up @@ -97,10 +99,11 @@ static inline void mcpwm_ll_group_enable_clock(mcpwm_dev_t *mcpwm, bool en)
* @param mcpwm Peripheral instance address
* @param pre_scale Prescale value
*/
static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale)
static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale)
{
// group clock: PWM_clk = CLK_160M / (prescale + 1)
HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->clk_cfg, clk_prescale, pre_scale - 1);
// group clock: PWM_clk = CLK_160M / (prescale)
HAL_ASSERT(prescale <= 256 && prescale > 0);
HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->clk_cfg, clk_prescale, prescale - 1);
}

/**
Expand Down
11 changes: 7 additions & 4 deletions components/hal/esp32c6/include/hal/mcpwm_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ extern "C" {
#define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27))

// Maximum values due to limited register bit width
#define MCPWM_LL_MAX_GROUP_PRESCALE 256
#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_CAPTURE_TIMER_PRESCALE 1
#define MCPWM_LL_MAX_DEAD_DELAY 65536
#define MCPWM_LL_MAX_COUNT_VALUE 65536

Expand Down Expand Up @@ -105,13 +107,14 @@ static inline void mcpwm_ll_group_enable_clock(mcpwm_dev_t *mcpwm, bool en)
* @brief Set the MCPWM group clock prescale
*
* @param mcpwm Peripheral instance address
* @param pre_scale Prescale value
* @param prescale Prescale value
*/
static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale)
static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale)
{
(void)mcpwm; // only one MCPWM instance
// group clock: PWM_clk = source_clock / (prescale + 1)
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, pre_scale - 1);
// group clock: PWM_clk = source_clock / (prescale)
HAL_ASSERT(prescale <= 256 && prescale > 0);
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, prescale - 1);
}

/**
Expand Down
11 changes: 7 additions & 4 deletions components/hal/esp32h2/include/hal/mcpwm_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ extern "C" {
#define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27))

// Maximum values due to limited register bit width
#define MCPWM_LL_MAX_GROUP_PRESCALE 256
#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_CAPTURE_TIMER_PRESCALE 1
#define MCPWM_LL_MAX_DEAD_DELAY 65536
#define MCPWM_LL_MAX_COUNT_VALUE 65536

Expand Down Expand Up @@ -103,13 +105,14 @@ static inline void mcpwm_ll_group_enable_clock(mcpwm_dev_t *mcpwm, bool en)
* @brief Set the MCPWM group clock prescale
*
* @param mcpwm Peripheral instance address
* @param pre_scale Prescale value
* @param prescale Prescale value
*/
static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale)
static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale)
{
(void)mcpwm; // only one MCPWM instance
// group clock: PWM_clk = source_clock / (prescale + 1)
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, pre_scale - 1);
// group clock: PWM_clk = source_clock / (prescale)
HAL_ASSERT(prescale <= 256 && prescale > 0);
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, prescale - 1);
}

/**
Expand Down
Loading

0 comments on commit 3e5906a

Please sign in to comment.