Skip to content

Commit

Permalink
feat(mcpwm): Set group clock prescale dynamically
Browse files Browse the repository at this point in the history
MCPWM group clock pre scale was originally fixed to 2, which is
inconvenient. Set group clock prescale dynamically. Now the maximum
resolution of the MCPWM timer is up to 160MHz(when the prescale set
to 1). And add a resulotion config for MCPWM capture.
  • Loading branch information
Kainarx committed Sep 8, 2023
1 parent 78af508 commit fc80d3e
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 fc80d3e

Please sign in to comment.