hpm_pwm_drv.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /*
  2. * Copyright (c) 2021 hpmicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_PWM_DRV_H
  8. #define HPM_PWM_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_pwm_regs.h"
  11. /**
  12. * @brief PWM driver APIs
  13. * @defgroup pwm_interface PWM driver APIs
  14. * @ingroup io_interfaces
  15. * @{
  16. *
  17. */
  18. #define PWM_UNLOCK_KEY (0xB0382607UL)
  19. /* IRQ enable bit mask */
  20. #define PWM_IRQ_FAULT PWM_IRQEN_FAULTIRQE_MASK
  21. #define PWM_IRQ_EX_RELOAD PWM_IRQEN_XRLDIRQE_MASK
  22. #define PWM_IRQ_HALF_RELOAD PWM_IRQEN_HALFRLDIRQE_MASK
  23. #define PWM_IRQ_RELOAD PWM_IRQEN_RLDIRQE_MASK
  24. #define PWM_IRQ_CMP(x) PWM_IRQEN_CMPIRQEX_SET((1 << x))
  25. /* PWM force output mask */
  26. #define PWM_FORCE_OUTPUT(pwm_index, force_output) \
  27. (force_output << (pwm_index << 1))
  28. #define PWM_DUTY_CYCLE_FP_MAX ((1U << 24) - 1)
  29. /**
  30. * @brief pwm trigger mode
  31. *
  32. */
  33. typedef enum pwm_counter_type {
  34. pwm_counter_type_capture_rising_edge, /**< rising edge trigger*/
  35. pwm_counter_type_capture_falling_edge, /**< falling edge trigger*/
  36. } pwm_counter_type_t;
  37. /**
  38. * @brief pwm cmp mode
  39. *
  40. */
  41. typedef enum pwm_cmp_mode {
  42. pwm_cmp_mode_output_compare = 0, /**< output compare*/
  43. pwm_cmp_mode_input_capture = 1, /**< input compare*/
  44. } pwm_cmp_mode_t;
  45. /**
  46. * @brief update time of the shadow register
  47. *
  48. */
  49. typedef enum pwm_register_update {
  50. pwm_shadow_register_update_on_shlk = 0, /**< after software set shlk bit of shlk register*/
  51. pwm_shadow_register_update_on_modify = 1, /**< immediately after the register being modified*/
  52. pwm_shadow_register_update_on_hw_event = 2, /**< after hardware event assert*/
  53. pwm_shadow_register_update_on_sh_synci = 3, /**< after SHSYNCI assert */
  54. } pwm_shadow_register_update_trigger_t;
  55. /**
  56. * @brief configure the state of channel 0∼7 outputs when the forced output is in effect
  57. *
  58. */
  59. typedef enum pwm_fault_mode {
  60. pwm_fault_mode_force_output_0 = 0, /**< fault forced output logic 0 */
  61. pwm_fault_mode_force_output_1 = 1, /**< fault forced output logic 1 */
  62. pwm_fault_mode_force_output_highz = 2, /**< turn off output, pin becomes high resistance */
  63. } pwm_fault_mode_t;
  64. /**
  65. * @brief select when to recover PWM output after fault
  66. *
  67. */
  68. typedef enum pwm_fault_recovery_trigger {
  69. pwm_fault_recovery_immediately = 0, /**< immediately*/
  70. pwm_fault_recovery_on_reload = 1, /**< after pwm timer counter reload time*/
  71. pwm_fault_recovery_on_hw_event = 2, /**< after hardware event assert*/
  72. pwm_fault_recovery_on_fault_clear = 3, /**< after software write faultclr bit in GCR register*/
  73. } pwm_fault_recovery_trigger_t;
  74. /**
  75. * @brief fault input signal
  76. *
  77. */
  78. typedef enum pwm_fault_source {
  79. pwm_fault_source_internal_0 = PWM_GCR_FAULTI0EN_MASK, /**< FAULTI0 */
  80. pwm_fault_source_internal_1 = PWM_GCR_FAULTI1EN_MASK, /**< FAULTI1 */
  81. pwm_fault_source_internal_2 = PWM_GCR_FAULTI2EN_MASK, /**< FAULTI2 */
  82. pwm_fault_source_internal_3 = PWM_GCR_FAULTI3EN_MASK, /**< FAULTI3 */
  83. pwm_fault_source_external_0 = PWM_GCR_FAULTE0EN_MASK, /**< EXFAULTI0 */
  84. pwm_fault_source_external_1 = PWM_GCR_FAULTE1EN_MASK, /**< EXFAULTI1 */
  85. } pwm_fault_source_t;
  86. /**
  87. * @brief Select sources for force output
  88. *
  89. */
  90. typedef enum pwm_force_source {
  91. pwm_force_source_force_input = 0, /**< force output is enabled when FRCI assert */
  92. pwm_force_source_software = 1, /**< force output is enabled by software write swfrc to 1 */
  93. } pwm_force_source_t;
  94. /**
  95. * @brief select when the FRCMD shadow register will be loaded to its work register
  96. *
  97. */
  98. typedef enum pwm_force_cmd_timing {
  99. pwm_force_immediately = 0, /**< after software set shlk bit of shlk register */
  100. pwm_force_at_reload = 1, /**< immediately after the register being modified */
  101. pwm_force_at_synci = 2, /**< after hardware event assert */
  102. pwm_force_none = 3, /**< after SHSYNCI assert */
  103. } pwm_force_cmd_timing_t;
  104. /**
  105. * @brief pwm output type
  106. *
  107. */
  108. typedef enum pwm_output_type {
  109. pwm_output_0 = 0, /**< output 0 */
  110. pwm_output_1 = 1, /**< output 1 */
  111. pwm_output_high_z = 2, /**< output */
  112. pwm_output_no_force = 3,
  113. } pwm_output_type_t;
  114. /**
  115. * @brief pwm compare config
  116. *
  117. */
  118. typedef struct pwm_cmp_config {
  119. uint32_t cmp; /**< compare value */
  120. bool enable_ex_cmp; /**< enable extended compare value */
  121. uint8_t mode; /**< compare work mode: pwm_cmp_mode_output_compare or pwm_cmp_mode_input_capture */
  122. uint8_t update_trigger; /**< compare configuration update trigger */
  123. uint8_t ex_cmp; /**< extended compare value */
  124. uint8_t half_clock_cmp; /**< half clock compare value*/
  125. uint8_t jitter_cmp; /**< jitter compare value */
  126. } pwm_cmp_config_t;
  127. /**
  128. * @brief pwm output channel config
  129. *
  130. */
  131. typedef struct pwm_output_channel {
  132. uint8_t cmp_start_index; /**< output channel compare start index */
  133. uint8_t cmp_end_index; /**< output channel compare end index */
  134. bool invert_output; /**< invert output */
  135. } pwm_output_channel_t;
  136. /**
  137. * @brief pwm fault source config
  138. *
  139. */
  140. typedef struct pwm_fault_source_config {
  141. uint32_t source_mask; /**< fault source mask*/
  142. bool fault_recover_at_rising_edge; /**< recover fault at rising edge */
  143. bool external_fault_active_low; /**< active external fault by low */
  144. uint8_t fault_output_recovery_trigger; /**< fault output recoverty trigger */
  145. } pwm_fault_source_config_t;
  146. /**
  147. * @brief pwm config data
  148. *
  149. */
  150. typedef struct pwm_config {
  151. bool enable_output; /**< enable pwm output */
  152. bool invert_output; /**< invert pwm output level */
  153. uint8_t update_trigger; /**< pwm config update trigger */
  154. uint8_t fault_mode; /**< fault mode */
  155. uint8_t fault_recovery_trigger; /**< fault recoverty trigger */
  156. uint8_t force_source; /**< fault source */
  157. uint32_t dead_zone_in_half_cycle; /**< dead zone in half cycle*/
  158. } pwm_config_t;
  159. /**
  160. * @brief pair pwm config
  161. *
  162. */
  163. typedef struct pwm_pair_config {
  164. pwm_config_t pwm[2]; /**< pwm config data */
  165. } pwm_pair_config_t;
  166. #ifdef __cplusplus
  167. extern "C" {
  168. #endif
  169. /**
  170. * @brief issue all shawdow register
  171. *
  172. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  173. */
  174. static inline void pwm_issue_shadow_register_lock_event(PWM_Type *pwm_x)
  175. {
  176. if (pwm_x->SHCR & PWM_SHCR_SHLKEN_MASK) {
  177. /*
  178. * if lock shadow register has been enabled in SHCR, it has to set
  179. * the lock bit twice to issue shadow register lock event.
  180. */
  181. pwm_x->SHLK = PWM_SHLK_SHLK_MASK;
  182. }
  183. pwm_x->SHLK = PWM_SHLK_SHLK_MASK;
  184. }
  185. /**
  186. * @brief lock all shawdow register
  187. *
  188. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  189. */
  190. static inline void pwm_shadow_register_lock(PWM_Type *pwm_x)
  191. {
  192. pwm_x->SHCR |= PWM_SHCR_SHLKEN_MASK;
  193. pwm_x->SHLK = PWM_SHLK_SHLK_MASK;
  194. }
  195. /**
  196. * @brief unlock all shadow register
  197. *
  198. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  199. */
  200. static inline void pwm_shadow_register_unlock(PWM_Type *pwm_x)
  201. {
  202. pwm_x->UNLK = PWM_UNLOCK_KEY;
  203. }
  204. /**
  205. * @brief set counter start value and extended start value
  206. *
  207. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  208. * @param[in] ex_start pwm timer counter extended start value
  209. * @param[in] start pwm timer counter start value
  210. */
  211. static inline void pwm_set_start_count(PWM_Type *pwm_x,
  212. uint8_t ex_start,
  213. uint32_t start)
  214. {
  215. pwm_x->STA = PWM_STA_XSTA_SET(ex_start)
  216. | PWM_STA_STA_SET(start);
  217. }
  218. /**
  219. * @brief set the reload value
  220. *
  221. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  222. * @param[in] ex_reload pwm timer counter extended reload value
  223. * @param[in] reload pwm timer counter reload value
  224. */
  225. static inline void pwm_set_reload(PWM_Type *pwm_x,
  226. uint8_t ex_reload,
  227. uint32_t reload)
  228. {
  229. pwm_shadow_register_unlock(pwm_x);
  230. pwm_x->RLD = PWM_RLD_XRLD_SET(ex_reload)
  231. | PWM_RLD_RLD_SET(reload);
  232. }
  233. /**
  234. * @brief clear pwm status register
  235. *
  236. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  237. * @param[in] mask :
  238. * @arg PWM_IRQ_FAULT: fault condition flag
  239. * @arg PWM_IRQ_EX_RELOAD : extended reload flag, this flag set when xcnt count to xrld value or when SYNCI assert
  240. * @arg PWM_IRQ_HALF_RELOAD: half reload flag, this flag set when cnt count to rld/2
  241. * @arg PWM_IRQ_RELOAD: reload flag, this flag set when cnt count to rld value or when SYNCI assert
  242. * @arg PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag
  243. */
  244. static inline void pwm_clear_status(PWM_Type *pwm_x, uint32_t mask)
  245. {
  246. pwm_x->SR |= mask;
  247. }
  248. /**
  249. * @brief get pwm status register
  250. *
  251. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  252. * @retval uint32_t SR register value
  253. */
  254. static inline uint32_t pwm_get_status(PWM_Type *pwm_x)
  255. {
  256. return pwm_x->SR;
  257. }
  258. /**
  259. * @brief disable pwm irq
  260. *
  261. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  262. * @param[in] mask :
  263. * @arg PWM_IRQ_FAULT: fault condition interrupt enable
  264. * @arg PWM_IRQ_EX_RELOAD: extended reload flag interrupt enable
  265. * @arg PWM_IRQ_HALF_RELOAD: half reload flag interrupt enable
  266. * @arg PWM_IRQ_RELOAD: reload flag interrupt enable
  267. * @arg PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag interrupt enable
  268. */
  269. static inline void pwm_disable_irq(PWM_Type *pwm_x, uint32_t mask)
  270. {
  271. pwm_x->IRQEN &= ~mask;
  272. }
  273. /**
  274. * @brief enable pwm irq
  275. *
  276. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  277. * @param[in] mask :
  278. * @arg PWM_IRQ_FAULT: fault condition interrupt enable
  279. * @arg PWM_IRQ_EX_RELOAD: extended reload flag interrupt enable
  280. * @arg PWM_IRQ_HALF_RELOAD: half reload flag interrupt enable
  281. * @arg PWM_IRQ_RELOAD: reload flag interrupt enable
  282. * @arg PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag interrupt enable
  283. */
  284. static inline void pwm_enable_irq(PWM_Type *pwm_x, uint32_t mask)
  285. {
  286. pwm_x->IRQEN |= mask;
  287. }
  288. /**
  289. * @brief disable pwm dma request
  290. *
  291. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  292. * @param[in] mask :
  293. * @arg PWM_IRQ_FAULT: fault condition DMA request enable
  294. * @arg PWM_IRQ_EX_RELOAD: extended reload flag DMA request enable
  295. * @arg PWM_IRQ_HALF_RELOAD: half reload flag DMA request enable
  296. * @arg PWM_IRQ_RELOAD: reload flag DMA request enable
  297. * @arg PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag DMA request enable
  298. *
  299. */
  300. static inline void pwm_disable_dma_request(PWM_Type *pwm_x, uint32_t mask)
  301. {
  302. pwm_x->DMAEN &= ~mask;
  303. }
  304. /**
  305. * @brief enable pwm dma request
  306. *
  307. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  308. * @param[in] mask :
  309. * @arg PWM_IRQ_FAULT: fault condition DMA request enable
  310. * @arg PWM_IRQ_EX_RELOAD: extended reload flag DMA request enable
  311. * @arg PWM_IRQ_HALF_RELOAD: half reload flag DMA request enable
  312. * @arg PWM_IRQ_RELOAD: reload flag DMA request enable
  313. * @arg PWM_IRQ_CMP(x)(x=0...n): comparator output compare or input capture flag DMA request enable
  314. *
  315. */
  316. static inline void pwm_enable_dma_request(PWM_Type *pwm_x, uint32_t mask)
  317. {
  318. pwm_x->DMAEN |= mask;
  319. }
  320. /**
  321. * @brief set target cmp as hardware event to trigger force cmd output
  322. *
  323. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  324. * @param[in] target_cmp_index cmp index select one of the cmp as hardware event time to load FRCMD shadow registers [0-23]
  325. */
  326. static inline void pwm_set_force_cmd_shadow_register_hwevent(PWM_Type *pwm_x,
  327. uint8_t target_cmp_index)
  328. {
  329. pwm_x->SHCR = ((pwm_x->SHCR & ~(PWM_SHCR_FRCSHDWSEL_MASK))
  330. | PWM_SHCR_FRCSHDWSEL_SET(target_cmp_index));
  331. }
  332. /**
  333. * @note if trigger is not set to hardware event, target_cmp_index can be
  334. * passed with any value
  335. *
  336. */
  337. /**
  338. * @brief set shadow register control register
  339. *
  340. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  341. * @param[in] trigger select when the counter related shadow registers @ref pwm_shadow_register_update_trigger_t
  342. * @param[in] target_cmp_index select one of the comparators as hardware event (0..(PWM_SOC_CMP_MAX_COUNT-1))
  343. */
  344. static inline void pwm_set_load_counter_shadow_register_trigger(PWM_Type *pwm_x,
  345. pwm_shadow_register_update_trigger_t trigger,
  346. uint8_t target_cmp_index)
  347. {
  348. if (trigger == pwm_shadow_register_update_on_hw_event) {
  349. pwm_x->SHCR = ((pwm_x->SHCR & ~(PWM_SHCR_CNTSHDWSEL_MASK
  350. | PWM_SHCR_CNTSHDWUPT_MASK))
  351. | PWM_SHCR_CNTSHDWSEL_SET(target_cmp_index)
  352. | PWM_SHCR_CNTSHDWUPT_SET(trigger));
  353. } else {
  354. pwm_x->SHCR = ((pwm_x->SHCR & ~(PWM_SHCR_CNTSHDWUPT_MASK))
  355. | PWM_SHCR_CNTSHDWUPT_SET(trigger));
  356. }
  357. }
  358. /**
  359. * @brief configure the hardware to trigger the shadow register to update the CMP
  360. *
  361. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  362. * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  363. * @param[in] edge which edge is used as shadow register hardware load event
  364. * @arg 1- falling edge
  365. * @arg 0- rising edge
  366. */
  367. static inline void pwm_load_cmp_shadow_on_capture(PWM_Type *pwm_x,
  368. uint8_t index,
  369. bool edge)
  370. {
  371. pwm_x->CMPCFG[index] |= PWM_CMPCFG_CMPMODE_MASK;
  372. pwm_x->GCR = ((pwm_x->GCR & ~(PWM_GCR_CMPSHDWSEL_MASK | PWM_GCR_HWSHDWEDG_MASK))
  373. | PWM_GCR_CMPSHDWSEL_SET(index)
  374. | PWM_GCR_HWSHDWEDG_SET(edge));
  375. }
  376. /**
  377. * @brief disable pwn cmp half clock
  378. *
  379. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  380. * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  381. */
  382. static inline void pwm_cmp_disable_half_clock(PWM_Type *pwm_x, uint8_t index)
  383. {
  384. pwm_x->CMP[index] &= ~PWM_CMP_CMPHLF_MASK;
  385. }
  386. /**
  387. * @brief enable pwm cmp half clock
  388. *
  389. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  390. * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  391. */
  392. static inline void pwm_cmp_enable_half_clock(PWM_Type *pwm_x, uint8_t index)
  393. {
  394. pwm_x->CMP[index] |= PWM_CMP_CMPHLF_MASK;
  395. }
  396. /**
  397. * @brief update pwm cmp jitter counter compare value
  398. *
  399. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  400. * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  401. * @param[in] jitter jitter value
  402. */
  403. static inline void pwm_cmp_update_jitter_value(PWM_Type *pwm_x, uint8_t index, uint8_t jitter)
  404. {
  405. pwm_x->CMP[index] = (pwm_x->CMP[index] & ~PWM_CMP_CMPJIT_MASK) | PWM_CMP_CMPJIT_SET(jitter);
  406. }
  407. /**
  408. * @brief update pwm cmp value
  409. *
  410. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  411. * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  412. * @param[in] cmp clock counter compare value
  413. * @param[in] ex_cmp extended counter compare value
  414. */
  415. static inline void pwm_cmp_update_cmp_value(PWM_Type *pwm_x, uint8_t index,
  416. uint32_t cmp, uint16_t ex_cmp)
  417. {
  418. pwm_x->CMP[index] = (pwm_x->CMP[index] & ~(PWM_CMP_CMP_MASK | PWM_CMP_XCMP_MASK))
  419. | PWM_CMP_CMP_SET(cmp) | PWM_CMP_XCMP_SET(ex_cmp);
  420. }
  421. /**
  422. * @brief config pwm cmp
  423. *
  424. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  425. * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  426. * @param[in] config @ref pwm_cmp_config_t
  427. */
  428. static inline void pwm_config_cmp(PWM_Type *pwm_x, uint8_t index, pwm_cmp_config_t *config)
  429. {
  430. pwm_shadow_register_unlock(pwm_x);
  431. if (config->mode == pwm_cmp_mode_output_compare) {
  432. pwm_x->CMPCFG[index] = PWM_CMPCFG_XCNTCMPEN_SET(config->enable_ex_cmp)
  433. | PWM_CMPCFG_CMPSHDWUPT_SET(config->update_trigger);
  434. pwm_x->CMP[index] = PWM_CMP_CMP_SET(config->cmp)
  435. | PWM_CMP_XCMP_SET(config->ex_cmp)
  436. | PWM_CMP_CMPHLF_SET(config->half_clock_cmp)
  437. | PWM_CMP_CMPJIT_SET(config->jitter_cmp);
  438. } else {
  439. pwm_x->CMPCFG[index] |= PWM_CMPCFG_CMPMODE_MASK;
  440. }
  441. }
  442. /**
  443. * @brief config pwm output channel
  444. *
  445. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  446. * @param[in] index channel index (0..(PWM_SOC_PWM_MAX_COUNT-1))
  447. * @param[in] config @ref pwm_output_channel_t
  448. */
  449. static inline void pwm_config_output_channel(PWM_Type *pwm_x, uint8_t index, pwm_output_channel_t *config)
  450. {
  451. pwm_x->CHCFG[index] = PWM_CHCFG_CMPSELBEG_SET(config->cmp_start_index)
  452. | PWM_CHCFG_CMPSELEND_SET(config->cmp_end_index)
  453. | PWM_CHCFG_OUTPOL_SET(config->invert_output);
  454. }
  455. /**
  456. * @brief config pwm fault source
  457. *
  458. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  459. * @param[in] config @ref pwm_fault_source_config_t
  460. */
  461. static inline void pwm_config_fault_source(PWM_Type *pwm_x, pwm_fault_source_config_t *config)
  462. {
  463. pwm_x->GCR = (pwm_x->GCR & ~(PWM_GCR_FAULTI0EN_MASK | PWM_GCR_FAULTI1EN_MASK
  464. | PWM_GCR_FAULTI2EN_MASK | PWM_GCR_FAULTI3EN_MASK
  465. | PWM_GCR_FAULTE0EN_MASK | PWM_GCR_FAULTE1EN_MASK
  466. | PWM_GCR_FAULTRECEDG_MASK | PWM_GCR_FAULTEXPOL_MASK
  467. | PWM_GCR_FAULTRECHWSEL_MASK))
  468. | config->source_mask
  469. | PWM_GCR_FAULTEXPOL_SET(config->external_fault_active_low)
  470. | PWM_GCR_FAULTRECEDG_SET(config->fault_recover_at_rising_edge)
  471. | PWM_GCR_FAULTRECHWSEL_SET(config->fault_output_recovery_trigger);
  472. }
  473. /**
  474. * @brief clear pwm fault status
  475. *
  476. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  477. */
  478. static inline void pwm_clear_fault(PWM_Type *pwm_x)
  479. {
  480. pwm_x->GCR |= PWM_GCR_FAULTCLR_MASK;
  481. }
  482. /**
  483. * @brief stop the pwm timer counter
  484. *
  485. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  486. */
  487. static inline void pwm_stop_counter(PWM_Type *pwm_x)
  488. {
  489. pwm_x->GCR &= ~PWM_GCR_CEN_MASK;
  490. }
  491. /**
  492. * @brief start pwm timer counter
  493. *
  494. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  495. */
  496. static inline void pwm_start_counter(PWM_Type *pwm_x)
  497. {
  498. pwm_x->GCR |= PWM_GCR_CEN_MASK;
  499. }
  500. /**
  501. * @brief enable software force
  502. *
  503. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  504. */
  505. static inline void pwm_enable_sw_force(PWM_Type *pwm_x)
  506. {
  507. pwm_x->GCR |= PWM_GCR_SWFRC_MASK;
  508. }
  509. /**
  510. * @brief disable software force , force will take effect
  511. *
  512. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  513. */
  514. static inline void pwm_disable_sw_force(PWM_Type *pwm_x)
  515. {
  516. pwm_x->GCR &= ~PWM_GCR_SWFRC_MASK;
  517. }
  518. /**
  519. * @brief enable pwm reload value by synci
  520. *
  521. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  522. */
  523. static inline void pwm_enable_reload_at_synci(PWM_Type *pwm_x)
  524. {
  525. pwm_x->GCR |= PWM_GCR_XRLDSYNCEN_MASK | PWM_GCR_RLDSYNCEN_MASK;
  526. }
  527. /**
  528. * @brief disable pwm output
  529. *
  530. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  531. * @param[in] index pwm index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  532. */
  533. static inline void pwm_disable_output(PWM_Type *pwm_x, uint8_t index)
  534. {
  535. pwm_x->PWMCFG[index] &= ~PWM_PWMCFG_OEN_MASK;
  536. }
  537. /**
  538. * @brief enable pwm output
  539. *
  540. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  541. * @param[in] index pwm index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  542. */
  543. static inline void pwm_enable_output(PWM_Type *pwm_x, uint8_t index)
  544. {
  545. pwm_x->PWMCFG[index] |= PWM_PWMCFG_OEN_MASK;
  546. }
  547. /**
  548. * @brief config pwm force output level per output channel
  549. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  550. * @param[in] output_mask PWM output channel force level, set it using the macro
  551. * @arg PWM_FORCE_OUTPUT(pwm_index, force_output)
  552. */
  553. static inline void pwm_set_force_output(PWM_Type *pwm_x, uint32_t output_mask)
  554. {
  555. pwm_x->FRCMD = PWM_FRCMD_FRCMD_SET(output_mask);
  556. }
  557. /**
  558. * @brief config pwm force polarity
  559. *
  560. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  561. * @param[in] polarity polarity of input pwm_force
  562. * @arg 1- active low
  563. * @arg 0- active high
  564. */
  565. static inline void pwm_config_force_polarity(PWM_Type *pwm_x, bool polarity)
  566. {
  567. pwm_x->GCR = (pwm_x->GCR & ~(PWM_GCR_FRCPOL_MASK)) | PWM_GCR_FRCPOL_SET(polarity);
  568. }
  569. /**
  570. * @brief config the force effective time
  571. *
  572. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  573. * @param[in] timing @ref pwm_force_cmd_timing_t
  574. */
  575. static inline void pwm_config_force_cmd_timing(PWM_Type *pwm_x, pwm_force_cmd_timing_t timing)
  576. {
  577. pwm_x->GCR = (pwm_x->GCR & ~(PWM_GCR_FRCTIME_MASK)) | PWM_GCR_FRCTIME_SET(timing);
  578. }
  579. /**
  580. * @brief enable pwm sw force output
  581. *
  582. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  583. * @param[in] index pwm cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  584. */
  585. static inline void pwm_enable_pwm_sw_force_output(PWM_Type *pwm_x, uint8_t index)
  586. {
  587. pwm_x->PWMCFG[index] |= PWM_PWMCFG_OEN_MASK | PWM_PWMCFG_FRCSRCSEL_MASK
  588. | PWM_PWMCFG_FRCSHDWUPT_SET(pwm_shadow_register_update_on_modify);
  589. }
  590. /**
  591. * @brief disable pwm sw force output
  592. *
  593. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  594. * @param[in] index pwm cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  595. */
  596. static inline void pwm_disable_pwm_sw_force_output(PWM_Type *pwm_x, uint8_t index)
  597. {
  598. pwm_x->PWMCFG[index] &= ~PWM_PWMCFG_FRCSRCSEL_MASK;
  599. }
  600. /**
  601. * @brief config PWM channel configure registe
  602. *
  603. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  604. * @param[in] index pwm channel index (0..(PWM_SOC_PWM_MAX_COUNT-1))
  605. * @param[in] config @ref pwm_config_t
  606. * @param[in] enable_pair_mode enable pair mode
  607. * @arg 1- PWM output is in pair mode
  608. * @arg 0- PWM output is in indepandent mode
  609. */
  610. static inline void pwm_config_pwm(PWM_Type *pwm_x, uint8_t index,
  611. pwm_config_t *config, bool enable_pair_mode)
  612. {
  613. pwm_x->PWMCFG[index] = PWM_PWMCFG_OEN_SET(config->enable_output)
  614. | PWM_PWMCFG_FRCSHDWUPT_SET(config->update_trigger)
  615. | PWM_PWMCFG_FAULTMODE_SET(config->fault_mode)
  616. | PWM_PWMCFG_FAULTRECTIME_SET(config->fault_recovery_trigger)
  617. | PWM_PWMCFG_FRCSRCSEL_SET(config->force_source)
  618. | PWM_PWMCFG_PAIR_SET(enable_pair_mode)
  619. | PWM_PWMCFG_DEADAREA_SET(config->dead_zone_in_half_cycle);
  620. }
  621. /**
  622. * @brief pwm load cmp shadow on match
  623. *
  624. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  625. * @param[in] index cmp index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  626. * @param[in] config @ref pwm_cmp_config_t
  627. * @retval status_invalid_argument or status_success
  628. */
  629. hpm_stat_t pwm_load_cmp_shadow_on_match(PWM_Type *pwm_x,
  630. uint8_t index,
  631. pwm_cmp_config_t *config);
  632. /**
  633. * @brief pwm get captured count
  634. *
  635. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  636. * @param[out] buf count value
  637. * @param[in] counter @ref pwm_counter_type_t
  638. * @param[in] start_index start capture index (0..(PWM_SOC_CMP_MAX_COUNT-1))
  639. * @param[in] num capture num (1..PWM_SOC_CMP_MAX_COUNT)
  640. */
  641. void pwm_get_captured_count(PWM_Type *pwm_x, uint32_t *buf, pwm_counter_type_t counter, uint8_t start_index, uint8_t num);
  642. /**
  643. * @brief get default cmp config
  644. *
  645. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  646. * @param[out] config @ref pwm_cmp_config_t
  647. */
  648. void pwm_get_default_cmp_config(PWM_Type *pwm_x, pwm_cmp_config_t *config);
  649. /**
  650. * @brief get default output channel config
  651. *
  652. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  653. * @param[out] config @ref pwm_output_channel_t
  654. */
  655. void pwm_get_default_output_channel_config(PWM_Type *pwm_x, pwm_output_channel_t *config);
  656. /**
  657. * @brief get default pwm config
  658. *
  659. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  660. * @param[out] config @ref pwm_config_t
  661. */
  662. void pwm_get_default_pwm_config(PWM_Type *pwm_x, pwm_config_t *config);
  663. /**
  664. * @brief get default pwm pair config
  665. *
  666. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  667. * @param[out] config @ref pwm_pair_config_t
  668. */
  669. void pwm_get_default_pwm_pair_config(PWM_Type *pwm_x, pwm_pair_config_t *config);
  670. /**
  671. * @brief setup waveform
  672. *
  673. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  674. * @param[in] pwm_index pwm channel index (0..(PWM_SOC_PWM_MAX_COUNT-1))
  675. * @param[in] pwm_config @ref pwm_config_t
  676. * @param[in] cmp_start_index pwm cmp index (0..(PWM_SOC_PWM_MAX_COUNT-1))
  677. * @param[in] cmp @ref pwm_cmp_config_t
  678. * @param[in] cmp_num cmp num (1..PWM_SOC_CMP_MAX_COUNT), cmp[cmp_num-1] must not overflow
  679. * @retval hpm_stat_t
  680. */
  681. hpm_stat_t pwm_setup_waveform(PWM_Type *pwm_x,
  682. uint8_t pwm_index, pwm_config_t *pwm_config,
  683. uint8_t cmp_start_index, pwm_cmp_config_t *cmp, uint8_t cmp_num);
  684. /**
  685. * @brief setup pwm waveform in pair
  686. *
  687. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  688. * @param[in] pwm_index pwm channel index (0..(PWM_SOC_PWM_MAX_COUNT-1))
  689. * @param[in] pwm_pair_config @ref pwm_pair_config_t
  690. * @param[in] cmp_start_index pwm cmp index (0..(PWM_SOC_PWM_MAX_COUNT-1))
  691. * @param[in] cmp @ref pwm_cmp_config_t
  692. * @param[in] cmp_num cmp num (1..PWM_SOC_CMP_MAX_COUNT), cmp[cmp_num-1] must not overflow
  693. * @retval hpm_stat_t @ref status_invalid_argument or @ref status_success
  694. */
  695. hpm_stat_t pwm_setup_waveform_in_pair(PWM_Type *pwm_x,
  696. uint8_t pwm_index, pwm_pair_config_t *pwm_pair_config,
  697. uint8_t cmp_start_index, pwm_cmp_config_t *cmp, uint8_t cmp_num);
  698. /**
  699. * @brief update raw compare value for edge aligned waveform
  700. *
  701. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  702. * @param[in] cmp_index index of cmp to be adjusted (0..(PWM_SOC_PWM_MAX_COUNT-1))
  703. * @param[in] target_cmp target compare value
  704. * @retval hpm_stat_t @ref status_invalid_argument or @ref status_success
  705. */
  706. hpm_stat_t pwm_update_raw_cmp_edge_aligned(PWM_Type *pwm_x, uint8_t cmp_index,
  707. uint32_t target_cmp);
  708. /**
  709. * @brief update raw compare value for central aligned waveform
  710. *
  711. * @param[in] pwm_x PWM base address, HPM_PWMx(x=0..n)
  712. * @param[in] cmp1_index index of cmp1 to be adjusted (cmp1_index must even number)
  713. * @param[in] cmp2_index index of cmp2 to be adjusted (cmp2_index must odd number)
  714. * @param[in] target_cmp1 target compare value for cmp1
  715. * @param[in] target_cmp2 target compare value for cmp2
  716. * @retval hpm_stat_t @ref status_invalid_argument or @ref status_success cmp1_index
  717. */
  718. hpm_stat_t pwm_update_raw_cmp_central_aligned(PWM_Type *pwm_x, uint8_t cmp1_index,
  719. uint8_t cmp2_index, uint32_t target_cmp1, uint32_t target_cmp2);
  720. #ifdef __cplusplus
  721. }
  722. #endif
  723. /**
  724. * @}
  725. */
  726. #endif /* HPM_PWM_DRV_H */