nu_timer_pwm.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /**************************************************************************//**
  2. * @file timer_pwm.c
  3. * @brief M480 Timer PWM Controller(Timer PWM) driver source file
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. * @copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
  7. *****************************************************************************/
  8. #include "NuMicro.h"
  9. /** @addtogroup Standard_Driver Standard Driver
  10. @{
  11. */
  12. /** @addtogroup TIMER_PWM_Driver TIMER PWM Driver
  13. @{
  14. */
  15. /** @addtogroup TIMER_PWM_EXPORTED_FUNCTIONS TIMER PWM Exported Functions
  16. @{
  17. */
  18. /**
  19. * @brief Set PWM Counter Clock Source
  20. *
  21. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  22. * @param[in] u32CntClkSrc PWM counter clock source, could be one of following source
  23. * - \ref TPWM_CNTR_CLKSRC_TMR_CLK
  24. * - \ref TPWM_CNTR_CLKSRC_TIMER0_INT
  25. * - \ref TPWM_CNTR_CLKSRC_TIMER1_INT
  26. * - \ref TPWM_CNTR_CLKSRC_TIMER2_INT
  27. * - \ref TPWM_CNTR_CLKSRC_TIMER3_INT
  28. *
  29. * @return None
  30. *
  31. * @details This function is used to set PWM counter clock source.
  32. */
  33. void TPWM_SetCounterClockSource(TIMER_T *timer, uint32_t u32CntClkSrc)
  34. {
  35. (timer)->PWMCLKSRC = ((timer)->PWMCLKSRC & ~TIMER_PWMCLKSRC_CLKSRC_Msk) | u32CntClkSrc;
  36. }
  37. /**
  38. * @brief Configure PWM Output Frequency and Duty Cycle
  39. *
  40. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  41. * @param[in] u32Frequency Target generator frequency.
  42. * @param[in] u32DutyCycle Target generator duty cycle percentage. Valid range are between 0~100. 10 means 10%, 20 means 20%...
  43. *
  44. * @return Nearest frequency clock in nano second
  45. *
  46. * @details This API is used to configure PWM output frequency and duty cycle in up count type and auto-reload operation mode.
  47. * @note This API is only available if Timer PWM counter clock source is from TMRx_CLK.
  48. */
  49. uint32_t TPWM_ConfigOutputFreqAndDuty(TIMER_T *timer, uint32_t u32Frequency, uint32_t u32DutyCycle)
  50. {
  51. uint32_t u32PWMClockFreq, u32TargetFreq;
  52. uint32_t u32Prescaler = 0x1000UL, u32Period, u32CMP;
  53. if((timer == TIMER0) || (timer == TIMER1))
  54. {
  55. u32PWMClockFreq = CLK_GetPCLK0Freq();
  56. }
  57. else
  58. {
  59. u32PWMClockFreq = CLK_GetPCLK1Freq();
  60. }
  61. /* Calculate u16PERIOD and u16PSC */
  62. for(u32Prescaler = 1UL; u32Prescaler <= 0x1000UL; u32Prescaler++)
  63. {
  64. u32Period = (u32PWMClockFreq / u32Prescaler) / u32Frequency;
  65. /* If target u32Period is larger than 0x10000, need to use a larger prescaler */
  66. if(u32Period <= 0x10000UL)
  67. {
  68. break;
  69. }
  70. }
  71. /* Store return value here 'cos we're gonna change u32Prescaler & u32Period to the real value to fill into register */
  72. u32TargetFreq = (u32PWMClockFreq / u32Prescaler) / u32Period;
  73. /* Set PWM to up count type */
  74. timer->PWMCTL = (timer->PWMCTL & ~TIMER_PWMCTL_CNTTYPE_Msk) | (TPWM_UP_COUNT << TIMER_PWMCTL_CNTTYPE_Pos);
  75. /* Set PWM to auto-reload mode */
  76. timer->PWMCTL = (timer->PWMCTL & ~TIMER_PWMCTL_CNTMODE_Msk) | TPWM_AUTO_RELOAD_MODE;
  77. /* Convert to real register value */
  78. TPWM_SET_PRESCALER(timer, (u32Prescaler - 1UL));
  79. TPWM_SET_PERIOD(timer, (u32Period - 1UL));
  80. if(u32DutyCycle)
  81. {
  82. u32CMP = (u32DutyCycle * u32Period) / 100UL;
  83. }
  84. else
  85. {
  86. u32CMP = 0UL;
  87. }
  88. TPWM_SET_CMPDAT(timer, u32CMP);
  89. return (u32TargetFreq);
  90. }
  91. /**
  92. * @brief Enable Dead-Time Function
  93. *
  94. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  95. * @param[in] u32DTCount Dead-Time duration in PWM clock count, valid values are between 0x0~0xFFF, but 0x0 means there is no Dead-Time insertion.
  96. *
  97. * @return None
  98. *
  99. * @details This function is used to enable Dead-Time function and counter source is the same as Timer PWM clock source.
  100. * @note The register write-protection function should be disabled before using this function.
  101. */
  102. void TPWM_EnableDeadTime(TIMER_T *timer, uint32_t u32DTCount)
  103. {
  104. timer->PWMDTCTL = TIMER_PWMDTCTL_DTEN_Msk | u32DTCount;
  105. }
  106. /**
  107. * @brief Enable Dead-Time Function
  108. *
  109. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  110. * @param[in] u32DTCount Dead-Time duration in PWM clock count, valid values are between 0x0~0xFFF, but 0x0 means there is no Dead-Time insertion.
  111. *
  112. * @return None
  113. *
  114. * @details This function is used to enable Dead-Time function and counter source is the Timer PWM clock source with prescale.
  115. * @note The register write-protection function should be disabled before using this function.
  116. */
  117. void TPWM_EnableDeadTimeWithPrescale(TIMER_T *timer, uint32_t u32DTCount)
  118. {
  119. timer->PWMDTCTL = TIMER_PWMDTCTL_DTCKSEL_Msk | TIMER_PWMDTCTL_DTEN_Msk | u32DTCount;
  120. }
  121. /**
  122. * @brief Disable Dead-Time Function
  123. *
  124. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  125. *
  126. * @return None
  127. *
  128. * @details This function is used to enable Dead-time of selected channel.
  129. * @note The register write-protection function should be disabled before using this function.
  130. */
  131. void TPWM_DisableDeadTime(TIMER_T *timer)
  132. {
  133. timer->PWMDTCTL = 0x0UL;
  134. }
  135. /**
  136. * @brief Enable PWM Counter
  137. *
  138. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  139. *
  140. * @return None
  141. *
  142. * @details This function is used to enable PWM generator and start counter counting.
  143. */
  144. void TPWM_EnableCounter(TIMER_T *timer)
  145. {
  146. timer->PWMCTL |= TIMER_PWMCTL_CNTEN_Msk;
  147. }
  148. /**
  149. * @brief Disable PWM Generator
  150. *
  151. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  152. *
  153. * @return None
  154. *
  155. * @details This function is used to disable PWM counter immediately by clear CNTEN (TIMERx_PWMCTL[0]) bit.
  156. */
  157. void TPWM_DisableCounter(TIMER_T *timer)
  158. {
  159. timer->PWMCTL &= ~TIMER_PWMCTL_CNTEN_Msk;
  160. }
  161. /**
  162. * @brief Enable Trigger ADC
  163. *
  164. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  165. * @param[in] u32Condition The condition to trigger ADC. It could be one of following conditions:
  166. * - \ref TPWM_TRIGGER_ADC_AT_ZERO_POINT
  167. * - \ref TPWM_TRIGGER_ADC_AT_PERIOD_POINT
  168. * - \ref TPWM_TRIGGER_ADC_AT_ZERO_OR_PERIOD_POINT
  169. * - \ref TPWM_TRIGGER_ADC_AT_COMPARE_UP_COUNT_POINT
  170. * - \ref TPWM_TRIGGER_ADC_AT_COMPARE_DOWN_COUNT_POINT
  171. *
  172. * @return None
  173. *
  174. * @details This function is used to enable specified counter compare event to trigger ADC.
  175. */
  176. void TPWM_EnableTriggerADC(TIMER_T *timer, uint32_t u32Condition)
  177. {
  178. timer->PWMEADCTS = TIMER_PWMEADCTS_TRGEN_Msk | u32Condition;
  179. }
  180. /**
  181. * @brief Disable Trigger ADC
  182. *
  183. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  184. *
  185. * @return None
  186. *
  187. * @details This function is used to disable counter compare event to trigger ADC.
  188. */
  189. void TPWM_DisableTriggerADC(TIMER_T *timer)
  190. {
  191. timer->PWMEADCTS = 0x0UL;
  192. }
  193. /**
  194. * @brief Enable Fault Brake Function
  195. *
  196. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  197. * @param[in] u32CH0Level PWMx_CH0 output level while fault brake event occurs. Valid value is one of following setting
  198. * - \ref TPWM_OUTPUT_TOGGLE
  199. * - \ref TPWM_OUTPUT_NOTHING
  200. * - \ref TPWM_OUTPUT_LOW
  201. * - \ref TPWM_OUTPUT_HIGH
  202. * @param[in] u32CH1Level PWMx_CH1 output level while fault brake event occurs. Valid value is one of following setting
  203. * - \ref TPWM_OUTPUT_TOGGLE
  204. * - \ref TPWM_OUTPUT_NOTHING
  205. * - \ref TPWM_OUTPUT_LOW
  206. * - \ref TPWM_OUTPUT_HIGH
  207. * @param[in] u32BrakeSource Fault brake source, combination of following source
  208. * - \ref TPWM_BRAKE_SOURCE_EDGE_ACMP0
  209. * - \ref TPWM_BRAKE_SOURCE_EDGE_ACMP1
  210. * - \ref TPWM_BRAKE_SOURCE_EDGE_BKPIN
  211. * - \ref TPWM_BRAKE_SOURCE_EDGE_SYS_CSS
  212. * - \ref TPWM_BRAKE_SOURCE_EDGE_SYS_BOD
  213. * - \ref TPWM_BRAKE_SOURCE_EDGE_SYS_COR
  214. * - \ref TPWM_BRAKE_SOURCE_EDGE_SYS_RAM
  215. * - \ref TPWM_BRAKE_SOURCE_LEVEL_ACMP0
  216. * - \ref TPWM_BRAKE_SOURCE_LEVEL_ACMP1
  217. * - \ref TPWM_BRAKE_SOURCE_LEVEL_BKPIN
  218. * - \ref TPWM_BRAKE_SOURCE_LEVEL_SYS_CSS
  219. * - \ref TPWM_BRAKE_SOURCE_LEVEL_SYS_BOD
  220. * - \ref TPWM_BRAKE_SOURCE_LEVEL_SYS_COR
  221. * - \ref TPWM_BRAKE_SOURCE_LEVEL_SYS_RAM
  222. *
  223. * @return None
  224. *
  225. * @details This function is used to enable fault brake function.
  226. * @note The register write-protection function should be disabled before using this function.
  227. */
  228. void TPWM_EnableFaultBrake(TIMER_T *timer, uint32_t u32CH0Level, uint32_t u32CH1Level, uint32_t u32BrakeSource)
  229. {
  230. timer->PWMFAILBRK |= ((u32BrakeSource >> 16) & 0xFUL);
  231. timer->PWMBRKCTL = (timer->PWMBRKCTL & ~(TIMER_PWMBRKCTL_BRKAEVEN_Msk | TIMER_PWMBRKCTL_BRKAODD_Msk)) |
  232. (u32BrakeSource & 0xFFFFUL) | (u32CH0Level << TIMER_PWMBRKCTL_BRKAEVEN_Pos) | (u32CH1Level << TIMER_PWMBRKCTL_BRKAODD_Pos);
  233. }
  234. /**
  235. * @brief Enable Fault Brake Interrupt
  236. *
  237. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  238. * @param[in] u32IntSource Interrupt source, could be one of following source
  239. * - \ref TPWM_BRAKE_EDGE
  240. * - \ref TPWM_BRAKE_LEVEL
  241. *
  242. * @return None
  243. *
  244. * @details This function is used to enable fault brake interrupt.
  245. * @note The register write-protection function should be disabled before using this function.
  246. */
  247. void TPWM_EnableFaultBrakeInt(TIMER_T *timer, uint32_t u32IntSource)
  248. {
  249. timer->PWMINTEN1 |= u32IntSource;
  250. }
  251. /**
  252. * @brief Disable Fault Brake Interrupt
  253. *
  254. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  255. * @param[in] u32IntSource Interrupt source, could be one of following source
  256. * - \ref TPWM_BRAKE_EDGE
  257. * - \ref TPWM_BRAKE_LEVEL
  258. *
  259. * @return None
  260. *
  261. * @details This function is used to disable fault brake interrupt.
  262. * @note The register write-protection function should be disabled before using this function.
  263. */
  264. void TPWM_DisableFaultBrakeInt(TIMER_T *timer, uint32_t u32IntSource)
  265. {
  266. timer->PWMINTEN1 &= ~u32IntSource;
  267. }
  268. /**
  269. * @brief Indicate Fault Brake Interrupt Flag
  270. *
  271. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  272. * @param[in] u32IntSource Interrupt source, could be one of following source
  273. * - \ref TPWM_BRAKE_EDGE
  274. * - \ref TPWM_BRAKE_LEVEL
  275. *
  276. * @return Fault brake interrupt flag of specified source
  277. * @retval 0 Fault brake interrupt did not occurred
  278. * @retval 1 Fault brake interrupt occurred
  279. *
  280. * @details This function is used to indicate fault brake interrupt flag occurred or not of selected source.
  281. */
  282. uint32_t TPWM_GetFaultBrakeIntFlag(TIMER_T *timer, uint32_t u32IntSource)
  283. {
  284. return ((timer->PWMINTSTS1 & (0x3UL << u32IntSource))? 1UL : 0UL);
  285. }
  286. /**
  287. * @brief Clear Fault Brake Interrupt Flags
  288. *
  289. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  290. * @param[in] u32IntSource Interrupt source, could be one of following source
  291. * - \ref TPWM_BRAKE_EDGE
  292. * - \ref TPWM_BRAKE_LEVEL
  293. *
  294. * @return None
  295. *
  296. * @details This function is used to clear fault brake interrupt flags of selected source.
  297. * @note The register write-protection function should be disabled before using this function.
  298. */
  299. void TPWM_ClearFaultBrakeIntFlag(TIMER_T *timer, uint32_t u32IntSource)
  300. {
  301. timer->PWMINTSTS1 = (0x3UL << u32IntSource);
  302. }
  303. /**
  304. * @brief Enable load mode of selected channel
  305. *
  306. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  307. * @param[in] u32LoadMode Timer PWM counter loading mode, could be one of following mode
  308. * - \ref TPWM_LOAD_MODE_PERIOD
  309. * - \ref TPWM_LOAD_MODE_IMMEDIATE
  310. * - \ref TPWM_LOAD_MODE_CENTER
  311. *
  312. * @return None
  313. *
  314. * @details This function is used to enable load mode of selected channel.
  315. * @note The default loading mode is period loading mode.
  316. */
  317. void TPWM_SetLoadMode(TIMER_T *timer, uint32_t u32LoadMode)
  318. {
  319. timer->PWMCTL = (timer->PWMCTL & ~(TIMER_PWMCTL_IMMLDEN_Msk | TIMER_PWMCTL_CTRLD_Msk)) | u32LoadMode;
  320. }
  321. /**
  322. * @brief Enable brake pin noise filter function
  323. *
  324. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  325. * @param[in] u32BrakePinSrc The external brake pin source, could be one of following source
  326. * - \ref TPWM_TM_BRAKE0
  327. * - \ref TPWM_TM_BRAKE1
  328. * - \ref TPWM_TM_BRAKE2
  329. * - \ref TPWM_TM_BRAKE3
  330. * @param[in] u32DebounceCnt This value controls the real debounce sample time.
  331. * The target debounce sample time is (debounce sample clock period) * (u32DebounceCnt).
  332. * @param[in] u32ClkSrcSel Brake pin detector debounce clock source, could be one of following source
  333. * - \ref TPWM_BKP_DBCLK_PCLK_DIV_1
  334. * - \ref TPWM_BKP_DBCLK_PCLK_DIV_2
  335. * - \ref TPWM_BKP_DBCLK_PCLK_DIV_4
  336. * - \ref TPWM_BKP_DBCLK_PCLK_DIV_8
  337. * - \ref TPWM_BKP_DBCLK_PCLK_DIV_16
  338. * - \ref TPWM_BKP_DBCLK_PCLK_DIV_32
  339. * - \ref TPWM_BKP_DBCLK_PCLK_DIV_64
  340. * - \ref TPWM_BKP_DBCLK_PCLK_DIV_128
  341. *
  342. * @return None
  343. *
  344. * @details This function is used to enable external brake pin detector noise filter function.
  345. */
  346. void TPWM_EnableBrakePinDebounce(TIMER_T *timer, uint32_t u32BrakePinSrc, uint32_t u32DebounceCnt, uint32_t u32ClkSrcSel)
  347. {
  348. timer->PWMBNF = (timer->PWMBNF & ~(TIMER_PWMBNF_BKPINSRC_Msk | TIMER_PWMBNF_BRKFCNT_Msk | TIMER_PWMBNF_BRKNFSEL_Msk)) |
  349. (u32BrakePinSrc << TIMER_PWMBNF_BKPINSRC_Pos) |
  350. (u32DebounceCnt << TIMER_PWMBNF_BRKFCNT_Pos) |
  351. (u32ClkSrcSel << TIMER_PWMBNF_BRKNFSEL_Pos) | TIMER_PWMBNF_BRKNFEN_Msk;
  352. }
  353. /**
  354. * @brief Disable brake pin noise filter function
  355. *
  356. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  357. *
  358. * @return None
  359. *
  360. * @details This function is used to disable external brake pin detector noise filter function.
  361. */
  362. void TPWM_DisableBrakePinDebounce(TIMER_T *timer)
  363. {
  364. timer->PWMBNF &= ~TIMER_PWMBNF_BRKNFEN_Msk;
  365. }
  366. /**
  367. * @brief Enable brake pin inverse function
  368. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  369. * @return None
  370. * @details This function is used to enable PWM brake pin inverse function.
  371. */
  372. void TPWM_EnableBrakePinInverse(TIMER_T *timer)
  373. {
  374. timer->PWMBNF |= TIMER_PWMBNF_BRKPINV_Msk;
  375. }
  376. /**
  377. * @brief Disable brake pin inverse function
  378. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  379. * @return None
  380. * @details This function is used to disable PWM brake pin inverse function.
  381. */
  382. void TPWM_DisableBrakePinInverse(TIMER_T *timer)
  383. {
  384. timer->PWMBNF &= ~TIMER_PWMBNF_BRKPINV_Msk;
  385. }
  386. /**
  387. * @brief Set brake pin source
  388. * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
  389. * @param[in] u32BrakePinNum Brake pin selection. One of the following:
  390. * - \ref TPWM_TM_BRAKE0
  391. * - \ref TPWM_TM_BRAKE1
  392. * - \ref TPWM_TM_BRAKE2
  393. * - \ref TPWM_TM_BRAKE3
  394. * @return None
  395. * @details This function is used to set PWM brake pin source.
  396. */
  397. void TPWM_SetBrakePinSource(TIMER_T *timer, uint32_t u32BrakePinNum)
  398. {
  399. timer->PWMBNF = (((timer)->PWMBNF & ~TIMER_PWMBNF_BKPINSRC_Msk) | (u32BrakePinNum << TIMER_PWMBNF_BKPINSRC_Pos));
  400. }
  401. /*@}*/ /* end of group TIMER_PWM_EXPORTED_FUNCTIONS */
  402. /*@}*/ /* end of group TIMER_PWM_Driver */
  403. /*@}*/ /* end of group Standard_Driver */
  404. /*** (C) COPYRIGHT 2017 Nuvoton Technology Corp. ***/