From e67bcda6d1d977171ce9232e0f6ac2e10f95f4dd Mon Sep 17 00:00:00 2001 From: SalimTerryLi Date: Wed, 25 Aug 2021 17:45:46 +0800 Subject: [PATCH] mcpwm: ISR can be placed to IRAM by menuconfig resolves https://github.com/espressif/esp-idf/issues/7449 --- components/driver/Kconfig | 14 ++++++++++++++ components/driver/mcpwm.c | 16 ++++++++++++---- components/hal/esp32/include/hal/mcpwm_ll.h | 4 ++++ components/hal/esp32s3/include/hal/mcpwm_ll.h | 4 ++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/components/driver/Kconfig b/components/driver/Kconfig index aedad08772..6ca95be2ca 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -21,6 +21,20 @@ menu "Driver configurations" endmenu # ADC Configuration + menu "MCPWM configuration" + + config MCPWM_ISR_IN_IRAM + bool "Place MCPWM ISR function into IRAM" + default n + help + If this option is not selected, the MCPWM interrupt will be deferred when the Cache + is in a disabled state (e.g. Flash write/erase operation). + + Note that if this option is selected, all user registered ISR callbacks should never + try to use cache as well. (with IRAM_ATTR) + + endmenu # MCPWM Configuration + menu "SPI configuration" config SPI_MASTER_IN_IRAM diff --git a/components/driver/mcpwm.c b/components/driver/mcpwm.c index be07fc9129..326680ab6b 100644 --- a/components/driver/mcpwm.c +++ b/components/driver/mcpwm.c @@ -36,6 +36,14 @@ static const char *TAG = "mcpwm"; #define MCPWM_DT_ERROR "MCPWM DEADTIME TYPE ERROR" #define MCPWM_CAP_EXIST_ERROR "MCPWM USER CAP INT SERVICE ALREADY EXISTS" +#ifdef CONFIG_MCPWM_ISR_IN_IRAM +#define MCPWM_ISR_ATTR IRAM_ATTR +#define MCPWM_INTR_FLAG (ESP_INTR_FLAG_IRAM) +#else +#define MCPWM_ISR_ATTR +#define MCPWM_INTR_FLAG 0 +#endif + #define MCPWM_GROUP_CLK_PRESCALE (16) #define MCPWM_GROUP_CLK_HZ (SOC_MCPWM_BASE_CLK_HZ / MCPWM_GROUP_CLK_PRESCALE) #define MCPWM_TIMER_CLK_HZ (MCPWM_GROUP_CLK_HZ / 10) @@ -729,7 +737,7 @@ esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t tim return ESP_OK; } -static void mcpwm_default_isr_handler(void *arg) { +static void MCPWM_ISR_ATTR mcpwm_default_isr_handler(void *arg) { mcpwm_context_t *curr_context = (mcpwm_context_t *) arg; uint32_t intr_status = mcpwm_ll_intr_get_capture_status(curr_context->hal.dev); mcpwm_ll_intr_clear_capture_status(curr_context->hal.dev, intr_status); @@ -826,7 +834,7 @@ esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_cha context[mcpwm_num].cap_isr_func[cap_channel].args = cap_conf->user_data; esp_err_t ret = ESP_OK; if (context[mcpwm_num].mcpwm_intr_handle == NULL) { - ret = esp_intr_alloc(mcpwm_periph_signals.groups[mcpwm_num].irq_id, 0, + ret = esp_intr_alloc(mcpwm_periph_signals.groups[mcpwm_num].irq_id, MCPWM_INTR_FLAG, mcpwm_default_isr_handler, (void *) (context + mcpwm_num), &(context[mcpwm_num].mcpwm_intr_handle)); } @@ -873,7 +881,7 @@ esp_err_t mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_ch return ret; } -uint32_t mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig) +uint32_t MCPWM_ISR_ATTR mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig) { ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); ESP_RETURN_ON_FALSE(cap_sig < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR); @@ -881,7 +889,7 @@ uint32_t mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_si return mcpwm_ll_capture_get_value(hal->dev, cap_sig); } -uint32_t mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig) +uint32_t MCPWM_ISR_ATTR mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig) { ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); ESP_RETURN_ON_FALSE(cap_sig < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR); diff --git a/components/hal/esp32/include/hal/mcpwm_ll.h b/components/hal/esp32/include/hal/mcpwm_ll.h index f2e3b34183..006fc44c0c 100644 --- a/components/hal/esp32/include/hal/mcpwm_ll.h +++ b/components/hal/esp32/include/hal/mcpwm_ll.h @@ -126,6 +126,7 @@ static inline uint32_t mcpwm_ll_intr_get_trip_ost_status(mcpwm_dev_t *mcpwm) return (mcpwm->int_st.val >> 24) & 0x07; } +__attribute__((always_inline)) static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) { return (mcpwm->int_st.val >> 27) & 0x07; @@ -173,6 +174,7 @@ static inline void mcpwm_ll_intr_clear_trip_ost_status(mcpwm_dev_t *mcpwm, uint3 mcpwm->int_clr.val = (ost_mask & 0x07) << 24; } +__attribute__((always_inline)) static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) { mcpwm->int_clr.val = (capture_mask & 0x07) << 27; @@ -977,11 +979,13 @@ static inline void mcpwm_ll_trigger_soft_capture(mcpwm_dev_t *mcpwm, int channel mcpwm->cap_cfg_ch[channel].sw = 1; // auto clear } +__attribute__((always_inline)) static inline uint32_t mcpwm_ll_capture_get_value(mcpwm_dev_t *mcpwm, int channel) { return mcpwm->cap_val_ch[channel]; } +__attribute__((always_inline)) static inline bool mcpwm_ll_capture_is_negedge(mcpwm_dev_t *mcpwm, int channel) { return mcpwm->cap_status.val & (1 << channel) ? true : false; diff --git a/components/hal/esp32s3/include/hal/mcpwm_ll.h b/components/hal/esp32s3/include/hal/mcpwm_ll.h index 93f44e2470..4ad6b3a2e3 100644 --- a/components/hal/esp32s3/include/hal/mcpwm_ll.h +++ b/components/hal/esp32s3/include/hal/mcpwm_ll.h @@ -131,6 +131,7 @@ static inline uint32_t mcpwm_ll_intr_get_trip_ost_status(mcpwm_dev_t *mcpwm) return (mcpwm->int_st.val >> 24) & 0x07; } +__attribute__((always_inline)) static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) { return (mcpwm->int_st.val >> 27) & 0x07; @@ -178,6 +179,7 @@ static inline void mcpwm_ll_intr_clear_trip_ost_status(mcpwm_dev_t *mcpwm, uint3 mcpwm->int_clr.val = (ost_mask & 0x07) << 24; } +__attribute__((always_inline)) static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) { mcpwm->int_clr.val = (capture_mask & 0x07) << 27; @@ -996,11 +998,13 @@ static inline void mcpwm_ll_trigger_soft_capture(mcpwm_dev_t *mcpwm, int channel mcpwm->cap_cfg_ch[channel].sw = 1; // auto clear } +__attribute__((always_inline)) static inline uint32_t mcpwm_ll_capture_get_value(mcpwm_dev_t *mcpwm, int channel) { return mcpwm->cap_val_ch[channel]; } +__attribute__((always_inline)) static inline bool mcpwm_ll_capture_is_negedge(mcpwm_dev_t *mcpwm, int channel) { return mcpwm->cap_status.val & (1 << channel) ? true : false;