refactor(mcpwm): make mcpwm_hal independent & cleanup soc_caps

This commit is contained in:
Chen Chen
2025-11-10 10:47:10 +08:00
parent 0978fc13ae
commit ed64a767ef
57 changed files with 1041 additions and 1216 deletions
+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");