Преглед изворни кода

mcpwm: rename MCPWM_ISR_IN_IRAM to MCPWM_ISR_IRAM_SAFE

morris пре 3 година
родитељ
комит
a12936dca9

+ 18 - 19
components/driver/Kconfig

@@ -1,6 +1,6 @@
-menu "Driver configurations"
+menu "Driver Configurations"
 
-    menu "ADC configuration"
+    menu "ADC Configuration"
 
         config ADC_FORCE_XPD_FSM
             bool "Use the FSM to control ADC power"
@@ -21,20 +21,7 @@ menu "Driver configurations"
 
     endmenu  # ADC Configuration
 
-    menu "MCPWM configuration"
-        depends on SOC_MCPWM_SUPPORTED
-        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"
+    menu "SPI Configuration"
 
         config SPI_MASTER_IN_IRAM
             bool "Place transmitting functions of SPI master into IRAM"
@@ -84,7 +71,7 @@ menu "Driver configurations"
 
     endmenu # SPI Configuration
 
-    menu "TWAI configuration"
+    menu "TWAI Configuration"
         depends on SOC_TWAI_SUPPORTED
 
         config TWAI_ISR_IN_IRAM
@@ -166,7 +153,7 @@ menu "Driver configurations"
 
     endmenu # TEMP_SENSOR Configuration
 
-    menu "UART configuration"
+    menu "UART Configuration"
 
         config UART_ISR_IN_IRAM
             bool "Place UART ISR function into IRAM"
@@ -306,4 +293,16 @@ menu "Driver configurations"
                 Note that, this option only controls the RMT driver log, won't affect other drivers.
     endmenu # RMT Configuration
 
-endmenu  # Driver configurations
+    menu "MCPWM Configuration"
+        depends on SOC_MCPWM_SUPPORTED
+        config MCPWM_ISR_IRAM_SAFE
+            bool "Place MCPWM ISR function into IRAM"
+            default n
+            help
+                This will ensure the MCPWM interrupt handle is IRAM-Safe, allow to avoid flash
+                cache misses, and also be able to run whilst the cache is disabled.
+                (e.g. SPI Flash write)
+
+    endmenu # MCPWM Configuration
+
+endmenu  # Driver Configurations

+ 45 - 34
components/driver/mcpwm.c

@@ -19,6 +19,7 @@
 #include "hal/mcpwm_hal.h"
 #include "hal/gpio_hal.h"
 #include "hal/mcpwm_ll.h"
+#include "driver/gpio.h"
 #include "driver/mcpwm.h"
 #include "esp_private/periph_ctrl.h"
 
@@ -36,16 +37,17 @@ 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
+#ifdef CONFIG_MCPWM_ISR_IRAM_SAFE
 #define MCPWM_ISR_ATTR     IRAM_ATTR
-#define MCPWM_INTR_FLAG  (ESP_INTR_FLAG_IRAM)
+#define MCPWM_INTR_FLAG    ESP_INTR_FLAG_IRAM
 #else
 #define MCPWM_ISR_ATTR
 #define MCPWM_INTR_FLAG  0
 #endif
 
+#define MCPWM_GROUP_CLK_SRC_HZ 160000000
 #define MCPWM_GROUP_CLK_PRESCALE (16)
-#define MCPWM_GROUP_CLK_HZ (SOC_MCPWM_BASE_CLK_HZ / MCPWM_GROUP_CLK_PRESCALE)
+#define MCPWM_GROUP_CLK_HZ (MCPWM_GROUP_CLK_SRC_HZ / MCPWM_GROUP_CLK_PRESCALE)
 #define MCPWM_TIMER_CLK_HZ (MCPWM_GROUP_CLK_HZ / 10)
 
 _Static_assert(SOC_MCPWM_OPERATORS_PER_GROUP >= SOC_MCPWM_TIMERS_PER_GROUP, "This driver assumes the timer num equals to the operator num.");
