1 /*
2  * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "sdkconfig.h"
8 #include "freertos/FreeRTOS.h"
9 #include "freertos/task.h"
10 #include "esp_log.h"
11 #include "esp_err.h"
12 #include "esp_check.h"
13 #include "esp_rom_gpio.h"
14 #include "esp_intr_alloc.h"
15 #include "soc/mcpwm_periph.h"
16 #include "hal/mcpwm_hal.h"
17 #include "hal/gpio_hal.h"
18 #include "hal/mcpwm_ll.h"
19 #include "driver/mcpwm_types_legacy.h"
20 #include "driver/gpio.h"
21 #include "esp_private/periph_ctrl.h"
22 #include "esp_clk_tree.h"
23 #include "esp_private/esp_clk.h"
24 
25 static const char *TAG = "mcpwm(legacy)";
26 
27 _Static_assert(MCPWM_UNIT_MAX == SOC_MCPWM_GROUPS, "MCPWM unit number not equal to chip capabilities");
28 
29 #define MCPWM_DRIVER_INIT_ERROR "MCPWM DRIVER NOT INITIALIZED"
30 #define MCPWM_GROUP_NUM_ERROR   "MCPWM GROUP NUM ERROR"
31 #define MCPWM_PRESCALE_ERROR    "MCPWM PRESCALE ERROR"
32 #define MCPWM_TIMER_ERROR       "MCPWM TIMER NUM ERROR"
33 #define MCPWM_CAPTURE_ERROR     "MCPWM CAPTURE NUM ERROR"
34 #define MCPWM_PARAM_ADDR_ERROR  "MCPWM PARAM ADDR ERROR"
35 #define MCPWM_DUTY_TYPE_ERROR   "MCPWM DUTY TYPE ERROR"
36 #define MCPWM_GPIO_ERROR        "MCPWM GPIO NUM ERROR"
37 #define MCPWM_GEN_ERROR         "MCPWM GENERATOR ERROR"
38 #define MCPWM_DT_ERROR          "MCPWM DEADTIME TYPE ERROR"
39 #define MCPWM_CAP_EXIST_ERROR   "MCPWM USER CAP INT SERVICE ALREADY EXISTS"
40 
41 #ifdef CONFIG_MCPWM_ISR_IRAM_SAFE
42 #define MCPWM_ISR_ATTR     IRAM_ATTR
43 #define MCPWM_INTR_FLAG    ESP_INTR_FLAG_IRAM
44 #else
45 #define MCPWM_ISR_ATTR
46 #define MCPWM_INTR_FLAG  0
47 #endif
48 
49 // Note: we can't modify the default MCPWM group resolution once it's determined
50 // otherwise we may break user's existing code which configures the dead-time based on this resolution, see `mcpwm_deadtime_enable`
51 #if CONFIG_IDF_TARGET_ESP32H2
52 #define MCPWM_DEFAULT_GROUP_CLK_RESOLUTION_HZ (12 * 1000 * 1000)
53 #else
54 #define MCPWM_DEFAULT_GROUP_CLK_RESOLUTION_HZ (10 * 1000 * 1000)
55 #endif
56 
57 // Preset MCPWM Timer clock resolution (1MHz)
58 #define MCPWM_DEFAULT_TIMER_CLK_RESOLUTION_HZ (1 * 1000 * 1000)
59 
60 ESP_STATIC_ASSERT(SOC_MCPWM_OPERATORS_PER_GROUP >= SOC_MCPWM_TIMERS_PER_GROUP, "This driver assumes the timer num equals to the operator num.");
61 ESP_STATIC_ASSERT(SOC_MCPWM_COMPARATORS_PER_OPERATOR >= SOC_MCPWM_GENERATORS_PER_OPERATOR, "This driver assumes the generator num equals to the generator num.");
62 ESP_STATIC_ASSERT(SOC_MCPWM_GENERATORS_PER_OPERATOR == 2, "This driver assumes the generator num equals to 2.");
63 
64 #define MCPWM_TIMER_ID_CHECK(mcpwm_num, timer_num)                                                                  \
65     do {                                                                                                            \
66         ESP_RETURN_ON_FALSE((mcpwm_num) < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);       \
67         ESP_RETURN_ON_FALSE((timer_num) < SOC_MCPWM_TIMERS_PER_GROUP, ESP_ERR_INVALID_ARG, TAG, MCPWM_TIMER_ERROR); \
68     } while (0)
69 
70 #define MCPWM_TIMER_CHECK(mcpwm_num, timer_num)                                                               \
71     do {                                                                                                      \
72         MCPWM_TIMER_ID_CHECK(mcpwm_num, timer_num);                                                           \
73         ESP_RETURN_ON_FALSE(context[mcpwm_num].hal.dev, ESP_ERR_INVALID_STATE, TAG, MCPWM_DRIVER_INIT_ERROR); \
74     } while (0)
75 
76 #define MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen)                                             \
77     do {                                                                                       \
78         MCPWM_TIMER_CHECK(mcpwm_num, timer_num);                                               \
79         ESP_RETURN_ON_FALSE((gen) < MCPWM_GEN_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_GEN_ERROR); \
80     } while (0)
81 
82 typedef struct {
83     cap_isr_cb_t fn;   // isr function
84     void *args;      // isr function args
85 } cap_isr_func_t;
86 
87 typedef struct {
88     mcpwm_hal_context_t hal;
89     portMUX_TYPE spinlock;
90     _lock_t mutex_lock;
91     const int group_id;
92     int group_resolution_hz;
93     int timer_resolution_hz[SOC_MCPWM_TIMERS_PER_GROUP];
94     intr_handle_t mcpwm_intr_handle;  // handler for ISR register, one per MCPWM group
95     cap_isr_func_t cap_isr_func[SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER]; // handler for ISR callback, one for each cap ch
96 } mcpwm_context_t;
97 
98 static mcpwm_context_t context[SOC_MCPWM_GROUPS] = {
99     [0] = {
100         .hal = {MCPWM_LL_GET_HW(0)},
101         .spinlock = portMUX_INITIALIZER_UNLOCKED,
102         .group_id = 0,
103     },
104 #if SOC_MCPWM_GROUPS > 1
105     [1] = {
106         .hal = {MCPWM_LL_GET_HW(1)},
107         .spinlock = portMUX_INITIALIZER_UNLOCKED,
108         .group_id = 1,
109     },
110 #endif
111 };
112 
113 typedef void (*mcpwm_ll_gen_set_event_action_t)(mcpwm_dev_t *mcpwm, int op, int gen, int action);
114 
mcpwm_critical_enter(mcpwm_unit_t mcpwm_num)115 static inline void mcpwm_critical_enter(mcpwm_unit_t mcpwm_num)
116 {
117     portENTER_CRITICAL(&context[mcpwm_num].spinlock);
118 }
119 
mcpwm_critical_exit(mcpwm_unit_t mcpwm_num)120 static inline void mcpwm_critical_exit(mcpwm_unit_t mcpwm_num)
121 {
122     portEXIT_CRITICAL(&context[mcpwm_num].spinlock);
123 }
124 
mcpwm_mutex_lock(mcpwm_unit_t mcpwm_num)125 static inline void mcpwm_mutex_lock(mcpwm_unit_t mcpwm_num)
126 {
127     _lock_acquire(&context[mcpwm_num].mutex_lock);
128 }
129 
mcpwm_mutex_unlock(mcpwm_unit_t mcpwm_num)130 static inline void mcpwm_mutex_unlock(mcpwm_unit_t mcpwm_num)
131 {
132     _lock_release(&context[mcpwm_num].mutex_lock);
133 }
134 
mcpwm_gpio_init(mcpwm_unit_t mcpwm_num,mcpwm_io_signals_t io_signal,int gpio_num)135 esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal, int gpio_num)
136 {
137     if (gpio_num < 0) { // ignore on minus gpio number
138         return ESP_OK;
139     }
140 
141     ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
142     ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, MCPWM_GPIO_ERROR);
143 
144     if (io_signal <= MCPWM2B) { // Generator output signal
145         ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, MCPWM_GPIO_ERROR);
146         gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
147         int operator_id = io_signal / 2;
148         int generator_id = io_signal % 2;
149         esp_rom_gpio_connect_out_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].operators[operator_id].generators[generator_id].pwm_sig, 0, 0);
150     } else if (io_signal <= MCPWM_SYNC_2) { // External sync input signal
151         gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
152         int gpio_sync_id = io_signal - MCPWM_SYNC_0;
153         esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].gpio_synchros[gpio_sync_id].sync_sig, 0);
154     } else if (io_signal <= MCPWM_FAULT_2) { // Fault input signal
155         gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
156         int fault_id = io_signal - MCPWM_FAULT_0;
157         esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].gpio_faults[fault_id].fault_sig, 0);
158     } else if (io_signal >= MCPWM_CAP_0 && io_signal <= MCPWM_CAP_2) { // Capture input signal
159         gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
160         int capture_id = io_signal - MCPWM_CAP_0;
161         esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].captures[capture_id].cap_sig, 0);
162     }
163     gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
164     return ESP_OK;
165 }
166 
mcpwm_set_pin(mcpwm_unit_t mcpwm_num,const mcpwm_pin_config_t * mcpwm_pin)167 esp_err_t mcpwm_set_pin(mcpwm_unit_t mcpwm_num, const mcpwm_pin_config_t *mcpwm_pin)
168 {
169     ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
170     mcpwm_gpio_init(mcpwm_num, MCPWM0A, mcpwm_pin->mcpwm0a_out_num);    //MCPWM0A
171     mcpwm_gpio_init(mcpwm_num, MCPWM0B, mcpwm_pin->mcpwm0b_out_num);    //MCPWM0B
172     mcpwm_gpio_init(mcpwm_num, MCPWM1A, mcpwm_pin->mcpwm1a_out_num);    //MCPWM1A
173     mcpwm_gpio_init(mcpwm_num, MCPWM1B, mcpwm_pin->mcpwm1b_out_num);    //MCPWM1B
174     mcpwm_gpio_init(mcpwm_num, MCPWM2A, mcpwm_pin->mcpwm2a_out_num);    //MCPWM2A
175     mcpwm_gpio_init(mcpwm_num, MCPWM2B, mcpwm_pin->mcpwm2b_out_num);    //MCPWM2B
176     mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_0,  mcpwm_pin->mcpwm_sync0_in_num);   //SYNC0
177     mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_1,  mcpwm_pin->mcpwm_sync1_in_num);   //SYNC1
178     mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_2,  mcpwm_pin->mcpwm_sync2_in_num);   //SYNC2
179     mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_0, mcpwm_pin->mcpwm_fault0_in_num);  //FAULT0
180     mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_1, mcpwm_pin->mcpwm_fault1_in_num);  //FAULT1
181     mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_2, mcpwm_pin->mcpwm_fault2_in_num);  //FAULT2
182     mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_0,   mcpwm_pin->mcpwm_cap0_in_num);    //CAP0
183     mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_1,   mcpwm_pin->mcpwm_cap1_in_num);    //CAP1
184     mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_2,   mcpwm_pin->mcpwm_cap2_in_num);    //CAP2
185     return ESP_OK;
186 }
187 
mcpwm_start(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)188 esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
189 {
190     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
191 
192     mcpwm_critical_enter(mcpwm_num);
193     mcpwm_ll_timer_set_start_stop_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_START_NO_STOP);
194     mcpwm_critical_exit(mcpwm_num);
195     return ESP_OK;
196 }
197 
mcpwm_stop(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)198 esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
199 {
200     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
201 
202     mcpwm_critical_enter(mcpwm_num);
203     mcpwm_ll_timer_set_start_stop_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_STOP_EMPTY);
204     mcpwm_critical_exit(mcpwm_num);
205     return ESP_OK;
206 }
207 
mcpwm_group_get_resolution(mcpwm_unit_t mcpwm_num)208 static inline uint32_t mcpwm_group_get_resolution(mcpwm_unit_t mcpwm_num)
209 {
210     if (context[mcpwm_num].group_resolution_hz == 0) {
211         context[mcpwm_num].group_resolution_hz = MCPWM_DEFAULT_GROUP_CLK_RESOLUTION_HZ;
212     }
213     return context[mcpwm_num].group_resolution_hz;
214 }
215 
mcpwm_timer_get_resolution(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)216 static inline uint32_t mcpwm_timer_get_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
217 {
218     if (context[mcpwm_num].timer_resolution_hz[timer_num] == 0) {
219         context[mcpwm_num].timer_resolution_hz[timer_num] = MCPWM_DEFAULT_TIMER_CLK_RESOLUTION_HZ;
220     }
221     return context[mcpwm_num].timer_resolution_hz[timer_num];
222 }
223 
mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num,uint32_t resolution)224 esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, uint32_t resolution)
225 {
226     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
227     uint32_t clk_src_hz = 0;
228     esp_clk_tree_src_get_freq_hz(MCPWM_TIMER_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz);
229 
230     int pre_scale_temp = clk_src_hz / resolution;
231     ESP_RETURN_ON_FALSE(pre_scale_temp >= 1, ESP_ERR_INVALID_ARG, TAG, "invalid resolution");
232     context[mcpwm_num].group_resolution_hz = clk_src_hz / pre_scale_temp;
233 
234     mcpwm_critical_enter(mcpwm_num);
235     mcpwm_ll_group_set_clock_prescale(hal->dev, pre_scale_temp);
236     mcpwm_critical_exit(mcpwm_num);
237     return ESP_OK;
238 }
239 
mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint32_t resolution)240 esp_err_t mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t resolution)
241 {
242     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
243 
244     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
245     uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num);
246 
247     int pre_scale_temp = group_resolution / resolution;
248     ESP_RETURN_ON_FALSE(pre_scale_temp >= 1, ESP_ERR_INVALID_ARG, TAG, "invalid resolution");
249     context[mcpwm_num].timer_resolution_hz[timer_num] = context[mcpwm_num].group_resolution_hz / pre_scale_temp;
250 
251     mcpwm_critical_enter(mcpwm_num);
252     mcpwm_ll_timer_set_clock_prescale(hal->dev, timer_num, pre_scale_temp);
253     mcpwm_critical_exit(mcpwm_num);
254     return ESP_OK;
255 }
256 
mcpwm_set_frequency(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint32_t frequency)257 esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t frequency)
258 {
259     //the driver currently always use the timer x for operator x
260     const int op = timer_num;
261     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
262     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
263 
264     mcpwm_critical_enter(mcpwm_num);
265 
266     mcpwm_ll_timer_update_period_at_once(hal->dev, timer_num);
267     uint32_t previous_peak = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false);
268     uint32_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num);
269     uint32_t new_peak = timer_resolution / frequency;
270     mcpwm_ll_timer_set_peak(hal->dev, timer_num, new_peak, false);
271     // keep the duty cycle unchanged
272     float scale = ((float)new_peak) / previous_peak;
273     // the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
274     uint32_t previous_cmp_a = mcpwm_ll_operator_get_compare_value(hal->dev, op, 0);
275     uint32_t previous_cmp_b = mcpwm_ll_operator_get_compare_value(hal->dev, op, 1);
276     // update compare value immediately
277     mcpwm_ll_operator_update_compare_at_once(hal->dev, op, 0);
278     mcpwm_ll_operator_update_compare_at_once(hal->dev, op, 1);
279     mcpwm_ll_operator_set_compare_value(hal->dev, op, 0, (uint32_t)(previous_cmp_a * scale));
280     mcpwm_ll_operator_set_compare_value(hal->dev, op, 1, (uint32_t)(previous_cmp_b * scale));
281 
282     mcpwm_critical_exit(mcpwm_num);
283     return ESP_OK;
284 }
285 
mcpwm_set_duty(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen,float duty)286 esp_err_t mcpwm_set_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, float duty)
287 {
288     //the driver currently always use the timer x for operator x
289     const int op = timer_num;
290     //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
291     const int cmp = gen;
292     MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
293     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
294 
295     mcpwm_critical_enter(mcpwm_num);
296     uint32_t set_duty = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * duty / 100;
297     mcpwm_ll_operator_set_compare_value(hal->dev, op, cmp, set_duty);
298     mcpwm_ll_operator_enable_update_compare_on_tez(hal->dev, op, cmp, true);
299     mcpwm_ll_operator_enable_update_compare_on_tep(hal->dev, op, cmp, true);
300     mcpwm_critical_exit(mcpwm_num);
301     return ESP_OK;
302 }
303 
mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen,uint32_t duty_in_us)304 esp_err_t mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, uint32_t duty_in_us)
305 {
306     //the driver currently always use the timer x for operator x
307     const int op = timer_num;
308     //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
309     const int cmp = gen;
310     MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
311     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
312 
313     mcpwm_critical_enter(mcpwm_num);
314     // to avid multiplication overflow, use uint64_t here
315     uint64_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num);
316     uint64_t compare_val = timer_resolution * duty_in_us / 1000000;
317     mcpwm_ll_operator_set_compare_value(hal->dev, op, cmp, (uint32_t)compare_val);
318     mcpwm_ll_operator_enable_update_compare_on_tez(hal->dev, op, cmp, true);
319     mcpwm_ll_operator_enable_update_compare_on_tep(hal->dev, op, cmp, true);
320     mcpwm_critical_exit(mcpwm_num);
321     return ESP_OK;
322 }
323 
mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen,mcpwm_duty_type_t duty_type)324 esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen,
325                               mcpwm_duty_type_t duty_type)
326 {
327     //the driver currently always use the timer x for operator x
328     const int op = timer_num;
329     MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
330     ESP_RETURN_ON_FALSE(duty_type < MCPWM_DUTY_MODE_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_DUTY_TYPE_ERROR);
331     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
332 
333     //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
334     mcpwm_critical_enter(mcpwm_num);
335     switch (mcpwm_ll_timer_get_count_mode(hal->dev, timer_num)) {
336     case MCPWM_TIMER_COUNT_MODE_UP:
337         if (duty_type == MCPWM_DUTY_MODE_0) {
338             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH);
339             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_GEN_ACTION_KEEP);
340             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW);
341         } else if (duty_type == MCPWM_DUTY_MODE_1) {
342             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_LOW);
343             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_NO_CHANGE);
344             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH);
345         } else if (duty_type == MCPWM_DUTY_MODE_FORCE_LOW) {
346             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW);
347             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW);
348             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW);
349         } else if (duty_type == MCPWM_DUTY_MODE_FORCE_HIGH) {
350             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH);
351             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH);
352             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH);
353         }
354         break;
355     case MCPWM_TIMER_COUNT_MODE_DOWN:
356         if (duty_type == MCPWM_DUTY_MODE_0) {
357             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW);
358             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_NO_CHANGE);
359             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH);
360         } else if (duty_type == MCPWM_DUTY_MODE_1) {
361             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH);
362             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_NO_CHANGE);
363             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW);
364         } else if (duty_type == MCPWM_DUTY_MODE_FORCE_LOW) {
365             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW);
366             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW);
367             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW);
368         } else if (duty_type == MCPWM_DUTY_MODE_FORCE_HIGH) {
369             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH);
370             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH);
371             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH);
372         }
373         break;
374     case MCPWM_TIMER_COUNT_MODE_UP_DOWN:
375         if (duty_type == MCPWM_DUTY_MODE_0) {
376             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH);
377             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW);
378             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH);
379         } else if (duty_type == MCPWM_DUTY_MODE_1) {
380             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW);
381             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH);
382             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW);
383         } else if (duty_type == MCPWM_DUTY_MODE_FORCE_LOW) {
384             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW);
385             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW);
386             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW);
387             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW);
388             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW);
389             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW);
390         } else if (duty_type == MCPWM_DUTY_MODE_FORCE_HIGH) {
391             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH);
392             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH);
393             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH);
394             mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH);
395             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH);
396             mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH);
397         }
398         break;
399     default:
400         break;
401     }
402     mcpwm_critical_exit(mcpwm_num);
403     return ESP_OK;
404 }
405 
mcpwm_init(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,const mcpwm_config_t * mcpwm_conf)406 esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_config_t *mcpwm_conf)
407 {
408     const int op = timer_num;
409     MCPWM_TIMER_ID_CHECK(mcpwm_num, op);
410     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
411     periph_module_enable(mcpwm_periph_signals.groups[mcpwm_num].module);
412     mcpwm_hal_init_config_t config = {
413         .group_id = mcpwm_num
414     };
415     mcpwm_hal_init(hal, &config);
416 
417     uint32_t clk_src_hz = 0;
418     esp_clk_tree_src_get_freq_hz(MCPWM_TIMER_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz);
419     uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num);
420     uint32_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num);
421     uint32_t group_pre_scale = clk_src_hz / group_resolution;
422     uint32_t timer_pre_scale = group_resolution / timer_resolution;
423 
424     mcpwm_critical_enter(mcpwm_num);
425     mcpwm_ll_group_enable_clock(hal->dev, true);
426     mcpwm_ll_group_set_clock_source(hal->dev, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT);
427     mcpwm_ll_group_set_clock_prescale(hal->dev, group_pre_scale);
428     mcpwm_ll_timer_set_clock_prescale(hal->dev, timer_num, timer_pre_scale);
429     mcpwm_ll_timer_set_count_mode(hal->dev, timer_num, mcpwm_conf->counter_mode);
430     mcpwm_ll_timer_update_period_at_once(hal->dev, timer_num);
431     mcpwm_ll_timer_set_peak(hal->dev, timer_num, timer_resolution / mcpwm_conf->frequency, false);
432     mcpwm_ll_operator_connect_timer(hal->dev, timer_num, timer_num); //the driver currently always use the timer x for operator x
433     mcpwm_critical_exit(mcpwm_num);
434 
435     mcpwm_set_duty(mcpwm_num, timer_num, 0, mcpwm_conf->cmpr_a);
436     mcpwm_set_duty(mcpwm_num, timer_num, 1, mcpwm_conf->cmpr_b);
437     mcpwm_set_duty_type(mcpwm_num, timer_num, 0, mcpwm_conf->duty_mode);
438     mcpwm_set_duty_type(mcpwm_num, timer_num, 1, mcpwm_conf->duty_mode);
439     mcpwm_start(mcpwm_num, timer_num);
440 
441     return ESP_OK;
442 }
443 
mcpwm_get_frequency(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)444 uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
445 {
446     if (mcpwm_num >= MCPWM_UNIT_MAX || timer_num >= MCPWM_TIMER_MAX) {
447         ESP_LOGE(TAG, "Invalid MCPWM timer instance");
448         return 0;
449     }
450 
451     uint32_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num);
452 
453     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
454     mcpwm_critical_enter(mcpwm_num);
455     uint32_t peak = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false);
456     uint32_t freq = timer_resolution / peak;
457     mcpwm_critical_exit(mcpwm_num);
458     return freq;
459 }
460 
mcpwm_get_duty(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen)461 float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
462 {
463     if (mcpwm_num >= MCPWM_UNIT_MAX || timer_num >= MCPWM_TIMER_MAX || gen >= MCPWM_GEN_MAX) {
464         ESP_LOGE(TAG, "Invalid MCPWM generator instance");
465         return 0;
466     }
467     //the driver currently always use the timer x for operator x
468     const int op = timer_num;
469     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
470     mcpwm_critical_enter(mcpwm_num);
471     float duty = 100.0 * mcpwm_ll_operator_get_compare_value(hal->dev, op, gen) / mcpwm_ll_timer_get_peak(hal->dev, timer_num, false);
472     mcpwm_critical_exit(mcpwm_num);
473     return duty;
474 }
475 
mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_operator_t gen)476 uint32_t mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen)
477 {
478     if (mcpwm_num >= MCPWM_UNIT_MAX || timer_num >= MCPWM_TIMER_MAX || gen >= MCPWM_GEN_MAX) {
479         ESP_LOGE(TAG, "Invalid MCPWM generator instance");
480         return 0;
481     }
482 
483     uint32_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num);
484 
485     //the driver currently always use the timer x for operator x
486     const int op = timer_num;
487     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
488     mcpwm_critical_enter(mcpwm_num);
489     uint32_t duty = mcpwm_ll_operator_get_compare_value(hal->dev, op, gen) * (1000000.0 / timer_resolution);
490     mcpwm_critical_exit(mcpwm_num);
491     return duty;
492 }
493 
mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen)494 esp_err_t mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
495 {
496     //the driver currently always use the timer x for operator x
497     return mcpwm_set_duty_type(mcpwm_num, timer_num, gen, MCPWM_DUTY_MODE_FORCE_HIGH);
498 }
499 
mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen)500 esp_err_t mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
501 {
502     //the driver currently always use the timer x for operator x
503     return mcpwm_set_duty_type(mcpwm_num, timer_num, gen, MCPWM_DUTY_MODE_FORCE_LOW);
504 }
505 
mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)506 esp_err_t mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
507 {
508     //the driver currently always use the timer x for operator x
509     const int op = timer_num;
510     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
511 
512     mcpwm_critical_enter(mcpwm_num);
513     mcpwm_ll_carrier_enable(context[mcpwm_num].hal.dev, op, true);
514     mcpwm_critical_exit(mcpwm_num);
515     return ESP_OK;
516 }
517 
mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)518 esp_err_t mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
519 {
520     //the driver currently always use the timer x for operator x
521     const int op = timer_num;
522     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
523 
524     mcpwm_critical_enter(mcpwm_num);
525     mcpwm_ll_carrier_enable(context[mcpwm_num].hal.dev, op, false);
526     mcpwm_critical_exit(mcpwm_num);
527     return ESP_OK;
528 }
529 
mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint8_t carrier_period)530 esp_err_t mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_period)
531 {
532     //the driver currently always use the timer x for operator x
533     const int op = timer_num;
534     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
535 
536     mcpwm_critical_enter(mcpwm_num);
537     mcpwm_ll_carrier_set_prescale(context[mcpwm_num].hal.dev, op, carrier_period + 1);
538     mcpwm_critical_exit(mcpwm_num);
539     return ESP_OK;
540 }
541 
mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint8_t carrier_duty)542 esp_err_t mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_duty)
543 {
544     //the driver currently always use the timer x for operator x
545     const int op = timer_num;
546     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
547 
548     mcpwm_critical_enter(mcpwm_num);
549     mcpwm_ll_carrier_set_duty(context[mcpwm_num].hal.dev, op, carrier_duty);
550     mcpwm_critical_exit(mcpwm_num);
551     return ESP_OK;
552 }
553 
mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint8_t pulse_width)554 esp_err_t mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t pulse_width)
555 {
556     //the driver currently always use the timer x for operator x
557     const int op = timer_num;
558     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
559 
560     mcpwm_critical_enter(mcpwm_num);
561     mcpwm_ll_carrier_set_first_pulse_width(context[mcpwm_num].hal.dev, op, pulse_width + 1);
562     mcpwm_critical_exit(mcpwm_num);
563     return ESP_OK;
564 }
565 
mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_carrier_out_ivt_t carrier_ivt_mode)566 esp_err_t mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num,
567                                       mcpwm_carrier_out_ivt_t carrier_ivt_mode)
568 {
569     //the driver currently always use the timer x for operator x
570     const int op = timer_num;
571     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
572 
573     mcpwm_critical_enter(mcpwm_num);
574     mcpwm_ll_carrier_out_invert(context[mcpwm_num].hal.dev, op, carrier_ivt_mode);
575     mcpwm_critical_exit(mcpwm_num);
576     return ESP_OK;
577 }
578 
mcpwm_carrier_init(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,const mcpwm_carrier_config_t * carrier_conf)579 esp_err_t mcpwm_carrier_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_carrier_config_t *carrier_conf)
580 {
581     //the driver currently always use the timer x for operator x
582     const int op = timer_num;
583     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
584     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
585 
586     mcpwm_carrier_enable(mcpwm_num, timer_num);
587     mcpwm_carrier_set_period(mcpwm_num, timer_num, carrier_conf->carrier_period);
588     mcpwm_carrier_set_duty_cycle(mcpwm_num, timer_num, carrier_conf->carrier_duty);
589     mcpwm_carrier_oneshot_mode_enable(mcpwm_num, timer_num, carrier_conf->pulse_width_in_os);
590     mcpwm_carrier_output_invert(mcpwm_num, timer_num, carrier_conf->carrier_ivt_mode);
591 
592     mcpwm_critical_enter(mcpwm_num);
593     mcpwm_ll_carrier_in_invert(hal->dev, op, false);
594     mcpwm_critical_exit(mcpwm_num);
595 
596     return ESP_OK;
597 }
598 
mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_deadtime_type_t dt_mode,uint32_t red,uint32_t fed)599 esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_deadtime_type_t dt_mode,
600                                 uint32_t red, uint32_t fed)
601 {
602     //the driver currently always use the timer x for operator x
603     const int op = timer_num;
604     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
605     ESP_RETURN_ON_FALSE(dt_mode < MCPWM_DEADTIME_TYPE_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_DT_ERROR);
606     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
607 
608     mcpwm_critical_enter(mcpwm_num);
609     mcpwm_ll_deadtime_enable_update_delay_on_tez(hal->dev, op, true);
610     // The dead time delay unit equals to MCPWM group resolution
611     mcpwm_ll_operator_set_deadtime_clock_src(hal->dev, op, MCPWM_LL_DEADTIME_CLK_SRC_GROUP);
612     mcpwm_ll_deadtime_set_rising_delay(hal->dev, op, red + 1);
613     mcpwm_ll_deadtime_set_falling_delay(hal->dev, op, fed + 1);
614     switch (dt_mode) {
615     case MCPWM_BYPASS_RED:
616         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false);    // S0=0
617         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, true);     // S1=1
618         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0
619         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
620         mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0);  // S4=0
621         mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0);  // S5=0
622         break;
623     case MCPWM_BYPASS_FED:
624         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, true);     // S0=1
625         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false);    // S1=0
626         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0
627         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
628         mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0);  // S4=0
629         mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0);  // S5=0
630         break;
631     case MCPWM_ACTIVE_HIGH_MODE:
632         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false);    // S0=0
633         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false);    // S1=0
634         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0
635         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
636         mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0);  // S4=0
637         mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0);  // S5=0
638         break;
639     case MCPWM_ACTIVE_LOW_MODE:
640         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false);   // S0=0
641         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false);   // S1=0
642         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, true); // S2=1
643         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, true); // S3=1
644         mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0
645         mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0
646         break;
647     case MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE:
648         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false);    // S0=0
649         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false);    // S1=0
650         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0
651         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, true);  // S3=1
652         mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0);  // S4=0
653         mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0);  // S5=0
654         break;
655     case MCPWM_ACTIVE_LOW_COMPLIMENT_MODE:
656         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false);    // S0=0
657         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false);    // S1=0
658         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, true);  // S2=1
659         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
660         mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0);  // S4=0
661         mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0);  // S5=0
662         break;
663     case MCPWM_ACTIVE_RED_FED_FROM_PWMXA:
664         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false);    // S0=0
665         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
666         mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0);  // S4=0
667         mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, true);   // S6=1
668         mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false);  // S7=0
669         mcpwm_ll_deadtime_enable_deb(hal->dev, op, true);         // S8=1
670         break;
671     case MCPWM_ACTIVE_RED_FED_FROM_PWMXB:
672         mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false);    // S0=0
673         mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
674         mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 1);  // S4=1
675         mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, true);   // S6=1
676         mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false);  // S7=0
677         mcpwm_ll_deadtime_enable_deb(hal->dev, op, true);         // S8=1
678         break;
679     default :
680         break;
681     }
682     mcpwm_critical_exit(mcpwm_num);
683     return ESP_OK;
684 }
685 
mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)686 esp_err_t mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
687 {
688     //the driver currently always use the timer x for operator x
689     const int op = timer_num;
690     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
691     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
692 
693     mcpwm_critical_enter(mcpwm_num);
694     mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, true);     // S0
695     mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, true);     // S1
696     mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2
697     mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3
698     mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0);  // S4
699     mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0);  // S5
700     mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, false);  // S6
701     mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false);  // S7
702     mcpwm_ll_deadtime_enable_deb(hal->dev, op, false);        // S8
703     mcpwm_critical_exit(mcpwm_num);
704     return ESP_OK;
705 }
706 
mcpwm_fault_init(mcpwm_unit_t mcpwm_num,mcpwm_fault_input_level_t intput_level,mcpwm_fault_signal_t fault_sig)707 esp_err_t mcpwm_fault_init(mcpwm_unit_t mcpwm_num, mcpwm_fault_input_level_t intput_level, mcpwm_fault_signal_t fault_sig)
708 {
709     ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
710     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
711 
712     mcpwm_critical_enter(mcpwm_num);
713     mcpwm_ll_fault_enable_detection(hal->dev, fault_sig, true);
714     mcpwm_ll_fault_set_active_level(hal->dev, fault_sig, intput_level);
715     mcpwm_critical_exit(mcpwm_num);
716     return ESP_OK;
717 }
718 
mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num,mcpwm_fault_signal_t fault_sig)719 esp_err_t mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num, mcpwm_fault_signal_t fault_sig)
720 {
721     ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
722     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
723 
724     mcpwm_critical_enter(mcpwm_num);
725     mcpwm_ll_fault_enable_detection(hal->dev, fault_sig, false);
726     for (int i = 0; i < SOC_MCPWM_OPERATORS_PER_GROUP; i++) {
727         mcpwm_ll_brake_clear_ost(hal->dev, i); // make sure operator has exit the ost fault state totally
728     }
729     mcpwm_critical_exit(mcpwm_num);
730     return ESP_OK;
731 }
732 
mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_fault_signal_t fault_sig,mcpwm_output_action_t action_on_pwmxa,mcpwm_output_action_t action_on_pwmxb)733 esp_err_t mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
734                                    mcpwm_output_action_t action_on_pwmxa, mcpwm_output_action_t action_on_pwmxb)
735 {
736     //the driver currently always use the timer x for operator x
737     const int op = timer_num;
738     MCPWM_TIMER_CHECK(mcpwm_num, op);
739     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
740 
741     mcpwm_critical_enter(mcpwm_num);
742     mcpwm_ll_brake_enable_cbc_mode(hal->dev, op, fault_sig, true);
743     mcpwm_ll_brake_enable_cbc_refresh_on_tez(hal->dev, op, true);
744     mcpwm_ll_brake_enable_oneshot_mode(hal->dev, op, fault_sig, false);
745     mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_OPER_BRAKE_MODE_CBC, action_on_pwmxa);
746     mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_OPER_BRAKE_MODE_CBC, action_on_pwmxa);
747     mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_OPER_BRAKE_MODE_CBC, action_on_pwmxb);
748     mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_OPER_BRAKE_MODE_CBC, action_on_pwmxb);
749     mcpwm_critical_exit(mcpwm_num);
750     return ESP_OK;
751 }
752 
mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_fault_signal_t fault_sig,mcpwm_action_on_pwmxa_t action_on_pwmxa,mcpwm_action_on_pwmxb_t action_on_pwmxb)753 esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
754                                        mcpwm_action_on_pwmxa_t action_on_pwmxa, mcpwm_action_on_pwmxb_t action_on_pwmxb)
755 {
756     //the driver currently always use the timer x for operator x
757     const int op = timer_num;
758     MCPWM_TIMER_CHECK(mcpwm_num, op);
759     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
760 
761     mcpwm_critical_enter(mcpwm_num);
762     mcpwm_ll_brake_clear_ost(hal->dev, op);
763     mcpwm_ll_brake_enable_oneshot_mode(hal->dev, op, fault_sig, true);
764     mcpwm_ll_brake_enable_cbc_mode(hal->dev, op, fault_sig, false);
765     mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_OPER_BRAKE_MODE_OST, action_on_pwmxa);
766     mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_OPER_BRAKE_MODE_OST, action_on_pwmxa);
767     mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_OPER_BRAKE_MODE_OST, action_on_pwmxb);
768     mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_OPER_BRAKE_MODE_OST, action_on_pwmxb);
769     mcpwm_critical_exit(mcpwm_num);
770     return ESP_OK;
771 }
772 
mcpwm_default_isr_handler(void * arg)773 static void MCPWM_ISR_ATTR mcpwm_default_isr_handler(void *arg)
774 {
775     mcpwm_context_t *curr_context = (mcpwm_context_t *) arg;
776     uint32_t intr_status = mcpwm_ll_intr_get_capture_status(curr_context->hal.dev);
777     mcpwm_ll_intr_clear_capture_status(curr_context->hal.dev, intr_status);
778     bool need_yield = false;
779     for (int i = 0; i < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; ++i) {
780         if ((intr_status >> i) & 0x1) {
781             if (curr_context->cap_isr_func[i].fn != NULL) {
782                 cap_event_data_t edata;
783                 edata.cap_edge = mcpwm_ll_capture_get_edge(curr_context->hal.dev, i) == MCPWM_CAP_EDGE_NEG ? MCPWM_NEG_EDGE
784                                  : MCPWM_POS_EDGE;
785                 edata.cap_value = mcpwm_ll_capture_get_value(curr_context->hal.dev, i);
786                 if (curr_context->cap_isr_func[i].fn(curr_context->group_id, i, &edata,
787                                                      curr_context->cap_isr_func[i].args)) {
788                     need_yield = true;
789                 }
790             }
791         }
792     }
793     if (need_yield) {
794         portYIELD_FROM_ISR();
795     }
796 }
797 
mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num,mcpwm_capture_channel_id_t cap_channel,const mcpwm_capture_config_t * cap_conf)798 esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel, const mcpwm_capture_config_t *cap_conf)
799 {
800     ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
801     ESP_RETURN_ON_FALSE(cap_channel < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
802     ESP_RETURN_ON_FALSE(context[mcpwm_num].cap_isr_func[cap_channel].fn == NULL, ESP_ERR_INVALID_STATE, TAG,
803                         MCPWM_CAP_EXIST_ERROR);
804     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
805 
806     // enable MCPWM module incase user don't use `mcpwm_init` at all. always increase reference count
807     periph_module_enable(mcpwm_periph_signals.groups[mcpwm_num].module);
808 
809     mcpwm_hal_init_config_t init_config = {
810         .group_id = mcpwm_num
811     };
812     mcpwm_hal_init(hal, &init_config);
813 
814     uint32_t clk_src_hz = 0;
815     esp_clk_tree_src_get_freq_hz(MCPWM_TIMER_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz);
816     uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num);
817     uint32_t group_pre_scale = clk_src_hz / group_resolution;
818 
819     mcpwm_critical_enter(mcpwm_num);
820     mcpwm_ll_group_enable_clock(hal->dev, true);
821     mcpwm_ll_group_set_clock_source(hal->dev, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT);
822     mcpwm_ll_group_set_clock_prescale(hal->dev, group_pre_scale);
823     mcpwm_ll_capture_enable_timer(hal->dev, true);
824     mcpwm_ll_capture_enable_channel(hal->dev, cap_channel, true);
825     mcpwm_ll_capture_enable_negedge(hal->dev, cap_channel, cap_conf->cap_edge & MCPWM_NEG_EDGE);
826     mcpwm_ll_capture_enable_posedge(hal->dev, cap_channel, cap_conf->cap_edge & MCPWM_POS_EDGE);
827     mcpwm_ll_capture_set_prescale(hal->dev, cap_channel, cap_conf->cap_prescale);
828     // capture feature should be used with interrupt, so enable it by default
829     mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_channel), true);
830     mcpwm_ll_intr_clear_capture_status(hal->dev, 1 << cap_channel);
831     mcpwm_critical_exit(mcpwm_num);
832 
833     mcpwm_mutex_lock(mcpwm_num);
834     context[mcpwm_num].cap_isr_func[cap_channel].fn = cap_conf->capture_cb;
835     context[mcpwm_num].cap_isr_func[cap_channel].args = cap_conf->user_data;
836     esp_err_t ret = ESP_OK;
837     if (context[mcpwm_num].mcpwm_intr_handle == NULL) {
838         ret = esp_intr_alloc(mcpwm_periph_signals.groups[mcpwm_num].irq_id, MCPWM_INTR_FLAG,
839                              mcpwm_default_isr_handler,
840                              (void *) (context + mcpwm_num), &(context[mcpwm_num].mcpwm_intr_handle));
841     }
842     mcpwm_mutex_unlock(mcpwm_num);
843 
844     return ret;
845 }
846 
mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num,mcpwm_capture_channel_id_t cap_channel)847 esp_err_t mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel)
848 {
849     ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
850     ESP_RETURN_ON_FALSE(cap_channel < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
851 
852     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
853 
854     mcpwm_critical_enter(mcpwm_num);
855     mcpwm_ll_capture_enable_channel(hal->dev, cap_channel, false);
856     mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_channel), false);
857     mcpwm_critical_exit(mcpwm_num);
858 
859     mcpwm_mutex_lock(mcpwm_num);
860     context[mcpwm_num].cap_isr_func[cap_channel].fn = NULL;
861     context[mcpwm_num].cap_isr_func[cap_channel].args = NULL;
862     // if all user defined ISR callback is disabled, free the handle
863     bool should_free_handle = true;
864     for (int i = 0; i < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; ++i) {
865         if (context[mcpwm_num].cap_isr_func[i].fn != NULL) {
866             should_free_handle = false;
867             break;
868         }
869     }
870     esp_err_t ret = ESP_OK;
871     if (should_free_handle) {
872         ret = esp_intr_free(context[mcpwm_num].mcpwm_intr_handle);
873         if (ret != ESP_OK) {
874             ESP_LOGE(TAG, "failed to free interrupt handle");
875         }
876         context[mcpwm_num].mcpwm_intr_handle = NULL;
877     }
878     mcpwm_mutex_unlock(mcpwm_num);
879 
880     // always decrease reference count
881     periph_module_disable(mcpwm_periph_signals.groups[mcpwm_num].module);
882     return ret;
883 }
884 
mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num,mcpwm_capture_signal_t cap_sig)885 uint32_t MCPWM_ISR_ATTR mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
886 {
887     if (mcpwm_num >= MCPWM_UNIT_MAX || cap_sig >= SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER) {
888         return 0;
889     }
890     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
891     return mcpwm_ll_capture_get_value(hal->dev, cap_sig);
892 }
893 
mcpwm_capture_get_resolution(mcpwm_unit_t mcpwm_num)894 uint32_t mcpwm_capture_get_resolution(mcpwm_unit_t mcpwm_num)
895 {
896     if (mcpwm_num >= MCPWM_UNIT_MAX) {
897         ESP_LOGE(TAG, "Invalid MCPWM instance");
898         return 0;
899     }
900 #if SOC_MCPWM_CAPTURE_CLK_FROM_GROUP
901     return mcpwm_group_get_resolution(mcpwm_num);
902 #else
903     return esp_clk_apb_freq();
904 #endif
905 }
906 
mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num,mcpwm_capture_signal_t cap_sig)907 uint32_t MCPWM_ISR_ATTR mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
908 {
909     if (mcpwm_num >= MCPWM_UNIT_MAX || cap_sig >= SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER) {
910         return 0;
911     }
912     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
913     return mcpwm_ll_capture_get_edge(hal->dev, cap_sig) == MCPWM_CAP_EDGE_NEG ? 2 : 1;
914 }
915 
mcpwm_sync_configure(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,const mcpwm_sync_config_t * sync_conf)916 esp_err_t mcpwm_sync_configure(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_sync_config_t *sync_conf)
917 {
918     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
919     ESP_RETURN_ON_FALSE(sync_conf->sync_sig <= MCPWM_SELECT_GPIO_SYNC2, ESP_ERR_INVALID_ARG, TAG, "invalid sync_sig");
920     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
921 
922     mcpwm_critical_enter(mcpwm_num);
923     mcpwm_ll_timer_set_sync_phase_direction(hal->dev, timer_num, sync_conf->count_direction);
924     // sync TEP with current setting
925     uint32_t set_phase = 0;
926     set_phase = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * sync_conf->timer_val / 1000;
927     mcpwm_ll_timer_set_sync_phase_value(hal->dev, timer_num, set_phase);
928     if (sync_conf->sync_sig == MCPWM_SELECT_NO_INPUT) {
929         mcpwm_ll_timer_clear_sync_input(hal->dev, timer_num);
930     } else if (sync_conf->sync_sig <= MCPWM_SELECT_TIMER2_SYNC) {
931         mcpwm_ll_timer_set_timer_sync_input(hal->dev, timer_num, sync_conf->sync_sig - MCPWM_SELECT_TIMER0_SYNC);
932     } else {
933         mcpwm_ll_timer_set_gpio_sync_input(hal->dev, timer_num, sync_conf->sync_sig - MCPWM_SELECT_GPIO_SYNC0);
934     }
935     mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, true);
936     mcpwm_critical_exit(mcpwm_num);
937     return ESP_OK;
938 }
939 
mcpwm_sync_disable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)940 esp_err_t mcpwm_sync_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
941 {
942     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
943     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
944 
945     mcpwm_critical_enter(mcpwm_num);
946     mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, false);
947     mcpwm_critical_exit(mcpwm_num);
948     return ESP_OK;
949 }
950 
mcpwm_timer_trigger_soft_sync(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)951 esp_err_t mcpwm_timer_trigger_soft_sync(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
952 {
953     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
954 
955     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
956     mcpwm_critical_enter(mcpwm_num);
957     mcpwm_ll_timer_trigger_soft_sync(hal->dev, timer_num);
958     mcpwm_critical_exit(mcpwm_num);
959 
960     return ESP_OK;
961 }
962 
mcpwm_sync_invert_gpio_synchro(mcpwm_unit_t mcpwm_num,mcpwm_sync_signal_t sync_sig,bool invert)963 esp_err_t mcpwm_sync_invert_gpio_synchro(mcpwm_unit_t mcpwm_num, mcpwm_sync_signal_t sync_sig, bool invert)
964 {
965     ESP_RETURN_ON_FALSE(sync_sig >= MCPWM_SELECT_GPIO_SYNC0 && sync_sig <= MCPWM_SELECT_GPIO_SYNC2,
966                         ESP_ERR_INVALID_ARG, TAG, "invalid sync sig");
967 
968     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
969     mcpwm_critical_enter(mcpwm_num);
970     mcpwm_ll_invert_gpio_sync_input(hal->dev, sync_sig - MCPWM_SELECT_GPIO_SYNC0, invert);
971     mcpwm_critical_exit(mcpwm_num);
972 
973     return ESP_OK;
974 }
975 
mcpwm_set_timer_sync_output(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_timer_sync_trigger_t trigger)976 esp_err_t mcpwm_set_timer_sync_output(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_timer_sync_trigger_t trigger)
977 {
978     MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
979 
980     mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
981     mcpwm_critical_enter(mcpwm_num);
982     switch (trigger) {
983     case MCPWM_SWSYNC_SOURCE_SYNCIN:
984         mcpwm_ll_timer_propagate_input_sync(hal->dev, timer_num);
985         break;
986     case MCPWM_SWSYNC_SOURCE_TEZ:
987         mcpwm_ll_timer_sync_out_on_timer_event(hal->dev, timer_num, MCPWM_TIMER_EVENT_EMPTY);
988         break;
989     case MCPWM_SWSYNC_SOURCE_TEP:
990         mcpwm_ll_timer_sync_out_on_timer_event(hal->dev, timer_num, MCPWM_TIMER_EVENT_FULL);
991         break;
992     case MCPWM_SWSYNC_SOURCE_DISABLED:
993     default:
994         mcpwm_ll_timer_disable_sync_out(hal->dev, timer_num);
995         break;
996     }
997     mcpwm_critical_exit(mcpwm_num);
998     return ESP_OK;
999 }
1000 
1001 /**
1002  * @brief This function will be called during start up, to check that this legacy mcpwm driver is not running along with the new MCPWM driver
1003  */
1004 __attribute__((constructor))
check_mcpwm_driver_conflict(void)1005 static void check_mcpwm_driver_conflict(void)
1006 {
1007     // This function was declared as weak here. The new MCPWM driver has the implementation.
1008     // So if the new MCPWM driver is not linked in, then `mcpwm_acquire_group_handle()` should be NULL at runtime.
1009     extern __attribute__((weak)) void *mcpwm_acquire_group_handle(int group_id);
1010     if ((void *)mcpwm_acquire_group_handle != NULL) {
1011         ESP_EARLY_LOGE(TAG, "CONFLICT! driver_ng is not allowed to be used with the legacy driver");
1012         abort();
1013     }
1014     ESP_EARLY_LOGW(TAG, "legacy driver is deprecated, please migrate to `driver/mcpwm_prelude.h`");
1015 }
1016