• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 /*******************************************************************************
16  * NOTICE
17  * The hal is not public api, don't use in application code.
18  * See readme.md in hal/include/hal/readme.md
19  ******************************************************************************/
20 
21 // The LL layer for ESP32 MCPWM register operations
22 
23 #pragma once
24 
25 #include "soc/soc_caps.h"
26 #include <soc/mcpwm_periph.h>
27 #include "soc/mcpwm_periph.h"
28 #include "hal/mcpwm_types.h"
29 #include "hal/hal_defs.h"
30 
31 #include "esp_types.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /// Get the address of peripheral registers
38 #define MCPWM_LL_GET_HW(ID) (((ID)==0)? &MCPWM0: &MCPWM1)
39 
40 
41 /********************* Global *******************/
42 /**
43  * Initialize common registers.
44  *
45  * @param mcpwm Address of the MCPWM peripheral registers.
46  */
mcpwm_ll_init(mcpwm_dev_t * mcpwm)47 static inline void mcpwm_ll_init(mcpwm_dev_t *mcpwm)
48 {
49     mcpwm->update_cfg.global_up_en = 1;
50     mcpwm->update_cfg.global_force_up = 1;
51     mcpwm->update_cfg.global_force_up = 0;
52 }
53 
54 /**
55  * Set the prescale of the PWM main clock to the input clock.
56  *
57  * Input clock is 160MHz, PWM main clock cycle = 6.25ns*(prescale + 1).
58  *
59  * @param mcpwm Address of the MCPWM peripheral registers.
60  * @param prescale Prescale factor, 0-255.
61  */
mcpwm_ll_set_clock_prescale(mcpwm_dev_t * mcpwm,int prescale)62 static inline void mcpwm_ll_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale)
63 {
64     mcpwm->clk_cfg.prescale = prescale;
65 }
66 
67 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP0, MCPWM_CAP0_INT_RAW);
68 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP1, MCPWM_CAP1_INT_RAW);
69 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP2, MCPWM_CAP2_INT_RAW);
70 
71 /**
72  * Get raw interrupt status.
73  *
74  * @param mcpwm Address of the MCPWM peripheral registers.
75  * @return The triggered interrupts, ORed by active interrupts.
76  */
mcpwm_ll_get_intr(mcpwm_dev_t * mcpwm)77 static inline mcpwm_intr_t mcpwm_ll_get_intr(mcpwm_dev_t *mcpwm)
78 {
79     return mcpwm->int_raw.val;
80 }
81 
82 /**
83  * Clear the interrupts.
84  *
85  * @param mcpwm Address of the MCPWM peripheral registers.
86  * @param intr Bitwise ORed interrupts to clear.
87  */
mcpwm_ll_clear_intr(mcpwm_dev_t * mcpwm,mcpwm_intr_t intr)88 static inline void mcpwm_ll_clear_intr(mcpwm_dev_t* mcpwm, mcpwm_intr_t intr)
89 {
90     mcpwm->int_clr.val = intr;
91 }
92 
93 /********************* Timer *******************/
94 /**
95  * Set the prescale of the Timer_x clock to the PWM main clock.
96  *
97  * Timer clock frequency = PWM main clock frequency/(prescale + 1).
98  *
99  * @param mcpwm Address of the MCPWM peripheral registers.
100  * @param timer The timer to set the prescale, 0-2.
101  * @param prescale Prescale factor, 0-255.
102  */
mcpwm_ll_timer_set_prescale(mcpwm_dev_t * mcpwm,int timer,uint32_t prescale)103 static inline void mcpwm_ll_timer_set_prescale(mcpwm_dev_t* mcpwm, int timer, uint32_t prescale)
104 {
105     mcpwm->timer[timer].period.prescale = prescale;
106 }
107 
108 
109 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_UP_COUNTER,        1);
110 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_DOWN_COUNTER,      2);
111 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_UP_DOWN_COUNTER,   3);
112 
113 /**
114  * Set the counting mode for the PWM timer.
115  *
116  * @param mcpwm Address of the MCPWM peripheral registers.
117  * @param timer The timer to change counting mode, 0-2.
118  * @param mode Counting mode to use.
119  */
mcpwm_ll_timer_set_count_mode(mcpwm_dev_t * mcpwm,int timer,mcpwm_counter_type_t mode)120 static inline void mcpwm_ll_timer_set_count_mode(mcpwm_dev_t *mcpwm, int timer, mcpwm_counter_type_t mode)
121 {
122     mcpwm->timer[timer].mode.mode = mode;
123 }
124 
125 /**
126  * Start a timer.
127  *
128  * @param mcpwm Address of the MCPWM peripheral registers.
129  * @param timer The timer to start, 0-2.
130  */
mcpwm_ll_timer_start(mcpwm_dev_t * mcpwm,int timer)131 static inline void mcpwm_ll_timer_start(mcpwm_dev_t *mcpwm, int timer)
132 {
133     mcpwm->timer[timer].mode.start = 2;
134 }
135 
136 /**
137  * Stop a timer.
138  *
139  * @param mcpwm Address of the MCPWM peripheral registers.
140  * @param timer The timer to stop, 0-2.
141  */
mcpwm_ll_timer_stop(mcpwm_dev_t * mcpwm,int timer)142 static inline void mcpwm_ll_timer_stop(mcpwm_dev_t *mcpwm, int timer)
143 {
144     mcpwm->timer[timer].mode.start = 0;
145 }
146 
147 /**
148  * Set the overflow period of a timer.
149  *
150  * The overflow rate will be Frequency of timer / period.
151  *
152  * @param mcpwm Address of the MCPWM peripheral registers.
153  * @param timer The timer to set period, 0-2.
154  * @param period Total timer count of each period, 0-65535.
155  */
mcpwm_ll_timer_set_period(mcpwm_dev_t * mcpwm,int timer,uint32_t period)156 static inline void mcpwm_ll_timer_set_period(mcpwm_dev_t *mcpwm, int timer, uint32_t period)
157 {
158 
159     mcpwm->timer[timer].period.period = period - 1;
160     mcpwm->timer[timer].period.upmethod = 0;
161 }
162 
163 /**
164  * Get the period setting of a timer.
165  *
166  * @param mcpwm Address of the MCPWM peripheral registers.
167  * @param timer The timer to get the period, 0-2.
168  * @return Period setting value.
169  */
mcpwm_ll_timer_get_period(mcpwm_dev_t * mcpwm,int timer)170 static inline uint32_t mcpwm_ll_timer_get_period(mcpwm_dev_t *mcpwm, int timer)
171 {
172     return mcpwm->timer[timer].period.period + 1;
173 }
174 
175 /********************* Sync *******************/
176 /**
177  * Enable the synchronization feature for a timer.
178  *
179  * @param mcpwm Address of the MCPWM peripheral registers.
180  * @param timer Timer to set, 0-2.
181  * @param enable true to enable, otherwise false.
182  */
mcpwm_ll_sync_enable(mcpwm_dev_t * mcpwm,int timer,bool enable)183 static inline void mcpwm_ll_sync_enable(mcpwm_dev_t *mcpwm, int timer, bool enable)
184 {
185     if (enable) {
186         mcpwm->timer[timer].sync.out_sel = 0;
187         mcpwm->timer[timer].sync.in_en = 1;
188     } else {
189         mcpwm->timer[timer].sync.in_en = 0;
190     }
191 }
192 
193 /**
194  * Set the phase (counter value) to reload when the sync signal triggers.
195  *
196  * @param mcpwm Address of the MCPWM peripheral registers.
197  * @param timer Timer to set, 0-2.
198  * @param reload_val The reloaded value.
199  */
mcpwm_ll_sync_set_phase(mcpwm_dev_t * mcpwm,int timer,uint32_t reload_val)200 static inline void mcpwm_ll_sync_set_phase(mcpwm_dev_t *mcpwm, int timer, uint32_t reload_val)
201 {
202     mcpwm->timer[timer].sync.timer_phase = reload_val;
203 }
204 
205 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC0, 4);
206 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC1, 5);
207 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC2, 6);
208 /**
209  * Set the sync signal source for a timer.
210  *
211  * @param mcpwm Address of the MCPWM peripheral registers.
212  * @param timer The timer to set, 0-2.
213  * @param sync_sig The synchronization signal to use.
214  */
mcpwm_ll_sync_set_input(mcpwm_dev_t * mcpwm,int timer,mcpwm_sync_signal_t sync_sig)215 static inline void mcpwm_ll_sync_set_input(mcpwm_dev_t *mcpwm, int timer, mcpwm_sync_signal_t sync_sig)
216 {
217     if (timer == 0) {
218         mcpwm->timer_synci_cfg.t0_in_sel = sync_sig;
219     } else if (timer == 1) {
220         mcpwm->timer_synci_cfg.t1_in_sel = sync_sig;
221     } else {   //MCPWM_TIMER_2
222         mcpwm->timer_synci_cfg.t2_in_sel = sync_sig;
223     }
224 }
225 
226 /********************* Comparator *******************/
227 /**
228  * Select a timer for the specified operator to use.
229  *
230  * @param mcpwm Address of the MCPWM peripheral registers.
231  * @param op    The operator to choose timer, 0-2.
232  * @param timer The timer to use, 0-2.
233  */
mcpwm_ll_operator_select_timer(mcpwm_dev_t * mcpwm,int op,int timer)234 static inline void mcpwm_ll_operator_select_timer(mcpwm_dev_t *mcpwm, int op, int timer)
235 {
236     if (op == 0) {
237         mcpwm->timer_sel.operator0_sel = timer;
238     } else if (op == 1) {
239         mcpwm->timer_sel.operator1_sel = timer;
240     } else {
241         mcpwm->timer_sel.operator2_sel = timer;
242     }
243 }
244 
245 /**
246  * Set the update method of the compare value of a timer
247  *
248  * @param mcpwm Address of the MCPWM peripheral registers.
249  * @param op    Operator to set, 0-2.
250  */
mcpwm_ll_operator_set_compare_upmethod(mcpwm_dev_t * mcpwm,int op)251 static inline void mcpwm_ll_operator_set_compare_upmethod(mcpwm_dev_t *mcpwm, int op)
252 {
253     mcpwm->channel[op].cmpr_cfg.a_upmethod = BIT(0);
254     mcpwm->channel[op].cmpr_cfg.b_upmethod = BIT(0);
255 }
256 
257 /**
258  * Get one of the compare value of a timer.
259  *
260  * @param mcpwm Address of the MCPWM peripheral registers.
261  * @param op    The operator to get, 0-2.
262  * @param cmp_n Comparer id to get, 0-1.
263  * @return The set compare value.
264  */
mcpwm_ll_operator_get_compare(mcpwm_dev_t * mcpwm,int op,int cmp_n)265 static inline uint32_t mcpwm_ll_operator_get_compare(mcpwm_dev_t *mcpwm, int op, int cmp_n)
266 {
267     return (mcpwm->channel[op].cmpr_value[cmp_n].cmpr_val);
268 }
269 
270 /**
271  * Set one of the compare value of a timer.
272  *
273  * @param mcpwm Address of the MCPWM peripheral registers.
274  * @param op    The operator to set, 0-2.
275  * @param cmp_n The comparer to set value, 0-1.
276  * @param compare The compare value, 0-65535.
277  */
mcpwm_ll_operator_set_compare(mcpwm_dev_t * mcpwm,int op,int cmp_n,uint32_t compare)278 static inline void mcpwm_ll_operator_set_compare(mcpwm_dev_t *mcpwm, int op, int cmp_n, uint32_t compare)
279 {
280     mcpwm->channel[op].cmpr_value[cmp_n].cmpr_val = compare;
281 }
282 
283 /********************* Generator *******************/
284 
285 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_NO_CHANGE, 0);
286 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_FORCE_LOW, 1);
287 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_FORCE_HIGH, 2);
288 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_TOGGLE,     3);
289 /**
290  * Set the action will be taken by a operator when its timer counts to zero.
291  *
292  * @param mcpwm Address of the MCPWM peripheral registers.
293  * @param op     The operator to set action, 0-2.
294  * @param gen    One generator of the operator to take the action, 0-1.
295  * @param action Action to take.
296  */
mcpwm_ll_gen_set_zero_action(mcpwm_dev_t * mcpwm,int op,int gen,mcpwm_output_action_t action)297 static inline void mcpwm_ll_gen_set_zero_action(mcpwm_dev_t *mcpwm, int op, int gen, mcpwm_output_action_t action)
298 {
299     mcpwm->channel[op].generator[gen].utez = action;
300     mcpwm->channel[op].generator[gen].dtez = action;
301 }
302 
303 /**
304  * Set the action will be taken by a operator when its timer counts to the period value.
305  *
306  * @param mcpwm Address of the MCPWM peripheral registers.
307  * @param op     The operator to set action, 0-2.
308  * @param gen    One generator of the operator to take the action, 0-1.
309  * @param action Action to take.
310  */
mcpwm_ll_gen_set_period_action(mcpwm_dev_t * mcpwm,int op,int gen,mcpwm_output_action_t action)311 static inline void mcpwm_ll_gen_set_period_action(mcpwm_dev_t *mcpwm, int op, int gen, mcpwm_output_action_t action)
312 {
313     mcpwm->channel[op].generator[gen].utep = action;
314     mcpwm->channel[op].generator[gen].dtep = action;
315 }
316 
317 /**
318  * Set the action will be taken by a operator when its timer counts to the compare value.
319  *
320  * @param mcpwm Address of the MCPWM peripheral registers.
321  * @param op        The operator to set action, 0-2.
322  * @param gen       One generator of the operator to take the action, 0-1.
323  * @param cmp_n     The comparer to use.
324  * @param up_action The action to take when the counter is counting up.
325  * @param down_action The action to take when the counter is counting down.
326  */
mcpwm_ll_gen_set_cmp_action(mcpwm_dev_t * mcpwm,int op,int gen,int cmp_n,mcpwm_output_action_t up_action,mcpwm_output_action_t down_action)327 static inline void mcpwm_ll_gen_set_cmp_action(mcpwm_dev_t *mcpwm, int op, int gen,
328                int cmp_n, mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
329 {
330     if (cmp_n == 0) {
331         mcpwm->channel[op].generator[gen].utea = up_action;
332         mcpwm->channel[op].generator[gen].dtea = down_action;
333     } else {
334         mcpwm->channel[op].generator[gen].uteb = up_action;
335         mcpwm->channel[op].generator[gen].dteb = down_action;
336     }
337 }
338 
339 /********************* Fault *******************/
340 /**
341  * Enable the fault detection feature for an input signal.
342  *
343  * @param mcpwm Address of the MCPWM peripheral registers.
344  * @param fault_sig One of the signals to select, 0-2.
345  * @param level The active level of the fault-detection signal.
346  */
mcpwm_ll_fault_enable(mcpwm_dev_t * mcpwm,int fault_sig,bool level)347 static inline void mcpwm_ll_fault_enable(mcpwm_dev_t *mcpwm, int fault_sig, bool level)
348 {
349     if (fault_sig == 0) {
350         mcpwm->fault_detect.f0_en = 1;
351         mcpwm->fault_detect.f0_pole = level;
352     } else if (fault_sig == 1) {
353         mcpwm->fault_detect.f1_en = 1;
354         mcpwm->fault_detect.f1_pole = level;
355     } else {   //MCPWM_SELECT_F2
356         mcpwm->fault_detect.f2_en = 1;
357         mcpwm->fault_detect.f2_pole = level;
358     }
359 }
360 
361 /**
362  * Disable the fault detection of an input signal.
363  * @param mcpwm Address of the MCPWM peripheral registers.
364  * @param fault_sig The signal to disable, 0-2.
365  */
mcpwm_ll_fault_disable(mcpwm_dev_t * mcpwm,int fault_sig)366 static inline void mcpwm_ll_fault_disable(mcpwm_dev_t *mcpwm, int fault_sig)
367 {
368     if (fault_sig == 0) {
369         mcpwm->fault_detect.f0_en = 0;
370     } else if (fault_sig == 1) {
371         mcpwm->fault_detect.f1_en = 0;
372     } else {   //MCPWM_SELECT_F2
373         mcpwm->fault_detect.f2_en = 0;
374     }
375 }
376 
377 /**
378  * Clear the oneshot fault status of an operator.
379  *
380  * @param mcpwm Address of the MCPWM peripheral registers.
381  * @param op The operator to clear, 0-2.
382  */
mcpwm_ll_fault_clear_ost(mcpwm_dev_t * mcpwm,int op)383 static inline void mcpwm_ll_fault_clear_ost(mcpwm_dev_t *mcpwm, int op)
384 {
385     mcpwm->channel[op].tz_cfg1.clr_ost = 1;
386     mcpwm->channel[op].tz_cfg1.clr_ost = 0;
387 }
388 
389 /**
390  * Use the oneshot mode to handle the fault when it occurs
391  *
392  * @param mcpwm Address of the MCPWM peripheral registers.
393  * @param op     The operator to handle the fault signal, 0-2.
394  * @param signal The fault signal to set, 0-2.
395  * @param enable true to enable oneshot, otherwise false.
396  */
mcpwm_ll_fault_oneshot_enable_signal(mcpwm_dev_t * mcpwm,int op,int signal,bool enable)397 static inline void mcpwm_ll_fault_oneshot_enable_signal(mcpwm_dev_t *mcpwm, int op, int signal, bool enable)
398 {
399     if (signal == 0) {
400         mcpwm->channel[op].tz_cfg0.f0_ost = enable;
401     } else if (signal == 1) {
402         mcpwm->channel[op].tz_cfg0.f1_ost = enable;
403     } else {   //MCPWM_SELECT_F2
404         mcpwm->channel[op].tz_cfg0.f2_ost = enable;
405     }
406 }
407 
408 /**
409  * @brief Get the oneshot enabled status of the operator
410  *
411  * @param mcpwm Address of the MCPWM peripheral registers.
412  * @param op     The operator to check, 0-2.
413  * @param signal The fault signal to get, 0-2.
414  */
mcpwm_ll_fault_oneshot_signal_enabled(mcpwm_dev_t * mcpwm,int op,int signal)415 static inline bool mcpwm_ll_fault_oneshot_signal_enabled(mcpwm_dev_t *mcpwm, int op, int signal)
416 {
417     if (signal == 0) {
418         return mcpwm->channel[op].tz_cfg0.f0_ost;
419     } else if (signal == 1) {
420         return mcpwm->channel[op].tz_cfg0.f1_ost;
421     } else {   //MCPWM_SELECT_F2
422         return mcpwm->channel[op].tz_cfg0.f2_ost;
423     }
424 }
425 
426 /**
427  * Use the CBC (cycle-by-cycle) mode to handle the fault when it occurs.
428  *
429  * @param mcpwm Address of the MCPWM peripheral registers.
430  * @param op     The operator to handle the fault signal, 0-2.
431  * @param signal The fault signal to set, 0-2.
432  * @param enable true to enable cbc mode, otherwise false.
433  */
mcpwm_ll_fault_cbc_enable_signal(mcpwm_dev_t * mcpwm,int op,int signal,bool enable)434 static inline void mcpwm_ll_fault_cbc_enable_signal(mcpwm_dev_t *mcpwm, int op, int signal, bool enable)
435 {
436     if (signal == 0) {
437         mcpwm->channel[op].tz_cfg0.f0_cbc = enable;
438     } else if (signal == 1) {
439         mcpwm->channel[op].tz_cfg0.f1_cbc = enable;
440     } else {   //MCPWM_SELECT_F2
441         mcpwm->channel[op].tz_cfg0.f2_cbc = enable;
442     }
443 }
444 
445 /**
446  * Set the action that will be taken when the fault is handled by oneshot.
447  *
448  * @param mcpwm Address of the MCPWM peripheral registers.
449  * @param op     The operator to handle the fault signal, 0-2.
450  * @param gen    The generator to take the action, 0-1.
451  * @param up_action     Action to take when fault happens when counting up.
452  * @param down_action   Action to take when fault happens when counting down.
453  */
mcpwm_ll_fault_set_oneshot_action(mcpwm_dev_t * mcpwm,int op,int gen,mcpwm_output_action_t up_action,mcpwm_output_action_t down_action)454 static inline void mcpwm_ll_fault_set_oneshot_action(mcpwm_dev_t *mcpwm, int op, int gen,
455         mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
456 {
457     if (gen == 0) {
458         mcpwm->channel[op].tz_cfg0.a_ost_u = up_action;
459         mcpwm->channel[op].tz_cfg0.a_ost_d = down_action;
460     } else {
461         mcpwm->channel[op].tz_cfg0.b_ost_u = up_action;
462         mcpwm->channel[op].tz_cfg0.b_ost_d = down_action;
463     }
464 }
465 
466 /**
467  * Set the action that will be taken when the fault is handled cycle by cycle.
468  *
469  * @param mcpwm Address of the MCPWM peripheral registers.
470  * @param op     The operator to handle the fault signal, 0-2.
471  * @param gen    The generator to take the action, 0-1.
472  * @param up_action     Action to take when fault happens when counting up.
473  * @param down_action   Action to take when fault happens when counting down.
474  */
mcpwm_ll_fault_set_cyc_action(mcpwm_dev_t * mcpwm,int op,int gen,mcpwm_output_action_t up_action,mcpwm_output_action_t down_action)475 static inline void mcpwm_ll_fault_set_cyc_action(mcpwm_dev_t *mcpwm, int op, int gen,
476                   mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
477 {
478     mcpwm->channel[op].tz_cfg1.cbcpulse = BIT(0);    //immediately
479     if (gen == 0) {
480         mcpwm->channel[op].tz_cfg0.a_cbc_u = up_action;
481         mcpwm->channel[op].tz_cfg0.a_cbc_d = down_action;
482     } else {
483         mcpwm->channel[op].tz_cfg0.b_cbc_u = up_action;
484         mcpwm->channel[op].tz_cfg0.b_cbc_d = down_action;
485     }
486 }
487 
488 /********************* Dead Zone (deadtime) *******************/
489 /**
490  * Initialize the dead zone feature.
491  *
492  * @param mcpwm Address of the MCPWM peripheral registers.
493  * @param op The operator to initialize, 0-2.
494  */
mcpwm_ll_deadtime_init(mcpwm_dev_t * mcpwm,int op)495 static inline void mcpwm_ll_deadtime_init(mcpwm_dev_t *mcpwm, int op)
496 {
497     mcpwm->channel[op].db_cfg.fed_upmethod = BIT(0);
498     mcpwm->channel[op].db_cfg.red_upmethod = BIT(0);
499     mcpwm->channel[op].db_cfg.clk_sel = 0;
500 }
501 
502 /**
503  * Set the output dead zone mode applying to the outputs of a timer.
504  *
505  * If the desired internal connection is not provided, you can write your own inside this function.
506  *
507  * @param mcpwm Address of the MCPWM peripheral registers.
508  * @param op    The operator to set, 0-2.
509  * @param mode  Dead zone mode to use.
510  */
mcpwm_ll_set_deadtime_mode(mcpwm_dev_t * mcpwm,int op,mcpwm_deadtime_type_t mode)511 static inline void mcpwm_ll_set_deadtime_mode(mcpwm_dev_t *mcpwm,
512     int op, mcpwm_deadtime_type_t mode)
513 {
514 #define MCPWM_LL_DEADTIME_REG_MASK (MCPWM_DT0_DEB_MODE_M | MCPWM_DT0_A_OUTSWAP_M | MCPWM_DT0_B_OUTSWAP_M | \
515     MCPWM_DT0_RED_INSEL_M | MCPWM_DT0_FED_INSEL_M | MCPWM_DT0_RED_OUTINVERT_M | MCPWM_DT0_FED_OUTINVERT_M | \
516     MCPWM_DT0_A_OUTBYPASS_M | MCPWM_DT0_B_OUTBYPASS_M)
517 
518     static uint32_t deadtime_mode_settings[MCPWM_DEADTIME_TYPE_MAX] = {
519         [MCPWM_BYPASS_RED] =                    0b010010000 << MCPWM_DT0_DEB_MODE_S,
520         [MCPWM_BYPASS_FED] =                    0b100000000 << MCPWM_DT0_DEB_MODE_S,
521         [MCPWM_ACTIVE_HIGH_MODE] =              0b000010000 << MCPWM_DT0_DEB_MODE_S,
522         [MCPWM_ACTIVE_LOW_MODE] =               0b001110000 << MCPWM_DT0_DEB_MODE_S,
523         [MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE] =   0b001010000 << MCPWM_DT0_DEB_MODE_S,
524         [MCPWM_ACTIVE_LOW_COMPLIMENT_MODE] =    0b000101000 << MCPWM_DT0_DEB_MODE_S,
525         [MCPWM_ACTIVE_RED_FED_FROM_PWMXA] =     0b000000011 << MCPWM_DT0_DEB_MODE_S,
526         [MCPWM_ACTIVE_RED_FED_FROM_PWMXB] =     0b000001011 << MCPWM_DT0_DEB_MODE_S,
527         [MCPWM_DEADTIME_BYPASS] =               0b110000000 << MCPWM_DT0_DEB_MODE_S,
528     };
529     mcpwm->channel[op].db_cfg.val =
530         (mcpwm->channel[op].db_cfg.val & (~MCPWM_LL_DEADTIME_REG_MASK)) | deadtime_mode_settings[mode];
531 
532 #undef MCPWM_LL_DEADTIME_REG_MASK
533 }
534 
535 /**
536  * Set the delay of the falling edge on the output.
537  *
538  * @param mcpwm Address of the MCPWM peripheral registers.
539  * @param op    The operator to set, 0-2.
540  * @param fed   Falling delay, by PWM main clock.
541  */
mcpwm_ll_deadtime_set_falling_delay(mcpwm_dev_t * mcpwm,int op,uint32_t fed)542 static inline void mcpwm_ll_deadtime_set_falling_delay(mcpwm_dev_t *mcpwm, int op, uint32_t fed)
543 {
544     mcpwm->channel[op].db_fed_cfg.fed = fed;
545 }
546 
547 /**
548  * Set the delay of the rising edge on the output.
549  *
550  * @param mcpwm Address of the MCPWM peripheral registers.
551  * @param op    The operator to set, 0-2.
552  * @param fed   Rising delay, by PWM main clock.
553  */
mcpwm_ll_deadtime_set_rising_delay(mcpwm_dev_t * mcpwm,int op,uint32_t red)554 static inline void mcpwm_ll_deadtime_set_rising_delay(mcpwm_dev_t *mcpwm, int op, uint32_t red)
555 {
556     mcpwm->channel[op].db_red_cfg.red = red;
557 }
558 
559 /**
560  * Disable (bypass) the dead zone feature.
561  *
562  * @param mcpwm Address of the MCPWM peripheral registers.
563  * @param op The operator to set, 0-2.
564  */
mcpwm_ll_deadtime_bypass(mcpwm_dev_t * mcpwm,int op)565 static inline void mcpwm_ll_deadtime_bypass(mcpwm_dev_t *mcpwm, int op)
566 {
567     mcpwm_ll_set_deadtime_mode(mcpwm, op, MCPWM_DEADTIME_BYPASS);
568 }
569 
570 /********************* Carrier *******************/
571 /**
572  * Initialize the carrier feature.
573  *
574  * @param mcpwm Address of the MCPWM peripheral registers.
575  * @param op The operator to set, 0-2.
576  */
mcpwm_ll_carrier_init(mcpwm_dev_t * mcpwm,int op)577 static inline void mcpwm_ll_carrier_init(mcpwm_dev_t *mcpwm, int op)
578 {
579     mcpwm->channel[op].carrier_cfg.in_invert = 0;
580 }
581 
582 /**
583  * Enable the carrier feature for a timer.
584  *
585  * @param mcpwm Address of the MCPWM peripheral registers.
586  * @param op The operator to set, 0-2.
587  * @param enable true to enable, otherwise false.
588  */
mcpwm_ll_carrier_enable(mcpwm_dev_t * mcpwm,int op,bool enable)589 static inline void mcpwm_ll_carrier_enable(mcpwm_dev_t *mcpwm, int op, bool enable)
590 {
591     mcpwm->channel[op].carrier_cfg.en = enable;
592 }
593 
594 /**
595  * Set the prescale of the carrier timer.
596  *
597  * The carrier period will be Frequency of PWM main clock/(carrier_period+1).
598  *
599  * @param mcpwm Address of the MCPWM peripheral registers.
600  * @param op The operator to set, 0-2.
601  * @param carrier_period The prescale of the carrier clock, 0-15.
602  */
mcpwm_ll_carrier_set_prescale(mcpwm_dev_t * mcpwm,int op,uint8_t carrier_period)603 static inline void mcpwm_ll_carrier_set_prescale(mcpwm_dev_t *mcpwm, int op, uint8_t carrier_period)
604 {
605     mcpwm->channel[op].carrier_cfg.prescale = carrier_period;
606 }
607 
608 /**
609  * Set the duty rate of the carrier.
610  *
611  * @param mcpwm Address of the MCPWM peripheral registers.
612  * @param op The operator to set, 0-2.
613  * @param carrier_duty Duty rate will be (carrier_duty/8)*100%. 0-7.
614  */
mcpwm_ll_carrier_set_duty(mcpwm_dev_t * mcpwm,int op,uint8_t carrier_duty)615 static inline void mcpwm_ll_carrier_set_duty(mcpwm_dev_t *mcpwm, int op, uint8_t carrier_duty)
616 {
617     mcpwm->channel[op].carrier_cfg.duty = carrier_duty;
618 }
619 
620 /**
621  * Invert output of the carrier.
622  *
623  * @param mcpwm Address of the MCPWM peripheral registers.
624  * @param op The operator to set, 0-2.
625  * @param invert true to invert, otherwise false.
626  */
mcpwm_ll_carrier_out_invert(mcpwm_dev_t * mcpwm,int op,bool invert)627 static inline void mcpwm_ll_carrier_out_invert(mcpwm_dev_t *mcpwm, int op, bool invert)
628 {
629     mcpwm->channel[op].carrier_cfg.out_invert = invert;
630 }
631 
632 /**
633  * Set the oneshot pulse width of the carrier.
634  *
635  * @param mcpwm Address of the MCPWM peripheral registers.
636  * @param op The operator to set, 0-2.
637  * @param pulse_width The width of the oneshot pulse, by carrier period. 0 to disable the oneshot pulse.
638  */
mcpwm_ll_carrier_set_oneshot_width(mcpwm_dev_t * mcpwm,int op,uint8_t pulse_width)639 static inline void mcpwm_ll_carrier_set_oneshot_width(mcpwm_dev_t *mcpwm, int op, uint8_t pulse_width)
640 {
641     mcpwm->channel[op].carrier_cfg.oshtwth = pulse_width;
642 }
643 
644 /********************* Capture *******************/
645 /**
646  * Enable the capture feature for a signal
647  *
648  * @param mcpwm Address of the MCPWM peripheral registers.
649  * @param cap_sig Signal to enable, 0-2.
650  * @param enable true to enable, otherwise false.
651  */
mcpwm_ll_capture_enable(mcpwm_dev_t * mcpwm,int cap_sig,int enable)652 static inline void mcpwm_ll_capture_enable(mcpwm_dev_t *mcpwm, int cap_sig, int enable)
653 {
654     if (enable) {
655         mcpwm->cap_timer_cfg.timer_en = 1;
656         mcpwm->cap_cfg_ch[cap_sig].en = 1;
657     } else {
658         mcpwm->cap_cfg_ch[cap_sig].en = 0;
659     }
660 }
661 
662 /**
663  * Get the captured value.
664  *
665  * @param mcpwm Address of the MCPWM peripheral registers.
666  * @param cap_sig Of which signal to get the captured value.
667  * @return The captured value
668  */
mcpwm_ll_get_capture_val(mcpwm_dev_t * mcpwm,int cap_sig)669 static inline uint32_t mcpwm_ll_get_capture_val(mcpwm_dev_t *mcpwm, int cap_sig)
670 {
671     return mcpwm->cap_val_ch[cap_sig];
672 }
673 
674 /**
675  * Get the set capture edge.
676  *
677  * @param mcpwm Address of the MCPWM peripheral registers.
678  * @param cap_sig Which signal the edge capture is applied.
679  * @return Capture signal edge: 1 - positive edge, 2 - negtive edge
680  */
mcpwm_ll_get_captured_edge(mcpwm_dev_t * mcpwm,int cap_sig)681 static inline mcpwm_capture_on_edge_t mcpwm_ll_get_captured_edge(mcpwm_dev_t *mcpwm, int cap_sig)
682 {
683     bool edge;
684     if (cap_sig == 0) {
685         edge = mcpwm->cap_status.cap0_edge;
686     } else if (cap_sig == 1) {
687         edge = mcpwm->cap_status.cap1_edge;
688     } else {   //2
689         edge = mcpwm->cap_status.cap2_edge;
690     }
691     return (edge? MCPWM_NEG_EDGE: MCPWM_POS_EDGE);
692 }
693 
694 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_NEG_EDGE, BIT(0));
695 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_POS_EDGE, BIT(1));
696 
697 /**
698  * Select the edge to capture.
699  *
700  * @param mcpwm Address of the MCPWM peripheral registers.
701  * @param cap_sig   The signal to capture, 0-2.
702  * @param cap_edge  The edge to capture, bitwise.
703  */
mcpwm_ll_capture_select_edge(mcpwm_dev_t * mcpwm,int cap_sig,mcpwm_capture_on_edge_t cap_edge)704 static inline void mcpwm_ll_capture_select_edge(mcpwm_dev_t *mcpwm, int cap_sig,
705                                   mcpwm_capture_on_edge_t cap_edge)
706 {
707     mcpwm->cap_cfg_ch[cap_sig].mode = cap_edge;
708 }
709 
710 /**
711  * Set the prescale of the input signal to capture.
712  *
713  * @param mcpwm Address of the MCPWM peripheral registers.
714  * @param cap_sig   The prescaled signal to capture, 0-2.
715  * @param prescale  Prescal value, 0 to disable.
716  */
mcpwm_ll_capture_set_prescale(mcpwm_dev_t * mcpwm,int cap_sig,uint32_t prescale)717 static inline void mcpwm_ll_capture_set_prescale(mcpwm_dev_t *mcpwm, int cap_sig, uint32_t prescale)
718 {
719     mcpwm->cap_cfg_ch[cap_sig].prescale = prescale;
720 }
721 
722 /**
723  * Utility function, get the `mcpwm_intr_t` interrupt enum of a specific capture signal.
724  *
725  * @param bit x for CAPx.
726  * @return the corresponding `mcpwm_intr_t`.
727  */
mcpwm_ll_get_cap_intr_def(int bit)728 static inline mcpwm_intr_t mcpwm_ll_get_cap_intr_def(int bit)
729 {
730     return BIT(bit+MCPWM_CAP0_INT_RAW_S);
731 }
732 
733 #ifdef __cplusplus
734 }
735 #endif
736