1 /*
2  * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include "esp_bit_defs.h"
12 #include "soc/soc_caps.h"
13 #include "hal/mcpwm_types.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @brief IO signals for the MCPWM
21  *
22  *        - 6 MCPWM output pins that generate PWM signals
23  *        - 3 MCPWM fault input pins to detect faults like over-current, over-voltage, etc.
24  *        - 3 MCPWM sync input pins to synchronize MCPWM outputs signals
25  *        - 3 MCPWM capture input pins to gather feedback from controlled motors, using e.g. hall sensors
26  */
27 typedef enum {
28     MCPWM0A = 0,        /*!<PWM0A output pin*/
29     MCPWM0B,            /*!<PWM0B output pin*/
30     MCPWM1A,            /*!<PWM1A output pin*/
31     MCPWM1B,            /*!<PWM1B output pin*/
32     MCPWM2A,            /*!<PWM2A output pin*/
33     MCPWM2B,            /*!<PWM2B output pin*/
34     MCPWM_SYNC_0,       /*!<SYNC0  input pin*/
35     MCPWM_SYNC_1,       /*!<SYNC1  input pin*/
36     MCPWM_SYNC_2,       /*!<SYNC2  input pin*/
37     MCPWM_FAULT_0,      /*!<FAULT0 input pin*/
38     MCPWM_FAULT_1,      /*!<FAULT1 input pin*/
39     MCPWM_FAULT_2,      /*!<FAULT2 input pin*/
40     MCPWM_CAP_0 = 84,   /*!<CAP0   input pin*/
41     MCPWM_CAP_1,        /*!<CAP1   input pin*/
42     MCPWM_CAP_2,        /*!<CAP2   input pin*/
43 } mcpwm_io_signals_t;
44 
45 /**
46  * @brief pin number for MCPWM
47  */
48 typedef struct {
49     int mcpwm0a_out_num;       /*!<MCPWM0A out pin*/
50     int mcpwm0b_out_num;       /*!<MCPWM0A out pin*/
51     int mcpwm1a_out_num;       /*!<MCPWM0A out pin*/
52     int mcpwm1b_out_num;       /*!<MCPWM0A out pin*/
53     int mcpwm2a_out_num;       /*!<MCPWM0A out pin*/
54     int mcpwm2b_out_num;       /*!<MCPWM0A out pin*/
55     int mcpwm_sync0_in_num;    /*!<SYNC0  in pin*/
56     int mcpwm_sync1_in_num;    /*!<SYNC1  in pin*/
57     int mcpwm_sync2_in_num;    /*!<SYNC2  in pin*/
58     int mcpwm_fault0_in_num;   /*!<FAULT0 in pin*/
59     int mcpwm_fault1_in_num;   /*!<FAULT1 in pin*/
60     int mcpwm_fault2_in_num;   /*!<FAULT2 in pin*/
61     int mcpwm_cap0_in_num;     /*!<CAP0   in pin*/
62     int mcpwm_cap1_in_num;     /*!<CAP1   in pin*/
63     int mcpwm_cap2_in_num;     /*!<CAP2   in pin*/
64 } mcpwm_pin_config_t;
65 
66 /**
67  * @brief Select MCPWM unit
68  */
69 typedef enum {
70     MCPWM_UNIT_0,   /*!<MCPWM unit0 selected*/
71 #if SOC_MCPWM_GROUPS > 1
72     MCPWM_UNIT_1,   /*!<MCPWM unit1 selected*/
73 #endif
74     MCPWM_UNIT_MAX, /*!<Max number of MCPWM units*/
75 } mcpwm_unit_t;
76 
77 /**
78  * @brief Select MCPWM timer
79  */
80 typedef enum {
81     MCPWM_TIMER_0,   /*!<Select MCPWM timer0*/
82     MCPWM_TIMER_1,   /*!<Select MCPWM timer1*/
83     MCPWM_TIMER_2,   /*!<Select MCPWM timer2*/
84     MCPWM_TIMER_MAX, /*!<Max number of timers in a unit*/
85 } mcpwm_timer_t;
86 
87 /**
88  * @brief Select MCPWM operator
89  */
90 typedef enum {
91     MCPWM_GEN_A,   /*!<Select MCPWMXA, where 'X' is operator number*/
92     MCPWM_GEN_B,   /*!<Select MCPWMXB, where 'X' is operator number*/
93     MCPWM_GEN_MAX, /*!<Num of generators to each operator of MCPWM*/
94 } mcpwm_generator_t;
95 
96 //definitions and macros to be back-compatible before IDFv4.1
97 #define MCPWM_OPR_A     MCPWM_GEN_A         ///< @deprecated
98 #define MCPWM_OPR_B     MCPWM_GEN_B         ///< @deprecated
99 #define MCPWM_OPR_MAX   MCPWM_GEN_MAX       ///< @deprecated
100 typedef mcpwm_generator_t mcpwm_operator_t; ///< @deprecated
101 
102 /**
103  * @brief MCPWM carrier output inversion, high frequency carrier signal active with MCPWM signal is high
104  */
105 typedef enum {
106     MCPWM_CARRIER_OUT_IVT_DIS, /*!<Enable  carrier output inversion*/
107     MCPWM_CARRIER_OUT_IVT_EN,  /*!<Disable carrier output inversion*/
108 } mcpwm_carrier_out_ivt_t;
109 
110 /**
111  * @brief MCPWM select fault signal input
112  */
113 typedef enum {
114     MCPWM_SELECT_F0, /*!<Select F0 as input*/
115     MCPWM_SELECT_F1, /*!<Select F1 as input*/
116     MCPWM_SELECT_F2, /*!<Select F2 as input*/
117 } mcpwm_fault_signal_t;
118 
119 /**
120  * @brief MCPWM select sync signal input
121  */
122 typedef enum {
123     MCPWM_SELECT_NO_INPUT,        /*!<No sync input selected*/
124     MCPWM_SELECT_TIMER0_SYNC,     /*!<Select software sync signal from timer0 as input*/
125     MCPWM_SELECT_TIMER1_SYNC,     /*!<Select software sync signal from timer1 as input*/
126     MCPWM_SELECT_TIMER2_SYNC,     /*!<Select software sync signal from timer2 as input*/
127     MCPWM_SELECT_GPIO_SYNC0,      /*!<Select GPIO SYNC0 as input*/
128     MCPWM_SELECT_GPIO_SYNC1,      /*!<Select GPIO SYNC1 as input*/
129     MCPWM_SELECT_GPIO_SYNC2,      /*!<Select GPIO SYNC2 as input*/
130 } mcpwm_sync_signal_t;
131 
132 // backward compatibility
133 #define MCPWM_SELECT_SYNC0 MCPWM_SELECT_GPIO_SYNC0
134 #define MCPWM_SELECT_SYNC1 MCPWM_SELECT_GPIO_SYNC1
135 #define MCPWM_SELECT_SYNC2 MCPWM_SELECT_GPIO_SYNC2
136 
137 /**
138  * @brief MCPWM timer sync event trigger
139  */
140 typedef enum {
141     MCPWM_SWSYNC_SOURCE_SYNCIN,      /*!<the input sync signal will be routed to its sync output path*/
142     MCPWM_SWSYNC_SOURCE_TEZ,         /*!<sync signal generated when timer counts to zero*/
143     MCPWM_SWSYNC_SOURCE_TEP,         /*!<sync signal generated when timer counts to peak*/
144     MCPWM_SWSYNC_SOURCE_DISABLED,    /*!<timer does not generate sync signals*/
145 } mcpwm_timer_sync_trigger_t;
146 
147 /**
148  * @brief MCPWM select triggering level of fault signal
149  */
150 typedef enum {
151     MCPWM_LOW_LEVEL_TGR,  /*!<Fault condition occurs when fault input signal goes from high to low*/
152     MCPWM_HIGH_LEVEL_TGR, /*!<Fault condition occurs when fault input signal goes low to high*/
153 } mcpwm_fault_input_level_t;
154 
155 /**
156  * @brief MCPWM select capture starts from which edge
157  */
158 typedef enum {
159     MCPWM_NEG_EDGE = BIT(0),           /*!<Capture the negative edge*/
160     MCPWM_POS_EDGE = BIT(1),           /*!<Capture the positive edge*/
161     MCPWM_BOTH_EDGE = BIT(1) | BIT(0), /*!<Capture both edges*/
162 } mcpwm_capture_on_edge_t;
163 
164 /**
165  * @brief Select type of MCPWM counter
166  */
167 typedef enum {
168     MCPWM_FREEZE_COUNTER,   /*!<Counter freeze */
169     MCPWM_UP_COUNTER,       /*!<For asymmetric MCPWM*/
170     MCPWM_DOWN_COUNTER,     /*!<For asymmetric MCPWM*/
171     MCPWM_UP_DOWN_COUNTER,  /*!<For symmetric MCPWM, frequency is half of MCPWM frequency set*/
172     MCPWM_COUNTER_MAX,      /*!<Maximum counter mode*/
173 } mcpwm_counter_type_t;
174 
175 /**
176  * @brief Select type of MCPWM duty cycle mode
177  */
178 typedef enum {
179     MCPWM_DUTY_MODE_0 = 0,      /*!<Active high duty, i.e. duty cycle proportional to high time for asymmetric MCPWM*/
180     MCPWM_DUTY_MODE_1,          /*!<Active low duty,  i.e. duty cycle proportional to low  time for asymmetric MCPWM, out of phase(inverted) MCPWM*/
181     MCPWM_DUTY_MODE_FORCE_LOW,  /*!< Forced to output low level */
182     MCPWM_DUTY_MODE_FORCE_HIGH, /*!< Forced to output high level */
183     MCPWM_DUTY_MODE_MAX,        /*!<Num of duty cycle modes*/
184 } mcpwm_duty_type_t;
185 
186 #define MCPWM_HAL_GENERATOR_MODE_FORCE_LOW MCPWM_DUTY_MODE_FORCE_LOW    /*!< @deprecated Forced to output low level */
187 #define MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH MCPWM_DUTY_MODE_FORCE_HIGH  /*!< @deprecated Forced to output low level */
188 
189 /**
190  * @brief MCPWM deadtime types, used to generate deadtime, RED refers to rising edge delay and FED refers to falling edge delay
191  */
192 typedef enum {
193     MCPWM_DEADTIME_BYPASS = 0,          /*!<Bypass the deadtime*/
194     MCPWM_BYPASS_RED,                   /*!<MCPWMXA Out = MCPWMXA In with no delay, MCPWMXB Out = MCPWMXA In with falling edge delay*/
195     MCPWM_BYPASS_FED,                   /*!<MCPWMXA Out = MCPWMXA In with rising edge delay, MCPWMXB Out = MCPWMXB In with no delay*/
196     MCPWM_ACTIVE_HIGH_MODE,             /*!<MCPWMXA Out = MCPWMXA In with rising edge delay,  MCPWMXB Out = MCPWMXA In with falling edge delay*/
197     MCPWM_ACTIVE_LOW_MODE,              /*!<MCPWMXA Out = MCPWMXA In with compliment of rising edge delay,  MCPWMXB Out = MCPWMXA In with compliment of falling edge delay*/
198     MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE,  /*!<MCPWMXA Out = MCPWMXA In with rising edge delay,  MCPWMXB = MCPWMXA In with compliment of falling edge delay*/
199     MCPWM_ACTIVE_LOW_COMPLIMENT_MODE,   /*!<MCPWMXA Out = MCPWMXA In with compliment of rising edge delay,  MCPWMXB Out = MCPWMXA In with falling edge delay*/
200     MCPWM_ACTIVE_RED_FED_FROM_PWMXA,    /*!<MCPWMXA Out = MCPWMXB Out = MCPWMXA In with rising edge delay as well as falling edge delay*/
201     MCPWM_ACTIVE_RED_FED_FROM_PWMXB,    /*!<MCPWMXA Out = MCPWMXB Out = MCPWMXB In with rising edge delay as well as falling edge delay*/
202     MCPWM_DEADTIME_TYPE_MAX,            /*!<Maximum number of supported dead time modes*/
203 } mcpwm_deadtime_type_t;
204 
205 /**
206  * @brief MCPWM select action to be taken on the output when event happens
207  */
208 typedef enum {
209     MCPWM_ACTION_NO_CHANGE = 0,  /*!<No change in the output*/
210     MCPWM_ACTION_FORCE_LOW,      /*!<Make output low*/
211     MCPWM_ACTION_FORCE_HIGH,     /*!<Make output high*/
212     MCPWM_ACTION_TOGGLE,         /*!<Make output toggle*/
213 } mcpwm_output_action_t;
214 
215 /// @deprecated MCPWM select action to be taken on MCPWMXA when fault occurs
216 typedef mcpwm_output_action_t mcpwm_action_on_pwmxa_t;
217 #define MCPWM_NO_CHANGE_IN_MCPWMXA  MCPWM_ACTION_NO_CHANGE      /*!< @deprecated No change in MCPWMXA output*/
218 #define MCPWM_FORCE_MCPWMXA_LOW     MCPWM_ACTION_FORCE_LOW      /*!< @deprecated Make MCPWMXA output low*/
219 #define MCPWM_FORCE_MCPWMXA_HIGH    MCPWM_ACTION_FORCE_HIGH     /*!< @deprecated Make MCPWMXA output high*/
220 #define MCPWM_TOG_MCPWMXA           MCPWM_ACTION_TOGGLE         /*!< @deprecated Make MCPWMXA output toggle*/
221 
222 /// @deprecated MCPWM select action to be taken on MCPWMXB when fault occurs
223 typedef mcpwm_output_action_t mcpwm_action_on_pwmxb_t;
224 #define MCPWM_NO_CHANGE_IN_MCPWMXB  MCPWM_ACTION_NO_CHANGE      /*!< @deprecated No change in MCPWMXB output*/
225 #define MCPWM_FORCE_MCPWMXB_LOW     MCPWM_ACTION_FORCE_LOW      /*!< @deprecated Make MCPWMXB output low*/
226 #define MCPWM_FORCE_MCPWMXB_HIGH    MCPWM_ACTION_FORCE_HIGH     /*!< @deprecated Make MCPWMXB output high*/
227 #define MCPWM_TOG_MCPWMXB           MCPWM_ACTION_TOGGLE         /*!< @deprecated Make MCPWMXB output toggle*/
228 
229 /**
230  * @brief MCPWM select capture signal input
231  */
232 typedef enum {
233     MCPWM_SELECT_CAP0, /*!<Select CAP0 as input*/
234     MCPWM_SELECT_CAP1, /*!<Select CAP1 as input*/
235     MCPWM_SELECT_CAP2, /*!<Select CAP2 as input*/
236 } mcpwm_capture_signal_t;
237 
238 /**
239  * @brief MCPWM capture channel ID alias
240  */
241 typedef mcpwm_capture_signal_t mcpwm_capture_channel_id_t;
242 
243 /**
244  * @brief event data that will be passed into ISR callback
245  */
246 typedef struct {
247     mcpwm_capture_on_edge_t cap_edge;   /*!<Which signal edge is detected*/
248     uint32_t cap_value;                 /*!<Corresponding timestamp when event occurs. Clock rate = APB(usually 80M)*/
249 } cap_event_data_t;
250 
251 /**
252  * @brief Type of capture event callback
253  * @param mcpwm MCPWM unit(0-1)
254  * @param cap_channel capture channel ID
255  * @param edata Capture event data, contains capture edge and capture value, fed by the driver
256  * @param user_data User registered data, passed from `mcpwm_capture_config_t`
257  *
258  * @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)
259  *
260  * @return Whether a task switch is needed after the callback function returns,
261  *         this is usually due to the callback wakes up some high priority task.
262  *
263  */
264 typedef bool (*cap_isr_cb_t)(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_channel, const cap_event_data_t *edata,
265                              void *user_data);
266 
267 /**
268  * @brief MCPWM config structure
269  */
270 typedef struct {
271     uint32_t frequency;              /*!<Set frequency of MCPWM in Hz*/
272     float cmpr_a;                    /*!<Set % duty cycle for operator a(MCPWMXA), i.e for 62.3% duty cycle, duty_a = 62.3*/
273     float cmpr_b;                    /*!<Set % duty cycle for operator b(MCPWMXB), i.e for 48% duty cycle, duty_b = 48.0*/
274     mcpwm_duty_type_t duty_mode;     /*!<Set type of duty cycle*/
275     mcpwm_counter_type_t counter_mode;  /*!<Set  type of MCPWM counter*/
276 } mcpwm_config_t;
277 
278 /**
279  * @brief MCPWM carrier configuration structure
280  */
281 typedef struct {
282     uint8_t carrier_period;                    /*!<Set carrier period = (carrier_period + 1)*800ns, carrier_period should be < 16*/
283     uint8_t carrier_duty;                      /*!<Set carrier duty cycle, carrier_duty should be less than 8 (increment every 12.5%)*/
284     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*/
285     mcpwm_carrier_out_ivt_t carrier_ivt_mode;  /*!<Invert output of carrier*/
286 } mcpwm_carrier_config_t;
287 
288 /**
289  * @brief MCPWM config capture structure
290  */
291 typedef struct {
292     mcpwm_capture_on_edge_t cap_edge;      /*!<Set capture edge*/
293     uint32_t cap_prescale;                 /*!<Prescale of capture signal, ranging from 1 to 256*/
294     cap_isr_cb_t capture_cb;               /*!<User defined capture event callback, running under interrupt context */
295     void *user_data;                       /*!<User defined ISR callback function args*/
296 } mcpwm_capture_config_t;
297 
298 /**
299  * @brief MCPWM config sync structure
300  */
301 typedef struct {
302     mcpwm_sync_signal_t sync_sig;              /*!<Set sync input signal that will cause timer to sync*/
303     uint32_t timer_val;                        /*!<Counter value to be set after sync, in 0 ~ 999, unit: 1 / 1000 * peak*/
304     mcpwm_timer_direction_t count_direction;   /*!<Counting direction to be set after sync */
305 } mcpwm_sync_config_t;
306 
307 #ifdef __cplusplus
308 }
309 #endif
310