@@ -87,26 +89,30 @@ typedef struct {
 } mcpwm_context_t;
 
 static mcpwm_context_t context[SOC_MCPWM_GROUPS] = {
-        [0] = {
-                .hal = {MCPWM_LL_GET_HW(0)},
-                .spinlock = portMUX_INITIALIZER_UNLOCKED,
-                .group_id = 0,
-                .group_pre_scale = SOC_MCPWM_BASE_CLK_HZ / MCPWM_GROUP_CLK_HZ,
-                .timer_pre_scale = {[0 ... SOC_MCPWM_TIMERS_PER_GROUP - 1] =
-                MCPWM_GROUP_CLK_HZ / MCPWM_TIMER_CLK_HZ},
-                .mcpwm_intr_handle = NULL,
-                .cap_isr_func = {[0 ... SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER - 1] = {NULL, NULL}},
+    [0] = {
+        .hal = {MCPWM_LL_GET_HW(0)},
+        .spinlock = portMUX_INITIALIZER_UNLOCKED,
+        .group_id = 0,
+        .group_pre_scale = MCPWM_GROUP_CLK_SRC_HZ / MCPWM_GROUP_CLK_HZ,
+        .timer_pre_scale = {
+            [0 ... SOC_MCPWM_TIMERS_PER_GROUP - 1] =
+            MCPWM_GROUP_CLK_HZ / MCPWM_TIMER_CLK_HZ
         },
-        [1] = {
-                .hal = {MCPWM_LL_GET_HW(1)},
-                .spinlock = portMUX_INITIALIZER_UNLOCKED,
-                .group_id = 1,
-                .group_pre_scale = SOC_MCPWM_BASE_CLK_HZ / MCPWM_GROUP_CLK_HZ,
-                .timer_pre_scale = {[0 ... SOC_MCPWM_TIMERS_PER_GROUP - 1] =
-                MCPWM_GROUP_CLK_HZ / MCPWM_TIMER_CLK_HZ},
-                .mcpwm_intr_handle = NULL,
-                .cap_isr_func = {[0 ... SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER - 1] = {NULL, NULL}},
-        }
+        .mcpwm_intr_handle = NULL,
+        .cap_isr_func = {[0 ... SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER - 1] = {NULL, NULL}},
+    },
+    [1] = {
+        .hal = {MCPWM_LL_GET_HW(1)},
+        .spinlock = portMUX_INITIALIZER_UNLOCKED,
+        .group_id = 1,
+        .group_pre_scale = MCPWM_GROUP_CLK_SRC_HZ / MCPWM_GROUP_CLK_HZ,
+        .timer_pre_scale = {
+            [0 ... SOC_MCPWM_TIMERS_PER_GROUP - 1] =
+            MCPWM_GROUP_CLK_HZ / MCPWM_TIMER_CLK_HZ
+        },
+        .mcpwm_intr_handle = NULL,
+        .cap_isr_func = {[0 ... SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER - 1] = {NULL, NULL}},
+    }
 };
 
 typedef void (*mcpwm_ll_gen_set_event_action_t)(mcpwm_dev_t *mcpwm, int op, int gen, int action);
@@ -121,11 +127,13 @@ static inline void mcpwm_critical_exit(mcpwm_unit_t mcpwm_num)
     portEXIT_CRITICAL(&context[mcpwm_num].spinlock);
 }
 
-static inline void mcpwm_mutex_lock(mcpwm_unit_t mcpwm_num){
+static inline void mcpwm_mutex_lock(mcpwm_unit_t mcpwm_num)
+{
     _lock_acquire(&context[mcpwm_num].mutex_lock);
 }
 
-static inline void mcpwm_mutex_unlock(mcpwm_unit_t mcpwm_num){
+static inline void mcpwm_mutex_unlock(mcpwm_unit_t mcpwm_num)
+{
     _lock_release(&context[mcpwm_num].mutex_lock);
 }
 
@@ -202,9 +210,10 @@ esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
     return ESP_OK;
 }
 
-esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, unsigned long int resolution) {
+esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, unsigned long int resolution)
+{
     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
-    int pre_scale_temp = SOC_MCPWM_BASE_CLK_HZ / resolution;
+    int pre_scale_temp = MCPWM_GROUP_CLK_SRC_HZ / resolution;
     ESP_RETURN_ON_FALSE(pre_scale_temp >= 1, ESP_ERR_INVALID_ARG, TAG, "invalid resolution");
     context[mcpwm_num].group_pre_scale = pre_scale_temp;
     mcpwm_critical_enter(mcpwm_num);
@@ -213,11 +222,12 @@ esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, unsigned long int r
     return ESP_OK;
 }
 
