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