1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include "soc/soc_caps.h"
10 #if SOC_MCPWM_SUPPORTED
11 #include "esp_err.h"
12 #include "soc/soc.h"
13 #ifndef __ZEPHYR__
14 #include "driver/gpio.h"
15 #include "esp_intr_alloc.h"
16 #endif
17 #include "hal/mcpwm_types.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 /**
24  * @brief IO signals for the MCPWM
25  *
26  *        - 6 MCPWM output pins that generate PWM signals
27  *        - 3 MCPWM fault input pins to detect faults like overcurrent, overvoltage, etc.
28  *        - 3 MCPWM sync input pins to synchronize MCPWM outputs signals
29  *        - 3 MCPWM capture input pins to gather feedback from controlled motors, using e.g. hall sensors
30  */
31 typedef enum {
32     MCPWM0A = 0,        /*!<PWM0A output pin*/
33     MCPWM0B,            /*!<PWM0B output pin*/
34     MCPWM1A,            /*!<PWM1A output pin*/
35     MCPWM1B,            /*!<PWM1B output pin*/
36     MCPWM2A,            /*!<PWM2A output pin*/
37     MCPWM2B,            /*!<PWM2B output pin*/
38     MCPWM_SYNC_0,       /*!<SYNC0  input pin*/
39     MCPWM_SYNC_1,       /*!<SYNC1  input pin*/
40     MCPWM_SYNC_2,       /*!<SYNC2  input pin*/
41     MCPWM_FAULT_0,      /*!<FAULT0 input pin*/
42     MCPWM_FAULT_1,      /*!<FAULT1 input pin*/
43     MCPWM_FAULT_2,      /*!<FAULT2 input pin*/
44     MCPWM_CAP_0 = 84,   /*!<CAP0   input pin*/
45     MCPWM_CAP_1,        /*!<CAP1   input pin*/
46     MCPWM_CAP_2,        /*!<CAP2   input pin*/
47 } mcpwm_io_signals_t;
48 
49 /**
50  * @brief pin number for MCPWM
51  */
52 typedef struct {
53     int mcpwm0a_out_num;       /*!<MCPWM0A out pin*/
54     int mcpwm0b_out_num;       /*!<MCPWM0A out pin*/
55     int mcpwm1a_out_num;       /*!<MCPWM0A out pin*/
56     int mcpwm1b_out_num;       /*!<MCPWM0A out pin*/
57     int mcpwm2a_out_num;       /*!<MCPWM0A out pin*/
58     int mcpwm2b_out_num;       /*!<MCPWM0A out pin*/
59     int mcpwm_sync0_in_num;    /*!<SYNC0  in pin*/
60     int mcpwm_sync1_in_num;    /*!<SYNC1  in pin*/
61     int mcpwm_sync2_in_num;    /*!<SYNC2  in pin*/
62     int mcpwm_fault0_in_num;   /*!<FAULT0 in pin*/
63     int mcpwm_fault1_in_num;   /*!<FAULT1 in pin*/
64     int mcpwm_fault2_in_num;   /*!<FAULT2 in pin*/
65     int mcpwm_cap0_in_num;     /*!<CAP0   in pin*/
66     int mcpwm_cap1_in_num;     /*!<CAP1   in pin*/
67     int mcpwm_cap2_in_num;     /*!<CAP2   in pin*/
68 } mcpwm_pin_config_t;
69 
70 /**
71  * @brief Select MCPWM unit
72  */
73 typedef enum {
74     MCPWM_UNIT_0,   /*!<MCPWM unit0 selected*/
75     MCPWM_UNIT_1,   /*!<MCPWM unit1 selected*/
76     MCPWM_UNIT_MAX, /*!<Max number of MCPWM units*/
77 } mcpwm_unit_t;
78 
79 _Static_assert(MCPWM_UNIT_MAX == SOC_MCPWM_GROUPS, "MCPWM unit number not equal to chip capabilities");
80 
81 /**
82  * @brief Select MCPWM timer
83  */
84 typedef enum {
85     MCPWM_TIMER_0,   /*!<Select MCPWM timer0*/
86     MCPWM_TIMER_1,   /*!<Select MCPWM timer1*/
87     MCPWM_TIMER_2,   /*!<Select MCPWM timer2*/
88     MCPWM_TIMER_MAX, /*!<Max number of timers in a unit*/
89 } mcpwm_timer_t;
90 
91 /**
92  * @brief Select MCPWM operator
93  */
94 typedef enum {
95     MCPWM_GEN_A,   /*!<Select MCPWMXA, where 'X' is operator number*/
96     MCPWM_GEN_B,   /*!<Select MCPWMXB, where 'X' is operator number*/
97     MCPWM_GEN_MAX, /*!<Num of generators to each operator of MCPWM*/
98 } mcpwm_generator_t;
99 
100 //definitions and macros to be back-compatible before IDFv4.1
101 #define MCPWM_OPR_A     MCPWM_GEN_A         ///< @deprecated
102 #define MCPWM_OPR_B     MCPWM_GEN_B         ///< @deprecated
103 #define MCPWM_OPR_MAX   MCPWM_GEN_MAX       ///< @deprecated
104 typedef mcpwm_generator_t mcpwm_operator_t; ///< @deprecated
105 
106 /**
107  * @brief MCPWM carrier oneshot mode, in this mode the width of the first pulse of carrier can be programmed
108  */
109 typedef enum {
110     MCPWM_ONESHOT_MODE_DIS, /*!<Enable oneshot mode*/
111     MCPWM_ONESHOT_MODE_EN,  /*!<Disable oneshot mode*/
112 } mcpwm_carrier_os_t;
113 
114 /**
115  * @brief MCPWM carrier output inversion, high frequency carrier signal active with MCPWM signal is high
116  */
117 typedef enum {
118     MCPWM_CARRIER_OUT_IVT_DIS, /*!<Enable  carrier output inversion*/
119     MCPWM_CARRIER_OUT_IVT_EN,  /*!<Disable carrier output inversion*/
120 } mcpwm_carrier_out_ivt_t;
121 
122 /**
123  * @brief MCPWM select fault signal input
124  */
125 typedef enum {
126     MCPWM_SELECT_F0, /*!<Select F0 as input*/
127     MCPWM_SELECT_F1, /*!<Select F1 as input*/
128     MCPWM_SELECT_F2, /*!<Select F2 as input*/
129 } mcpwm_fault_signal_t;
130 
131 /**
132  * @brief MCPWM select sync signal input
133  */
134 typedef enum {
135     MCPWM_SELECT_NO_INPUT,        /*!<No sync input selected*/
136     MCPWM_SELECT_TIMER0_SYNC,     /*!<Select software sync signal from timer0 as input*/
137     MCPWM_SELECT_TIMER1_SYNC,     /*!<Select software sync signal from timer1 as input*/
138     MCPWM_SELECT_TIMER2_SYNC,     /*!<Select software sync signal from timer2 as input*/
139     MCPWM_SELECT_GPIO_SYNC0,      /*!<Select GPIO SYNC0 as input*/
140     MCPWM_SELECT_GPIO_SYNC1,      /*!<Select GPIO SYNC1 as input*/
141     MCPWM_SELECT_GPIO_SYNC2,      /*!<Select GPIO SYNC2 as input*/
142 } mcpwm_sync_signal_t;
143 
144  // backward compatibility
145 #define MCPWM_SELCT_SYNC0 MCPWM_SELCT_GPIO_SYNC0
146 #define MCPWM_SELCT_SYNC1 MCPWM_SELCT_GPIO_SYNC1
147 #define MCPWM_SELCT_SYNC2 MCPWM_SELCT_GPIO_SYNC2
148 
149 /**
150  * @brief MCPWM timer sync event trigger
151  */
152 typedef enum {
153     MCPWM_SWSYNC_SOURCE_SYNCIN,      /*!<the input sync signal will be routed to its sync output path*/
154     MCPWM_SWSYNC_SOURCE_TEZ,         /*!<sync signal generated when timer counts to zero*/
155     MCPWM_SWSYNC_SOURCE_TEP,         /*!<sync signal generated when timer counts to peak*/
156     MCPWM_SWSYNC_SOURCE_DISABLED,    /*!<timer does not generate sync signals*/
157 } mcpwm_timer_sync_trigger_t;
158 
159 /**
160  * @brief MCPWM select triggering level of fault signal
161  */
162 typedef enum {
163     MCPWM_LOW_LEVEL_TGR,  /*!<Fault condition occurs when fault input signal goes from high to low*/
164     MCPWM_HIGH_LEVEL_TGR, /*!<Fault condition occurs when fault input signal goes low to high*/
165 } mcpwm_fault_input_level_t;
166 
167 /**
168  * @brief MCPWM select capture starts from which edge
169  */
170 typedef enum {
171     MCPWM_NEG_EDGE = BIT(0),           /*!<Capture the negative edge*/
172     MCPWM_POS_EDGE = BIT(1),           /*!<Capture the positive edge*/
173     MCPWM_BOTH_EDGE = BIT(1) | BIT(0), /*!<Capture both edges*/
174 } mcpwm_capture_on_edge_t;
175 
176 /**
177  * @brief Interrupt masks for MCPWM capture
178  */
179 typedef enum {
180     MCPWM_LL_INTR_CAP0 = BIT(27), ///< Capture 0 happened
181     MCPWM_LL_INTR_CAP1 = BIT(28), ///< Capture 1 happened
182     MCPWM_LL_INTR_CAP2 = BIT(29), ///< Capture 2 happened
183 } mcpwm_intr_t;
184 
185 /**
186  * @brief Select type of MCPWM counter
187  */
188 typedef enum {
189     MCPWM_FREEZE_COUNTER,   /*!<Counter freeze */
190     MCPWM_UP_COUNTER,       /*!<For asymmetric MCPWM*/
191     MCPWM_DOWN_COUNTER,     /*!<For asymmetric MCPWM*/
192     MCPWM_UP_DOWN_COUNTER,  /*!<For symmetric MCPWM, frequency is half of MCPWM frequency set*/
193     MCPWM_COUNTER_MAX,      /*!<Maximum counter mode*/
194 } mcpwm_counter_type_t;
195 
196 /**
197  * @brief Select type of MCPWM duty cycle mode
198  */
199 typedef enum {
200     MCPWM_DUTY_MODE_0 = 0, /*!<Active high duty, i.e. duty cycle proportional to high time for asymmetric MCPWM*/
201     MCPWM_DUTY_MODE_1,     /*!<Active low duty,  i.e. duty cycle proportional to low  time for asymmetric MCPWM, out of phase(inverted) MCPWM*/
202     MCPWM_HAL_GENERATOR_MODE_FORCE_LOW,
203     MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH,
204     MCPWM_DUTY_MODE_MAX,   /*!<Num of duty cycle modes*/
205 } mcpwm_duty_type_t;
206 
207 /**
208  * @brief MCPWM deadtime types, used to generate deadtime, RED refers to rising edge delay and FED refers to falling edge delay
209  */
210 typedef enum {
211     MCPWM_DEADTIME_BYPASS = 0,          /*!<Bypass the deadtime*/
212     MCPWM_BYPASS_RED,                   /*!<MCPWMXA Out = MCPWMXA In with no delay, MCPWMXB Out = MCPWMXA In with falling edge delay*/
213     MCPWM_BYPASS_FED,                   /*!<MCPWMXA Out = MCPWMXA In with rising edge delay, MCPWMXB Out = MCPWMXB In with no delay*/
214     MCPWM_ACTIVE_HIGH_MODE,             /*!<MCPWMXA Out = MCPWMXA In with rising edge delay,  MCPWMXB Out = MCPWMXA In with falling edge delay*/
215     MCPWM_ACTIVE_LOW_MODE,              /*!<MCPWMXA Out = MCPWMXA In with compliment of rising edge delay,  MCPWMXB Out = MCPWMXA In with compliment of falling edge delay*/
216     MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE,  /*!<MCPWMXA Out = MCPWMXA In with rising edge delay,  MCPWMXB = MCPWMXA In with compliment of falling edge delay*/
217     MCPWM_ACTIVE_LOW_COMPLIMENT_MODE,   /*!<MCPWMXA Out = MCPWMXA In with compliment of rising edge delay,  MCPWMXB Out = MCPWMXA In with falling edge delay*/
218     MCPWM_ACTIVE_RED_FED_FROM_PWMXA,    /*!<MCPWMXA Out = MCPWMXB Out = MCPWMXA In with rising edge delay as well as falling edge delay*/
219     MCPWM_ACTIVE_RED_FED_FROM_PWMXB,    /*!<MCPWMXA Out = MCPWMXB Out = MCPWMXB In with rising edge delay as well as falling edge delay*/
220     MCPWM_DEADTIME_TYPE_MAX,            /*!<Maximum number of supported dead time modes*/
221 } mcpwm_deadtime_type_t;
222 
223 /**
224  * @brief MCPWM select action to be taken on the output when event happens
225  */
226 typedef enum {
227     MCPWM_ACTION_NO_CHANGE = 0,  /*!<No change in the output*/
228     MCPWM_ACTION_FORCE_LOW,      /*!<Make output low*/
229     MCPWM_ACTION_FORCE_HIGH,     /*!<Make output high*/
230     MCPWM_ACTION_TOGGLE,         /*!<Make output toggle*/
231 } mcpwm_output_action_t;
232 
233 /// @deprecated MCPWM select action to be taken on MCPWMXA when fault occurs
234 typedef mcpwm_output_action_t mcpwm_action_on_pwmxa_t;
235 #define MCPWM_NO_CHANGE_IN_MCPWMXA  MCPWM_ACTION_NO_CHANGE      /*!< @deprecated No change in MCPWMXA output*/
236 #define MCPWM_FORCE_MCPWMXA_LOW     MCPWM_ACTION_FORCE_LOW      /*!< @deprecated Make MCPWMXA output low*/
237 #define MCPWM_FORCE_MCPWMXA_HIGH    MCPWM_ACTION_FORCE_HIGH     /*!< @deprecated Make MCPWMXA output high*/
238 #define MCPWM_TOG_MCPWMXA           MCPWM_ACTION_TOGGLE         /*!< @deprecated Make MCPWMXA output toggle*/
239 
240 /// @deprecated MCPWM select action to be taken on MCPWMXB when fault occurs
241 typedef mcpwm_output_action_t mcpwm_action_on_pwmxb_t;
242 #define MCPWM_NO_CHANGE_IN_MCPWMXB  MCPWM_ACTION_NO_CHANGE      /*!< @deprecated No change in MCPWMXB output*/
243 #define MCPWM_FORCE_MCPWMXB_LOW     MCPWM_ACTION_FORCE_LOW      /*!< @deprecated Make MCPWMXB output low*/
244 #define MCPWM_FORCE_MCPWMXB_HIGH    MCPWM_ACTION_FORCE_HIGH     /*!< @deprecated Make MCPWMXB output high*/
245 #define MCPWM_TOG_MCPWMXB           MCPWM_ACTION_TOGGLE         /*!< @deprecated Make MCPWMXB output toggle*/
246 
247 /**
248  * @brief MCPWM select capture signal input
249  */
250 typedef enum {
251     MCPWM_SELECT_CAP0, /*!<Select CAP0 as input*/
252     MCPWM_SELECT_CAP1, /*!<Select CAP1 as input*/
253     MCPWM_SELECT_CAP2, /*!<Select CAP2 as input*/
254 } mcpwm_capture_signal_t;
255 
256 /**
257  * @brief MCPWM capture channel ID alias
258  */
259 typedef mcpwm_capture_signal_t mcpwm_capture_channel_id_t;
260 
261 /**
262  * @brief event data that will be passed into ISR callback
263  */
264 typedef struct {
265     mcpwm_capture_on_edge_t cap_edge;   /*!<Which signal edge is detected*/
266     uint32_t cap_value;                 /*!<Corresponding timestamp when event occurs. Clock rate = APB(usually 80M)*/
267 } cap_event_data_t;
268 
269 /**
270  * @brief Type of capture event callback
271  * @param mcpwm MCPWM unit(0-1)
272  * @param cap_channel capture channel ID
273  * @param edata Capture event data, contains capture edge and capture value, fed by the driver
274  * @param user_data User registered data, passed from `mcpwm_capture_config_t`
275  *
276  * @note Since this an ISR callback so do not do anything that may block and call APIs that is designed to be used within ISR(usually has '_ISR' postfix)
277  *
278  * @return Whether a task switch is needed after the callback function returns,
279  *         this is usually due to the callback wakes up some high priority task.
280  *
281  */
282 typedef bool (*cap_isr_cb_t)(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_channel, const cap_event_data_t *edata,
283                              void *user_data);
284 
285 /**
286  * @brief MCPWM config structure
287  */
288 typedef struct {
289     uint32_t frequency;              /*!<Set frequency of MCPWM in Hz*/
290     float cmpr_a;                    /*!<Set % duty cycle for operator a(MCPWMXA), i.e for 62.3% duty cycle, duty_a = 62.3*/
291     float cmpr_b;                    /*!<Set % duty cycle for operator b(MCPWMXB), i.e for 48% duty cycle, duty_b = 48.0*/
292     mcpwm_duty_type_t duty_mode;     /*!<Set type of duty cycle*/
293     mcpwm_counter_type_t counter_mode;  /*!<Set  type of MCPWM counter*/
294 } mcpwm_config_t;
295 
296 /**
297  * @brief MCPWM carrier configuration structure
298  */
299 typedef struct {
300     uint8_t carrier_period;                    /*!<Set carrier period = (carrier_period + 1)*800ns, carrier_period should be < 16*/
301     uint8_t carrier_duty;                      /*!<Set carrier duty cycle, carrier_duty should be less than 8 (increment every 12.5%)*/
302     uint8_t pulse_width_in_os;                 /*!<Set pulse width of first pulse in one shot mode = (carrier period)*(pulse_width_in_os + 1), should be less then 16*/
303     mcpwm_carrier_os_t carrier_os_mode;        /*!<Enable or disable carrier oneshot mode*/
304     mcpwm_carrier_out_ivt_t carrier_ivt_mode;  /*!<Invert output of carrier*/
305 } mcpwm_carrier_config_t;
306 
307 /**
308  * @brief MCPWM config capture structure
309  */
310 typedef struct {
311     mcpwm_capture_on_edge_t cap_edge;      /*!<Set capture edge*/
312     uint32_t cap_prescale;                 /*!<Prescale of capture signal, ranging from 1 to 256*/
313     cap_isr_cb_t capture_cb;               /*!<User defined capture event callback, running under interrupt context */
314     void *user_data;                       /*!<User defined ISR callback function args*/
315 } mcpwm_capture_config_t;
316 
317 /**
318  * @brief MCPWM config sync structure
319  */
320 typedef struct {
321     mcpwm_sync_signal_t sync_sig;              /*!<Set sync input signal that will cause timer to sync*/
322     uint32_t timer_val;                        /*!<Counter value to be set after sync, in 0 ~ 999, unit: 1 / 1000 * peak*/
323     mcpwm_timer_direction_t count_direction;   /*!<Counting direction to be set after sync */
324 } mcpwm_sync_config_t;
325 
326 /**
327  * @brief This function initializes each gpio signal for MCPWM
328  *
329  * @note This function initializes one gpio at a time.
330  *
331  * @param mcpwm_num set MCPWM unit(0-1)
332  * @param io_signal set MCPWM signals, each MCPWM unit has 6 output(MCPWMXA, MCPWMXB) and 9 input(SYNC_X, FAULT_X, CAP_X)
333  *                  'X' is timer_num(0-2)
334  * @param gpio_num set this to configure gpio for MCPWM, if you want to use gpio16, gpio_num = 16
335  *
336  * @return
337  *     - ESP_OK Success
338  *     - ESP_ERR_INVALID_ARG Parameter error
339  */
340 esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal, int gpio_num);
341 
342 /**
343  * @brief Initialize MCPWM gpio structure
344  *
345  * @note This function initialize a group of MCPWM GPIOs at a time.
346  *
347  * @param mcpwm_num set MCPWM unit(0-1)
348  * @param mcpwm_pin MCPWM pin structure
349  *
350  * @return
351  *     - ESP_OK Success
352  *     - ESP_ERR_INVALID_ARG Parameter error
353  */
354 esp_err_t mcpwm_set_pin(mcpwm_unit_t mcpwm_num, const mcpwm_pin_config_t *mcpwm_pin);
355 
356 /**
357  * @brief Initialize MCPWM parameters
358  * @note
359  *        The default resolution configured for MCPWM group and timer are 160M / 16 = 10M and 10M / 10 = 1M
360  *        The default resolution can be changed by calling mcpwm_group_set_resolution() and mcpwm_timer_set_resolution(),
361  *        before calling this function.
362  *
363  * @param mcpwm_num set MCPWM unit(0-1)
364  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers.
365  * @param mcpwm_conf configure structure mcpwm_config_t
366  *
367  * @return
368  *     - ESP_OK Success
369  *     - ESP_ERR_INVALID_ARG Parameter error
370  */
371 esp_err_t mcpwm_init( mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_config_t  *mcpwm_conf);
372 
373 /**
374  * @brief Set resolution of the MCPWM group
375  * @note
376  *        This will override default resolution of group(=10,000,000).
377  *        This WILL NOT automatically update frequency and duty. Call mcpwm_set_frequency() and mcpwm_set_duty() manually
378  *        to set them back.
379  *
380  * @param mcpwm_num set MCPWM unit(0-1)
381  * @param resolution set expected frequency resolution
382  *
383  * @return
384  *     - ESP_OK Success
385  *     - ESP_ERR_INVALID_ARG Parameter error
386  */
387 esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, unsigned long int resolution);
388 
389 /**
390  * @brief Set resolution of each timer
391  * @note
392  *        This WILL override default resolution of timer(=1,000,000).
393  *        This WILL NOT automatically update frequency and duty. Call mcpwm_set_frequency() and mcpwm_set_duty() manually
394  *        to set them back.
395  *
396  * @param mcpwm_num set MCPWM unit(0-1)
397  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
398  * @param resolution set expected frequency resolution
399  *
400  * @return
401  *     - ESP_OK Success
402  *     - ESP_ERR_INVALID_ARG Parameter error
403  */
404 esp_err_t mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, unsigned long int resolution);
405 
406 /**
407  * @brief Set frequency(in Hz) of MCPWM timer
408  *
409  * @param mcpwm_num set MCPWM unit(0-1)
410  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
411  * @param frequency set the frequency in Hz of each timer
412  *
413  * @return
414  *     - ESP_OK Success
415  *     - ESP_ERR_INVALID_ARG Parameter error
416  */
417 esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t frequency);
418 
419 /**
420  * @brief Set duty cycle of each operator(MCPWMXA/MCPWMXB)
421  *
422  * @param mcpwm_num set MCPWM unit(0-1)
423  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
424  * @param gen set the generator(MCPWMXA/MCPWMXB), 'X' is operator number selected
425  * @param duty set duty cycle in %(i.e for 62.3% duty cycle, duty = 62.3) of each operator
426  *
427  * @return
428  *     - ESP_OK Success
429  *     - ESP_ERR_INVALID_ARG Parameter error
430  */
431 esp_err_t mcpwm_set_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, float duty);
432 
433 /**
434  * @brief Set duty cycle of each operator(MCPWMXA/MCPWMXB) in us
435  *
436  * @param mcpwm_num set MCPWM unit(0-1)
437  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
438  * @param gen set the generator(MCPWMXA/MCPWMXB), 'x' is operator number selected
439  * @param duty_in_us set duty value in microseconds of each operator
440  *
441  * @return
442  *     - ESP_OK Success
443  *     - ESP_ERR_INVALID_ARG Parameter error
444  */
445 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);
446 
447 /**
448  * @brief Set duty either active high or active low(out of phase/inverted)
449  * @note
450  *        Call this function every time after mcpwm_set_signal_high or mcpwm_set_signal_low to resume with previously set duty cycle
451  *
452  * @param mcpwm_num set MCPWM unit(0-1)
453  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
454  * @param gen set the generator(MCPWMXA/MCPWMXB), 'x' is operator number selected
455  * @param duty_type set active low or active high duty type
456  *
457  * @return
458  *     - ESP_OK Success
459  *     - ESP_ERR_INVALID_ARG Parameter error
460  */
461 esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, mcpwm_duty_type_t duty_type);
462 
463 /**
464 * @brief Get frequency of timer
465 *
466 * @param mcpwm_num set MCPWM unit(0-1)
467 * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
468 *
469 * @return
470 *     - frequency of timer
471 */
472 uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
473 
474 /**
475  * @brief Get duty cycle of each operator
476  *
477  * @param mcpwm_num set MCPWM unit(0-1)
478  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
479  * @param gen set the generator(MCPWMXA/MCPWMXB), 'x' is operator number selected
480  *
481  * @return
482  *     - duty cycle in % of each operator(56.7 means duty is 56.7%)
483  */
484 float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen);
485 
486 /**
487  * @brief Get duty cycle of each operator in us
488  *
489  * @param mcpwm_num set MCPWM unit(0-1)
490  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
491  * @param gen set the generator(MCPWMXA/MCPWMXB), 'x' is operator number selected
492  *
493  * @return
494  *     - duty cycle in us of each operator
495  */
496 uint32_t mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen);
497 
498 /**
499  * @brief Use this function to set MCPWM signal high
500  *
501  * @param mcpwm_num set MCPWM unit(0-1)
502  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
503  * @param gen set the operator(MCPWMXA/MCPWMXB), 'x' is timer number selected
504 
505  *
506  * @return
507  *     - ESP_OK Success
508  *     - ESP_ERR_INVALID_ARG Parameter error
509  */
510 esp_err_t mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen);
511 
512 /**
513  * @brief Use this function to set MCPWM signal low
514  *
515  * @param mcpwm_num set MCPWM unit(0-1)
516  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
517  * @param gen set the operator(MCPWMXA/MCPWMXB), 'x' is timer number selected
518 
519  *
520  * @return
521  *     - ESP_OK Success
522  *     - ESP_ERR_INVALID_ARG Parameter error
523  */
524 esp_err_t mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen);
525 
526 /**
527  * @brief Start MCPWM signal on timer 'x'
528  *
529  * @param mcpwm_num set MCPWM unit(0-1)
530  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
531  *
532  * @return
533  *     - ESP_OK Success
534  *     - ESP_ERR_INVALID_ARG Parameter error
535  */
536 esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
537 
538 /**
539  * @brief Start MCPWM signal on timer 'x'
540  *
541  * @param mcpwm_num set MCPWM unit(0-1)
542  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
543  *
544  * @return
545  *     - ESP_OK Success
546  *     - ESP_ERR_INVALID_ARG Parameter error
547  */
548 esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
549 
550 /**
551  * @brief  Initialize carrier configuration
552  *
553  * @param mcpwm_num set MCPWM unit(0-1)
554  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
555  * @param carrier_conf configure structure mcpwm_carrier_config_t
556  *
557  * @return
558  *     - ESP_OK Success
559  *     - ESP_ERR_INVALID_ARG Parameter error
560  */
561 esp_err_t mcpwm_carrier_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_carrier_config_t *carrier_conf);
562 
563 /**
564 * @brief Enable MCPWM carrier submodule, for respective timer
565 *
566 * @param mcpwm_num set MCPWM unit(0-1)
567 * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
568 *
569 * @return
570 *     - ESP_OK Success
571 *     - ESP_ERR_INVALID_ARG Parameter error
572 */
573 esp_err_t mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
574 
575 /**
576  * @brief Disable MCPWM carrier submodule, for respective timer
577  *
578  * @param mcpwm_num set MCPWM unit(0-1)
579  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
580  *
581  * @return
582  *     - ESP_OK Success
583  *     - ESP_ERR_INVALID_ARG Parameter error
584  */
585 esp_err_t mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
586 
587 /**
588  * @brief Set period of carrier
589  *
590  * @param mcpwm_num set MCPWM unit(0-1)
591  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
592  * @param carrier_period set the carrier period of each timer, carrier period = (carrier_period + 1)*800ns
593  *                    (carrier_period <= 15)
594  *
595  * @return
596  *     - ESP_OK Success
597  *     - ESP_ERR_INVALID_ARG Parameter error
598  */
599 esp_err_t mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_period);
600 
601 /**
602  * @brief Set duty_cycle of carrier
603  *
604  * @param mcpwm_num set MCPWM unit(0-1)
605  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
606  * @param carrier_duty set duty_cycle of carrier , carrier duty cycle = carrier_duty*12.5%
607  *                  (chop_duty <= 7)
608  *
609  * @return
610  *     - ESP_OK Success
611  *     - ESP_ERR_INVALID_ARG Parameter error
612  */
613 esp_err_t mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_duty);
614 
615 /**
616  * @brief Enable and set width of first pulse in carrier oneshot mode
617  *
618  * @param mcpwm_num set MCPWM unit(0-1)
619  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
620  * @param pulse_width set pulse width of first pulse in oneshot mode, width = (carrier period)*(pulse_width +1)
621  *                    (pulse_width <= 15)
622  *
623  * @return
624  *     - ESP_OK Success
625  *     - ESP_ERR_INVALID_ARG Parameter error
626  */
627 esp_err_t mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t pulse_width);
628 
629 /**
630  * @brief Disable oneshot mode, width of first pulse = carrier period
631  *
632  * @param mcpwm_num set MCPWM unit(0-1)
633  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
634  *
635  * @return
636  *     - ESP_OK Success
637  *     - ESP_ERR_INVALID_ARG Parameter error
638  */
639 esp_err_t mcpwm_carrier_oneshot_mode_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
640 
641 /**
642  * @brief Enable or disable carrier output inversion
643  *
644  * @param mcpwm_num set MCPWM unit(0-1)
645  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
646  * @param carrier_ivt_mode enable or disable carrier output inversion
647  *
648  * @return
649  *     - ESP_OK Success
650  *     - ESP_ERR_INVALID_ARG Parameter error
651  */
652 esp_err_t mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num,
653                                       mcpwm_carrier_out_ivt_t carrier_ivt_mode);
654 
655 /**
656  * @brief Enable and initialize deadtime for each MCPWM timer
657  *
658  * @param mcpwm_num set MCPWM unit(0-1)
659  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
660  * @param dt_mode set deadtime mode
661  * @param red set rising edge delay = red*100ns
662  * @param fed set rising edge delay = fed*100ns
663  *
664  * @return
665  *     - ESP_OK Success
666  *     - ESP_ERR_INVALID_ARG Parameter error
667  */
668 esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_deadtime_type_t dt_mode,
669                                 uint32_t red, uint32_t fed);
670 
671 /**
672  * @brief Disable deadtime on MCPWM timer
673  *
674  * @param mcpwm_num set MCPWM unit(0-1)
675  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
676  *
677  * @return
678  *     - ESP_OK Success
679  *     - ESP_ERR_INVALID_ARG Parameter error
680  */
681 esp_err_t mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
682 
683 /**
684  * @brief Initialize fault submodule, currently low level triggering is not supported
685  *
686  * @param mcpwm_num set MCPWM unit(0-1)
687  * @param intput_level set fault signal level, which will cause fault to occur
688  * @param fault_sig set the fault pin, which needs to be enabled
689  *
690  * @return
691  *     - ESP_OK Success
692  *     - ESP_ERR_INVALID_ARG Parameter error
693  */
694 esp_err_t mcpwm_fault_init(mcpwm_unit_t mcpwm_num, mcpwm_fault_input_level_t intput_level, mcpwm_fault_signal_t fault_sig);
695 
696 /**
697  * @brief Set oneshot mode on fault detection, once fault occur in oneshot mode reset is required to resume MCPWM signals
698  * @note
699  *        currently low level triggering is not supported
700  *
701  * @param mcpwm_num set MCPWM unit(0-1)
702  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
703  * @param fault_sig set the fault pin, which needs to be enabled for oneshot mode
704  * @param action_on_pwmxa action to be taken on MCPWMXA when fault occurs, either no change or high or low or toggle
705  * @param action_on_pwmxb action to be taken on MCPWMXB when fault occurs, either no change or high or low or toggle
706  *
707  * @return
708  *     - ESP_OK Success
709  *     - ESP_ERR_INVALID_ARG Parameter error
710  */
711 esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
712                                        mcpwm_output_action_t action_on_pwmxa, mcpwm_output_action_t action_on_pwmxb);
713 
714 /**
715  * @brief Set cycle-by-cycle mode on fault detection, once fault occur in cyc mode MCPWM signal resumes as soon as fault signal becomes inactive
716  * @note
717  *        currently low level triggering is not supported
718  *
719  * @param mcpwm_num set MCPWM unit(0-1)
720  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
721  * @param fault_sig set the fault pin, which needs to be enabled for cyc mode
722  * @param action_on_pwmxa action to be taken on MCPWMXA when fault occurs, either no change or high or low or toggle
723  * @param action_on_pwmxb action to be taken on MCPWMXB when fault occurs, either no change or high or low or toggle
724  *
725  * @return
726  *     - ESP_OK Success
727  *     - ESP_ERR_INVALID_ARG Parameter error
728  */
729 esp_err_t mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
730                                    mcpwm_output_action_t action_on_pwmxa, mcpwm_output_action_t action_on_pwmxb);
731 
732 /**
733  * @brief Disable fault signal
734  *
735  * @param mcpwm_num set MCPWM unit(0-1)
736  * @param fault_sig fault pin, which needs to be disabled
737  *
738  * @return
739  *     - ESP_OK Success
740  *     - ESP_ERR_INVALID_ARG Parameter error
741  */
742 esp_err_t mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num, mcpwm_fault_signal_t fault_sig);
743 
744 /**
745  * @brief Initialize capture submodule
746  *
747  * @note Enabling capture feature would also enable the capture interrupt event,
748  *       users have to register an interrupt handler by `mcpwm_isr_register`, and in there, query the capture data.
749  * @note The capture timer uses APB_CLK (typically 80MHz) as the count source.
750  *
751  * @param mcpwm_num set MCPWM unit(0-1)
752  * @param cap_edge set capture edge, BIT(0) - negative edge, BIT(1) - positive edge
753  * @param cap_sig capture pin, which needs to be enabled
754  * @param num_of_pulse Input capture signal prescaling, ranges from 0 to 255, representing prescaling from 1 to 256.
755  *
756  * @return
757  *     - ESP_OK Success
758  *     - ESP_ERR_INVALID_ARG Parameter error
759  */
760 __attribute__((deprecated("please use mcpwm_capture_enable_channel instead")))
761 esp_err_t mcpwm_capture_enable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig, mcpwm_capture_on_edge_t cap_edge,
762                                uint32_t num_of_pulse);
763 
764 /**
765  * @brief Disable capture signal
766  *
767  * @param mcpwm_num set MCPWM unit(0-1)
768  * @param cap_sig capture pin, which needs to be disabled
769  *
770  * @return
771  *     - ESP_OK Success
772  *     - ESP_ERR_INVALID_ARG Parameter error
773  */
774 __attribute__((deprecated("please use mcpwm_capture_disable_channel instead")))
775 esp_err_t mcpwm_capture_disable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig);
776 
777 /**
778  * @brief Enable capture channel
779  *
780  * @param mcpwm_num set MCPWM unit(0-1)
781  * @param cap_channel capture channel, which needs to be enabled
782  * @param cap_conf capture channel configuration
783  *
784  * @return
785  *     - ESP_OK Success
786  *     - ESP_ERR_INVALID_ARG Parameter error
787  */
788 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);
789 
790 /**
791  * @brief Disable capture channel
792  *
793  * @param mcpwm_num set MCPWM unit(0-1)
794  * @param cap_channel capture channel, which needs to be disabled
795  *
796  * @return
797  *     - ESP_OK Success
798  *     - ESP_ERR_INVALID_ARG Parameter error
799  */
800 esp_err_t mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel);
801 
802 /**
803  * @brief Get capture value
804  *
805  * @param mcpwm_num set MCPWM unit(0-1)
806  * @param cap_sig capture channel on which value is to be measured
807  *
808  * @return
809  *     Captured value
810  */
811 uint32_t mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig);
812 
813 /**
814  * @brief Get edge of capture signal
815  *
816  * @param mcpwm_num set MCPWM unit(0-1)
817  * @param cap_sig capture channel of whose edge is to be determined
818  *
819  * @return
820  *     Capture signal edge: 1 - positive edge, 2 - negtive edge
821  */
822 uint32_t mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig);
823 
824 /**
825  * @brief Initialize sync submodule and sets the signal that will cause the timer be loaded with pre-defined value
826  *
827  * @param mcpwm_num set MCPWM unit(0-1)
828  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
829  * @param sync_sig set the synchronization input signal
830  * @param phase_val phase value in 1/1000 (for 86.7%, phase_val = 867) which timer moves to on sync signal
831  *
832  * @note Count direction is undefined within this API
833  *
834  * @return
835  *     - ESP_OK Success
836  *     - ESP_ERR_INVALID_ARG Parameter error
837  */
838 __attribute__((deprecated("please use mcpwm_sync_configure() instead")))
839 esp_err_t mcpwm_sync_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_sync_signal_t sync_sig,
840                             uint32_t phase_val);
841 
842 /**
843  * @brief Initialize sync submodule and sets the signal that will cause the timer be loaded with pre-defined value
844  *
845  * @param mcpwm_num set MCPWM unit(0-1)
846  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
847  * @param sync_conf sync configuration on this timer
848  *
849  * @return
850  *     - ESP_OK Success
851  *     - ESP_ERR_INVALID_ARG Parameter error
852  */
853 esp_err_t mcpwm_sync_configure(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_sync_config_t *sync_conf);
854 
855 /**
856  * @brief Disable sync submodule on given timer
857  *
858  * @param mcpwm_num set MCPWM unit(0-1)
859  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
860  *
861  * @return
862  *     - ESP_OK Success
863  *     - ESP_ERR_INVALID_ARG Parameter error
864  */
865 esp_err_t mcpwm_sync_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
866 
867 /**
868  * @brief Set sync output on given timer
869  *        Configures what event triggers MCPWM timer to output a sync signal.
870  *
871  * @param mcpwm_num set MCPWM unit(0-1)
872  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
873  * @param trigger set the trigger that will cause the timer to generate a software sync signal.
874  *                Specifically, `MCPWM_SWSYNC_SOURCE_DISABLED` will disable the timer from generating sync signal.
875  * @return
876  *     - ESP_OK Success
877  *     - ESP_ERR_INVALID_ARG Parameter error
878  */
879 esp_err_t mcpwm_set_timer_sync_output(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_timer_sync_trigger_t trigger);
880 
881 /**
882  * @brief Trigger a software sync event and sends it to a specific timer.
883  *
884  * @param mcpwm_num set MCPWM unit(0-1)
885  * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers
886  *
887  * @note This software sync event will have the same effect as hw one, except that:
888  *         - On esp32s3 the soft sync event can be routed to its output if `MCPWM_SWSYNC_SOURCE_SYNCIN` is selected via `mcpwm_set_timer_sync_output()`
889  *         - On esp32 there is no such behavior and soft sync event will only take effect on this timer and can not be propagated to others.
890  *
891  * @return
892  *     - ESP_OK Success
893  *     - ESP_ERR_INVALID_ARG Function pointer error.
894  */
895 esp_err_t mcpwm_timer_trigger_soft_sync(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num);
896 
897 /**
898  * @brief Set external GPIO sync input inverter
899  *
900  * @param mcpwm_num set MCPWM unit(0-1)
901  * @param sync_sig set sync signal of MCPWM, only supports GPIO sync signal
902  * @param invert whether GPIO sync source input is inverted (to get negative edge trigger)
903  *
904  * @return
905  *     - ESP_OK Success
906  *     - ESP_ERR_INVALID_ARG Function pointer error.
907  */
908 esp_err_t mcpwm_sync_invert_gpio_synchro(mcpwm_unit_t mcpwm_num, mcpwm_sync_signal_t sync_sig, bool invert);
909 
910 /**
911  * @brief Register MCPWM interrupt handler, the handler is an ISR.
912  *        the handler will be attached to the same CPU core that this function is running on.
913  *
914  * @param mcpwm_num set MCPWM unit(0-1)
915  * @param fn interrupt handler function.
916  * @param arg user-supplied argument passed to the handler function.
917  * @param intr_alloc_flags flags used to allocate the interrupt. One or multiple (ORred)
918  *        ESP_INTR_FLAG_* values. see esp_intr_alloc.h for more info.
919  * @param handle pointer to return handle. If non-NULL, a handle for the interrupt will
920  *        be returned here.
921  *
922  * @return
923  *     - ESP_OK Success
924  *     - ESP_ERR_INVALID_ARG Function pointer error.
925  */
926 #ifndef __ZEPHYR__
927 esp_err_t mcpwm_isr_register(mcpwm_unit_t mcpwm_num, void (*fn)(void *), void *arg, int intr_alloc_flags,
928                              intr_handle_t *handle);
929 #endif
930 
931 #ifdef __cplusplus
932 }
933 #endif
934 
935 #endif  //SOC_MCPWM_SUPPORTED
936