-esp_err_t mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, unsigned long int resolution) {
+esp_err_t mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, unsigned long int resolution)
+{
     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
 
     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
-    int pre_scale_temp = SOC_MCPWM_BASE_CLK_HZ / context[mcpwm_num].group_pre_scale / resolution;
+    int pre_scale_temp = MCPWM_GROUP_CLK_SRC_HZ / context[mcpwm_num].group_pre_scale / resolution;
     ESP_RETURN_ON_FALSE(pre_scale_temp >= 1, ESP_ERR_INVALID_ARG, TAG, "invalid resolution");
     context[mcpwm_num].timer_pre_scale[timer_num] = pre_scale_temp;
     mcpwm_critical_enter(mcpwm_num);
@@ -239,7 +249,7 @@ esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, u
     uint32_t previous_peak = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false);
     int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
     unsigned long int real_timer_clk_hz =
-            SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
+        MCPWM_GROUP_CLK_SRC_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
     uint32_t new_peak = real_timer_clk_hz / frequency;
     mcpwm_ll_timer_set_peak(hal->dev, timer_num, new_peak, false);
     // keep the duty cycle unchanged
@@ -286,7 +296,7 @@ esp_err_t mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num,
     mcpwm_critical_enter(mcpwm_num);
     int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
     unsigned long int real_timer_clk_hz =
-            SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
+        MCPWM_GROUP_CLK_SRC_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
     mcpwm_ll_operator_set_compare_value(hal->dev, op, cmp, duty_in_us * real_timer_clk_hz / 1000000);
     mcpwm_ll_operator_enable_update_compare_on_tez(hal->dev, op, cmp, true);
     mcpwm_critical_exit(mcpwm_num);
@@ -393,7 +403,7 @@ esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpw
     mcpwm_ll_timer_update_period_at_once(hal->dev, timer_num);
     int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
     unsigned long int real_timer_clk_hz =
-            SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
+        MCPWM_GROUP_CLK_SRC_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
     mcpwm_ll_timer_set_peak(hal->dev, timer_num, real_timer_clk_hz / mcpwm_conf->frequency, false);
     mcpwm_ll_operator_connect_timer(hal->dev, timer_num, timer_num); //the driver currently always use the timer x for operator x
     mcpwm_critical_exit(mcpwm_num);
@@ -414,7 +424,7 @@ uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
     mcpwm_critical_enter(mcpwm_num);
     int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
     unsigned long int real_timer_clk_hz =
-            SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
+        MCPWM_GROUP_CLK_SRC_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
     uint32_t peak = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false);
     uint32_t freq = real_timer_clk_hz / peak;
     mcpwm_critical_exit(mcpwm_num);
@@ -433,7 +443,8 @@ float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_gene
     return duty;
 }
 
-uint32_t mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen){
+uint32_t mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen)
+{
     //the driver currently always use the timer x for operator x
     const int op = timer_num;
     MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
@@ -441,7 +452,7 @@ uint32_t mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, m
     mcpwm_critical_enter(mcpwm_num);
     int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
     unsigned long int real_timer_clk_hz =
-            SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
+        MCPWM_GROUP_CLK_SRC_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
     uint32_t duty = mcpwm_ll_operator_get_compare_value(hal->dev, op, gen) * (1000000.0 / real_timer_clk_hz);
     mcpwm_critical_exit(mcpwm_num);
     return duty;

+ 1 - 0
components/driver/sdkconfig.rename

@@ -2,3 +2,4 @@
 # CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
 
 CONFIG_ADC2_DISABLE_DAC     CONFIG_ADC_DISABLE_DAC
+CONFIG_MCPWM_ISR_IN_IRAM    CONFIG_MCPWM_ISR_IRAM_SAFE

+ 2 - 2
components/driver/test/test_pwm.c

@@ -6,7 +6,6 @@
 #include <stdio.h>
 #include <unistd.h>
 #include "unity.h"
-#include "test_utils.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "soc/soc_caps.h"
@@ -27,7 +26,8 @@
 #define TEST_SYNC_GPIO_2 (19)
 #define TEST_CAP_GPIO (21)
 
-#define MCPWM_TEST_GROUP_CLK_HZ (SOC_MCPWM_BASE_CLK_HZ / 16)
+#define MCPWM_GROUP_CLK_SRC_HZ  160000000
+#define MCPWM_TEST_GROUP_CLK_HZ (MCPWM_GROUP_CLK_SRC_HZ / 16)
 #define MCPWM_TEST_TIMER_CLK_HZ (MCPWM_TEST_GROUP_CLK_HZ / 10)
 
 const static mcpwm_io_signals_t pwma[] = {MCPWM0A, MCPWM1A, MCPWM2A};