1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_PWM_DRV_H
9 #define HPM_PWM_DRV_H
10 
11 #include "hpm_common.h"
12 #include "hpm_pwm_regs.h"
13 #include "hpm_soc_feature.h"
14 /**
15  * @brief PWM driver APIs
16  * @defgroup pwm_interface PWM driver APIs
17  * @ingroup motor_interfaces
18  * @{
19  *
20  */
21 #define PWM_UNLOCK_KEY (0xB0382607UL)
22 
23 /* IRQ enable bit mask */
24 #define PWM_IRQ_FAULT PWM_IRQEN_FAULTIRQE_MASK
25 #define PWM_IRQ_EX_RELOAD PWM_IRQEN_XRLDIRQE_MASK
26 #define PWM_IRQ_HALF_RELOAD PWM_IRQEN_HALFRLDIRQE_MASK
27 #define PWM_IRQ_RELOAD PWM_IRQEN_RLDIRQE_MASK
28 #define PWM_IRQ_CMP(x) PWM_IRQEN_CMPIRQEX_SET((1 << x))
29 
30 /* PWM force output mask */
31 #define PWM_FORCE_OUTPUT(pwm_index, force_output) \
32     (force_output << (pwm_index << 1))
33 
34 #define PWM_DUTY_CYCLE_FP_MAX ((1U << 24) - 1)
35 
36 /**
37  * @brief pwm trigger mode
38  *
39  */
40 typedef enum pwm_counter_type {
41     pwm_counter_type_capture_rising_edge,   /**< rising edge trigger*/
42     pwm_counter_type_capture_falling_edge,  /**< falling edge trigger*/
43 } pwm_counter_type_t;
44 
45 /**
46  * @brief pwm cmp mode
47  *
48  */
49 typedef enum pwm_cmp_mode {
50     pwm_cmp_mode_output_compare = 0,    /**< output compare*/
51     pwm_cmp_mode_input_capture = 1,     /**< input compare*/
52 } pwm_cmp_mode_t;
53 
54 /**
55  * @brief update time of the shadow register
56  *
57  */
58 typedef enum pwm_register_update {
59     pwm_shadow_register_update_on_shlk = 0,     /**< after software set shlk bit of shlk register*/
60     pwm_shadow_register_update_on_modify = 1,   /**<  immediately after the register being modified*/
61     pwm_shadow_register_update_on_hw_event = 2, /**<  after hardware event assert*/
62     pwm_shadow_register_update_on_sh_synci = 3, /**< after SHSYNCI assert */
63 } pwm_shadow_register_update_trigger_t;
64 
65 /**
66  * @brief configure the state of channel 0-7 outputs when the forced output is in effect
67  *
68  */
69 typedef enum pwm_fault_mode {
70     pwm_fault_mode_force_output_0 = 0, /**< fault forced output logic 0 */
71     pwm_fault_mode_force_output_1 = 1,  /**< fault forced output logic 1 */
72     pwm_fault_mode_force_output_highz = 2,  /**< turn off output, pin becomes high resistance */
73 } pwm_fault_mode_t;
74 
75 /**
76  * @brief  select when to recover PWM output after fault
77  *
78  */
79 typedef enum pwm_fault_recovery_trigger {
80     pwm_fault_recovery_immediately = 0, /**< immediately*/
81     pwm_fault_recovery_on_reload = 1,   /**<  after pwm timer counter reload time*/
82     pwm_fault_recovery_on_hw_event = 2, /**< after hardware event assert*/
83     pwm_fault_recovery_on_fault_clear = 3,  /**<  after software write faultclr bit in GCR register*/
84 } pwm_fault_recovery_trigger_t;
85 
86 /**
87  * @brief fault input signal
88  *
89  */
90 typedef enum pwm_fault_source {
91     pwm_fault_source_internal_0 = PWM_GCR_FAULTI0EN_MASK, /**< FAULTI0 */
92     pwm_fault_source_internal_1 = PWM_GCR_FAULTI1EN_MASK, /**< FAULTI1 */
93     pwm_fault_source_internal_2 = PWM_GCR_FAULTI2EN_MASK, /**< FAULTI2 */
94     pwm_fault_source_internal_3 = PWM_GCR_FAULTI3EN_MASK, /**< FAULTI3 */
95     pwm_fault_source_external_0 = PWM_GCR_FAULTE0EN_MASK, /**< EXFAULTI0 */
96     pwm_fault_source_external_1 = PWM_GCR_FAULTE1EN_MASK, /**< EXFAULTI1 */
97     pwm_fault_source_debug = PWM_GCR_DEBUGFAULT_MASK,   /**< Debug fault */
98 } pwm_fault_source_t;
99 
100 /**
101  * @brief Select sources for force output
102  *
103  */
104 typedef enum pwm_force_source {
105     pwm_force_source_force_input = 0, /**< force output is enabled when FRCI assert */
106     pwm_force_source_software = 1,  /**<  force output is enabled by software write swfrc to 1 */
107 } pwm_force_source_t;
108 /**
109  * @brief select when the FRCMD shadow register will be loaded to its work register
110  *
111  */
112 typedef enum pwm_force_cmd_timing {
113     pwm_force_immediately = 0,  /**< after software set shlk bit of shlk register */
114     pwm_force_at_reload = 1,    /**< immediately after the register being modified */
115     pwm_force_at_synci = 2,     /**< after hardware event assert */
116     pwm_force_none = 3,         /**< after SHSYNCI assert */
117 } pwm_force_cmd_timing_t;
118 
119 /**
120  * @brief pwm output type
121  *
122  */
123 typedef enum pwm_output_type {
124     pwm_output_0 = 0, /**< output 0 */
125     pwm_output_1 = 1, /**< output 1 */
126     pwm_output_high_z = 2, /**< output */
127     pwm_output_no_force = 3,
128 } pwm_output_type_t;
129 
130 /**
131  * @brief pwm compare config
132  *
133  */
134 typedef struct pwm_cmp_config {
135     uint32_t cmp;         /**< compare value */
136     bool enable_ex_cmp;   /**< enable extended compare value */
137 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
138     bool enable_hrcmp;     /**< enable high precision pwm */
139 #endif
140     uint8_t mode;         /**< compare work mode: pwm_cmp_mode_output_compare or pwm_cmp_mode_input_capture */
141     uint8_t update_trigger;  /**< compare configuration update trigger */
142     uint8_t ex_cmp;       /**< extended compare value */
143     uint8_t half_clock_cmp; /**< half clock compare value*/
144     uint8_t jitter_cmp;     /**< jitter compare value */
145 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
146     uint8_t hrcmp;         /**< high precision pwm */
147 #endif
148 } pwm_cmp_config_t;
149 
150 /**
151  * @brief pwm output channel config
152  *
153  */
154 typedef struct pwm_output_channel {
155     uint8_t cmp_start_index; /**< output channel compare start index */
156     uint8_t cmp_end_index;   /**< output channel compare end index */
157     bool invert_output;      /**< invert output */
158 } pwm_output_channel_t;
159 /**
160  * @brief pwm fault source config
161  *
162  */
163 typedef struct pwm_fault_source_config {
164     uint32_t source_mask;                   /**< fault source mask*/
165     bool fault_recover_at_rising_edge;      /**< recover fault at rising edge */
166     bool fault_external_0_active_low;       /**< active external fault0 by low */
167     bool fault_external_1_active_low;       /**< active external fault1 by low */
168     uint8_t fault_output_recovery_trigger;  /**< fault output recoverty trigger */
169 } pwm_fault_source_config_t;
170 
171 /**
172  * @brief pwm config data
173  *
174  */
175 typedef struct pwm_config {
176 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
177     bool hrpwm_update_mode;             /**< mode one or zero, HR CMP update timing */
178 #endif
179     bool enable_output;                 /**< enable pwm output */
180     bool invert_output;                 /**< invert pwm output level */
181     uint8_t update_trigger;             /**< pwm config update trigger */
182     uint8_t fault_mode;                 /**< fault mode */
183     uint8_t fault_recovery_trigger;     /**< fault recoverty trigger */
184     uint8_t force_source;               /**< fault source */
185     uint32_t dead_zone_in_half_cycle;   /**< dead zone in half cycle*/
186 } pwm_config_t;
187 
188 /**
189  * @brief pair pwm config
190  *
191  */
192 typedef struct pwm_pair_config {
193     pwm_config_t pwm[2];    /**< pwm config data */
194 } pwm_pair_config_t;
195 
196 #ifdef __cplusplus
197 extern "C" {
198 #endif
199 
200 /**
201  * @brief pwm deinitialize function
202  *
203  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
204  *
205  */
pwm_deinit(PWM_Type * pwm_x)206 static inline void pwm_deinit(PWM_Type *pwm_x)
207 {
208     pwm_x->IRQEN = 0;
209     pwm_x->DMAEN = 0;
210     pwm_x->SR |= pwm_x->SR;
211     pwm_x->STA = 0;
212     pwm_x->RLD = PWM_RLD_RLD_MASK;
213     for (uint8_t i = 0; i < PWM_SOC_CMP_MAX_COUNT; i++) {
214         pwm_x->CMP[i] = PWM_CMP_CMP_MASK;
215         pwm_x->CMPCFG[i] = 0;
216         pwm_x->CHCFG[i] = PWM_CHCFG_CMPSELEND_SET(PWM_SOC_CMP_MAX_COUNT - 1) | PWM_CHCFG_CMPSELBEG_SET(PWM_SOC_CMP_MAX_COUNT - 1);
217     }
218     pwm_x->FRCMD = 0;
219     pwm_x->GCR = 0;
220     pwm_x->SHCR = 0;
221 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
222     pwm_x->HRPWM_CFG = 0;
223 #endif
224     for (uint8_t i = 0; i < PWM_SOC_OUTPUT_TO_PWM_MAX_COUNT; i++) {
225         pwm_x->PWMCFG[i] = 0;
226     }
227 }
228 
229 /**
230  * @brief issue all shawdow register
231  *
232  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
233  */
pwm_issue_shadow_register_lock_event(PWM_Type * pwm_x)234 static inline void pwm_issue_shadow_register_lock_event(PWM_Type *pwm_x)
235 {
236     if (pwm_x->SHCR & PWM_SHCR_SHLKEN_MASK) {
237         /*
238          * if lock shadow register has been enabled in SHCR, it has to set
239          * the lock bit twice to issue shadow register lock event.
240          */
241         pwm_x->SHLK = PWM_SHLK_SHLK_MASK;
242     }
243     pwm_x->SHLK = PWM_SHLK_SHLK_MASK;
244 }
245 
246 /**
247  * @brief lock all shawdow register
248  *
249  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
250  */
pwm_shadow_register_lock(PWM_Type * pwm_x)251 static inline void pwm_shadow_register_lock(PWM_Type *pwm_x)
252 {
253     pwm_x->SHCR |= PWM_SHCR_SHLKEN_MASK;
254     pwm_x->SHLK = PWM_SHLK_SHLK_MASK;
255 }
256 
257 /**
258  * @brief unlock all shadow register
259  *
260  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
261  */
pwm_shadow_register_unlock(PWM_Type * pwm_x)262 static inline void pwm_shadow_register_unlock(PWM_Type *pwm_x)
263 {
264     pwm_x->UNLK = PWM_UNLOCK_KEY;
265 }
266 
267 /**
268  * @brief set counter start value and extended start value
269  *
270  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
271  * @param[in] ex_start pwm timer counter extended start value
272  * @param[in] start pwm timer counter start value
273  */
pwm_set_start_count(PWM_Type * pwm_x,uint8_t ex_start,uint32_t start)274 static inline void pwm_set_start_count(PWM_Type *pwm_x,
275                                         uint8_t ex_start,
276                                         uint32_t start)
277 {
278     pwm_x->STA = PWM_STA_XSTA_SET(ex_start)
279         | PWM_STA_STA_SET(start);
280 }
281 
282 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
283 
284 /**
285  * @brief set hrpwm counter start value
286  *
287  * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
288  * @param start pwm timer counter start value
289  */
pwm_set_hrpwm_start_count(PWM_Type * pwm_x,uint32_t start)290 static inline void pwm_set_hrpwm_start_count(PWM_Type *pwm_x,
291                                         uint32_t start)
292 {
293     pwm_x->STA_HRPWM = PWM_STA_HRPWM_STA_SET(start);
294 }
295 
296 #endif
297 
298 /**
299  * @brief set the reload value
300  *
301  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
302  * @param[in] ex_reload pwm timer counter extended reload value
303  * @param[in] reload pwm timer counter reload value
304  */
pwm_set_reload(PWM_Type * pwm_x,uint8_t ex_reload,uint32_t reload)305 static inline void pwm_set_reload(PWM_Type *pwm_x,
306                                    uint8_t ex_reload,
307                                    uint32_t reload)
308 {
309     pwm_shadow_register_unlock(pwm_x);
310     pwm_x->RLD = PWM_RLD_XRLD_SET(ex_reload)
311         | PWM_RLD_RLD_SET(reload);
312 }
313 
314 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
315 
316 /**
317  * @brief set the hr pwm reload value
318  *
319  * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
320  * @param hr_reload pwm timer counter hrpwm reload value
321  * @param reload pwm timer counter reload value
322  */
pwm_set_hrpwm_reload(PWM_Type * pwm_x,uint16_t hrpwm_reload,uint32_t reload)323 static inline void pwm_set_hrpwm_reload(PWM_Type *pwm_x,
324                                    uint16_t hrpwm_reload,
325                                    uint32_t reload)
326 {
327     pwm_shadow_register_unlock(pwm_x);
328     pwm_x->RLD_HRPWM = PWM_RLD_HRPWM_RLD_HR_SET(hrpwm_reload)
329         | PWM_RLD_HRPWM_RLD_SET(reload);
330 }
331 
332 #endif
333 
334 /**
335  * @brief clear pwm status register
336  *
337  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
338  * @param[in] mask :
339  *  @arg        PWM_IRQ_FAULT: fault condition flag
340  *  @arg        PWM_IRQ_EX_RELOAD : extended reload flag, this flag set when xcnt count to xrld value or when SYNCI assert
341  *  @arg        PWM_IRQ_HALF_RELOAD: half reload flag, this flag set when cnt count to rld/2
342  *  @arg        PWM_IRQ_RELOAD: reload flag, this flag set when cnt count to rld value or when SYNCI assert
343  *  @arg        PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag
344  */
pwm_clear_status(PWM_Type * pwm_x,uint32_t mask)345 static inline void pwm_clear_status(PWM_Type *pwm_x, uint32_t mask)
346 {
347     pwm_x->SR |= mask;
348 }
349 
350 #if defined(PWM_SOC_TIMER_RESET_SUPPORT) && PWM_SOC_TIMER_RESET_SUPPORT
351 
352 /**
353  * @brief Reset timer and extension timer
354  *
355  * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
356  */
pwm_timer_reset(PWM_Type * pwm_x)357 static inline void pwm_timer_reset(PWM_Type *pwm_x)
358 {
359      pwm_x->GCR = ((pwm_x->GCR & ~(PWM_GCR_TIMERRESET_MASK)) | PWM_GCR_TIMERRESET_SET(1));
360 }
361 
362 #endif
363 
364 /**
365  * @brief get pwm status register
366  *
367  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
368  * @retval uint32_t SR register value
369  */
pwm_get_status(PWM_Type * pwm_x)370 static inline uint32_t pwm_get_status(PWM_Type *pwm_x)
371 {
372     return pwm_x->SR;
373 }
374 
375 /**
376  * @brief disable pwm irq
377  *
378  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
379  * @param[in] mask :
380  *  @arg        PWM_IRQ_FAULT: fault condition interrupt enable
381  *  @arg        PWM_IRQ_EX_RELOAD: extended reload flag interrupt enable
382  *  @arg        PWM_IRQ_HALF_RELOAD: half reload flag interrupt enable
383  *  @arg        PWM_IRQ_RELOAD: reload flag interrupt enable
384  *  @arg        PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag interrupt enable
385  */
pwm_disable_irq(PWM_Type * pwm_x,uint32_t mask)386 static inline void pwm_disable_irq(PWM_Type *pwm_x, uint32_t mask)
387 {
388     pwm_x->IRQEN &= ~mask;
389 }
390 
391 /**
392  * @brief enable pwm irq
393  *
394  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
395  * @param[in] mask :
396  *  @arg        PWM_IRQ_FAULT: fault condition interrupt enable
397  *  @arg        PWM_IRQ_EX_RELOAD: extended reload flag interrupt enable
398  *  @arg        PWM_IRQ_HALF_RELOAD: half reload flag interrupt enable
399  *  @arg        PWM_IRQ_RELOAD: reload flag interrupt enable
400  *  @arg        PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag interrupt enable
401  */
pwm_enable_irq(PWM_Type * pwm_x,uint32_t mask)402 static inline void pwm_enable_irq(PWM_Type *pwm_x, uint32_t mask)
403 {
404     pwm_x->IRQEN |= mask;
405 }
406 
407 /**
408  * @brief disable pwm dma request
409  *
410  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
411  * @param[in] mask :
412  *  @arg        PWM_IRQ_FAULT: fault condition DMA request enable
413  *  @arg        PWM_IRQ_EX_RELOAD: extended reload flag DMA request enable
414  *  @arg        PWM_IRQ_HALF_RELOAD: half reload flag DMA request enable
415  *  @arg        PWM_IRQ_RELOAD: reload flag DMA request enable
416  *  @arg        PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag DMA request enable
417  *
418  */
pwm_disable_dma_request(PWM_Type * pwm_x,uint32_t mask)419 static inline void pwm_disable_dma_request(PWM_Type *pwm_x, uint32_t mask)
420 {
421     pwm_x->DMAEN &= ~mask;
422 }
423 
424 /**
425  * @brief enable pwm dma request
426  *
427  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
428  * @param[in] mask :
429  *  @arg        PWM_IRQ_FAULT: fault condition DMA request enable
430  *  @arg        PWM_IRQ_EX_RELOAD: extended reload flag DMA request enable
431  *  @arg        PWM_IRQ_HALF_RELOAD: half reload flag DMA request enable
432  *  @arg        PWM_IRQ_RELOAD: reload flag DMA request enable
433  *  @arg        PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag DMA request enable
434  *
435  */
pwm_enable_dma_request(PWM_Type * pwm_x,uint32_t mask)436 static inline void pwm_enable_dma_request(PWM_Type *pwm_x, uint32_t mask)
437 {
438     pwm_x->DMAEN |= mask;
439 }
440 
441 /**
442  * @brief set target cmp as hardware event to trigger force cmd output
443  *
444  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
445  * @param[in] target_cmp_index cmp index  select one of the cmp as hardware event time to load FRCMD shadow registers [0-23]
446  */
pwm_set_force_cmd_shadow_register_hwevent(PWM_Type * pwm_x,uint8_t target_cmp_index)447 static inline void pwm_set_force_cmd_shadow_register_hwevent(PWM_Type *pwm_x,
448                                                     uint8_t target_cmp_index)
449 {
450     pwm_x->SHCR = ((pwm_x->SHCR & ~(PWM_SHCR_FRCSHDWSEL_MASK))
451                     | PWM_SHCR_FRCSHDWSEL_SET(target_cmp_index));
452 }
453 /**
454  * @note if trigger is not set to hardware event, target_cmp_index can be
455  * passed with any value
456  *
457  */
458 
459 /**
460  * @brief set shadow register control register
461  *
462  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
463  * @param[in] trigger  select when the counter related shadow registers @ref pwm_shadow_register_update_trigger_t
464  * @param[in] target_cmp_index  select one of the comparators as hardware event (0..(PWM_SOC_CMP_MAX_COUNT-1))
465  */
pwm_set_load_counter_shadow_register_trigger(PWM_Type * pwm_x,pwm_shadow_register_update_trigger_t trigger,uint8_t target_cmp_index)466 static inline void pwm_set_load_counter_shadow_register_trigger(PWM_Type *pwm_x,
467                                 pwm_shadow_register_update_trigger_t trigger,
468                                 uint8_t target_cmp_index)
469 {
470     if (trigger == pwm_shadow_register_update_on_hw_event) {
471         pwm_x->SHCR = ((pwm_x->SHCR & ~(PWM_SHCR_CNTSHDWSEL_MASK
472                         | PWM_SHCR_CNTSHDWUPT_MASK))
473                 | PWM_SHCR_CNTSHDWSEL_SET(target_cmp_index)
474                 | PWM_SHCR_CNTSHDWUPT_SET(trigger));
475     } else {
476         pwm_x->SHCR = ((pwm_x->SHCR & ~(PWM_SHCR_CNTSHDWUPT_MASK))
477                 | PWM_SHCR_CNTSHDWUPT_SET(trigger));
478     }
479 }
480 
481 /**
482  * @brief Configure input capture cmp to trigger shadow register updates
483  *
484  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
485  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
486  * @param[in] is_falling_edge  which edge is used as shadow register hardware load event
487  *  @arg 1- falling edge
488  *  @arg 0- rising edge
489  */
pwm_load_cmp_shadow_on_capture(PWM_Type * pwm_x,uint8_t index,bool is_falling_edge)490 static inline void pwm_load_cmp_shadow_on_capture(PWM_Type *pwm_x,
491                                                    uint8_t index,
492                                                    bool is_falling_edge)
493 {
494     pwm_x->CMPCFG[index] |= PWM_CMPCFG_CMPMODE_MASK;
495     pwm_x->GCR = ((pwm_x->GCR & ~(PWM_GCR_CMPSHDWSEL_MASK | PWM_GCR_HWSHDWEDG_MASK))
496             | PWM_GCR_CMPSHDWSEL_SET(index)
497             | PWM_GCR_HWSHDWEDG_SET(is_falling_edge));
498 }
499 
500 #if defined(PWM_SOC_SHADOW_TRIG_SUPPORT) && PWM_SOC_SHADOW_TRIG_SUPPORT
501 
502 /**
503  * @brief RLD, STA shadow registers take effect at the reload point
504  *
505  * @param pwm_x pwm_x PWM base address, HPM_PWMx(x=0..n)
506  * @param is_enable true or false
507  */
pwm_set_cnt_shadow_trig_reload(PWM_Type * pwm_x,bool is_enable)508 static inline void pwm_set_cnt_shadow_trig_reload(PWM_Type *pwm_x, bool is_enable)
509 {
510 	pwm_x->SHCR = ((pwm_x->SHCR & ~PWM_SHCR_CNT_UPDATE_RELOAD_MASK)
511             | PWM_SHCR_CNT_UPDATE_RELOAD_SET(is_enable));
512 }
513 
514 /**
515  * @brief Set the timer shadow register to update the trigger edge
516  *
517  * @param[in] pwm_x pwm_x PWM base address, HPM_PWMx(x=0..n)
518  * @param[in] is_falling_edge which edge is used as shadow register hardware load event
519  *  @arg 1- falling edge
520  *  @arg 0- rising edge
521  */
pwm_set_cnt_shadow_trig_edge(PWM_Type * pwm_x,bool is_falling_edge)522 static inline void pwm_set_cnt_shadow_trig_edge(PWM_Type *pwm_x,
523                                                    bool is_falling_edge)
524 {
525     pwm_x->SHCR = ((pwm_x->SHCR & ~PWM_SHCR_CNT_UPDATE_EDGE_MASK)
526             | PWM_SHCR_CNT_UPDATE_EDGE_SET(is_falling_edge));
527 }
528 
529 /**
530  * @brief Set the force output shadow register to update the trigger edge
531  *
532  * @param[in] pwm_x pwm_x PWM base address, HPM_PWMx(x=0..n)
533  * @param[in] is_falling_edge which edge is used as shadow register hardware load event
534  *  @arg 1- falling edge
535  *  @arg 0- rising edge
536  */
pwm_set_force_shadow_trig_edge(PWM_Type * pwm_x,bool is_falling_edge)537 static inline void pwm_set_force_shadow_trig_edge(PWM_Type *pwm_x,
538                                                    bool is_falling_edge)
539 {
540     pwm_x->SHCR = ((pwm_x->SHCR & ~PWM_SHCR_FORCE_UPDATE_EDGE_MASK)
541             | PWM_SHCR_FORCE_UPDATE_EDGE_SET(is_falling_edge));
542 }
543 
544 #endif
545 /**
546  * @brief disable pwn cmp half clock
547  *
548  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
549  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
550  */
pwm_cmp_disable_half_clock(PWM_Type * pwm_x,uint8_t index)551 static inline void pwm_cmp_disable_half_clock(PWM_Type *pwm_x, uint8_t index)
552 {
553     pwm_x->CMP[index] &= ~PWM_CMP_CMPHLF_MASK;
554 }
555 
556 /**
557  * @brief enable pwm cmp half clock
558  *
559  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
560  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
561  */
pwm_cmp_enable_half_clock(PWM_Type * pwm_x,uint8_t index)562 static inline void pwm_cmp_enable_half_clock(PWM_Type *pwm_x, uint8_t index)
563 {
564     pwm_x->CMP[index] |= PWM_CMP_CMPHLF_MASK;
565 }
566 
567 /**
568  * @brief update pwm cmp jitter counter compare value
569  *
570  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
571  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
572  * @param[in] jitter jitter value
573  */
pwm_cmp_update_jitter_value(PWM_Type * pwm_x,uint8_t index,uint8_t jitter)574 static inline void pwm_cmp_update_jitter_value(PWM_Type *pwm_x, uint8_t index, uint8_t jitter)
575 {
576     pwm_x->CMP[index] = (pwm_x->CMP[index] & ~PWM_CMP_CMPJIT_MASK) | PWM_CMP_CMPJIT_SET(jitter);
577 }
578 
579 /**
580  * @brief update pwm cmp value
581  *
582  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
583  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
584  * @param[in] cmp clock counter compare value
585  * @param[in] ex_cmp extended counter compare value
586  */
pwm_cmp_update_cmp_value(PWM_Type * pwm_x,uint8_t index,uint32_t cmp,uint16_t ex_cmp)587 static inline void pwm_cmp_update_cmp_value(PWM_Type *pwm_x, uint8_t index,
588                                             uint32_t cmp, uint16_t ex_cmp)
589 {
590     pwm_x->CMP[index] = (pwm_x->CMP[index] & ~(PWM_CMP_CMP_MASK | PWM_CMP_XCMP_MASK))
591         | PWM_CMP_CMP_SET(cmp) | PWM_CMP_XCMP_SET(ex_cmp);
592 }
593 
594 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
595 /**
596  * @brief update high-precision cmp value
597  *
598  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
599  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
600  * @param[in] cmp clock counter compare value
601  * @param[in] hrcmp high-precision pwm
602  */
pwm_cmp_update_hrcmp_value(PWM_Type * pwm_x,uint8_t index,uint32_t cmp,uint16_t hrcmp)603 static inline void pwm_cmp_update_hrcmp_value(PWM_Type *pwm_x, uint8_t index,
604                                             uint32_t cmp, uint16_t hrcmp)
605 {
606     pwm_x->CMP_HRPWM[index] = (pwm_x->CMP_HRPWM[index] & ~(PWM_CMP_HRPWM_CMP_MASK | PWM_CMP_HRPWM_CMP_HR_MASK))
607         | PWM_CMP_HRPWM_CMP_SET(cmp) | PWM_CMP_HRPWM_CMP_HR_SET(hrcmp);
608 }
609 #endif
610 
611 /**
612  * @brief Forced update of pwm cmp register value, cmp content guaranteed accurate by user
613  *
614  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
615  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
616  * @param[in] cmp cmp register data
617  */
pwm_cmp_force_value(PWM_Type * pwm_x,uint8_t index,uint32_t cmp)618 static inline void pwm_cmp_force_value(PWM_Type *pwm_x, uint8_t index, uint32_t cmp)
619 {
620     pwm_x->CMP[index] = cmp;
621 }
622 
623 /**
624  * @brief config pwm cmp
625  *
626  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
627  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
628  * @param[in] config @ref pwm_cmp_config_t
629  */
pwm_config_cmp(PWM_Type * pwm_x,uint8_t index,pwm_cmp_config_t * config)630 static inline void pwm_config_cmp(PWM_Type *pwm_x, uint8_t index, pwm_cmp_config_t *config)
631 {
632     pwm_shadow_register_unlock(pwm_x);
633     if (config->mode == pwm_cmp_mode_output_compare) {
634 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
635         if (config->enable_hrcmp) {
636             pwm_x->CMPCFG[index] = PWM_CMPCFG_CMPSHDWUPT_SET(config->update_trigger);
637             pwm_x->CMP[index] = PWM_CMP_HRPWM_CMP_SET(config->cmp)
638                         | PWM_CMP_HRPWM_CMP_HR_SET(config->hrcmp);
639         } else {
640 #endif
641             pwm_x->CMPCFG[index] = (config->enable_ex_cmp ? PWM_CMPCFG_XCNTCMPEN_MASK : 0)
642                         | PWM_CMPCFG_CMPSHDWUPT_SET(config->update_trigger);
643             pwm_x->CMP[index] = PWM_CMP_CMP_SET(config->cmp)
644                         | PWM_CMP_XCMP_SET(config->ex_cmp)
645                         | PWM_CMP_CMPHLF_SET(config->half_clock_cmp)
646                         | PWM_CMP_CMPJIT_SET(config->jitter_cmp);
647 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
648         }
649 #endif
650     } else {
651         pwm_x->CMPCFG[index] |= PWM_CMPCFG_CMPMODE_MASK;
652     }
653 }
654 
655 /**
656  * @brief config pwm output channel
657  *
658  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
659  * @param[in] index channel index (0..(PWM_SOC_PWM_MAX_COUNT-1))
660  * @param[in] config @ref pwm_output_channel_t
661  */
pwm_config_output_channel(PWM_Type * pwm_x,uint8_t index,pwm_output_channel_t * config)662 static inline void pwm_config_output_channel(PWM_Type *pwm_x, uint8_t index, pwm_output_channel_t *config)
663 {
664     pwm_x->CHCFG[index] = PWM_CHCFG_CMPSELBEG_SET(config->cmp_start_index)
665                             | PWM_CHCFG_CMPSELEND_SET(config->cmp_end_index)
666                             | PWM_CHCFG_OUTPOL_SET(config->invert_output);
667 }
668 
669 /**
670  * @brief config pwm fault source
671  *
672  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
673  * @param[in] config @ref pwm_fault_source_config_t
674  */
pwm_config_fault_source(PWM_Type * pwm_x,pwm_fault_source_config_t * config)675 static inline void pwm_config_fault_source(PWM_Type *pwm_x, pwm_fault_source_config_t *config)
676 {
677     pwm_x->GCR = (pwm_x->GCR & ~(PWM_GCR_FAULTI0EN_MASK | PWM_GCR_FAULTI1EN_MASK
678                 | PWM_GCR_FAULTI2EN_MASK | PWM_GCR_FAULTI3EN_MASK
679                 | PWM_GCR_FAULTE0EN_MASK | PWM_GCR_FAULTE1EN_MASK
680                 | PWM_GCR_FAULTRECEDG_MASK | PWM_GCR_FAULTEXPOL_MASK
681                 | PWM_GCR_FAULTRECHWSEL_MASK))
682         | config->source_mask
683         | PWM_GCR_FAULTEXPOL_SET((config->fault_external_0_active_low ? 0x1 : 0) | (config->fault_external_1_active_low ? 0x2 : 0))
684         | PWM_GCR_FAULTRECEDG_SET(config->fault_recover_at_rising_edge)
685         | PWM_GCR_FAULTRECHWSEL_SET(config->fault_output_recovery_trigger);
686 }
687 
688 /**
689  * @brief clear pwm fault status
690  *
691  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
692  */
pwm_clear_fault(PWM_Type * pwm_x)693 static inline void pwm_clear_fault(PWM_Type *pwm_x)
694 {
695     pwm_x->GCR |= PWM_GCR_FAULTCLR_MASK;
696     pwm_x->GCR &= ~PWM_GCR_FAULTCLR_MASK;
697 }
698 
699 /**
700  * @brief stop the pwm timer counter
701  *
702  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
703  */
pwm_stop_counter(PWM_Type * pwm_x)704 static inline void pwm_stop_counter(PWM_Type *pwm_x)
705 {
706     pwm_x->GCR &= ~PWM_GCR_CEN_MASK;
707 }
708 
709 /**
710  * @brief start pwm timer counter
711  *
712  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
713  */
pwm_start_counter(PWM_Type * pwm_x)714 static inline void pwm_start_counter(PWM_Type *pwm_x)
715 {
716     pwm_x->GCR |= PWM_GCR_CEN_MASK;
717 }
718 
719 /**
720  * @brief enable software force
721  *
722  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
723  */
pwm_enable_sw_force(PWM_Type * pwm_x)724 static inline void pwm_enable_sw_force(PWM_Type *pwm_x)
725 {
726     pwm_x->GCR |= PWM_GCR_SWFRC_MASK;
727 }
728 
729 /**
730  * @brief disable software force , force will take effect
731  *
732  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
733  */
pwm_disable_sw_force(PWM_Type * pwm_x)734 static inline void pwm_disable_sw_force(PWM_Type *pwm_x)
735 {
736     pwm_x->GCR &= ~PWM_GCR_SWFRC_MASK;
737 }
738 
739 /**
740  * @brief enable pwm reload value by synci
741  *
742  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
743  */
pwm_enable_reload_at_synci(PWM_Type * pwm_x)744 static inline void pwm_enable_reload_at_synci(PWM_Type *pwm_x)
745 {
746     pwm_x->GCR |= PWM_GCR_XRLDSYNCEN_MASK | PWM_GCR_RLDSYNCEN_MASK;
747 }
748 
749 /**
750  * @brief disable pwm output
751  *
752  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
753  * @param[in] index pwm index (0..(PWM_SOC_CMP_MAX_COUNT-1))
754  */
pwm_disable_output(PWM_Type * pwm_x,uint8_t index)755 static inline void pwm_disable_output(PWM_Type *pwm_x, uint8_t index)
756 {
757     pwm_x->PWMCFG[index] &= ~PWM_PWMCFG_OEN_MASK;
758 }
759 
760 /**
761  * @brief enable pwm output
762  *
763  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
764  * @param[in] index pwm index (0..(PWM_SOC_CMP_MAX_COUNT-1))
765  */
pwm_enable_output(PWM_Type * pwm_x,uint8_t index)766 static inline void pwm_enable_output(PWM_Type *pwm_x, uint8_t index)
767 {
768     pwm_x->PWMCFG[index] |= PWM_PWMCFG_OEN_MASK;
769 }
770 
771 /**
772  * @brief config pwm force output level per output channel
773  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
774  * @param[in] output_mask PWM output channel force level, set it using the macro
775  *  @arg PWM_FORCE_OUTPUT(pwm_index, force_output)
776  */
pwm_set_force_output(PWM_Type * pwm_x,uint32_t output_mask)777 static inline void pwm_set_force_output(PWM_Type *pwm_x, uint32_t output_mask)
778 {
779     pwm_x->FRCMD = PWM_FRCMD_FRCMD_SET(output_mask);
780 }
781 
782 /**
783  * @brief config pwm force polarity
784  *
785  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
786  * @param[in] polarity polarity of input pwm_force
787  *  @arg 1- active low
788  *  @arg 0- active high
789  */
pwm_config_force_polarity(PWM_Type * pwm_x,bool polarity)790 static inline void pwm_config_force_polarity(PWM_Type *pwm_x, bool polarity)
791 {
792     pwm_x->GCR = (pwm_x->GCR & ~(PWM_GCR_FRCPOL_MASK)) | PWM_GCR_FRCPOL_SET(polarity);
793 }
794 
795 /**
796  * @brief config the force effective time
797  *
798  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
799  * @param[in] timing @ref pwm_force_cmd_timing_t
800  */
pwm_config_force_cmd_timing(PWM_Type * pwm_x,pwm_force_cmd_timing_t timing)801 static inline void pwm_config_force_cmd_timing(PWM_Type *pwm_x, pwm_force_cmd_timing_t timing)
802 {
803     pwm_x->GCR = (pwm_x->GCR & ~(PWM_GCR_FRCTIME_MASK)) | PWM_GCR_FRCTIME_SET(timing);
804 }
805 
806 /**
807  * @brief enable pwm sw force output
808  *
809  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
810  * @param[in] index pwm cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
811  */
pwm_enable_pwm_sw_force_output(PWM_Type * pwm_x,uint8_t index)812 static inline void pwm_enable_pwm_sw_force_output(PWM_Type *pwm_x, uint8_t index)
813 {
814     pwm_x->PWMCFG[index] |= PWM_PWMCFG_OEN_MASK | PWM_PWMCFG_FRCSRCSEL_MASK
815         | PWM_PWMCFG_FRCSHDWUPT_SET(pwm_shadow_register_update_on_modify);
816 }
817 
818 /**
819  * @brief disable pwm sw force output
820  *
821  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
822  * @param[in] index pwm cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
823  */
pwm_disable_pwm_sw_force_output(PWM_Type * pwm_x,uint8_t index)824 static inline void pwm_disable_pwm_sw_force_output(PWM_Type *pwm_x, uint8_t index)
825 {
826     pwm_x->PWMCFG[index] &= ~PWM_PWMCFG_FRCSRCSEL_MASK;
827 }
828 
829 /**
830  * @brief config PWM channel configure registe
831  *
832  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
833  * @param[in] index pwm channel index (0..(PWM_SOC_PWM_MAX_COUNT-1))
834  * @param[in] config @ref pwm_config_t
835  * @param[in] enable_pair_mode enable pair mode
836  *  @arg 1- PWM output is in pair mode
837  *  @arg 0- PWM output is in indepandent mode
838  */
pwm_config_pwm(PWM_Type * pwm_x,uint8_t index,pwm_config_t * config,bool enable_pair_mode)839 static inline void pwm_config_pwm(PWM_Type *pwm_x, uint8_t index,
840                                   pwm_config_t *config, bool enable_pair_mode)
841 {
842     pwm_x->PWMCFG[index] = PWM_PWMCFG_OEN_SET(config->enable_output)
843         | PWM_PWMCFG_FRCSHDWUPT_SET(config->update_trigger)
844         | PWM_PWMCFG_FAULTMODE_SET(config->fault_mode)
845         | PWM_PWMCFG_FAULTRECTIME_SET(config->fault_recovery_trigger)
846         | PWM_PWMCFG_FRCSRCSEL_SET(config->force_source)
847         | PWM_PWMCFG_PAIR_SET(enable_pair_mode)
848 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
849         | PWM_PWMCFG_HR_UPDATE_MODE_SET(config->hrpwm_update_mode)
850 #endif
851         | PWM_PWMCFG_DEADAREA_SET(config->dead_zone_in_half_cycle);
852 }
853 
854 /**
855  * @brief getting the counter reload value for a pwm timer
856  *
857  * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
858  * @retval pwm reload value
859  */
pwm_get_reload_val(PWM_Type * pwm_x)860 static inline uint32_t pwm_get_reload_val(PWM_Type *pwm_x)
861 {
862     return PWM_RLD_RLD_GET(pwm_x->RLD);
863 }
864 
865 /**
866  * @brief getting the extended counter reload value for a pwm timer
867  *
868  * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
869  * @retval pwm extended reload value
870  */
pwm_get_ex_reload_val(PWM_Type * pwm_x)871 static inline uint32_t pwm_get_ex_reload_val(PWM_Type *pwm_x)
872 {
873     return PWM_RLD_XRLD_GET(pwm_x->RLD);
874 }
875 
876 /**
877  * @brief getting the value of the pwm counter
878  *
879  * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
880  * @retval pwm counter value
881  */
pwm_get_counter_val(PWM_Type * pwm_x)882 static inline uint32_t pwm_get_counter_val(PWM_Type *pwm_x)
883 {
884     return PWM_CNT_CNT_GET(pwm_x->CNT);
885 }
886 
887 /**
888  * @brief getting the value of the pwm extended counter
889  *
890  * @param pwm_x PWM base address, HPM_PWMx(x=0..n)
891  * @retval pwm counter value
892  */
pwm_get_ex_counter_val(PWM_Type * pwm_x)893 static inline uint32_t pwm_get_ex_counter_val(PWM_Type *pwm_x)
894 {
895     return PWM_CNT_XCNT_GET(pwm_x->CNT);
896 }
897 
898 /**
899  * @brief pwm load cmp shadow on match
900  *
901  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
902  * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
903  * @param[in] config @ref pwm_cmp_config_t
904  * @retval status_invalid_argument or status_success
905  */
906 hpm_stat_t pwm_load_cmp_shadow_on_match(PWM_Type *pwm_x,
907                                          uint8_t index,
908                                          pwm_cmp_config_t *config);
909 
910 /**
911  * @brief pwm get captured count
912  *
913  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
914  * @param[out] buf count value
915  * @param[in] counter @ref pwm_counter_type_t
916  * @param[in] start_index start capture index (0..(PWM_SOC_CMP_MAX_COUNT-1))
917  * @param[in] num capture num (1..PWM_SOC_CMP_MAX_COUNT)
918  */
919 void pwm_get_captured_count(PWM_Type *pwm_x, uint32_t *buf, pwm_counter_type_t counter, uint8_t start_index, uint8_t num);
920 
921 /**
922  * @brief get default cmp config
923  *
924  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
925  * @param[out] config @ref pwm_cmp_config_t
926  */
927 void pwm_get_default_cmp_config(PWM_Type *pwm_x, pwm_cmp_config_t *config);
928 
929 /**
930  * @brief get default output channel config
931  *
932  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
933  * @param[out] config @ref pwm_output_channel_t
934  */
935 void pwm_get_default_output_channel_config(PWM_Type *pwm_x, pwm_output_channel_t *config);
936 
937 /**
938  * @brief get default pwm config
939  *
940  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
941  * @param[out] config @ref pwm_config_t
942  */
943 void pwm_get_default_pwm_config(PWM_Type *pwm_x, pwm_config_t *config);
944 
945 /**
946  * @brief get default pwm pair config
947  *
948  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
949  * @param[out] config @ref pwm_pair_config_t
950  */
951 void pwm_get_default_pwm_pair_config(PWM_Type *pwm_x, pwm_pair_config_t *config);
952 
953 /**
954  * @brief setup waveform
955  *
956  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
957  * @param[in] pwm_index pwm channel index (0..(PWM_SOC_PWM_MAX_COUNT-1))
958  * @param[in] pwm_config @ref pwm_config_t
959  * @param[in] cmp_start_index pwm cmp index (0..(PWM_SOC_PWM_MAX_COUNT-1))
960  * @param[in] cmp @ref pwm_cmp_config_t
961  * @param[in] cmp_num cmp num (1..PWM_SOC_CMP_MAX_COUNT), cmp[cmp_num-1] must not overflow
962  * @retval hpm_stat_t
963  */
964 hpm_stat_t pwm_setup_waveform(PWM_Type *pwm_x,
965                         uint8_t pwm_index, pwm_config_t *pwm_config,
966                         uint8_t cmp_start_index, pwm_cmp_config_t *cmp, uint8_t cmp_num);
967 /**
968  * @brief setup pwm waveform in pair
969  *
970  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
971  * @param[in] pwm_index pwm channel index (0..(PWM_SOC_PWM_MAX_COUNT-1))
972  * @param[in] pwm_pair_config @ref pwm_pair_config_t
973  * @param[in] cmp_start_index pwm cmp index (0..(PWM_SOC_PWM_MAX_COUNT-1))
974  * @param[in] cmp @ref pwm_cmp_config_t
975  * @param[in] cmp_num cmp num (1..PWM_SOC_CMP_MAX_COUNT), cmp[cmp_num-1] must not overflow
976  * @retval hpm_stat_t @ref status_invalid_argument or @ref status_success
977  */
978 hpm_stat_t pwm_setup_waveform_in_pair(PWM_Type *pwm_x,
979                         uint8_t pwm_index, pwm_pair_config_t *pwm_pair_config,
980                         uint8_t cmp_start_index, pwm_cmp_config_t *cmp, uint8_t cmp_num);
981 
982 /**
983  * @brief update raw compare value for edge aligned waveform
984  *
985  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
986  * @param[in] cmp_index index of cmp to be adjusted (0..(PWM_SOC_PWM_MAX_COUNT-1))
987  * @param[in] target_cmp target compare value
988  * @retval hpm_stat_t @ref status_invalid_argument or @ref status_success
989  */
990 hpm_stat_t pwm_update_raw_cmp_edge_aligned(PWM_Type *pwm_x, uint8_t cmp_index,
991                                 uint32_t target_cmp);
992 
993 /**
994  * @brief update raw compare value for central aligned waveform
995  *
996  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
997  * @param[in] cmp1_index index of cmp1 to be adjusted (cmp1_index must be even number)
998  * @param[in] cmp2_index index of cmp2 to be adjusted (cmp2_index must be odd number)
999  * @param[in] target_cmp1 target compare value for cmp1
1000  * @param[in] target_cmp2 target compare value for cmp2
1001  * @retval hpm_stat_t @ref status_invalid_argument or @ref status_success cmp1_index
1002  */
1003 hpm_stat_t pwm_update_raw_cmp_central_aligned(PWM_Type *pwm_x, uint8_t cmp1_index,
1004                                        uint8_t cmp2_index, uint32_t target_cmp1, uint32_t target_cmp2);
1005 #if defined(PWM_SOC_HRPWM_SUPPORT) && PWM_SOC_HRPWM_SUPPORT
1006 
1007 /**
1008  * @brief recovery hrpwm output
1009  *
1010  * @param pwm_x @ref PWM_Type PWM base address
1011  */
pwm_recovery_hrpwm_output(PWM_Type * pwm_x)1012 static inline void pwm_recovery_hrpwm_output(PWM_Type *pwm_x)
1013 {
1014     pwm_x->HRPWM_CFG |= PWM_HRPWM_CFG_CAL_SW_EN_MASK;
1015     pwm_x->ANA_CFG0 |= PWM_ANA_CFG0_CAL_SW_TRIG_H_MASK;
1016     pwm_x->ANA_CFG0 &= ~PWM_ANA_CFG0_CAL_SW_TRIG_H_MASK;
1017     pwm_x->ANA_CFG0 |= PWM_ANA_CFG0_CAL_SW_TRIG_H_MASK;
1018     pwm_x->ANA_CFG0 &= ~PWM_ANA_CFG0_CAL_SW_TRIG_H_MASK;
1019     pwm_x->HRPWM_CFG &= ~PWM_HRPWM_CFG_CAL_SW_EN_MASK;
1020 }
1021 
1022 /**
1023  * @brief Enable high-precision pwm
1024  *
1025  * @param[in] pwm_x @ref PWM_Type PWM base address
1026  */
pwm_enable_hrpwm(PWM_Type * pwm_x)1027 static inline void pwm_enable_hrpwm(PWM_Type *pwm_x)
1028 {
1029     pwm_x->GCR = (pwm_x->GCR & ~(PWM_GCR_HR_PWM_EN_MASK)) | PWM_GCR_HR_PWM_EN_SET(1);
1030 }
1031 
1032 /**
1033  * @brief Disable high-precision pwm
1034  *
1035  * @param[in] pwm_x @ref PWM_Type PWM base address
1036  */
pwm_disable_hrpwm(PWM_Type * pwm_x)1037 static inline void pwm_disable_hrpwm(PWM_Type *pwm_x)
1038 {
1039     pwm_x->GCR = pwm_x->GCR & ~(PWM_GCR_HR_PWM_EN_MASK);
1040 }
1041 
1042 /**
1043  * @brief Calibrate all channels of hrpwm
1044  *
1045  * @param[in] pwm_x @ref PWM_Type PWM base address
1046  */
pwm_cal_hrpwm_start(PWM_Type * pwm_x)1047 static inline void pwm_cal_hrpwm_start(PWM_Type *pwm_x)
1048 {
1049     pwm_x->HRPWM_CFG |= PWM_HRPWM_CFG_CAL_START_MASK;
1050 }
1051 
1052 /**
1053  * @brief Calibrate specified hrpwm channels
1054  *
1055  * @param[in] pwm_x @ref PWM_Type PWM base address
1056  * @param[in] chn Channel number
1057  */
pwm_cal_hrpwm_chn_start(PWM_Type * pwm_x,uint8_t chn)1058 static inline void pwm_cal_hrpwm_chn_start(PWM_Type *pwm_x, uint8_t chn)
1059 {
1060     pwm_x->HRPWM_CFG |= PWM_HRPWM_CFG_CAL_START_SET(chn);
1061 }
1062 
1063 /**
1064  * @brief Wait for the completion of calibration of the specified channel of high-precision PWM, blocking
1065  *
1066  * @param[in] pwm_x @ref PWM_Type PWM base address
1067  * @param[in] chn Channel number
1068  */
pwm_cal_hrpwm_chn_wait(PWM_Type * pwm_x,uint8_t chn)1069 static inline void pwm_cal_hrpwm_chn_wait(PWM_Type *pwm_x, uint8_t chn)
1070 {
1071     while (PWM_ANASTS_CALON_GET(pwm_x->ANASTS[chn])) {
1072     };
1073 }
1074 
1075 /**
1076  * @brief get calibration status
1077  *
1078  * @param[in] pwm_x pwm_x @ref PWM_Type PWM base address
1079  * @param[in] chn Channel number
1080  * @return uint32_t  finished will be set zero.
1081  */
pwm_get_cal_hrpwm_status(PWM_Type * pwm_x,uint8_t chn)1082 static inline uint32_t pwm_get_cal_hrpwm_status(PWM_Type *pwm_x, uint8_t chn)
1083 {
1084     return PWM_ANASTS_CALON_GET(pwm_x->ANASTS[chn]);
1085 }
1086 
1087 /**
1088  * @brief getting the counter reload value for hrpwm counter
1089  *
1090  * @param pwm_x pwm_x @ref PWM_Type PWM base address
1091  * @return uint32_t hrpwm reload
1092  */
pwm_get_hrpwm_reload_val(PWM_Type * pwm_x)1093 static inline uint32_t pwm_get_hrpwm_reload_val(PWM_Type *pwm_x)
1094 {
1095     return PWM_RLD_HRPWM_RLD_GET(pwm_x->RLD_HRPWM);
1096 }
1097 
1098 /**
1099  * @brief getting the counter reload value for hrpwm hr counter
1100  *
1101  * @param pwm_x pwm_x @ref PWM_Type PWM base address
1102  * @return uint32_t hrpwm hr reload
1103  */
pwm_get_hrpwm_hr_reload_val(PWM_Type * pwm_x)1104 static inline uint32_t pwm_get_hrpwm_hr_reload_val(PWM_Type *pwm_x)
1105 {
1106     return PWM_RLD_HRPWM_RLD_HR_GET(pwm_x->RLD_HRPWM);
1107 }
1108 
1109 
1110 /**
1111  * @brief update raw high-precision compare value for edge aligned waveform
1112  *
1113  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
1114  * @param[in] cmp_index index of cmp to be adjusted (0..(PWM_SOC_PWM_MAX_COUNT-1))
1115  * @param[in] target_cmp target compare value
1116  * @param[in] target_hrcmp target high-precision compare value
1117  * @return hpm_stat_t
1118  */
1119 hpm_stat_t pwm_update_raw_hrcmp_edge_aligned(PWM_Type *pwm_x, uint8_t cmp_index, uint32_t target_cmp,
1120             uint16_t target_hrcmp);
1121 
1122 /**
1123  * @brief update raw high-precision compare value for central aligned waveform
1124  *
1125  * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
1126  * @param[in] cmp1_index index of cmp1 to be adjusted (cmp1_index must be even number)
1127  * @param[in] cmp2_index index of cmp2 to be adjusted (cmp2_index must be odd number)
1128  * @param[in] target_cmp1 target compare value for cmp1
1129  * @param[in] target_cmp2 target compare value for cmp2
1130  * @param[in] target_hrcmp1 target high-precision compare value for cmp1
1131  * @param[in] target_hrcmp2 target high-precision compare value for cmp2
1132  * @return hpm_stat_t
1133  */
1134 hpm_stat_t pwm_update_raw_hrcmp_central_aligned(PWM_Type *pwm_x, uint8_t cmp1_index,
1135                                        uint8_t cmp2_index, uint32_t target_cmp1, uint32_t target_cmp2,
1136                                         uint16_t target_hrcmp1, uint16_t target_hrcmp2);
1137 #endif
1138 
1139 #ifdef __cplusplus
1140 }
1141 #endif
1142 /**
1143  * @}
1144  */
1145 #endif /* HPM_PWM_DRV_H */
1146