feat(mcpwm): clean up MCPWM ETM driver

This commit is contained in:
morris
2023-09-11 16:53:34 +08:00
parent 7638235311
commit 47e499de52
14 changed files with 106 additions and 99 deletions
@@ -28,14 +28,6 @@ typedef struct {
} flags; /*!< Extra configuration flags for comparator */
} mcpwm_comparator_config_t;
/**
* @brief MCPWM event comparator configuration
*/
typedef struct {
} mcpwm_event_comparator_config_t;
/**
* @brief Create MCPWM comparator
*
@@ -63,6 +55,12 @@ esp_err_t mcpwm_new_comparator(mcpwm_oper_handle_t oper, const mcpwm_comparator_
esp_err_t mcpwm_del_comparator(mcpwm_cmpr_handle_t cmpr);
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
/**
* @brief MCPWM event comparator configuration
*/
typedef struct {
} mcpwm_event_comparator_config_t;
/**
* @brief Create MCPWM event comparator
*
@@ -77,7 +75,7 @@ esp_err_t mcpwm_del_comparator(mcpwm_cmpr_handle_t cmpr);
* - ESP_FAIL: Create MCPWM event comparator failed because of other error
*/
esp_err_t mcpwm_new_event_comparator(mcpwm_oper_handle_t oper, const mcpwm_event_comparator_config_t *config, mcpwm_cmpr_handle_t *ret_cmpr);
#endif
#endif // SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
/**
* @brief Group of supported MCPWM compare event callbacks
+5
View File
@@ -0,0 +1,5 @@
[mapping:mcpwm_driver]
archive: libdriver.a
entries:
if MCPWM_CTRL_FUNC_IN_IRAM = y:
mcpwm_cmpr: mcpwm_comparator_set_compare_value (noflash)
+16 -35
View File
@@ -34,7 +34,7 @@ static esp_err_t mcpwm_comparator_register_to_operator(mcpwm_cmpr_t *cmpr, mcpwm
int cmpr_id = -1;
portENTER_CRITICAL(&oper->spinlock);
switch (cmpr->type) {
case MCPWM_OPERATOR_COMPARATOR:
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++) {
if (!oper->comparators[i]) {
@@ -44,8 +44,9 @@ static esp_err_t mcpwm_comparator_register_to_operator(mcpwm_cmpr_t *cmpr, mcpwm
}
}
break;
}
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
case MCPWM_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++) {
if (!oper->event_comparators[i]) {
@@ -55,12 +56,9 @@ static esp_err_t mcpwm_comparator_register_to_operator(mcpwm_cmpr_t *cmpr, mcpwm
}
}
break;
#endif
default:
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_ARG, TAG, "unknown comparator type:%d", cmpr->type);
break;
}
#endif
}
portEXIT_CRITICAL(&oper->spinlock);
ESP_RETURN_ON_FALSE(cmpr_id >= 0, ESP_ERR_NOT_FOUND, TAG, "no free comparator in operator (%d,%d)", oper->group->group_id, oper->oper_id);
@@ -94,19 +92,21 @@ static esp_err_t mcpwm_comparator_destroy(mcpwm_cmpr_t *cmpr)
mcpwm_comparator_unregister_from_operator(cmpr);
}
switch (cmpr->type) {
case MCPWM_OPERATOR_COMPARATOR:
case MCPWM_OPERATOR_COMPARATOR: {
mcpwm_oper_cmpr_t *oper_cmpr = __containerof(cmpr, mcpwm_oper_cmpr_t, base);
if (oper_cmpr->intr) {
ESP_RETURN_ON_ERROR(esp_intr_free(oper_cmpr->intr), TAG, "uninstall interrupt service failed");
}
free(oper_cmpr);
break;
}
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
case MCPWM_EVENT_COMPARATOR:
case MCPWM_EVENT_COMPARATOR: {
mcpwm_evt_cmpr_t *evt_cmpr = __containerof(cmpr, mcpwm_evt_cmpr_t, base);
free(evt_cmpr);
break;
#endif
}
#endif // SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
}
return ESP_OK;
}
@@ -132,8 +132,8 @@ esp_err_t mcpwm_new_comparator(mcpwm_oper_handle_t oper, const mcpwm_comparator_
int cmpr_id = cmpr->base.cmpr_id;
// if interrupt priority specified before, it cannot be changed until the group is released
// check if the new priority specified consistents with the old one
ESP_GOTO_ON_ERROR(mcpwm_check_intr_priority(group, config->intr_priority), err, TAG, "set group intrrupt priority failed");
// check if the new priority specified consistent with the old one
ESP_GOTO_ON_ERROR(mcpwm_check_intr_priority(group, config->intr_priority), err, TAG, "set group interrupt priority failed");
mcpwm_ll_operator_enable_update_compare_on_tez(hal->dev, oper_id, cmpr_id, config->flags.update_cmp_on_tez);
mcpwm_ll_operator_enable_update_compare_on_tep(hal->dev, oper_id, cmpr_id, config->flags.update_cmp_on_tep);
@@ -142,7 +142,7 @@ esp_err_t mcpwm_new_comparator(mcpwm_oper_handle_t oper, const mcpwm_comparator_
// fill in other comparator members
cmpr->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
*ret_cmpr = &cmpr->base;
ESP_LOGD(TAG, "new comparator (%d,%d,%d) at %p", group->group_id, oper_id, cmpr_id, cmpr);
ESP_LOGD(TAG, "new operator comparator (%d,%d,%d) at %p", group->group_id, oper_id, cmpr_id, cmpr);
return ESP_OK;
err:
@@ -166,16 +166,9 @@ esp_err_t mcpwm_del_comparator(mcpwm_cmpr_handle_t cmpr)
case MCPWM_OPERATOR_COMPARATOR:
mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CMP_EQUAL(oper_id, cmpr_id), false);
mcpwm_ll_intr_clear_status(hal->dev, MCPWM_LL_EVENT_CMP_EQUAL(oper_id, cmpr_id));
mcpwm_ll_operator_enable_update_compare_on_sync(hal->dev, oper_id, cmpr_id, false);
#if SOC_MCPWM_SUPPORT_ETM
mcpwm_ll_etm_enable_comparator_event(hal->dev, oper_id, cmpr_id, false);
#endif
break;
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
case MCPWM_EVENT_COMPARATOR:
mcpwm_ll_etm_enable_evt_comparator_event(hal->dev, oper_id, cmpr_id, false);
default:
break;
#endif
}
portEXIT_CRITICAL(&group->spinlock);
@@ -191,26 +184,16 @@ esp_err_t mcpwm_new_event_comparator(mcpwm_oper_handle_t oper, const mcpwm_event
esp_err_t ret = ESP_OK;
mcpwm_evt_cmpr_t *cmpr = NULL;
ESP_GOTO_ON_FALSE(oper && config && ret_cmpr, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
cmpr = heap_caps_calloc(1, sizeof(mcpwm_evt_cmpr_t), MCPWM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(cmpr, ESP_ERR_NO_MEM, err, TAG, "no mem for event comparator");
cmpr->base.type = MCPWM_EVENT_COMPARATOR;
ESP_GOTO_ON_ERROR(mcpwm_comparator_register_to_operator(&cmpr->base, oper), err, TAG, "register event comparator failed");
mcpwm_group_t *group = oper->group;
mcpwm_hal_context_t *hal = &group->hal;
int oper_id = oper->oper_id;
int cmpr_id = cmpr->base.cmpr_id;
portENTER_CRITICAL(&group->spinlock);
mcpwm_ll_etm_enable_evt_comparator_event(hal->dev, oper_id, cmpr_id, true);
portEXIT_CRITICAL(&group->spinlock);
// fill in other comparator members
cmpr->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
*ret_cmpr = &cmpr->base;
ESP_LOGD(TAG, "new comparator (%d,%d,%d) at %p", group->group_id, oper_id, cmpr_id, cmpr);
ESP_LOGD(TAG, "new event comparator (%d,%d,%d) at %p", oper->group->group_id, oper->oper_id, cmpr->base.cmpr_id, cmpr);
return ESP_OK;
err:
@@ -219,7 +202,7 @@ err:
}
return ret;
}
# endif
#endif // SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
esp_err_t mcpwm_comparator_set_compare_value(mcpwm_cmpr_handle_t cmpr, uint32_t cmp_ticks)
{
@@ -230,7 +213,6 @@ esp_err_t mcpwm_comparator_set_compare_value(mcpwm_cmpr_handle_t cmpr, uint32_t
ESP_RETURN_ON_FALSE_ISR(timer, ESP_ERR_INVALID_STATE, TAG, "timer and operator are not connected");
ESP_RETURN_ON_FALSE_ISR(cmp_ticks <= timer->peak_ticks, ESP_ERR_INVALID_ARG, TAG, "compare value out of range");
portENTER_CRITICAL_SAFE(&cmpr->spinlock);
switch (cmpr->type) {
case MCPWM_OPERATOR_COMPARATOR:
mcpwm_ll_operator_set_compare_value(group->hal.dev, oper->oper_id, cmpr->cmpr_id, cmp_ticks);
@@ -241,7 +223,6 @@ esp_err_t mcpwm_comparator_set_compare_value(mcpwm_cmpr_handle_t cmpr, uint32_t
break;
#endif
}
portEXIT_CRITICAL_SAFE(&cmpr->spinlock);
cmpr->compare_ticks = cmp_ticks;
return ESP_OK;
+41 -16
View File
@@ -8,11 +8,6 @@
#include <stdarg.h>
#include <sys/cdefs.h>
#include "sdkconfig.h"
#if CONFIG_MCPWM_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include "freertos/FreeRTOS.h"
#include "esp_attr.h"
#include "esp_check.h"
@@ -27,19 +22,44 @@
static const char *TAG = "mcpwm-etm";
typedef struct {
esp_etm_event_t base;
mcpwm_cmpr_handle_t cmpr;
} mcpwm_comparator_etm_event_t;
static esp_err_t mcpwm_del_etm_event(esp_etm_event_t *event)
{
free(event);
mcpwm_comparator_etm_event_t *etm_event = __containerof(event, mcpwm_comparator_etm_event_t, base);
mcpwm_cmpr_handle_t cmpr = etm_event->cmpr;
mcpwm_oper_t *oper = cmpr->oper;
mcpwm_group_t *group = oper->group;
mcpwm_hal_context_t *hal = &group->hal;
switch (cmpr->type) {
case MCPWM_OPERATOR_COMPARATOR:
portENTER_CRITICAL(&group->spinlock);
mcpwm_ll_etm_enable_comparator_event(hal->dev, oper->oper_id, cmpr->cmpr_id, false);
portEXIT_CRITICAL(&group->spinlock);
break;
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
case MCPWM_EVENT_COMPARATOR:
portENTER_CRITICAL(&group->spinlock);
mcpwm_ll_etm_enable_evt_comparator_event(hal->dev, oper->oper_id, cmpr->cmpr_id, false);
portEXIT_CRITICAL(&group->spinlock);
break;
#endif // SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
}
free(etm_event);
return ESP_OK;
}
esp_err_t mcpwm_comparator_new_etm_event(mcpwm_cmpr_handle_t cmpr, const mcpwm_cmpr_etm_event_config_t *config, esp_etm_event_handle_t *out_event)
{
esp_etm_event_t *event = NULL;
esp_err_t ret = ESP_OK;
ESP_GOTO_ON_FALSE(cmpr && config && out_event, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
event = heap_caps_calloc(1, sizeof(esp_etm_event_t), MCPWM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(event, ESP_ERR_NO_MEM, err, TAG, "no memory for ETM event");
mcpwm_comparator_etm_event_t *event = NULL;
ESP_RETURN_ON_FALSE(cmpr && config && out_event, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
event = heap_caps_calloc(1, sizeof(mcpwm_comparator_etm_event_t), MCPWM_MEM_ALLOC_CAPS);
ESP_RETURN_ON_FALSE(event, ESP_ERR_NO_MEM, TAG, "no memory for ETM event");
mcpwm_oper_t *oper = cmpr->oper;
mcpwm_group_t *group = oper->group;
@@ -58,23 +78,28 @@ esp_err_t mcpwm_comparator_new_etm_event(mcpwm_cmpr_handle_t cmpr, const mcpwm_c
break;
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
case MCPWM_EVENT_COMPARATOR:
portENTER_CRITICAL(&group->spinlock);
mcpwm_ll_etm_enable_evt_comparator_event(hal->dev, oper->oper_id, cmpr->cmpr_id, true);
portEXIT_CRITICAL(&group->spinlock);
event_id = MCPWM_LL_ETM_EVENT_COMPARATOR_EVENT_TABLE(group_id, oper_id, cmpr_id, config->event_type);
break;
#endif
#endif // SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
}
ESP_GOTO_ON_FALSE(event_id != 0, ESP_ERR_NOT_SUPPORTED, err, TAG, "not supported event type");
ESP_LOGD(TAG, "MCPWM (%d) oper (%d) cmpr(%d) event_id (%"PRId32")", group_id, oper_id, cmpr_id, event_id);
// fill the ETM event object
event->event_id = event_id;
event->trig_periph = ETM_TRIG_PERIPH_MCPWM;
event->del = mcpwm_del_etm_event;
*out_event = event;
event->cmpr = cmpr;
event->base.event_id = event_id;
event->base.trig_periph = ETM_TRIG_PERIPH_MCPWM;
event->base.del = mcpwm_del_etm_event;
*out_event = &event->base;
return ESP_OK;
err:
if (event) {
mcpwm_del_etm_event(event);
mcpwm_del_etm_event(&event->base);
}
return ret;
}
+5 -9
View File
@@ -45,9 +45,7 @@ typedef struct mcpwm_cap_timer_t mcpwm_cap_timer_t;
typedef struct mcpwm_oper_t mcpwm_oper_t;
typedef struct mcpwm_cmpr_t mcpwm_cmpr_t;
typedef struct mcpwm_oper_cmpr_t mcpwm_oper_cmpr_t;
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
typedef struct mcpwm_evt_cmpr_t mcpwm_evt_cmpr_t;
#endif
typedef struct mcpwm_gen_t mcpwm_gen_t;
typedef struct mcpwm_fault_t mcpwm_fault_t;
typedef struct mcpwm_gpio_fault_t mcpwm_gpio_fault_t;
@@ -128,9 +126,9 @@ struct mcpwm_oper_t {
};
typedef enum {
MCPWM_OPERATOR_COMPARATOR, // operator comparator
MCPWM_OPERATOR_COMPARATOR, // operator comparator, can affect generator's behaviour
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
MCPWM_EVENT_COMPARATOR, // event comparator
MCPWM_EVENT_COMPARATOR, // event comparator, can only generate ETM event
#endif
} mcpwm_comparator_type_t;
@@ -143,17 +141,15 @@ struct mcpwm_cmpr_t {
};
struct mcpwm_oper_cmpr_t {
mcpwm_cmpr_t base; // base class
mcpwm_cmpr_t base; // base class
intr_handle_t intr; // interrupt handle
mcpwm_compare_event_cb_t on_reach; // ISR callback function which would be invoked on timer counter reaches compare value
void *user_data; // user data which would be passed to the comparator callbacks
};
#if SOC_MCPWM_SUPPORT_EVENT_COMPARATOR
struct mcpwm_evt_cmpr_t {
mcpwm_cmpr_t base; // base class
mcpwm_cmpr_t base; // base class
};
#endif
struct mcpwm_gen_t {
int gen_id; // generator ID, index from 0
@@ -264,7 +260,7 @@ void mcpwm_release_group_handle(mcpwm_group_t *group);
esp_err_t mcpwm_check_intr_priority(mcpwm_group_t *group, int intr_priority);
int mcpwm_get_intr_priority_flag(mcpwm_group_t *group);
esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_src);
esp_err_t mcpwm_set_prescale(mcpwm_group_t *group, uint32_t expect_module_resolution_hz, uint32_t module_prescale_max, uint32_t* ret_module_prescale);
esp_err_t mcpwm_set_prescale(mcpwm_group_t *group, uint32_t expect_module_resolution_hz, uint32_t module_prescale_max, uint32_t *ret_module_prescale);
#ifdef __cplusplus
}