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