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