Merge branch 'refactor/mcpwm_independent_hal_v6.0' into 'release/v6.0'

refactor(mcpwm): make mcpwm_hal independent & cleanup soc_caps (Backport v6.0)

See merge request espressif/esp-idf!43103
This commit is contained in:
morris
2025-11-12 14:39:00 +08:00
57 changed files with 1041 additions and 1216 deletions
@@ -16,6 +16,7 @@ if(CONFIG_SOC_MCPWM_SUPPORTED)
endif()
endif()
set(requires esp_hal_mcpwm)
if(${target} STREQUAL "linux")
set(priv_requires "")
else()
@@ -24,6 +25,7 @@ endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${public_include}
REQUIRES "${requires}"
PRIV_REQUIRES "${priv_requires}"
LDFRAGMENTS "linker.lf"
)
+8 -8
View File
@@ -68,7 +68,7 @@ esp_err_t mcpwm_new_capture_timer(const mcpwm_capture_timer_config_t *config, mc
esp_err_t ret = ESP_OK;
mcpwm_cap_timer_t *cap_timer = NULL;
ESP_GOTO_ON_FALSE(config && ret_cap_timer, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(config->group_id < SOC_MCPWM_GROUPS && config->group_id >= 0, ESP_ERR_INVALID_ARG,
ESP_GOTO_ON_FALSE(config->group_id < MCPWM_LL_GET(GROUP_NUM) && config->group_id >= 0, ESP_ERR_INVALID_ARG,
err, TAG, "invalid group ID:%d", config->group_id);
#if !SOC_MCPWM_SUPPORT_SLEEP_RETENTION
@@ -96,7 +96,7 @@ esp_err_t mcpwm_new_capture_timer(const mcpwm_capture_timer_config_t *config, mc
uint32_t cap_timer_prescale = group->prescale > 0 ? group->prescale : MCPWM_GROUP_CLOCK_DEFAULT_PRESCALE;
uint32_t resolution_hz = config->resolution_hz ? config->resolution_hz : periph_src_clk_hz / cap_timer_prescale;
ESP_GOTO_ON_ERROR(mcpwm_set_prescale(group, resolution_hz, MCPWM_LL_MAX_CAPTURE_TIMER_PRESCALE, NULL), err, TAG, "set prescale failed");
ESP_GOTO_ON_ERROR(mcpwm_set_prescale(group, resolution_hz, MCPWM_LL_GET(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);
@@ -144,7 +144,7 @@ esp_err_t mcpwm_del_capture_timer(mcpwm_cap_timer_handle_t cap_timer)
{
ESP_RETURN_ON_FALSE(cap_timer, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
ESP_RETURN_ON_FALSE(cap_timer->fsm == MCPWM_CAP_TIMER_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "timer not in init state");
for (int i = 0; i < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; i++) {
for (int i = 0; i < MCPWM_LL_GET(CAPTURE_CHANNELS_PER_TIMER); i++) {
ESP_RETURN_ON_FALSE(!cap_timer->cap_channels[i], ESP_ERR_INVALID_STATE, TAG, "cap channel still in working");
}
mcpwm_group_t *group = cap_timer->group;
@@ -218,7 +218,7 @@ static esp_err_t mcpwm_capture_channel_register_to_timer(mcpwm_cap_channel_t *ca
{
int cap_chan_id = -1;
portENTER_CRITICAL(&cap_timer->spinlock);
for (int i = 0; i < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; i++) {
for (int i = 0; i < MCPWM_LL_GET(CAPTURE_CHANNELS_PER_TIMER); i++) {
if (!cap_timer->cap_channels[i]) {
cap_timer->cap_channels[i] = cap_channel;
cap_chan_id = i;
@@ -260,7 +260,7 @@ esp_err_t mcpwm_new_capture_channel(mcpwm_cap_timer_handle_t cap_timer, const mc
esp_err_t ret = ESP_OK;
mcpwm_cap_channel_t *cap_chan = NULL;
ESP_GOTO_ON_FALSE(cap_timer && config && ret_cap_channel, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(config->prescale && config->prescale <= MCPWM_LL_MAX_CAPTURE_PRESCALE, ESP_ERR_INVALID_ARG, err, TAG, "invalid prescale");
ESP_GOTO_ON_FALSE(config->prescale && config->prescale <= MCPWM_LL_GET(MAX_CAPTURE_PRESCALE), ESP_ERR_INVALID_ARG, err, TAG, "invalid prescale");
if (config->intr_priority) {
ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & MCPWM_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err,
TAG, "invalid interrupt priority:%d", config->intr_priority);
@@ -288,7 +288,7 @@ esp_err_t mcpwm_new_capture_channel(mcpwm_cap_timer_handle_t cap_timer, const mc
// GPIO configuration
gpio_func_sel(config->gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->gpio_num);
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group->group_id].captures[cap_chan_id].cap_sig, 0);
esp_rom_gpio_connect_in_signal(config->gpio_num, soc_mcpwm_signals[group->group_id].captures[cap_chan_id].cap_sig, 0);
}
cap_chan->gpio_num = config->gpio_num;
@@ -322,7 +322,7 @@ esp_err_t mcpwm_del_capture_channel(mcpwm_cap_channel_handle_t cap_channel)
// disconnect signal from the GPIO pin
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT,
mcpwm_periph_signals.groups[group->group_id].captures[cap_chan_id].cap_sig, 0);
soc_mcpwm_signals[group->group_id].captures[cap_chan_id].cap_sig, 0);
// recycle memory resource
ESP_RETURN_ON_ERROR(mcpwm_capture_channel_destroy(cap_channel), TAG, "destroy capture channel failed");
@@ -386,7 +386,7 @@ esp_err_t mcpwm_capture_channel_register_event_callbacks(mcpwm_cap_channel_handl
ESP_RETURN_ON_FALSE(cap_channel->fsm == MCPWM_CAP_CHAN_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "channel not in init state");
int isr_flags = MCPWM_INTR_ALLOC_FLAG;
isr_flags |= mcpwm_get_intr_priority_flag(group);
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(mcpwm_periph_signals.groups[group_id].irq_id, isr_flags,
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(soc_mcpwm_signals[group_id].irq_id, isr_flags,
(uint32_t)mcpwm_ll_intr_get_status_reg(hal->dev), MCPWM_LL_EVENT_CAPTURE(cap_chan_id),
mcpwm_capture_default_isr, cap_channel, &cap_channel->intr), TAG, "install interrupt service for cap channel failed");
}
+3 -3
View File
@@ -17,7 +17,7 @@ static esp_err_t mcpwm_comparator_register_to_operator(mcpwm_cmpr_t *cmpr, mcpwm
switch (cmpr->type) {
case MCPWM_OPERATOR_COMPARATOR: {
mcpwm_oper_cmpr_t *oper_cmpr = __containerof(cmpr, mcpwm_oper_cmpr_t, base);
for (int i = 0; i < SOC_MCPWM_COMPARATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(COMPARATORS_PER_OPERATOR); i++) {
if (!oper->comparators[i]) {
oper->comparators[i] = oper_cmpr;
cmpr_id = i;
@@ -29,7 +29,7 @@ static esp_err_t mcpwm_comparator_register_to_operator(mcpwm_cmpr_t *cmpr, mcpwm
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
case MCPWM_EVENT_COMPARATOR: {
mcpwm_evt_cmpr_t *evt_cmpr = __containerof(cmpr, mcpwm_evt_cmpr_t, base);
for (int i = 0; i < SOC_MCPWM_EVENT_COMPARATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(EVENT_COMPARATORS_PER_OPERATOR); i++) {
if (!oper->event_comparators[i]) {
oper->event_comparators[i] = evt_cmpr;
cmpr_id = i;
@@ -235,7 +235,7 @@ esp_err_t mcpwm_comparator_register_event_callbacks(mcpwm_cmpr_handle_t cmpr, co
// we want the interrupt service to be enabled after allocation successfully
int isr_flags = MCPWM_INTR_ALLOC_FLAG & ~ ESP_INTR_FLAG_INTRDISABLED;
isr_flags |= mcpwm_get_intr_priority_flag(group);
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(mcpwm_periph_signals.groups[group_id].irq_id, isr_flags,
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(soc_mcpwm_signals[group_id].irq_id, isr_flags,
(uint32_t)mcpwm_ll_intr_get_status_reg(hal->dev), MCPWM_LL_EVENT_CMP_EQUAL(oper_id, cmpr_id),
mcpwm_comparator_default_isr, oper_cmpr, &oper_cmpr->intr), TAG, "install interrupt service for comparator failed");
}
+5 -5
View File
@@ -28,8 +28,8 @@ static esp_err_t mcpwm_create_sleep_retention_link_cb(void *arg);
typedef struct {
_lock_t mutex; // platform level mutex lock
mcpwm_group_t *groups[SOC_MCPWM_GROUPS]; // array of MCPWM group instances
int group_ref_counts[SOC_MCPWM_GROUPS]; // reference count used to protect group install/uninstall
mcpwm_group_t *groups[MCPWM_LL_GET(GROUP_NUM)]; // array of MCPWM group instances
int group_ref_counts[MCPWM_LL_GET(GROUP_NUM)]; // reference count used to protect group install/uninstall
} mcpwm_platform_t;
static mcpwm_platform_t s_platform; // singleton platform
@@ -197,7 +197,7 @@ esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_s
// thus we want to use the APB_MAX lock
pm_lock_type = ESP_PM_APB_FREQ_MAX;
#endif
ret = esp_pm_lock_create(pm_lock_type, 0, mcpwm_periph_signals.groups[group_id].module_name, &group->pm_lock);
ret = esp_pm_lock_create(pm_lock_type, 0, soc_mcpwm_signals[group_id].module_name, &group->pm_lock);
ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed");
#endif // CONFIG_PM_ENABLE
@@ -231,7 +231,7 @@ esp_err_t mcpwm_set_prescale(mcpwm_group_t *group, uint32_t expect_module_resolu
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) {
while (++group_prescale <= MCPWM_LL_GET(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) {
@@ -248,7 +248,7 @@ esp_err_t mcpwm_set_prescale(mcpwm_group_t *group, uint32_t expect_module_resolu
}
module_prescale = fit_module_prescale;
group_prescale = fit_group_prescale;
ESP_RETURN_ON_FALSE(group_prescale > 0 && group_prescale <= MCPWM_LL_MAX_GROUP_PRESCALE, ESP_ERR_INVALID_STATE, TAG,
ESP_RETURN_ON_FALSE(group_prescale > 0 && group_prescale <= MCPWM_LL_GET(MAX_GROUP_PRESCALE), ESP_ERR_INVALID_STATE, TAG,
"set group prescale failed, group clock cannot match the resolution");
group_resolution_hz = periph_src_clk_hz / group_prescale;
}
@@ -21,7 +21,7 @@ static esp_err_t mcpwm_gpio_fault_register_to_group(mcpwm_gpio_fault_t *fault, i
int fault_id = -1;
portENTER_CRITICAL(&group->spinlock);
for (int i = 0; i < SOC_MCPWM_GPIO_FAULTS_PER_GROUP; i++) {
for (int i = 0; i < MCPWM_LL_GET(GPIO_FAULTS_PER_GROUP); i++) {
if (!group->gpio_faults[i]) {
fault_id = i;
group->gpio_faults[i] = fault;
@@ -70,7 +70,7 @@ esp_err_t mcpwm_new_gpio_fault(const mcpwm_gpio_fault_config_t *config, mcpwm_fa
esp_err_t ret = ESP_OK;
mcpwm_gpio_fault_t *fault = NULL;
ESP_GOTO_ON_FALSE(config && ret_fault, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(config->group_id < SOC_MCPWM_GROUPS && config->group_id >= 0, ESP_ERR_INVALID_ARG,
ESP_GOTO_ON_FALSE(config->group_id < MCPWM_LL_GET(GROUP_NUM) && config->group_id >= 0, ESP_ERR_INVALID_ARG,
err, TAG, "invalid group ID:%d", config->group_id);
if (config->intr_priority) {
ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & MCPWM_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err,
@@ -93,7 +93,7 @@ esp_err_t mcpwm_new_gpio_fault(const mcpwm_gpio_fault_config_t *config, mcpwm_fa
// GPIO configuration
gpio_func_sel(config->gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->gpio_num);
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group_id].gpio_faults[fault_id].fault_sig, 0);
esp_rom_gpio_connect_in_signal(config->gpio_num, soc_mcpwm_signals[group_id].gpio_faults[fault_id].fault_sig, 0);
// set fault detection polarity
// different gpio faults share the same config register, using a group level spin lock
@@ -139,7 +139,7 @@ static esp_err_t mcpwm_del_gpio_fault(mcpwm_fault_handle_t fault)
// disconnect signal from the GPIO pin
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT,
mcpwm_periph_signals.groups[group_id].gpio_faults[fault_id].fault_sig, 0);
soc_mcpwm_signals[group_id].gpio_faults[fault_id].fault_sig, 0);
// recycle memory resource
ESP_RETURN_ON_ERROR(mcpwm_gpio_fault_destroy(gpio_fault), TAG, "destroy GPIO fault failed");
@@ -231,7 +231,7 @@ esp_err_t mcpwm_fault_register_event_callbacks(mcpwm_fault_handle_t fault, const
// we want the interrupt service to be enabled after allocation successfully
int isr_flags = MCPWM_INTR_ALLOC_FLAG & ~ESP_INTR_FLAG_INTRDISABLED;
isr_flags |= mcpwm_get_intr_priority_flag(group);
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(mcpwm_periph_signals.groups[group_id].irq_id, isr_flags,
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(soc_mcpwm_signals[group_id].irq_id, isr_flags,
(uint32_t)mcpwm_ll_intr_get_status_reg(hal->dev), MCPWM_LL_EVENT_FAULT_MASK(fault_id),
mcpwm_gpio_fault_default_isr, gpio_fault, &gpio_fault->intr), TAG, "install interrupt service for gpio fault failed");
}
+5 -5
View File
@@ -14,7 +14,7 @@ static esp_err_t mcpwm_generator_register_to_operator(mcpwm_gen_t *gen, mcpwm_op
{
int gen_id = -1;
portENTER_CRITICAL(&oper->spinlock);
for (int i = 0; i < SOC_MCPWM_GENERATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(GENERATORS_PER_OPERATOR); i++) {
if (!oper->generators[i]) {
oper->generators[i] = gen;
gen_id = i;
@@ -78,7 +78,7 @@ esp_err_t mcpwm_new_generator(mcpwm_oper_handle_t oper, const mcpwm_generator_co
gpio_func_sel(config->gen_gpio_num, PIN_FUNC_GPIO);
// connect the signal to the GPIO by matrix, it will also enable the output path properly
esp_rom_gpio_connect_out_signal(config->gen_gpio_num,
mcpwm_periph_signals.groups[group->group_id].operators[oper_id].generators[gen_id].pwm_sig,
soc_mcpwm_signals[group->group_id].operators[oper_id].generators[gen_id].pwm_sig,
config->flags.invert_pwm, 0);
// fill in other generator members
@@ -192,7 +192,7 @@ esp_err_t mcpwm_generator_set_action_on_fault_event(mcpwm_gen_handle_t gen, mcpw
// check the remained triggers
int trigger_id = -1;
portENTER_CRITICAL(&oper->spinlock);
for (int i = 0; i < SOC_MCPWM_TRIGGERS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(TRIGGERS_PER_OPERATOR); i++) {
if (oper->triggers[i] == MCPWM_TRIGGER_NO_ASSIGN) {
trigger_id = i;
oper->triggers[i] = MCPWM_TRIGGER_GPIO_FAULT;
@@ -217,7 +217,7 @@ esp_err_t mcpwm_generator_set_action_on_sync_event(mcpwm_gen_handle_t gen, mcpwm
int trigger_id = -1;
int trigger_sync_used = 0;
portENTER_CRITICAL(&oper->spinlock);
for (int i = 0; i < SOC_MCPWM_TRIGGERS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(TRIGGERS_PER_OPERATOR); i++) {
if (oper->triggers[i] == MCPWM_TRIGGER_SYNC_EVENT) {
trigger_sync_used = 1;
break;
@@ -241,7 +241,7 @@ esp_err_t mcpwm_generator_set_dead_time(mcpwm_gen_handle_t in_generator, mcpwm_g
{
ESP_RETURN_ON_FALSE(in_generator && out_generator && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
ESP_RETURN_ON_FALSE(in_generator->oper == out_generator->oper, ESP_ERR_INVALID_ARG, TAG, "in/out generator are not derived from the same operator");
ESP_RETURN_ON_FALSE(config->negedge_delay_ticks < MCPWM_LL_MAX_DEAD_DELAY && config->posedge_delay_ticks < MCPWM_LL_MAX_DEAD_DELAY,
ESP_RETURN_ON_FALSE(config->negedge_delay_ticks < MCPWM_LL_GET(MAX_DEAD_DELAY) && config->posedge_delay_ticks < MCPWM_LL_GET(MAX_DEAD_DELAY),
ESP_ERR_INVALID_ARG, TAG, "delay time out of range");
mcpwm_oper_t *oper = in_generator->oper;
mcpwm_group_t *group = oper->group;
+9 -9
View File
@@ -17,7 +17,7 @@ static esp_err_t mcpwm_operator_register_to_group(mcpwm_oper_t *oper, int group_
int oper_id = -1;
portENTER_CRITICAL(&group->spinlock);
for (int i = 0; i < SOC_MCPWM_OPERATORS_PER_GROUP; i++) {
for (int i = 0; i < MCPWM_LL_GET(OPERATORS_PER_GROUP); i++) {
if (!group->operators[i]) {
oper_id = i;
group->operators[i] = oper;
@@ -66,7 +66,7 @@ esp_err_t mcpwm_new_operator(const mcpwm_operator_config_t *config, mcpwm_oper_h
esp_err_t ret = ESP_OK;
mcpwm_oper_t *oper = NULL;
ESP_GOTO_ON_FALSE(config && ret_oper, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(config->group_id < SOC_MCPWM_GROUPS && config->group_id >= 0, ESP_ERR_INVALID_ARG,
ESP_GOTO_ON_FALSE(config->group_id < MCPWM_LL_GET(GROUP_NUM) && config->group_id >= 0, ESP_ERR_INVALID_ARG,
err, TAG, "invalid group ID:%d", config->group_id);
if (config->intr_priority) {
ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & MCPWM_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err,
@@ -117,15 +117,15 @@ err:
esp_err_t mcpwm_del_operator(mcpwm_oper_handle_t oper)
{
ESP_RETURN_ON_FALSE(oper, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
for (int i = 0; i < SOC_MCPWM_COMPARATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(COMPARATORS_PER_OPERATOR); i++) {
ESP_RETURN_ON_FALSE(!oper->comparators[i], ESP_ERR_INVALID_STATE, TAG, "comparator still in working");
}
for (int i = 0; i < SOC_MCPWM_GENERATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(GENERATORS_PER_OPERATOR); i++) {
ESP_RETURN_ON_FALSE(!oper->generators[i], ESP_ERR_INVALID_STATE, TAG, "generator still in working");
}
ESP_RETURN_ON_FALSE(!oper->soft_fault, ESP_ERR_INVALID_STATE, TAG, "soft fault still in working");
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
for (int i = 0; i < SOC_MCPWM_EVENT_COMPARATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(EVENT_COMPARATORS_PER_OPERATOR); i++) {
ESP_RETURN_ON_FALSE(!oper->event_comparators[i], ESP_ERR_INVALID_STATE, TAG, "event comparator still in working");
}
#endif
@@ -178,10 +178,10 @@ esp_err_t mcpwm_operator_apply_carrier(mcpwm_oper_handle_t oper, const mcpwm_car
ESP_RETURN_ON_ERROR(mcpwm_select_periph_clock(group, (soc_module_clk_t)clk_src), TAG, "set group clock failed");
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");
ESP_RETURN_ON_ERROR(mcpwm_set_prescale(group, config->frequency_hz, MCPWM_LL_GET(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");
ESP_RETURN_ON_FALSE(prescale > 0 && prescale <= MCPWM_LL_GET(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;
@@ -190,7 +190,7 @@ esp_err_t mcpwm_operator_apply_carrier(mcpwm_oper_handle_t oper, const mcpwm_car
real_duty = (float) duty / 8.0F;
uint8_t first_pulse_ticks = (uint8_t)(config->first_pulse_duration_us * real_frequency / 1000000UL);
ESP_RETURN_ON_FALSE(first_pulse_ticks > 0 && first_pulse_ticks <= MCPWM_LL_MAX_CARRIER_ONESHOT,
ESP_RETURN_ON_FALSE(first_pulse_ticks > 0 && first_pulse_ticks <= MCPWM_LL_GET(MAX_CARRIER_ONESHOT),
ESP_ERR_INVALID_ARG, TAG, "invalid first pulse duration");
mcpwm_ll_carrier_set_first_pulse_width(hal->dev, oper_id, first_pulse_ticks);
real_fpd = first_pulse_ticks * 1000000UL / real_frequency;
@@ -235,7 +235,7 @@ esp_err_t mcpwm_operator_register_event_callbacks(mcpwm_oper_handle_t oper, cons
// we want the interrupt service to be enabled after allocation successfully
int isr_flags = MCPWM_INTR_ALLOC_FLAG & ~ ESP_INTR_FLAG_INTRDISABLED;
isr_flags |= mcpwm_get_intr_priority_flag(group);
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(mcpwm_periph_signals.groups[group_id].irq_id, isr_flags,
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(soc_mcpwm_signals[group_id].irq_id, isr_flags,
(uint32_t)mcpwm_ll_intr_get_status_reg(hal->dev), MCPWM_LL_EVENT_OPER_MASK(oper_id),
mcpwm_operator_default_isr, oper, &oper->intr), TAG, "install interrupt service for operator failed");
}
+12 -12
View File
@@ -24,9 +24,9 @@
#include "esp_intr_alloc.h"
#include "esp_heap_caps.h"
#include "esp_pm.h"
#include "soc/mcpwm_periph.h"
#include "hal/mcpwm_hal.h"
#include "hal/mcpwm_periph.h"
#include "hal/mcpwm_ll.h"
#include "hal/mcpwm_hal.h"
#include "hal/mcpwm_types.h"
#include "driver/mcpwm_types.h"
#include "esp_private/sleep_retention.h"
@@ -86,10 +86,10 @@ struct mcpwm_group_t {
#endif
soc_module_clk_t clk_src; // peripheral source clock
mcpwm_cap_timer_t *cap_timer; // mcpwm capture timers
mcpwm_timer_t *timers[SOC_MCPWM_TIMERS_PER_GROUP]; // mcpwm timer array
mcpwm_oper_t *operators[SOC_MCPWM_OPERATORS_PER_GROUP]; // mcpwm operator array
mcpwm_gpio_fault_t *gpio_faults[SOC_MCPWM_GPIO_FAULTS_PER_GROUP]; // mcpwm fault detectors array
mcpwm_gpio_sync_src_t *gpio_sync_srcs[SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP]; // mcpwm gpio sync array
mcpwm_timer_t *timers[MCPWM_LL_GET(TIMERS_PER_GROUP)]; // mcpwm timer array
mcpwm_oper_t *operators[MCPWM_LL_GET(OPERATORS_PER_GROUP)]; // mcpwm operator array
mcpwm_gpio_fault_t *gpio_faults[MCPWM_LL_GET(GPIO_FAULTS_PER_GROUP)]; // mcpwm fault detectors array
mcpwm_gpio_sync_src_t *gpio_sync_srcs[MCPWM_LL_GET(GPIO_SYNCHROS_PER_GROUP)]; // mcpwm gpio sync array
};
typedef enum {
@@ -125,15 +125,15 @@ struct mcpwm_oper_t {
mcpwm_timer_t *timer; // which timer is connected to this operator
portMUX_TYPE spinlock; // spin lock
intr_handle_t intr; // interrupt handle
mcpwm_gen_t *generators[SOC_MCPWM_GENERATORS_PER_OPERATOR]; // mcpwm generator array
mcpwm_oper_cmpr_t *comparators[SOC_MCPWM_COMPARATORS_PER_OPERATOR]; // mcpwm operator comparator array
mcpwm_gen_t *generators[MCPWM_LL_GET(GENERATORS_PER_OPERATOR)]; // mcpwm generator array
mcpwm_oper_cmpr_t *comparators[MCPWM_LL_GET(COMPARATORS_PER_OPERATOR)]; // mcpwm operator comparator array
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
mcpwm_evt_cmpr_t *event_comparators[SOC_MCPWM_EVENT_COMPARATORS_PER_OPERATOR]; // mcpwm event comparator array
mcpwm_evt_cmpr_t *event_comparators[MCPWM_LL_GET(EVENT_COMPARATORS_PER_OPERATOR)]; // mcpwm event comparator array
#endif
mcpwm_trigger_source_t triggers[SOC_MCPWM_TRIGGERS_PER_OPERATOR]; // mcpwm trigger array, can be either a fault or a sync
mcpwm_trigger_source_t triggers[MCPWM_LL_GET(TRIGGERS_PER_OPERATOR)]; // mcpwm trigger array, can be either a fault or a sync
mcpwm_soft_fault_t *soft_fault; // mcpwm software fault
mcpwm_operator_brake_mode_t brake_mode_on_soft_fault; // brake mode on software triggered fault
mcpwm_operator_brake_mode_t brake_mode_on_gpio_fault[SOC_MCPWM_GPIO_FAULTS_PER_GROUP]; // brake mode on GPIO triggered faults
mcpwm_operator_brake_mode_t brake_mode_on_gpio_fault[MCPWM_LL_GET(GPIO_FAULTS_PER_GROUP)]; // brake mode on GPIO triggered faults
uint32_t deadtime_resolution_hz; // resolution of deadtime submodule
mcpwm_gen_t *posedge_delay_owner; // which generator owns the positive edge delay
mcpwm_gen_t *negedge_delay_owner; // which generator owns the negative edge delay
@@ -257,7 +257,7 @@ struct mcpwm_cap_timer_t {
#if CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock; // power management lock
#endif
mcpwm_cap_channel_t *cap_channels[SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER]; // capture channel array
mcpwm_cap_channel_t *cap_channels[MCPWM_LL_GET(CAPTURE_CHANNELS_PER_TIMER)]; // capture channel array
};
struct mcpwm_cap_channel_t {
+4 -4
View File
@@ -110,7 +110,7 @@ static esp_err_t mcpwm_gpio_sync_src_register_to_group(mcpwm_gpio_sync_src_t *gp
int sync_id = -1;
portENTER_CRITICAL(&group->spinlock);
for (int i = 0; i < SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP; i++) {
for (int i = 0; i < MCPWM_LL_GET(GPIO_SYNCHROS_PER_GROUP); i++) {
if (!group->gpio_sync_srcs[i]) {
sync_id = i;
group->gpio_sync_srcs[i] = gpio_sync_src;
@@ -158,7 +158,7 @@ esp_err_t mcpwm_new_gpio_sync_src(const mcpwm_gpio_sync_src_config_t *config, mc
esp_err_t ret = ESP_OK;
mcpwm_gpio_sync_src_t *gpio_sync_src = NULL;
ESP_GOTO_ON_FALSE(config && ret_sync, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(config->group_id < SOC_MCPWM_GROUPS && config->group_id >= 0, ESP_ERR_INVALID_ARG,
ESP_GOTO_ON_FALSE(config->group_id < MCPWM_LL_GET(GROUP_NUM) && config->group_id >= 0, ESP_ERR_INVALID_ARG,
err, TAG, "invalid group ID:%d", config->group_id);
gpio_sync_src = heap_caps_calloc(1, sizeof(mcpwm_gpio_sync_src_t), MCPWM_MEM_ALLOC_CAPS);
@@ -173,7 +173,7 @@ esp_err_t mcpwm_new_gpio_sync_src(const mcpwm_gpio_sync_src_config_t *config, mc
gpio_func_sel(config->gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->gpio_num);
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group_id].gpio_synchros[sync_id].sync_sig, 0);
esp_rom_gpio_connect_in_signal(config->gpio_num, soc_mcpwm_signals[group_id].gpio_synchros[sync_id].sync_sig, 0);
// different ext sync share the same config register, using a group level spin lock
portENTER_CRITICAL(&group->spinlock);
@@ -203,7 +203,7 @@ static esp_err_t mcpwm_del_gpio_sync_src(mcpwm_sync_t *sync_src)
int sync_id = gpio_sync_src->sync_id;
ESP_LOGD(TAG, "del gpio sync_src (%d,%d)", group->group_id, gpio_sync_src->sync_id);
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, mcpwm_periph_signals.groups[group_id].gpio_synchros[sync_id].sync_sig, 0);
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, soc_mcpwm_signals[group_id].gpio_synchros[sync_id].sync_sig, 0);
// recycle memory resource
ESP_RETURN_ON_ERROR(mcpwm_gpio_sync_src_destroy(gpio_sync_src), TAG, "destroy GPIO sync_src failed");
@@ -19,7 +19,7 @@ static esp_err_t mcpwm_timer_register_to_group(mcpwm_timer_t *timer, int group_i
int timer_id = -1;
portENTER_CRITICAL(&group->spinlock);
for (int i = 0; i < SOC_MCPWM_TIMERS_PER_GROUP; i++) {
for (int i = 0; i < MCPWM_LL_GET(TIMERS_PER_GROUP); i++) {
if (!group->timers[i]) {
timer_id = i;
group->timers[i] = timer;
@@ -68,7 +68,7 @@ esp_err_t mcpwm_new_timer(const mcpwm_timer_config_t *config, mcpwm_timer_handle
esp_err_t ret = ESP_OK;
mcpwm_timer_t *timer = NULL;
ESP_GOTO_ON_FALSE(config && ret_timer, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
ESP_GOTO_ON_FALSE(config->group_id < SOC_MCPWM_GROUPS && config->group_id >= 0, ESP_ERR_INVALID_ARG,
ESP_GOTO_ON_FALSE(config->group_id < MCPWM_LL_GET(GROUP_NUM) && config->group_id >= 0, ESP_ERR_INVALID_ARG,
err, TAG, "invalid group ID:%d", config->group_id);
if (config->intr_priority) {
ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & MCPWM_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err,
@@ -79,7 +79,7 @@ esp_err_t mcpwm_new_timer(const mcpwm_timer_config_t *config, mcpwm_timer_handle
if (config->count_mode == MCPWM_TIMER_COUNT_MODE_UP_DOWN) {
peak_ticks /= 2; // in symmetric mode, peak_ticks = period_ticks / 2
}
ESP_GOTO_ON_FALSE(peak_ticks > 0 && peak_ticks < MCPWM_LL_MAX_COUNT_VALUE, ESP_ERR_INVALID_ARG, err, TAG, "invalid period ticks");
ESP_GOTO_ON_FALSE(peak_ticks > 0 && peak_ticks < MCPWM_LL_GET(MAX_COUNT_VALUE), ESP_ERR_INVALID_ARG, err, TAG, "invalid period ticks");
#if !SOC_MCPWM_SUPPORT_SLEEP_RETENTION
ESP_RETURN_ON_FALSE(config->flags.allow_pd == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported");
@@ -105,7 +105,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 = 0;
ESP_GOTO_ON_ERROR(mcpwm_set_prescale(group, config->resolution_hz, MCPWM_LL_MAX_TIMER_PRESCALE, &prescale), err, TAG, "set prescale failed");
ESP_GOTO_ON_ERROR(mcpwm_set_prescale(group, config->resolution_hz, MCPWM_LL_GET(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) {
@@ -176,7 +176,7 @@ esp_err_t mcpwm_timer_set_period(mcpwm_timer_handle_t timer, uint32_t period_tic
if (timer->count_mode == MCPWM_TIMER_COUNT_MODE_UP_DOWN) {
peak_ticks /= 2; // in symmetric mode, peak_ticks = period_ticks / 2
}
ESP_RETURN_ON_FALSE_ISR(peak_ticks > 0 && peak_ticks < MCPWM_LL_MAX_COUNT_VALUE, ESP_ERR_INVALID_ARG, TAG, "invalid period ticks");
ESP_RETURN_ON_FALSE_ISR(peak_ticks > 0 && peak_ticks < MCPWM_LL_GET(MAX_COUNT_VALUE), ESP_ERR_INVALID_ARG, TAG, "invalid period ticks");
mcpwm_ll_timer_set_peak(hal->dev, timer_id, peak_ticks, timer->count_mode == MCPWM_TIMER_COUNT_MODE_UP_DOWN);
timer->peak_ticks = peak_ticks;
return ESP_OK;
@@ -210,7 +210,7 @@ esp_err_t mcpwm_timer_register_event_callbacks(mcpwm_timer_handle_t timer, const
ESP_RETURN_ON_FALSE(timer->fsm == MCPWM_TIMER_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "timer not in init state");
int isr_flags = MCPWM_INTR_ALLOC_FLAG;
isr_flags |= mcpwm_get_intr_priority_flag(group);
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(mcpwm_periph_signals.groups[group_id].irq_id, isr_flags,
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(soc_mcpwm_signals[group_id].irq_id, isr_flags,
(uint32_t)mcpwm_ll_intr_get_status_reg(hal->dev), MCPWM_LL_EVENT_TIMER_MASK(timer_id),
mcpwm_timer_default_isr, timer, &timer->intr), TAG, "install interrupt service for timer failed");
}
@@ -312,7 +312,7 @@ esp_err_t mcpwm_timer_set_phase_on_sync(mcpwm_timer_handle_t timer, const mcpwm_
// enable sync feature and set sync phase
if (sync_source) {
ESP_RETURN_ON_FALSE(config->count_value < MCPWM_LL_MAX_COUNT_VALUE, ESP_ERR_INVALID_ARG, TAG, "invalid sync count value");
ESP_RETURN_ON_FALSE(config->count_value < MCPWM_LL_GET(MAX_COUNT_VALUE), ESP_ERR_INVALID_ARG, TAG, "invalid sync count value");
switch (sync_source->type) {
case MCPWM_SYNC_TYPE_TIMER: {
ESP_RETURN_ON_FALSE(group == sync_source->group, ESP_ERR_INVALID_ARG, TAG, "timer and sync source are not in the same group");
@@ -9,9 +9,15 @@ project(mcpwm_test)
idf_build_get_property(elf EXECUTABLE)
if(CONFIG_COMPILER_DUMP_RTL_FILES)
set(MCPWM_RTL_DIRS
${CMAKE_BINARY_DIR}/esp-idf/esp_driver_mcpwm
${CMAKE_BINARY_DIR}/esp-idf/esp_hal_mcpwm
${CMAKE_BINARY_DIR}/esp-idf/hal
)
string(JOIN "," MCPWM_RTL_DIRS_JOINED ${MCPWM_RTL_DIRS})
add_custom_target(check_test_app_sections ALL
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_mcpwm/,${CMAKE_BINARY_DIR}/esp-idf/hal/
--rtl-dirs ${MCPWM_RTL_DIRS_JOINED}
--elf-file ${CMAKE_BINARY_DIR}/mcpwm_test.elf
find-refs
--from-sections=.iram0.text
@@ -9,7 +9,7 @@
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "unity.h"
#include "soc/soc_caps.h"
#include "hal/mcpwm_ll.h"
#include "esp_private/esp_clk.h"
#include "driver/mcpwm_cap.h"
#include "driver/mcpwm_sync.h"
@@ -22,12 +22,12 @@ TEST_CASE("mcpwm_capture_install_uninstall", "[mcpwm]")
mcpwm_capture_timer_config_t cap_timer_config = {
.clk_src = MCPWM_CAPTURE_CLK_SRC_DEFAULT,
};
int total_cap_timers = SOC_MCPWM_GROUPS * SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP;
int total_cap_timers = MCPWM_LL_GET(GROUP_NUM) * MCPWM_LL_GET(CAPTURE_TIMERS_PER_GROUP);
mcpwm_cap_timer_handle_t cap_timers[total_cap_timers];
int k = 0;
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
cap_timer_config.group_id = i;
for (int j = 0; j < SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP; j++) {
for (int j = 0; j < MCPWM_LL_GET(CAPTURE_TIMERS_PER_GROUP); j++) {
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timers[k++]));
}
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, mcpwm_new_capture_timer(&cap_timer_config, &cap_timers[0]));
@@ -39,9 +39,9 @@ TEST_CASE("mcpwm_capture_install_uninstall", "[mcpwm]")
.prescale = 2,
.flags.pos_edge = true,
};
mcpwm_cap_channel_handle_t cap_channels[total_cap_timers][SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER];
mcpwm_cap_channel_handle_t cap_channels[total_cap_timers][MCPWM_LL_GET(CAPTURE_CHANNELS_PER_TIMER)];
for (int i = 0; i < total_cap_timers; i++) {
for (int j = 0; j < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; j++) {
for (int j = 0; j < MCPWM_LL_GET(CAPTURE_CHANNELS_PER_TIMER); j++) {
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timers[i], &cap_chan_config, &cap_channels[i][j]));
}
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, mcpwm_new_capture_channel(cap_timers[i], &cap_chan_config, &cap_channels[i][0]));
@@ -49,7 +49,7 @@ TEST_CASE("mcpwm_capture_install_uninstall", "[mcpwm]")
printf("uninstall mcpwm capture channels and timers\r\n");
for (int i = 0; i < total_cap_timers; i++) {
for (int j = 0; j < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; j++) {
for (int j = 0; j < MCPWM_LL_GET(CAPTURE_CHANNELS_PER_TIMER); j++) {
TEST_ESP_OK(mcpwm_del_capture_channel(cap_channels[i][j]));
}
TEST_ESP_OK(mcpwm_del_capture_timer(cap_timers[i]));
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -7,7 +7,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "unity.h"
#include "soc/soc_caps.h"
#include "hal/mcpwm_ll.h"
#include "driver/mcpwm_timer.h"
#include "driver/mcpwm_oper.h"
#include "driver/mcpwm_cmpr.h"
@@ -16,7 +16,7 @@ TEST_CASE("mcpwm_comparator_install_uninstall", "[mcpwm]")
{
mcpwm_timer_handle_t timer;
mcpwm_oper_handle_t oper;
mcpwm_cmpr_handle_t comparators[SOC_MCPWM_COMPARATORS_PER_OPERATOR];
mcpwm_cmpr_handle_t comparators[MCPWM_LL_GET(COMPARATORS_PER_OPERATOR)];
mcpwm_timer_config_t timer_config = {
.group_id = 0,
@@ -34,7 +34,7 @@ TEST_CASE("mcpwm_comparator_install_uninstall", "[mcpwm]")
printf("install comparator\r\n");
mcpwm_comparator_config_t comparator_config = {};
for (int i = 0; i < SOC_MCPWM_COMPARATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(COMPARATORS_PER_OPERATOR); i++) {
TEST_ESP_OK(mcpwm_new_comparator(oper, &comparator_config, &comparators[i]));
}
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, mcpwm_new_comparator(oper, &comparator_config, &comparators[0]));
@@ -45,7 +45,7 @@ TEST_CASE("mcpwm_comparator_install_uninstall", "[mcpwm]")
printf("uninstall timer, operator and comparators\r\n");
// can't delete operator if the comparators are still in working
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, mcpwm_del_operator(oper));
for (int i = 0; i < SOC_MCPWM_COMPARATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(COMPARATORS_PER_OPERATOR); i++) {
TEST_ESP_OK(mcpwm_del_comparator(comparators[i]));
}
TEST_ESP_OK(mcpwm_del_operator(oper));
@@ -1,11 +1,12 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "unity.h"
#include "hal/mcpwm_ll.h"
#include "driver/mcpwm_fault.h"
#include "driver/mcpwm_oper.h"
#include "driver/gpio.h"
@@ -17,12 +18,12 @@ TEST_CASE("mcpwm_fault_install_uninstall", "[mcpwm]")
mcpwm_gpio_fault_config_t gpio_fault_config = {
.gpio_num = TEST_FAULT_GPIO,
};
int total_gpio_faults = SOC_MCPWM_GPIO_FAULTS_PER_GROUP * SOC_MCPWM_GROUPS;
int total_gpio_faults = MCPWM_LL_GET(GPIO_FAULTS_PER_GROUP) * MCPWM_LL_GET(GROUP_NUM);
mcpwm_fault_handle_t gpio_faults[total_gpio_faults];
int fault_itor = 0;
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
gpio_fault_config.group_id = i;
for (int j = 0; j < SOC_MCPWM_GPIO_FAULTS_PER_GROUP; j++) {
for (int j = 0; j < MCPWM_LL_GET(GPIO_FAULTS_PER_GROUP); j++) {
TEST_ESP_OK(mcpwm_new_gpio_fault(&gpio_fault_config, &gpio_faults[fault_itor++]));
}
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, mcpwm_new_gpio_fault(&gpio_fault_config, &gpio_faults[0]));
@@ -1,12 +1,12 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "unity.h"
#include "soc/soc_caps.h"
#include "hal/mcpwm_ll.h"
#include "driver/mcpwm_cap.h"
#include "driver/mcpwm_timer.h"
#include "driver/mcpwm_oper.h"
@@ -28,11 +28,11 @@ TEST_CASE("mcpwm_generator_install_uninstall", "[mcpwm]")
TEST_ESP_OK(mcpwm_new_operator(&oper_config, &oper));
printf("create MCPWM generators from that operator\r\n");
mcpwm_gen_handle_t gens[SOC_MCPWM_GENERATORS_PER_OPERATOR];
mcpwm_gen_handle_t gens[MCPWM_LL_GET(GENERATORS_PER_OPERATOR)];
mcpwm_generator_config_t gen_config = {
.gen_gpio_num = TEST_PWMA_GPIO,
};
for (int i = 0; i < SOC_MCPWM_GENERATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(GENERATORS_PER_OPERATOR); i++) {
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gens[i]));
}
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, mcpwm_new_generator(oper, &gen_config, &gens[0]));
@@ -40,7 +40,7 @@ TEST_CASE("mcpwm_generator_install_uninstall", "[mcpwm]")
printf("delete generators and operator\r\n");
// can't delete operator if the generator is till in working
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, mcpwm_del_operator(oper));
for (int i = 0; i < SOC_MCPWM_GENERATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(GENERATORS_PER_OPERATOR); i++) {
TEST_ESP_OK(mcpwm_del_generator(gens[i]));
}
TEST_ESP_OK(mcpwm_del_operator(oper));
@@ -10,7 +10,6 @@
#include "freertos/event_groups.h"
#include "unity.h"
#include "unity_test_utils.h"
#include "soc/soc_caps.h"
#include "esp_private/esp_clk.h"
#include "driver/mcpwm_prelude.h"
#include "driver/gpio.h"
@@ -1,12 +1,12 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "unity.h"
#include "soc/soc_caps.h"
#include "hal/mcpwm_ll.h"
#include "driver/mcpwm_oper.h"
#include "driver/mcpwm_timer.h"
#include "driver/mcpwm_gen.h"
@@ -16,8 +16,8 @@
TEST_CASE("mcpwm_operator_install_uninstall", "[mcpwm]")
{
const int total_operators = SOC_MCPWM_OPERATORS_PER_GROUP * SOC_MCPWM_GROUPS;
mcpwm_timer_handle_t timers[SOC_MCPWM_GROUPS];
const int total_operators = MCPWM_LL_GET(OPERATORS_PER_GROUP) * MCPWM_LL_GET(GROUP_NUM);
mcpwm_timer_handle_t timers[MCPWM_LL_GET(GROUP_NUM)];
mcpwm_oper_handle_t operators[total_operators];
mcpwm_timer_config_t timer_config = {
@@ -29,28 +29,28 @@ TEST_CASE("mcpwm_operator_install_uninstall", "[mcpwm]")
mcpwm_operator_config_t operator_config = {
};
printf("install one MCPWM timer for each group\r\n");
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
timer_config.group_id = i;
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timers[i]));
}
printf("install MCPWM operators for each group\r\n");
int k = 0;
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
operator_config.group_id = i;
for (int j = 0; j < SOC_MCPWM_OPERATORS_PER_GROUP; j++) {
for (int j = 0; j < MCPWM_LL_GET(OPERATORS_PER_GROUP); j++) {
TEST_ESP_OK(mcpwm_new_operator(&operator_config, &operators[k++]));
}
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, mcpwm_new_operator(&operator_config, &operators[0]));
}
printf("connect MCPWM timer and operators\r\n");
k = 0;
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int j = 0; j < SOC_MCPWM_OPERATORS_PER_GROUP; j++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
for (int j = 0; j < MCPWM_LL_GET(OPERATORS_PER_GROUP); j++) {
TEST_ESP_OK(mcpwm_operator_connect_timer(operators[k++], timers[i]));
}
}
#if SOC_MCPWM_GROUPS > 1
#if MCPWM_LL_GET(GROUP_NUM) > 1
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, mcpwm_operator_connect_timer(operators[0], timers[1]));
#endif
@@ -58,7 +58,7 @@ TEST_CASE("mcpwm_operator_install_uninstall", "[mcpwm]")
for (int i = 0; i < total_operators; i++) {
TEST_ESP_OK(mcpwm_del_operator(operators[i]));
}
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
TEST_ESP_OK(mcpwm_del_timer(timers[i]));
}
}
@@ -1,12 +1,12 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "unity.h"
#include "soc/soc_caps.h"
#include "hal/mcpwm_ll.h"
#include "driver/mcpwm_timer.h"
#include "driver/mcpwm_sync.h"
#include "driver/gpio.h"
@@ -22,12 +22,12 @@ TEST_CASE("mcpwm_sync_source_install_uninstall", "[mcpwm]")
.period_ticks = 200,
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
};
const int total_timers = SOC_MCPWM_TIMERS_PER_GROUP * SOC_MCPWM_GROUPS;
const int total_timers = MCPWM_LL_GET(TIMERS_PER_GROUP) * MCPWM_LL_GET(GROUP_NUM);
mcpwm_timer_handle_t timers[total_timers];
int k = 0;
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
timer_config.group_id = i;
for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) {
for (int j = 0; j < MCPWM_LL_GET(TIMERS_PER_GROUP); j++) {
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timers[k++]));
}
}
@@ -44,12 +44,12 @@ TEST_CASE("mcpwm_sync_source_install_uninstall", "[mcpwm]")
mcpwm_gpio_sync_src_config_t gpio_sync_config = {
.gpio_num = TEST_SYNC_GPIO,
};
const int total_gpio_sync_srcs = SOC_MCPWM_GROUPS * SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP;
const int total_gpio_sync_srcs = MCPWM_LL_GET(GROUP_NUM) * MCPWM_LL_GET(GPIO_SYNCHROS_PER_GROUP);
mcpwm_sync_handle_t gpio_sync_srcs[total_gpio_sync_srcs];
k = 0;
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
gpio_sync_config.group_id = i;
for (int j = 0; j < SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP; j++) {
for (int j = 0; j < MCPWM_LL_GET(GPIO_SYNCHROS_PER_GROUP); j++) {
TEST_ESP_OK(mcpwm_new_gpio_sync_src(&gpio_sync_config, &gpio_sync_srcs[k++]));
}
}
@@ -123,9 +123,9 @@ TEST_CASE("mcpwm_gpio_sync_timer_phase_lock", "[mcpwm]")
mcpwm_timer_sync_src_config_t sync_config = {
.flags.propagate_input_sync = 1, // reuse the input sync source as the output sync trigger
};
mcpwm_timer_handle_t timers[SOC_MCPWM_TIMERS_PER_GROUP];
mcpwm_sync_handle_t sync_srcs[SOC_MCPWM_TIMERS_PER_GROUP];
for (int i = 0; i < SOC_MCPWM_TIMERS_PER_GROUP; i++) {
mcpwm_timer_handle_t timers[MCPWM_LL_GET(TIMERS_PER_GROUP)];
mcpwm_sync_handle_t sync_srcs[MCPWM_LL_GET(TIMERS_PER_GROUP)];
for (int i = 0; i < MCPWM_LL_GET(TIMERS_PER_GROUP); i++) {
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timers[i]));
TEST_ESP_OK(mcpwm_new_timer_sync_src(timers[i], &sync_config, &sync_srcs[i]));
}
@@ -141,7 +141,7 @@ TEST_CASE("mcpwm_gpio_sync_timer_phase_lock", "[mcpwm]")
TEST_ESP_OK(mcpwm_new_gpio_sync_src(&gpio_sync_config, &gpio_sync_src));
// put the GPIO into initial state
gpio_set_level(gpio_num, 0);
for (int i = 1; i < SOC_MCPWM_TIMERS_PER_GROUP; i++) {
for (int i = 1; i < MCPWM_LL_GET(TIMERS_PER_GROUP); i++) {
sync_phase_config.sync_src = sync_srcs[i - 1];
TEST_ESP_OK(mcpwm_timer_set_phase_on_sync(timers[i], &sync_phase_config));
}
@@ -151,10 +151,10 @@ TEST_CASE("mcpwm_gpio_sync_timer_phase_lock", "[mcpwm]")
// simulate an GPIO sync signal
gpio_set_level(gpio_num, 1);
gpio_set_level(gpio_num, 0);
check_mcpwm_timer_phase(timers, SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP, 100, MCPWM_TIMER_DIRECTION_UP);
check_mcpwm_timer_phase(timers, MCPWM_LL_GET(CAPTURE_TIMERS_PER_GROUP), 100, MCPWM_TIMER_DIRECTION_UP);
TEST_ESP_OK(mcpwm_del_sync_src(gpio_sync_src));
for (int i = 0; i < SOC_MCPWM_TIMERS_PER_GROUP; i++) {
for (int i = 0; i < MCPWM_LL_GET(TIMERS_PER_GROUP); i++) {
TEST_ESP_OK(mcpwm_del_sync_src(sync_srcs[i]));
TEST_ESP_OK(mcpwm_del_timer(timers[i]));
}
@@ -175,8 +175,8 @@ TEST_CASE("mcpwm_timer_sync_timer_phase_lock", "[mcpwm]")
.period_ticks = 500,
.count_mode = MCPWM_TIMER_COUNT_MODE_UP_DOWN,
};
mcpwm_timer_handle_t timers[SOC_MCPWM_TIMERS_PER_GROUP];
for (int i = 0; i < SOC_MCPWM_TIMERS_PER_GROUP; i++) {
mcpwm_timer_handle_t timers[MCPWM_LL_GET(TIMERS_PER_GROUP)];
for (int i = 0; i < MCPWM_LL_GET(TIMERS_PER_GROUP); i++) {
TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timers[i]));
}
@@ -191,7 +191,7 @@ TEST_CASE("mcpwm_timer_sync_timer_phase_lock", "[mcpwm]")
.direction = MCPWM_TIMER_DIRECTION_DOWN,
.sync_src = sync_src,
};
for (int i = 1; i < SOC_MCPWM_TIMERS_PER_GROUP; i++) {
for (int i = 1; i < MCPWM_LL_GET(TIMERS_PER_GROUP); i++) {
TEST_ESP_OK(mcpwm_timer_set_phase_on_sync(timers[i], &sync_phase_config));
}
@@ -203,7 +203,7 @@ TEST_CASE("mcpwm_timer_sync_timer_phase_lock", "[mcpwm]")
TEST_ESP_OK(mcpwm_timer_disable(timers[0]));
TEST_ESP_OK(mcpwm_del_sync_src(sync_src));
for (int i = 0; i < SOC_MCPWM_TIMERS_PER_GROUP; i++) {
for (int i = 0; i < MCPWM_LL_GET(TIMERS_PER_GROUP); i++) {
TEST_ESP_OK(mcpwm_del_timer(timers[i]));
}
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -7,7 +7,7 @@
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "unity.h"
#include "soc/soc_caps.h"
#include "hal/mcpwm_ll.h"
#include "driver/mcpwm_timer.h"
#include "esp_private/mcpwm.h"
#include "test_mcpwm_utils.h"
@@ -20,14 +20,14 @@ TEST_CASE("mcpwm_timer_start_stop", "[mcpwm]")
.period_ticks = 400,
.count_mode = MCPWM_TIMER_COUNT_MODE_UP_DOWN,
};
const int num_timers = SOC_MCPWM_TIMERS_PER_GROUP * SOC_MCPWM_GROUPS;
const int num_timers = MCPWM_LL_GET(TIMERS_PER_GROUP) * MCPWM_LL_GET(GROUP_NUM);
printf("create mcpwm timer instances\r\n");
mcpwm_timer_handle_t timers[num_timers];
for (int i = 0; i < SOC_MCPWM_GROUPS; i++) {
for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) {
for (int i = 0; i < MCPWM_LL_GET(GROUP_NUM); i++) {
for (int j = 0; j < MCPWM_LL_GET(TIMERS_PER_GROUP); j++) {
config.group_id = i;
TEST_ESP_OK(mcpwm_new_timer(&config, &timers[i * SOC_MCPWM_TIMERS_PER_GROUP + j]));
TEST_ESP_OK(mcpwm_new_timer(&config, &timers[i * MCPWM_LL_GET(TIMERS_PER_GROUP) + j]));
}
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, mcpwm_new_timer(&config, &timers[0]));
}
+22
View File
@@ -0,0 +1,22 @@
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
return() # This component is not supported by the POSIX/Linux simulator
endif()
set(srcs)
set(includes "include")
set(target_folder "${target}")
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${target}/include")
list(APPEND includes "${target}/include")
endif()
# MCPWM related source files
if(CONFIG_SOC_MCPWM_SUPPORTED)
list(APPEND srcs "mcpwm_hal.c" "${target_folder}/mcpwm_periph.c")
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${includes}
REQUIRES soc hal)
+16
View File
@@ -0,0 +1,16 @@
# ESP Hardware Abstraction Layer for MCPWM Peripheral
> [!NOTE]
> This component is currently in beta. Its API, behavior, and compatibility may change at any time and without notice; backward compatibility is not guaranteed. Use caution when integrating into production systems.
## Overview
The ESP Hardware Abstraction Layer for Motor Control PWM Peripherals (`esp_hal_mcpwm`) provides a unified interface to interact with MCPWM (Motor Control Pulse Width Modulation) peripherals across all ESP chip families. This component abstracts the hardware-specific details of different MCPWM implementations, enabling consistent usage patterns regardless of the underlying hardware.
The component supports comprehensive MCPWM functionality including:
- PWM signal generation with precise timing control
- Dead-time insertion for motor control applications
- Fault detection and protection mechanisms
- Capture functionality for feedback systems
- Synchronization between multiple MCPWM units
- Event-driven operation modes
@@ -26,9 +26,24 @@
extern "C" {
#endif
// Get MCPWM attribute
#define MCPWM_LL_GET(attr) (MCPWM_LL_ ## attr)
// Get MCPWM group register base address
#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : &MCPWM1)
// SoC-based capabilities
#define MCPWM_LL_GROUP_NUM (2) ///< 2 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define MCPWM_LL_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define MCPWM_LL_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define MCPWM_LL_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define MCPWM_LL_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define MCPWM_LL_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define MCPWM_LL_GPIO_FAULTS_PER_GROUP (3) ///< The number of GPIO fault signals that each group has
#define MCPWM_LL_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define MCPWM_LL_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define MCPWM_LL_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
// MCPWM interrupt event mask
#define MCPWM_LL_EVENT_TIMER_STOP(timer) (1 << (timer))
#define MCPWM_LL_EVENT_TIMER_EMPTY(timer) (1 << ((timer) + 3))
@@ -0,0 +1,151 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "hal/mcpwm_ll.h"
#include "hal/mcpwm_periph.h"
#include "soc/gpio_sig_map.h"
const soc_mcpwm_signal_desc_t soc_mcpwm_signals[2] = {
{
.module_name = "MCPWM0",
.irq_id = ETS_PWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
}
}
},
{
.module_name = "MCPWM1",
.irq_id = ETS_PWM1_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM1_F0_IN_IDX
},
[1] = {
.fault_sig = PWM1_F1_IN_IDX
},
[2] = {
.fault_sig = PWM1_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM1_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM1_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM1_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM1_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM1_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM1_SYNC2_IN_IDX
}
}
}
};
@@ -21,9 +21,25 @@
extern "C" {
#endif
// MCPWM LL get macro
#define MCPWM_LL_GET(attr) (MCPWM_LL_ ## attr)
// Get MCPWM group register base address
#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : NULL)
// MCPWM capabilities
#define MCPWM_LL_GROUP_NUM (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define MCPWM_LL_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define MCPWM_LL_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define MCPWM_LL_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define MCPWM_LL_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define MCPWM_LL_EVENT_COMPARATORS_PER_OPERATOR (2) ///< The number of event comparators that each operator has
#define MCPWM_LL_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define MCPWM_LL_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define MCPWM_LL_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define MCPWM_LL_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define MCPWM_LL_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
// MCPWM interrupt event mask
#define MCPWM_LL_EVENT_TIMER_STOP(timer) (1 << (timer))
#define MCPWM_LL_EVENT_TIMER_EMPTY(timer) (1 << ((timer) + 3))
@@ -1,86 +1,85 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/mcpwm_periph.h"
#include "hal/mcpwm_periph.h"
#include "soc/mcpwm_reg.h"
#include "soc/gpio_sig_map.h"
const mcpwm_signal_conn_t mcpwm_periph_signals = {
.groups = {
[0] = {
.module_name = "MCPWM0",
.irq_id = ETS_MCPWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
const soc_mcpwm_signal_desc_t soc_mcpwm_signals[1] = {
{
.module_name = "MCPWM0",
.irq_id = ETS_MCPWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
}
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
}
}
}
};
/**
@@ -124,7 +123,7 @@ static const regdma_entries_config_t mcpwm_regs_retention[] = {
},
};
const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[SOC_MCPWM_GROUPS] = {
const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[1] = {
[0] = {
.regdma_entry_array = mcpwm_regs_retention,
.array_size = ARRAY_SIZE(mcpwm_regs_retention),
@@ -28,9 +28,24 @@
extern "C" {
#endif
// MCPWM LL get macro
#define MCPWM_LL_GET(attr) (MCPWM_LL_ ## attr)
// Get MCPWM group register base address
#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : NULL)
// MCPWM capabilities
#define MCPWM_LL_GROUP_NUM (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define MCPWM_LL_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define MCPWM_LL_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define MCPWM_LL_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define MCPWM_LL_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define MCPWM_LL_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define MCPWM_LL_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define MCPWM_LL_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define MCPWM_LL_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define MCPWM_LL_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
// MCPWM interrupt event mask
#define MCPWM_LL_EVENT_TIMER_STOP(timer) (1 << (timer))
#define MCPWM_LL_EVENT_TIMER_EMPTY(timer) (1 << ((timer) + 3))
@@ -1,85 +1,83 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/mcpwm_periph.h"
#include "hal/mcpwm_periph.h"
#include "soc/mcpwm_reg.h"
#include "soc/gpio_sig_map.h"
const mcpwm_signal_conn_t mcpwm_periph_signals = {
.groups = {
[0] = {
.module_name = "MCPWM0",
.irq_id = ETS_MCPWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
const soc_mcpwm_signal_desc_t soc_mcpwm_signals[1] = {
{
.module_name = "MCPWM0",
.irq_id = ETS_MCPWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
}
}
}
};
@@ -124,7 +122,7 @@ static const regdma_entries_config_t mcpwm_regs_retention[] = {
},
};
const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[SOC_MCPWM_GROUPS] = {
const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[1] = {
[0] = {
.regdma_entry_array = mcpwm_regs_retention,
.array_size = ARRAY_SIZE(mcpwm_regs_retention),
@@ -26,9 +26,24 @@
extern "C" {
#endif
// MCPWM LL get macro
#define MCPWM_LL_GET(attr) (MCPWM_LL_ ## attr)
// Get MCPWM group register base address
#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : NULL)
// MCPWM capabilities
#define MCPWM_LL_GROUP_NUM (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define MCPWM_LL_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define MCPWM_LL_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define MCPWM_LL_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define MCPWM_LL_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define MCPWM_LL_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define MCPWM_LL_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define MCPWM_LL_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define MCPWM_LL_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define MCPWM_LL_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
// MCPWM interrupt event mask
#define MCPWM_LL_EVENT_TIMER_STOP(timer) (1 << (timer))
#define MCPWM_LL_EVENT_TIMER_EMPTY(timer) (1 << ((timer) + 3))
@@ -1,85 +1,83 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/mcpwm_periph.h"
#include "hal/mcpwm_periph.h"
#include "soc/mcpwm_reg.h"
#include "soc/gpio_sig_map.h"
const mcpwm_signal_conn_t mcpwm_periph_signals = {
.groups = {
[0] = {
.module_name = "MCPWM0",
.irq_id = ETS_MCPWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
const soc_mcpwm_signal_desc_t soc_mcpwm_signals[1] = {
{
.module_name = "MCPWM0",
.irq_id = ETS_MCPWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
}
}
}
};
@@ -124,7 +122,7 @@ static const regdma_entries_config_t mcpwm_regs_retention[] = {
},
};
const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[SOC_MCPWM_GROUPS] = {
const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[1] = {
[0] = {
.regdma_entry_array = mcpwm_regs_retention,
.array_size = ARRAY_SIZE(mcpwm_regs_retention),
@@ -29,9 +29,25 @@
extern "C" {
#endif
// MCPWM LL get macro
#define MCPWM_LL_GET(attr) (MCPWM_LL_ ## attr)
// Get MCPWM group register base address
#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : &MCPWM1)
// MCPWM capabilities
#define MCPWM_LL_GROUP_NUM (2U) ///< 2 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define MCPWM_LL_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define MCPWM_LL_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define MCPWM_LL_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define MCPWM_LL_EVENT_COMPARATORS_PER_OPERATOR (2) ///< The number of event comparators that each operator has
#define MCPWM_LL_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define MCPWM_LL_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define MCPWM_LL_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define MCPWM_LL_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define MCPWM_LL_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define MCPWM_LL_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
// MCPWM interrupt event mask
#define MCPWM_LL_EVENT_TIMER_STOP(timer) (1 << (timer))
#define MCPWM_LL_EVENT_TIMER_EMPTY(timer) (1 << ((timer) + 3))
@@ -0,0 +1,206 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "hal/mcpwm_periph.h"
#include "soc/mcpwm_reg.h"
#include "soc/gpio_sig_map.h"
const soc_mcpwm_signal_desc_t soc_mcpwm_signals[2] = {
{
.module_name = "MCPWM0",
.irq_id = ETS_PWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_CH0_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM0_CH0_B_PAD_OUT_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_CH1_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM0_CH1_B_PAD_OUT_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_CH2_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM0_CH2_B_PAD_OUT_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_PAD_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_PAD_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_PAD_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_PAD_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_PAD_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_PAD_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_PAD_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_PAD_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_PAD_IN_IDX
}
}
},
{
.module_name = "MCPWM1",
.irq_id = ETS_PWM1_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM1_CH0_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM1_CH0_B_PAD_OUT_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM1_CH1_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM1_CH1_B_PAD_OUT_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM1_CH2_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM1_CH2_B_PAD_OUT_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM1_F0_PAD_IN_IDX
},
[1] = {
.fault_sig = PWM1_F1_PAD_IN_IDX
},
[2] = {
.fault_sig = PWM1_F2_PAD_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM1_CAP0_PAD_IN_IDX
},
[1] = {
.cap_sig = PWM1_CAP1_PAD_IN_IDX
},
[2] = {
.cap_sig = PWM1_CAP2_PAD_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM1_SYNC0_PAD_IN_IDX
},
[1] = {
.sync_sig = PWM1_SYNC1_PAD_IN_IDX
},
[2] = {
.sync_sig = PWM1_SYNC2_PAD_IN_IDX
}
}
}
};
#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION
/**
* MCPWM Registers to be saved during sleep retention
* - Clk Configuration registers, e.g.: MCPWM_CLK_CFG_REG
* - Timer Configuration registers, e.g.: MCPWM_TIMER_SYNCI_CFG_REG, MCPWM_TIMER0_CFG0_REG, MCPWM_TIMER0_CFG1_REG, MCPWM_TIMER0_CFG1_REG
* - Operator Configuration registers, e.g.: MCPWM_OPERATOR_TIMERSEL_REG
* |- Generator Configuration registers, e.g.: MCPWM_GEN0_STMP_CFG_REG, MCPWM_GEN0_TSTMP_A_REG, MCPWM_GEN0_TSTMP_B_REG, MCPWM_GEN0_CFG0_REG, MCPWM_GEN0_FORCE_REG, MCPWM_GEN0_A_REG, MCPWM_GEN0_B_REG
* |- Dead Time Configuration registers, e.g.: MCPWM_DT0_CFG_REG, MCPWM_DT0_FED_CFG_REG, MCPWM_DT0_RED_CFG_REG
* |- Carrier Configuration registers, e.g.: MCPWM_CARRIER0_CFG_REG
* - Fault Handle Configuration registers, e.g.: MCPWM_FAULT_DETECT_REG, MCPWM_FH0_CFG0_REG, MCPWM_FH0_CFG1_REG
* - Capture Timer Configuration registers, e.g.: MCPWM_CAP_TIMER_CFG_REG, MCPWM_CAP_TIMER_PHASE_REG, MCPWM_CAP_CH0_CFG_REG, MCPWM_CAP_CH1_CFG_REG, MCPWM_CAP_CH2_CFG_REG
* - Interrupt enable registers, e.g.: MCPWM_INT_ENA_REG
* - ETM Configurations, e.g.: MCPWM_EVT_EN_REG, MCPWM_TASK_EN_REG
* - Misc Configurations, e.g.: MCPWM_UPDATE_CFG_REG
*/
#define MCPWM_RETENTION_REGS_CNT 68
#define MCPWM_RETENTION_REGS_BASE(i) REG_MCPWM_BASE(i)
static const uint32_t mcpwm_regs_map[4] = {0xefffeeef, 0x7efffbff, 0x1ff18, 0x0};
#define MCPWM_SLEEP_RETENTION_ENTRIES(mcpwm_port) { \
/* backup stage: save configuration registers \
restore stage: restore the configuration registers */ \
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT( \
REGDMA_MCPWM_LINK(0x00), \
MCPWM_RETENTION_REGS_BASE(mcpwm_port), \
MCPWM_RETENTION_REGS_BASE(mcpwm_port), \
MCPWM_RETENTION_REGS_CNT, 0, 0, \
mcpwm_regs_map[0], mcpwm_regs_map[1], \
mcpwm_regs_map[2], mcpwm_regs_map[3]), \
.owner = ENTRY(0)}, \
/* restore stage: trigger a forced update of all active registers*/ \
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_MCPWM_LINK(0x01), \
MCPWM_UPDATE_CFG_REG(mcpwm_port), MCPWM_GLOBAL_FORCE_UP, MCPWM_GLOBAL_FORCE_UP_M, 1, 0), \
.owner = ENTRY(0) }, \
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_MCPWM_LINK(0x02), \
MCPWM_UPDATE_CFG_REG(mcpwm_port), 0, MCPWM_GLOBAL_FORCE_UP_M, 1, 0), \
.owner = ENTRY(0) }, \
};
static const regdma_entries_config_t mcpwm0_regs_retention[] = MCPWM_SLEEP_RETENTION_ENTRIES(0);
static const regdma_entries_config_t mcpwm1_regs_retention[] = MCPWM_SLEEP_RETENTION_ENTRIES(1);
const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[2] = {
[0] = {
.regdma_entry_array = mcpwm0_regs_retention,
.array_size = ARRAY_SIZE(mcpwm0_regs_retention),
.retention_module = SLEEP_RETENTION_MODULE_MCPWM0
},
[1] = {
.regdma_entry_array = mcpwm1_regs_retention,
.array_size = ARRAY_SIZE(mcpwm1_regs_retention),
.retention_module = SLEEP_RETENTION_MODULE_MCPWM1
},
};
#endif //SOC_MCPWM_SUPPORT_SLEEP_RETENTION
@@ -26,9 +26,24 @@
extern "C" {
#endif
// MCPWM LL get macro
#define MCPWM_LL_GET(attr) (MCPWM_LL_ ## attr)
// Get MCPWM group register base address
#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : &MCPWM1)
// MCPWM capabilities
#define MCPWM_LL_GROUP_NUM (2) ///< 2 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define MCPWM_LL_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define MCPWM_LL_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define MCPWM_LL_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define MCPWM_LL_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define MCPWM_LL_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define MCPWM_LL_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define MCPWM_LL_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define MCPWM_LL_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define MCPWM_LL_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
// MCPWM interrupt event mask
#define MCPWM_LL_EVENT_TIMER_STOP(timer) (1 << (timer))
#define MCPWM_LL_EVENT_TIMER_EMPTY(timer) (1 << ((timer) + 3))
@@ -0,0 +1,150 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "hal/mcpwm_periph.h"
#include "soc/gpio_sig_map.h"
const soc_mcpwm_signal_desc_t soc_mcpwm_signals[2] = {
{
.module_name = "MCPWM0",
.irq_id = ETS_PWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
}
}
},
{
.module_name = "MCPWM1",
.irq_id = ETS_PWM1_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM1_F0_IN_IDX
},
[1] = {
.fault_sig = PWM1_F1_IN_IDX
},
[2] = {
.fault_sig = PWM1_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM1_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM1_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM1_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM1_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM1_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM1_SYNC2_IN_IDX
}
}
}
};
@@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/periph_defs.h"
#include "soc/regdma.h"
#if SOC_HAS(MCPWM)
#include "hal/mcpwm_ll.h"
#endif
#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION
#include "soc/retention_periph_defs.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_HAS(MCPWM)
typedef struct {
const char *module_name;
const int irq_id;
struct {
struct {
const uint32_t pwm_sig;
} generators[MCPWM_LL_GET(GENERATORS_PER_OPERATOR)];
} operators[MCPWM_LL_GET(OPERATORS_PER_GROUP)];
struct {
const uint32_t fault_sig;
} gpio_faults[MCPWM_LL_GET(GPIO_FAULTS_PER_GROUP)];
struct {
const uint32_t cap_sig;
} captures[MCPWM_LL_GET(CAPTURE_CHANNELS_PER_TIMER)];
struct {
const uint32_t sync_sig;
} gpio_synchros[MCPWM_LL_GET(GPIO_SYNCHROS_PER_GROUP)];
} soc_mcpwm_signal_desc_t;
extern const soc_mcpwm_signal_desc_t soc_mcpwm_signals[MCPWM_LL_GET(GROUP_NUM)];
#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION
typedef struct {
const regdma_entries_config_t *regdma_entry_array;
uint32_t array_size;
const periph_retention_module_t retention_module;
} mcpwm_reg_retention_info_t;
extern const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[MCPWM_LL_GET(GROUP_NUM)];
#endif // SOC_MCPWM_SUPPORT_SLEEP_RETENTION
#endif // SOC_HAS(MCPWM)
#ifdef __cplusplus
}
#endif
@@ -38,7 +38,7 @@ void mcpwm_hal_operator_reset(mcpwm_hal_context_t *hal, int oper_id)
mcpwm_ll_operator_update_action_at_once(hal->dev, oper_id);
mcpwm_ll_deadtime_stop_update_delay(hal->dev, oper_id, false);
mcpwm_ll_deadtime_update_delay_at_once(hal->dev, oper_id);
for (int i = 0; i < SOC_MCPWM_COMPARATORS_PER_OPERATOR; i++) {
for (int i = 0; i < MCPWM_LL_GET(COMPARATORS_PER_OPERATOR); i++) {
mcpwm_ll_operator_stop_update_compare(hal->dev, oper_id, i, false);
mcpwm_ll_operator_update_compare_at_once(hal->dev, oper_id, i);
}
+1
View File
@@ -81,6 +81,7 @@ else()
esp_hal_i2c
esp_hal_wdt
esp_hal_lcd
esp_hal_mcpwm
LDFRAGMENTS "linker.lf" "app.lf")
add_subdirectory(port)
-4
View File
@@ -100,10 +100,6 @@ elseif(NOT BOOTLOADER_BUILD)
list(APPEND srcs "pcnt_hal.c")
endif()
if(CONFIG_SOC_MCPWM_SUPPORTED)
list(APPEND srcs "mcpwm_hal.c")
endif()
if(CONFIG_SOC_UHCI_SUPPORTED)
list(APPEND srcs "uhci_hal.c")
endif()
-4
View File
@@ -132,10 +132,6 @@ if(CONFIG_SOC_PARLIO_SUPPORTED)
list(APPEND srcs "${target_folder}/parlio_periph.c")
endif()
if(CONFIG_SOC_MCPWM_SUPPORTED)
list(APPEND srcs "${target_folder}/mcpwm_periph.c")
endif()
if(CONFIG_SOC_MPI_SUPPORTED)
list(APPEND srcs "${target_folder}/mpi_periph.c")
endif()
@@ -455,46 +455,6 @@ config SOC_LEDC_TIMER_BIT_WIDTH
int
default 20
config SOC_MCPWM_GROUPS
int
default 2
config SOC_MCPWM_TIMERS_PER_GROUP
int
default 3
config SOC_MCPWM_OPERATORS_PER_GROUP
int
default 3
config SOC_MCPWM_COMPARATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GENERATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_TRIGGERS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GPIO_FAULTS_PER_GROUP
int
default 3
config SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP
bool
default y
config SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER
int
default 3
config SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP
int
default 3
config SOC_MMU_PERIPH_NUM
int
default 2
@@ -238,18 +238,6 @@
#define SOC_LEDC_CHANNEL_NUM (8)
#define SOC_LEDC_TIMER_BIT_WIDTH (20)
/*-------------------------- MCPWM CAPS --------------------------------------*/
#define SOC_MCPWM_GROUPS (2) ///< 2 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define SOC_MCPWM_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define SOC_MCPWM_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define SOC_MCPWM_GPIO_FAULTS_PER_GROUP (3) ///< The number of GPIO fault signals that each group has
#define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
/*-------------------------- MMU CAPS ----------------------------------------*/
#define SOC_MMU_PERIPH_NUM 2
#define SOC_MMU_LINEAR_ADDRESS_REGION_NUM 3
-152
View File
@@ -1,152 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/mcpwm_periph.h"
#include "soc/gpio_sig_map.h"
const mcpwm_signal_conn_t mcpwm_periph_signals = {
.groups = {
[0] = {
.module_name = "MCPWM0",
.irq_id = ETS_PWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
}
}
},
[1] = {
.module_name = "MCPWM1",
.irq_id = ETS_PWM1_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM1_F0_IN_IDX
},
[1] = {
.fault_sig = PWM1_F1_IN_IDX
},
[2] = {
.fault_sig = PWM1_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM1_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM1_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM1_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM1_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM1_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM1_SYNC2_IN_IDX
}
}
}
}
};
@@ -867,50 +867,6 @@ config SOC_RMT_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MCPWM_GROUPS
int
default 1
config SOC_MCPWM_TIMERS_PER_GROUP
int
default 3
config SOC_MCPWM_OPERATORS_PER_GROUP
int
default 3
config SOC_MCPWM_COMPARATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GENERATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_EVENT_COMPARATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_TRIGGERS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GPIO_FAULTS_PER_GROUP
int
default 3
config SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP
bool
default y
config SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER
int
default 3
config SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP
int
default 3
config SOC_MCPWM_SWSYNC_CAN_PROPAGATE
bool
default y
@@ -353,17 +353,6 @@
// #define SOC_RMT_SUPPORT_RC_FAST 1 /*!< Support set RC_FAST as the RMT clock source */
/*-------------------------- MCPWM CAPS --------------------------------------*/
#define SOC_MCPWM_GROUPS 1U ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define SOC_MCPWM_TIMERS_PER_GROUP 3 ///< The number of timers that each group has
#define SOC_MCPWM_OPERATORS_PER_GROUP 3 ///< The number of operators that each group has
#define SOC_MCPWM_COMPARATORS_PER_OPERATOR 2 ///< The number of comparators that each operator has
#define SOC_MCPWM_GENERATORS_PER_OPERATOR 2 ///< The number of generators that each operator has
#define SOC_MCPWM_EVENT_COMPARATORS_PER_OPERATOR 2 ///< The number of event comparators that each operator has
#define SOC_MCPWM_TRIGGERS_PER_OPERATOR 2 ///< The number of triggers that each operator has
#define SOC_MCPWM_GPIO_FAULTS_PER_GROUP 3 ///< The number of fault signal detectors that each group has
#define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP 1 ///< The number of capture timers that each group has
#define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER 3 ///< The number of capture channels that each capture timer has
#define SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP 3 ///< The number of GPIO synchros that each group has
#define SOC_MCPWM_SWSYNC_CAN_PROPAGATE 1 ///< Software sync event can be routed to its output
#define SOC_MCPWM_SUPPORT_ETM 1 ///< Support ETM (Event Task Matrix)
#define SOC_MCPWM_SUPPORT_EVENT_COMPARATOR 1 ///< Support event comparator (based on ETM)
@@ -811,46 +811,6 @@ config SOC_RMT_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MCPWM_GROUPS
int
default 1
config SOC_MCPWM_TIMERS_PER_GROUP
int
default 3
config SOC_MCPWM_OPERATORS_PER_GROUP
int
default 3
config SOC_MCPWM_COMPARATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GENERATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_TRIGGERS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GPIO_FAULTS_PER_GROUP
int
default 3
config SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP
bool
default y
config SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER
int
default 3
config SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP
int
default 3
config SOC_MCPWM_SWSYNC_CAN_PROPAGATE
bool
default y
+1 -10
View File
@@ -327,16 +327,7 @@
#define SOC_RMT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up RMT registers before sleep */
/*-------------------------- MCPWM CAPS --------------------------------------*/
#define SOC_MCPWM_GROUPS (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define SOC_MCPWM_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define SOC_MCPWM_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define SOC_MCPWM_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
#define SOC_MCPWM_SWSYNC_CAN_PROPAGATE (1) ///< Software sync event can be routed to its output
#define SOC_MCPWM_SUPPORT_ETM (1) ///< Support ETM (Event Task Matrix)
#define SOC_MCPWM_CAPTURE_CLK_FROM_GROUP (1) ///< Capture timer shares clock with other PWM timers
@@ -803,46 +803,6 @@ config SOC_RMT_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MCPWM_GROUPS
int
default 1
config SOC_MCPWM_TIMERS_PER_GROUP
int
default 3
config SOC_MCPWM_OPERATORS_PER_GROUP
int
default 3
config SOC_MCPWM_COMPARATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GENERATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_TRIGGERS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GPIO_FAULTS_PER_GROUP
int
default 3
config SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP
bool
default y
config SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER
int
default 3
config SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP
int
default 3
config SOC_MCPWM_SWSYNC_CAN_PROPAGATE
bool
default y
+1 -10
View File
@@ -340,16 +340,7 @@
#define SOC_RMT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up RMT registers before sleep */
/*-------------------------- MCPWM CAPS --------------------------------------*/
#define SOC_MCPWM_GROUPS (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define SOC_MCPWM_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define SOC_MCPWM_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define SOC_MCPWM_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
#define SOC_MCPWM_SWSYNC_CAN_PROPAGATE (1) ///< Software sync event can be routed to its output
#define SOC_MCPWM_SUPPORT_ETM (1) ///< Support ETM (Event Task Matrix)
#define SOC_MCPWM_CAPTURE_CLK_FROM_GROUP (1) ///< Capture timer shares clock with other PWM timers
@@ -1199,50 +1199,6 @@ config SOC_RMT_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MCPWM_GROUPS
int
default 2
config SOC_MCPWM_TIMERS_PER_GROUP
int
default 3
config SOC_MCPWM_OPERATORS_PER_GROUP
int
default 3
config SOC_MCPWM_COMPARATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_EVENT_COMPARATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GENERATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_TRIGGERS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GPIO_FAULTS_PER_GROUP
int
default 3
config SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP
bool
default y
config SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER
int
default 3
config SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP
int
default 3
config SOC_MCPWM_SWSYNC_CAN_PROPAGATE
bool
default y
+1 -11
View File
@@ -436,17 +436,7 @@
#define SOC_RMT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up RMT registers before sleep */
/*-------------------------- MCPWM CAPS --------------------------------------*/
#define SOC_MCPWM_GROUPS (2U) ///< 2 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define SOC_MCPWM_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define SOC_MCPWM_EVENT_COMPARATORS_PER_OPERATOR (2) ///< The number of event comparators that each operator has
#define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define SOC_MCPWM_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define SOC_MCPWM_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
#define SOC_MCPWM_SWSYNC_CAN_PROPAGATE (1) ///< Software sync event can be routed to its output
#define SOC_MCPWM_SUPPORT_ETM (1) ///< Support ETM (Event Task Matrix)
#define SOC_MCPWM_SUPPORT_EVENT_COMPARATOR (1) ///< Support event comparator (based on ETM)
-208
View File
@@ -1,208 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/mcpwm_periph.h"
#include "soc/mcpwm_reg.h"
#include "soc/gpio_sig_map.h"
const mcpwm_signal_conn_t mcpwm_periph_signals = {
.groups = {
[0] = {
.module_name = "MCPWM0",
.irq_id = ETS_PWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_CH0_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM0_CH0_B_PAD_OUT_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_CH1_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM0_CH1_B_PAD_OUT_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_CH2_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM0_CH2_B_PAD_OUT_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_PAD_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_PAD_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_PAD_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_PAD_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_PAD_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_PAD_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_PAD_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_PAD_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_PAD_IN_IDX
}
}
},
[1] = {
.module_name = "MCPWM1",
.irq_id = ETS_PWM1_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM1_CH0_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM1_CH0_B_PAD_OUT_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM1_CH1_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM1_CH1_B_PAD_OUT_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM1_CH2_A_PAD_OUT_IDX
},
[1] = {
.pwm_sig = PWM1_CH2_B_PAD_OUT_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM1_F0_PAD_IN_IDX
},
[1] = {
.fault_sig = PWM1_F1_PAD_IN_IDX
},
[2] = {
.fault_sig = PWM1_F2_PAD_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM1_CAP0_PAD_IN_IDX
},
[1] = {
.cap_sig = PWM1_CAP1_PAD_IN_IDX
},
[2] = {
.cap_sig = PWM1_CAP2_PAD_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM1_SYNC0_PAD_IN_IDX
},
[1] = {
.sync_sig = PWM1_SYNC1_PAD_IN_IDX
},
[2] = {
.sync_sig = PWM1_SYNC2_PAD_IN_IDX
}
}
}
}
};
#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION
/**
* MCPWM Registers to be saved during sleep retention
* - Clk Configuration registers, e.g.: MCPWM_CLK_CFG_REG
* - Timer Configuration registers, e.g.: MCPWM_TIMER_SYNCI_CFG_REG, MCPWM_TIMER0_CFG0_REG, MCPWM_TIMER0_CFG1_REG, MCPWM_TIMER0_CFG1_REG
* - Operator Configuration registers, e.g.: MCPWM_OPERATOR_TIMERSEL_REG
* |- Generator Configuration registers, e.g.: MCPWM_GEN0_STMP_CFG_REG, MCPWM_GEN0_TSTMP_A_REG, MCPWM_GEN0_TSTMP_B_REG, MCPWM_GEN0_CFG0_REG, MCPWM_GEN0_FORCE_REG, MCPWM_GEN0_A_REG, MCPWM_GEN0_B_REG
* |- Dead Time Configuration registers, e.g.: MCPWM_DT0_CFG_REG, MCPWM_DT0_FED_CFG_REG, MCPWM_DT0_RED_CFG_REG
* |- Carrier Configuration registers, e.g.: MCPWM_CARRIER0_CFG_REG
* - Fault Handle Configuration registers, e.g.: MCPWM_FAULT_DETECT_REG, MCPWM_FH0_CFG0_REG, MCPWM_FH0_CFG1_REG
* - Capture Timer Configuration registers, e.g.: MCPWM_CAP_TIMER_CFG_REG, MCPWM_CAP_TIMER_PHASE_REG, MCPWM_CAP_CH0_CFG_REG, MCPWM_CAP_CH1_CFG_REG, MCPWM_CAP_CH2_CFG_REG
* - Interrupt enable registers, e.g.: MCPWM_INT_ENA_REG
* - ETM Configurations, e.g.: MCPWM_EVT_EN_REG, MCPWM_TASK_EN_REG
* - Misc Configurations, e.g.: MCPWM_UPDATE_CFG_REG
*/
#define MCPWM_RETENTION_REGS_CNT 68
#define MCPWM_RETENTION_REGS_BASE(i) REG_MCPWM_BASE(i)
static const uint32_t mcpwm_regs_map[4] = {0xefffeeef, 0x7efffbff, 0x1ff18, 0x0};
#define MCPWM_SLEEP_RETENTION_ENTRIES(mcpwm_port) { \
/* backup stage: save configuration registers \
restore stage: restore the configuration registers */ \
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT( \
REGDMA_MCPWM_LINK(0x00), \
MCPWM_RETENTION_REGS_BASE(mcpwm_port), \
MCPWM_RETENTION_REGS_BASE(mcpwm_port), \
MCPWM_RETENTION_REGS_CNT, 0, 0, \
mcpwm_regs_map[0], mcpwm_regs_map[1], \
mcpwm_regs_map[2], mcpwm_regs_map[3]), \
.owner = ENTRY(0)}, \
/* restore stage: trigger a forced update of all active registers*/ \
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_MCPWM_LINK(0x01), \
MCPWM_UPDATE_CFG_REG(mcpwm_port), MCPWM_GLOBAL_FORCE_UP, MCPWM_GLOBAL_FORCE_UP_M, 1, 0), \
.owner = ENTRY(0) }, \
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_MCPWM_LINK(0x02), \
MCPWM_UPDATE_CFG_REG(mcpwm_port), 0, MCPWM_GLOBAL_FORCE_UP_M, 1, 0), \
.owner = ENTRY(0) }, \
};
static const regdma_entries_config_t mcpwm0_regs_retention[] = MCPWM_SLEEP_RETENTION_ENTRIES(0);
static const regdma_entries_config_t mcpwm1_regs_retention[] = MCPWM_SLEEP_RETENTION_ENTRIES(1);
const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[SOC_MCPWM_GROUPS] = {
[0] = {
.regdma_entry_array = mcpwm0_regs_retention,
.array_size = ARRAY_SIZE(mcpwm0_regs_retention),
.retention_module = SLEEP_RETENTION_MODULE_MCPWM0
},
[1] = {
.regdma_entry_array = mcpwm1_regs_retention,
.array_size = ARRAY_SIZE(mcpwm1_regs_retention),
.retention_module = SLEEP_RETENTION_MODULE_MCPWM1
},
};
#endif //SOC_MCPWM_SUPPORT_SLEEP_RETENTION
@@ -595,46 +595,6 @@ config SOC_LEDC_SUPPORT_FADE_STOP
bool
default y
config SOC_MCPWM_GROUPS
int
default 2
config SOC_MCPWM_TIMERS_PER_GROUP
int
default 3
config SOC_MCPWM_OPERATORS_PER_GROUP
int
default 3
config SOC_MCPWM_COMPARATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GENERATORS_PER_OPERATOR
int
default 2
config SOC_MCPWM_TRIGGERS_PER_OPERATOR
int
default 2
config SOC_MCPWM_GPIO_FAULTS_PER_GROUP
int
default 3
config SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP
bool
default y
config SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER
int
default 3
config SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP
int
default 3
config SOC_MCPWM_SWSYNC_CAN_PROPAGATE
bool
default y
+1 -11
View File
@@ -245,17 +245,7 @@
#define SOC_LEDC_TIMER_BIT_WIDTH (14)
#define SOC_LEDC_SUPPORT_FADE_STOP (1)
/*-------------------------- MCPWM CAPS --------------------------------------*/
#define SOC_MCPWM_GROUPS (2) ///< 2 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
#define SOC_MCPWM_TIMERS_PER_GROUP (3) ///< The number of timers that each group has
#define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define SOC_MCPWM_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define SOC_MCPWM_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
/*-------------------------- MCPWM CAPS ---------------------------------------*/
#define SOC_MCPWM_SWSYNC_CAN_PROPAGATE (1) ///< Software sync event can be routed to its output
/*-------------------------- MMU CAPS ----------------------------------------*/
-152
View File
@@ -1,152 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/soc.h"
#include "soc/mcpwm_periph.h"
#include "soc/gpio_sig_map.h"
const mcpwm_signal_conn_t mcpwm_periph_signals = {
.groups = {
[0] = {
.module_name = "MCPWM0",
.irq_id = ETS_PWM0_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM0_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM0_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM0_F0_IN_IDX
},
[1] = {
.fault_sig = PWM0_F1_IN_IDX
},
[2] = {
.fault_sig = PWM0_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM0_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM0_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM0_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM0_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM0_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM0_SYNC2_IN_IDX
}
}
},
[1] = {
.module_name = "MCPWM1",
.irq_id = ETS_PWM1_INTR_SOURCE,
.operators = {
[0] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT0A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT0B_IDX
}
}
},
[1] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT1A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT1B_IDX
}
}
},
[2] = {
.generators = {
[0] = {
.pwm_sig = PWM1_OUT2A_IDX
},
[1] = {
.pwm_sig = PWM1_OUT2B_IDX
}
}
}
},
.gpio_faults = {
[0] = {
.fault_sig = PWM1_F0_IN_IDX
},
[1] = {
.fault_sig = PWM1_F1_IN_IDX
},
[2] = {
.fault_sig = PWM1_F2_IN_IDX
}
},
.captures = {
[0] = {
.cap_sig = PWM1_CAP0_IN_IDX
},
[1] = {
.cap_sig = PWM1_CAP1_IN_IDX
},
[2] = {
.cap_sig = PWM1_CAP2_IN_IDX
}
},
.gpio_synchros = {
[0] = {
.sync_sig = PWM1_SYNC0_IN_IDX
},
[1] = {
.sync_sig = PWM1_SYNC1_IN_IDX
},
[2] = {
.sync_sig = PWM1_SYNC2_IN_IDX
}
}
}
}
};
-59
View File
@@ -1,59 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/periph_defs.h"
#include "soc/regdma.h"
#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION
#include "soc/retention_periph_defs.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_MCPWM_SUPPORTED
typedef struct {
struct {
const char *module_name;
const int irq_id;
struct {
struct {
const uint32_t pwm_sig;
} generators[SOC_MCPWM_GENERATORS_PER_OPERATOR];
} operators[SOC_MCPWM_OPERATORS_PER_GROUP];
struct {
const uint32_t fault_sig;
} gpio_faults[SOC_MCPWM_GPIO_FAULTS_PER_GROUP];
struct {
const uint32_t cap_sig;
} captures[SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER];
struct {
const uint32_t sync_sig;
} gpio_synchros[SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP];
} groups[SOC_MCPWM_GROUPS];
} mcpwm_signal_conn_t;
extern const mcpwm_signal_conn_t mcpwm_periph_signals;
#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION
typedef struct {
const regdma_entries_config_t *regdma_entry_array;
uint32_t array_size;
const periph_retention_module_t retention_module;
} mcpwm_reg_retention_info_t;
extern const mcpwm_reg_retention_info_t mcpwm_reg_retention_info[SOC_MCPWM_GROUPS];
#endif // SOC_MCPWM_SUPPORT_SLEEP_RETENTION
#endif // SOC_MCPWM_SUPPORTED
#ifdef __cplusplus
}
#endif
+10 -5
View File
@@ -67,7 +67,12 @@ MCPWM Timers
You can allocate a MCPWM timer object by calling :cpp:func:`mcpwm_new_timer` function, with a configuration structure :cpp:type:`mcpwm_timer_config_t` as the parameter. The configuration structure is defined as:
- :cpp:member:`mcpwm_timer_config_t::group_id` specifies the MCPWM group ID. The ID should belong to [0, :c:macro:`SOC_MCPWM_GROUPS` - 1] range. Please note, timers located in different groups are totally independent.
- :cpp:member:`mcpwm_timer_config_t::group_id` specifies the MCPWM group ID. The ID should belong to [0, ``MCPWM_GROUP_NUM`` - 1] range, where ``MCPWM_GROUP_NUM`` is the number of MCPWM groups available on the chip. Please note, timers located in different groups are totally independent.
.. note::
For the number of MCPWM groups available on the chip, please refer to *{IDF_TARGET_NAME} Technical Reference Manual* > *Motor Control PWM (MCPWM)* [`PDF <{IDF_TARGET_TRM_EN_URL}#mcpwm>`__].
- :cpp:member:`mcpwm_timer_config_t::intr_priority` sets the priority of the interrupt. If it is set to ``0``, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority.
- :cpp:member:`mcpwm_timer_config_t::clk_src` sets the clock source of the timer.
- :cpp:member:`mcpwm_timer_config_t::resolution_hz` sets the expected resolution of the timer. The driver internally sets a proper divider based on the clock source and the resolution.
@@ -89,7 +94,7 @@ MCPWM Operators
You can allocate a MCPWM operator object by calling :cpp:func:`mcpwm_new_operator` function, with a configuration structure :cpp:type:`mcpwm_operator_config_t` as the parameter. The configuration structure is defined as:
- :cpp:member:`mcpwm_operator_config_t::group_id` specifies the MCPWM group ID. The ID should belong to [0, :c:macro:`SOC_MCPWM_GROUPS` - 1] range. Please note, operators located in different groups are totally independent.
- :cpp:member:`mcpwm_operator_config_t::group_id` specifies the MCPWM group ID. The ID should belong to [0, ``MCPWM_GROUP_NUM`` - 1] range, where ``MCPWM_GROUP_NUM`` is the number of MCPWM groups available on the chip. Please note, operators located in different groups are totally independent.
- :cpp:member:`mcpwm_operator_config_t::intr_priority` sets the priority of the interrupt. If it is set to ``0``, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority.
- :cpp:member:`mcpwm_operator_config_t::update_gen_action_on_tez` sets whether to update the generator action when the timer counts to zero. Here and below, the timer refers to the one that is connected to the operator by :cpp:func:`mcpwm_operator_connect_timer`.
- :cpp:member:`mcpwm_operator_config_t::update_gen_action_on_tep` sets whether to update the generator action when the timer counts to peak.
@@ -140,7 +145,7 @@ There are two types of faults: A fault signal reflected from the GPIO and a faul
To allocate a GPIO fault object, you can call the :cpp:func:`mcpwm_new_gpio_fault` function, with the configuration structure :cpp:type:`mcpwm_gpio_fault_config_t` as the parameter. The configuration structure is defined as:
- :cpp:member:`mcpwm_gpio_fault_config_t::group_id` sets the MCPWM group ID. The ID should belong to [0, :c:macro:`SOC_MCPWM_GROUPS` - 1] range. Please note, GPIO faults located in different groups are totally independent, i.e., GPIO faults in group 0 can not be detected by the operator in group 1.
- :cpp:member:`mcpwm_gpio_fault_config_t::group_id` sets the MCPWM group ID. The ID should belong to [0, ``MCPWM_GROUP_NUM`` - 1] range, where ``MCPWM_GROUP_NUM`` is the number of MCPWM groups available on the chip. Please note, GPIO faults located in different groups are totally independent, i.e., GPIO faults in group 0 can not be detected by the operator in group 1.
- :cpp:member:`mcpwm_gpio_fault_config_t::intr_priority` sets the priority of the interrupt. If it is set to ``0``, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority.
- :cpp:member:`mcpwm_gpio_fault_config_t::gpio_num` sets the GPIO number used by the fault.
- :cpp:member:`mcpwm_gpio_fault_config_t::active_level` sets the active level of the fault signal.
@@ -161,7 +166,7 @@ The sync source is what can be used to synchronize the MCPWM timer and MCPWM cap
To allocate a GPIO sync source, you can call the :cpp:func:`mcpwm_new_gpio_sync_src` function, with configuration structure :cpp:type:`mcpwm_gpio_sync_src_config_t` as the parameter. The configuration structure is defined as:
- :cpp:member:`mcpwm_gpio_sync_src_config_t::group_id` sets the MCPWM group ID. The ID should belong to [0, :c:macro:`SOC_MCPWM_GROUPS` - 1] range. Please note, the GPIO sync sources located in different groups are totally independent, i.e., GPIO sync source in group 0 can not be detected by the timers in group 1.
- :cpp:member:`mcpwm_gpio_sync_src_config_t::group_id` sets the MCPWM group ID. The ID should belong to [0, ``MCPWM_GROUP_NUM`` - 1] range, where ``MCPWM_GROUP_NUM`` is the number of MCPWM groups available on the chip. Please note, the GPIO sync sources located in different groups are totally independent, i.e., GPIO sync source in group 0 can not be detected by the timers in group 1.
- :cpp:member:`mcpwm_gpio_sync_src_config_t::gpio_num` sets the GPIO number used by the sync source.
- :cpp:member:`mcpwm_gpio_sync_src_config_t::active_neg` sets whether the sync signal is active on falling edges.
- :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_up` and :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_down` set whether to pull up and/or pull down the GPIO internally.
@@ -188,7 +193,7 @@ The MCPWM group has a dedicated timer which is used to capture the timestamp whe
To allocate a capture timer, you can call the :cpp:func:`mcpwm_new_capture_timer` function, with configuration structure :cpp:type:`mcpwm_capture_timer_config_t` as the parameter. The configuration structure is defined as:
- :cpp:member:`mcpwm_capture_timer_config_t::group_id` sets the MCPWM group ID. The ID should belong to [0, :c:macro:`SOC_MCPWM_GROUPS` - 1] range.
- :cpp:member:`mcpwm_capture_timer_config_t::group_id` sets the MCPWM group ID. The ID should belong to [0, ``MCPWM_GROUP_NUM`` - 1] range, where ``MCPWM_GROUP_NUM`` is the number of MCPWM groups available on the chip.
- :cpp:member:`mcpwm_capture_timer_config_t::clk_src` sets the clock source of the capture timer.
- :cpp:member:`mcpwm_capture_timer_config_t::resolution_hz` The driver internally will set a proper divider based on the clock source and the resolution. If it is set to ``0``, the driver will pick an appropriate resolution on its own, and you can subsequently view the current timer resolution via :cpp:func:`mcpwm_capture_timer_get_resolution`.
+10 -5
View File
@@ -67,7 +67,12 @@ MCPWM 定时器
调用 :cpp:func:`mcpwm_new_timer` 函数,以配置结构体 :cpp:type:`mcpwm_timer_config_t` 为参数,分配一个 MCPWM 定时器为对象。结构体定义为:
- :cpp:member:`mcpwm_timer_config_t::group_id` 指定 MCPWM 组 ID,范围为 [0, :c:macro:`SOC_MCPWM_GROUPS` - 1]。需注意,位于不同组的定时器彼此独立。
- :cpp:member:`mcpwm_timer_config_t::group_id` 指定 MCPWM 组 ID,范围为 [0, ``MCPWM_GROUP_NUM`` - 1],其中 ``MCPWM_GROUP_NUM`` 是芯片上可用的 MCPWM 组数量。需注意,位于不同组的定时器彼此独立。
.. note::
对于芯片上可用的 MCPWM 组数量,请参阅 *{IDF_TARGET_NAME} 技术参考手册* > *电机控制脉宽调制器(MCPWM* [`PDF <{IDF_TARGET_TRM_CN_URL}#mcpwm>`__]。
- :cpp:member:`mcpwm_timer_config_t::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。
- :cpp:member:`mcpwm_timer_config_t::clk_src` 设置定时器的时钟源。
- :cpp:member:`mcpwm_timer_config_t::resolution_hz` 设置定时器的预期分辨率。内部驱动将根据时钟源和分辨率设置合适的分频器。
@@ -89,7 +94,7 @@ MCPWM 操作器
调用 :cpp:func:`mcpwm_new_operator` 函数,以配置结构体 :cpp:type:`mcpwm_operator_config_t` 为参数,分配一个 MCPWM 操作器为对象。结构体定义为:
- :cpp:member:`mcpwm_operator_config_t::group_id` 指定 MCPWM 组 ID,范围为 [0, :c:macro:`SOC_MCPWM_GROUPS` - 1]。需注意,位于不同组的操作器彼此独立。
- :cpp:member:`mcpwm_operator_config_t::group_id` 指定 MCPWM 组 ID,范围为 [0, ``MCPWM_GROUP_NUM`` - 1],其中 ``MCPWM_GROUP_NUM`` 是芯片上可用的 MCPWM 组数量。需注意,位于不同组的操作器彼此独立。
- :cpp:member:`mcpwm_operator_config_t::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。
- :cpp:member:`mcpwm_operator_config_t::update_gen_action_on_tez` 设置是否在定时器计数为零时更新生成器操作。此处及下文提到的定时器指通过 :cpp:func:`mcpwm_operator_connect_timer` 连接到操作器的定时器。
- :cpp:member:`mcpwm_operator_config_t::update_gen_action_on_tep` 设置当定时器计数达到峰值时是否更新生成器操作。
@@ -140,7 +145,7 @@ MCPWM 故障分为两种类型:来自 GPIO 的故障信号和软件故障。
调用 :cpp:func:`mcpwm_new_gpio_fault` 函数,以配置结构体 :cpp:type:`mcpwm_gpio_fault_config_t` 为参数,分配一个 GPIO 故障为对象。结构体定义为:
- :cpp:member:`mcpwm_gpio_fault_config_t::group_id` 设置 MCPWM 组 ID,范围为 [0, :c:macro:`SOC_MCPWM_GROUPS` - 1]。需注意,位于不同组的 GPIO 故障彼此独立,也就是说,1 组的操作器无法检测到 0 组的 GPIO 故障。
- :cpp:member:`mcpwm_gpio_fault_config_t::group_id` 设置 MCPWM 组 ID,范围为 [0, ``MCPWM_GROUP_NUM`` - 1],其中 ``MCPWM_GROUP_NUM`` 是芯片上可用的 MCPWM 组数量。需注意,位于不同组的 GPIO 故障彼此独立,也就是说,1 组的操作器无法检测到 0 组的 GPIO 故障。
- :cpp:member:`mcpwm_gpio_fault_config_t::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。
- :cpp:member:`mcpwm_gpio_fault_config_t::gpio_num` 设置故障所使用的 GPIO 编号。
- :cpp:member:`mcpwm_gpio_fault_config_t::active_level` 设置故障信号的有效电平。
@@ -161,7 +166,7 @@ MCPWM 同步源
调用 :cpp:func:`mcpwm_new_gpio_sync_src` 函数,以配置结构体 :cpp:type:`mcpwm_gpio_sync_src_config_t` 为参数,分配一个 GPIO 同步源。结构体定义为:
- :cpp:member:`mcpwm_gpio_sync_src_config_t::group_id` 指定 MCPWM 组 ID,范围为 [0, :c:macro:`SOC_MCPWM_GROUPS` - 1]。需注意,位于不同组的 GPIO 同步源彼此独立,也就是说,1 组的定时器无法检测到 0 组的 GPIO 同步源。
- :cpp:member:`mcpwm_gpio_sync_src_config_t::group_id` 指定 MCPWM 组 ID,范围为 [0, ``MCPWM_GROUP_NUM`` - 1],其中 ``MCPWM_GROUP_NUM`` 是芯片上可用的 MCPWM 组数量。需注意,位于不同组的 GPIO 同步源彼此独立,也就是说,1 组的定时器无法检测到 0 组的 GPIO 同步源。
- :cpp:member:`mcpwm_gpio_sync_src_config_t::gpio_num` 设置同步源使用的 GPIO 编号。
- :cpp:member:`mcpwm_gpio_sync_src_config_t::active_neg` 设置同步信号在下降沿是否有效。
- :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_up`:cpp:member:`mcpwm_gpio_sync_src_config_t::pull_down` 设置是否在内部拉高和/或拉低 GPIO。
@@ -188,7 +193,7 @@ MCPWM 组有一个专用定时器,用于捕获特定事件发生时的时间
调用 :cpp:func:`mcpwm_new_capture_timer` 函数,以配置结构体 :cpp:type:`mcpwm_capture_timer_config_t` 为参数,分配一个捕获定时器。结构体定义为:
- :cpp:member:`mcpwm_capture_timer_config_t::group_id` 设置 MCPWM 组 ID,范围为 [0, :c:macro:`SOC_MCPWM_GROUPS` - 1]
- :cpp:member:`mcpwm_capture_timer_config_t::group_id` 设置 MCPWM 组 ID,范围为 [0, ``MCPWM_GROUP_NUM`` - 1],其中 ``MCPWM_GROUP_NUM`` 是芯片上可用的 MCPWM 组数量
- :cpp:member:`mcpwm_capture_timer_config_t::clk_src` 设置捕获定时器的时钟源。
- :cpp:member:`mcpwm_capture_timer_config_t::resolution_hz` 设置捕获定时器的预期分辨率。内部驱动将根据时钟源和分辨率设置合适的分频器。设置为 ``0`` 时,驱动会自己选取一个适当的分辨率,后续你可以通过 :cpp:func:`mcpwm_capture_timer_get_resolution` 查看当前定时器的分辨率。