gd32f4xx_ctc.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*!
  2. \file gd32f4xx_ctc.c
  3. \brief CTC driver
  4. */
  5. /*
  6. Copyright (C) 2016 GigaDevice
  7. 2016-08-15, V1.0.0, firmware for GD32F4xx
  8. */
  9. #include "gd32f4xx_ctc.h"
  10. #define CTC_FLAG_MASK ((uint32_t)0x00000700U)
  11. /*!
  12. \brief reset CTC clock trim controller
  13. \param[in] none
  14. \param[out] none
  15. \retval none
  16. */
  17. void ctc_deinit(void)
  18. {
  19. /* reset CTC */
  20. rcu_periph_reset_enable(RCU_CTCRST);
  21. rcu_periph_reset_disable(RCU_CTCRST);
  22. }
  23. /*!
  24. \brief configure the IRC48M trim value
  25. \param[in] ctc_trim_value: 8-bit IRC48M trim value
  26. \param[out] none
  27. \retval none
  28. */
  29. void ctc_irc48m_trim_value_config(uint8_t ctc_trim_value)
  30. {
  31. /* clear TRIMVALUE bits */
  32. CTC_CTL0 &= (~(uint32_t)CTC_CTL0_TRIMVALUE);
  33. /* set TRIMVALUE bits */
  34. CTC_CTL0 |= ((uint32_t)ctc_trim_value << 8);
  35. }
  36. /*!
  37. \brief generate software reference source sync pulse
  38. \param[in] none
  39. \param[out] none
  40. \retval none
  41. */
  42. void ctc_software_refsource_pulse_generate(void)
  43. {
  44. CTC_CTL0 |= (uint32_t)CTC_CTL0_SWREFPUL;
  45. }
  46. /*!
  47. \brief configure hardware automatically trim mode
  48. \param[in] ctc_hardmode:
  49. \arg CTC_HARDWARE_TRIM_MODE_ENABLE: hardware automatically trim mode enable
  50. \arg CTC_HARDWARE_TRIM_MODE_DISABLE: hardware automatically trim mode disable
  51. \param[out] none
  52. \retval none
  53. */
  54. void ctc_hardware_trim_mode_config(uint32_t ctc_hardmode)
  55. {
  56. CTC_CTL0 &= (uint32_t)(~CTC_CTL0_AUTOTRIM);
  57. CTC_CTL0 |= (uint32_t)ctc_hardmode;
  58. }
  59. /*!
  60. \brief enable CTC counter
  61. \param[in] none
  62. \param[out] none
  63. \retval none
  64. */
  65. void ctc_counter_enable(void)
  66. {
  67. CTC_CTL0 |= (uint32_t)CTC_CTL0_CNTEN;
  68. }
  69. /*!
  70. \brief disable CTC counter
  71. \param[in] none
  72. \param[out] none
  73. \retval none
  74. */
  75. void ctc_counter_disable(void)
  76. {
  77. CTC_CTL0 &= (uint32_t)(~CTC_CTL0_CNTEN);
  78. }
  79. /*!
  80. \brief configure reference signal source polarity
  81. \param[in] ctc_polarity:
  82. \arg CTC_REFSOURCE_POLARITY_FALLING: reference signal source polarity is falling edge
  83. \arg CTC_REFSOURCE_POLARITY_RISING: reference signal source polarity is rising edge
  84. \param[out] none
  85. \retval none
  86. */
  87. void ctc_refsource_polarity_config(uint32_t ctc_polarity)
  88. {
  89. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPOL);
  90. CTC_CTL1 |= (uint32_t)ctc_polarity;
  91. }
  92. /*!
  93. \brief select USBFS or USBHS SOF signal
  94. \param[in] ctc_usbsof:
  95. \arg CTC_USBSOFSEL_USBHS: USBHS SOF signal is selected
  96. \arg CTC_USBSOFSEL_USBFS: USBFS SOF signal is selected
  97. \param[out] none
  98. \retval none
  99. */
  100. void ctc_usbsof_signal_select(uint32_t ctc_usbsof)
  101. {
  102. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_USBSOFSEL);
  103. CTC_CTL1 |= (uint32_t)ctc_usbsof;
  104. }
  105. /*!
  106. \brief select reference signal source
  107. \param[in] ctc_refs:
  108. \arg CTC_REFSOURCE_GPIO: GPIO is selected
  109. \arg CTC_REFSOURCE_LXTAL: LXTAL is clock selected
  110. \arg CTC_REFSOURCE_USBSOF: USBSOF is selected
  111. \param[out] none
  112. \retval none
  113. */
  114. void ctc_refsource_signal_select(uint32_t ctc_refs)
  115. {
  116. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL);
  117. CTC_CTL1 |= (uint32_t)ctc_refs;
  118. }
  119. /*!
  120. \brief configure reference signal source prescaler
  121. \param[in] ctc_prescaler:
  122. \arg CTC_REFSOURCE_PSC_OFF: reference signal not divided
  123. \arg CTC_REFSOURCE_PSC_DIV2: reference signal divided by 2
  124. \arg CTC_REFSOURCE_PSC_DIV4: reference signal divided by 4
  125. \arg CTC_REFSOURCE_PSC_DIV8: reference signal divided by 8
  126. \arg CTC_REFSOURCE_PSC_DIV16: reference signal divided by 16
  127. \arg CTC_REFSOURCE_PSC_DIV32: reference signal divided by 32
  128. \arg CTC_REFSOURCE_PSC_DIV64: reference signal divided by 64
  129. \arg CTC_REFSOURCE_PSC_DIV128: reference signal divided by 128
  130. \param[out] none
  131. \retval none
  132. */
  133. void ctc_refsource_prescaler_config(uint32_t ctc_prescaler)
  134. {
  135. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC);
  136. CTC_CTL1 |= (uint32_t)ctc_prescaler;
  137. }
  138. /*!
  139. \brief configure clock trim base limit value
  140. \param[in] ctc_limit_value: 8-bit clock trim base limit value
  141. \param[out] none
  142. \retval none
  143. */
  144. void ctc_clock_limit_value_config(uint8_t ctc_limit_value)
  145. {
  146. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM);
  147. CTC_CTL1 |= (uint32_t)((uint32_t)ctc_limit_value << 16);
  148. }
  149. /*!
  150. \brief configure CTC counter reload value
  151. \param[in] ctc_reload_value: 16-bit CTC counter reload value
  152. \param[out] none
  153. \retval none
  154. */
  155. void ctc_counter_reload_value_config(uint16_t ctc_reload_value)
  156. {
  157. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE);
  158. CTC_CTL1 |= (uint32_t)ctc_reload_value;
  159. }
  160. /*!
  161. \brief read CTC counter capture value when reference sync pulse occurred
  162. \param[in] none
  163. \param[out] none
  164. \retval the 16-bit CTC counter capture value
  165. */
  166. uint16_t ctc_counter_capture_value_read(void)
  167. {
  168. uint16_t capture_value = 0U;
  169. capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP)>> 16);
  170. return (capture_value);
  171. }
  172. /*!
  173. \brief read CTC trim counter direction when reference sync pulse occurred
  174. \param[in] none
  175. \param[out] none
  176. \retval FlagStatus: SET or RESET
  177. \arg SET: CTC trim counter direction is down-counting
  178. \arg RESET: CTC trim counter direction is up-counting
  179. */
  180. FlagStatus ctc_counter_direction_read(void)
  181. {
  182. if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){
  183. return SET;
  184. }else{
  185. return RESET;
  186. }
  187. }
  188. /*!
  189. \brief read CTC counter reload value
  190. \param[in] none
  191. \param[out] none
  192. \retval the 16-bit CTC counter reload value
  193. */
  194. uint16_t ctc_counter_reload_value_read(void)
  195. {
  196. uint16_t reload_value = 0U;
  197. reload_value = (uint16_t)(CTC_CTL1 & CTC_CTL1_RLVALUE);
  198. return (reload_value);
  199. }
  200. /*!
  201. \brief read the IRC48M trim value
  202. \param[in] none
  203. \param[out] none
  204. \retval the 8-bit IRC48M trim value
  205. */
  206. uint8_t ctc_irc48m_trim_value_read(void)
  207. {
  208. uint8_t trim_value = 0U;
  209. trim_value = (uint8_t)((CTC_CTL0 & CTC_CTL0_TRIMVALUE) >> 8);
  210. return (trim_value);
  211. }
  212. /*!
  213. \brief enable the CTC interrupt
  214. \param[in] ctc_interrupt: CTC interrupt enable
  215. \arg CTC_INT_CKOKIE: clock trim OK interrupt enable
  216. \arg CTC_INT_CKWARNIE: clock trim warning interrupt enable
  217. \arg CTC_INT_ERRIE: error interrupt enable
  218. \arg CTC_INT_EREFIE: expect reference interrupt enable
  219. \param[out] none
  220. \retval none
  221. */
  222. void ctc_interrupt_enable(uint32_t ctc_interrupt)
  223. {
  224. CTC_CTL0 |= (uint32_t)ctc_interrupt;
  225. }
  226. /*!
  227. \brief disable the CTC interrupt
  228. \param[in] ctc_interrupt: CTC interrupt enable source
  229. \arg CTC_INT_CKOKIE: clock trim OK interrupt enable
  230. \arg CTC_INT_CKWARNIE: clock trim warning interrupt enable
  231. \arg CTC_INT_ERRIE: error interrupt enable
  232. \arg CTC_INT_EREFIE: expect reference interrupt enable
  233. \param[out] none
  234. \retval none
  235. */
  236. void ctc_interrupt_disable(uint32_t ctc_interrupt)
  237. {
  238. CTC_CTL0 &= (uint32_t)(~ctc_interrupt);
  239. }
  240. /*!
  241. \brief get CTC interrupt flag
  242. \param[in] ctc_interrupt: the CTC interrupt flag
  243. \arg CTC_INT_CKOK: clock trim OK interrupt
  244. \arg CTC_INT_CKWARN: clock trim warning interrupt
  245. \arg CTC_INT_ERR: error interrupt
  246. \arg CTC_INT_EREF: expect reference interrupt
  247. \arg CTC_INT_CKERR: clock trim error bit interrupt
  248. \arg CTC_INT_REFMISS: reference sync pulse miss interrupt
  249. \arg CTC_INT_TRIMERR: trim value error interrupt
  250. \param[out] none
  251. \retval FlagStatus: SET or RESET
  252. */
  253. FlagStatus ctc_interrupt_flag_get(uint32_t ctc_interrupt)
  254. {
  255. uint32_t interrupt = 0U, intenable = 0U;
  256. if(ctc_interrupt & CTC_FLAG_MASK){
  257. intenable = CTC_CTL0 & CTC_INT_ERRIE;
  258. }else{
  259. intenable = CTC_CTL0 & ctc_interrupt;
  260. }
  261. interrupt = CTC_STAT & ctc_interrupt;
  262. if(interrupt && intenable){
  263. return SET;
  264. }else{
  265. return RESET;
  266. }
  267. }
  268. /*!
  269. \brief clear CTC interrupt flag
  270. \param[in] ctc_interrupt: the CTC interrupt flag
  271. \arg CTC_INT_CKOK: clock trim OK interrupt
  272. \arg CTC_INT_CKWARN: clock trim warning interrupt
  273. \arg CTC_INT_ERR: error interrupt
  274. \arg CTC_INT_EREF: expect reference interrupt
  275. \arg CTC_INT_CKERR: clock trim error bit interrupt
  276. \arg CTC_INT_REFMISS: reference sync pulse miss interrupt
  277. \arg CTC_INT_TRIMERR: trim value error interrupt
  278. \param[out] none
  279. \retval none
  280. */
  281. void ctc_interrupt_flag_clear(uint32_t ctc_interrupt)
  282. {
  283. if(ctc_interrupt & CTC_FLAG_MASK){
  284. CTC_INTC |= CTC_INTC_ERRIC;
  285. }else{
  286. CTC_INTC |= ctc_interrupt;
  287. }
  288. }
  289. /*!
  290. \brief get CTC flag
  291. \param[in] ctc_flag: the CTC flag
  292. \arg CTC_FLAG_CKOK: clock trim OK flag
  293. \arg CTC_FLAG_CKWARN: clock trim warning flag
  294. \arg CTC_FLAG_ERR: error flag
  295. \arg CTC_FLAG_EREF: expect reference flag
  296. \arg CTC_FLAG_CKERR: clock trim error bit
  297. \arg CTC_FLAG_REFMISS: reference sync pulse miss
  298. \arg CTC_FLAG_TRIMERR: trim value error bit
  299. \param[out] none
  300. \retval FlagStatus: SET or RESET
  301. */
  302. FlagStatus ctc_flag_get(uint32_t ctc_flag)
  303. {
  304. if(RESET != (CTC_STAT & ctc_flag)){
  305. return SET;
  306. }else{
  307. return RESET;
  308. }
  309. }
  310. /*!
  311. \brief clear CTC flag
  312. \param[in] ctc_flag: the CTC flag
  313. \arg CTC_FLAG_CKOK: clock trim OK flag
  314. \arg CTC_FLAG_CKWARN: clock trim warning flag
  315. \arg CTC_FLAG_ERR: error flag
  316. \arg CTC_FLAG_EREF: expect reference flag
  317. \arg CTC_FLAG_CKERR: clock trim error bit
  318. \arg CTC_FLAG_REFMISS: reference sync pulse miss
  319. \arg CTC_FLAG_TRIMERR: trim value error bit
  320. \param[out] none
  321. \retval none
  322. */
  323. void ctc_flag_clear(uint32_t ctc_flag)
  324. {
  325. if(ctc_flag & CTC_FLAG_MASK){
  326. CTC_INTC |= CTC_INTC_ERRIC;
  327. }else{
  328. CTC_INTC |= ctc_flag;
  329. }
  330. }