gd32f4xx_ctc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /*!
  2. \file gd32f4xx_ctc.c
  3. \brief CTC driver
  4. \version 2016-08-15, V1.0.0, firmware for GD32F4xx
  5. \version 2018-12-12, V2.0.0, firmware for GD32F4xx
  6. \version 2020-09-30, V2.1.0, firmware for GD32F4xx
  7. */
  8. /*
  9. Copyright (c) 2020, GigaDevice Semiconductor Inc.
  10. Redistribution and use in source and binary forms, with or without modification,
  11. are permitted provided that the following conditions are met:
  12. 1. Redistributions of source code must retain the above copyright notice, this
  13. list of conditions and the following disclaimer.
  14. 2. Redistributions in binary form must reproduce the above copyright notice,
  15. this list of conditions and the following disclaimer in the documentation
  16. and/or other materials provided with the distribution.
  17. 3. Neither the name of the copyright holder nor the names of its contributors
  18. may be used to endorse or promote products derived from this software without
  19. specific prior written permission.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  24. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  27. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  29. OF SUCH DAMAGE.
  30. */
  31. #include "gd32f4xx_ctc.h"
  32. #define CTC_FLAG_MASK ((uint32_t)0x00000700U)
  33. /* CTC register bit offset */
  34. #define CTC_TRIMVALUE_OFFSET ((uint32_t)8U)
  35. #define CTC_TRIM_VALUE_OFFSET ((uint32_t)8U)
  36. #define CTC_REFCAP_OFFSET ((uint32_t)16U)
  37. #define CTC_LIMIT_VALUE_OFFSET ((uint32_t)16U)
  38. /*!
  39. \brief reset CTC clock trim controller
  40. \param[in] none
  41. \param[out] none
  42. \retval none
  43. */
  44. void ctc_deinit(void)
  45. {
  46. /* reset CTC */
  47. rcu_periph_reset_enable(RCU_CTCRST);
  48. rcu_periph_reset_disable(RCU_CTCRST);
  49. }
  50. /*!
  51. \brief enable CTC trim counter
  52. \param[in] none
  53. \param[out] none
  54. \retval none
  55. */
  56. void ctc_counter_enable(void)
  57. {
  58. CTC_CTL0 |= (uint32_t)CTC_CTL0_CNTEN;
  59. }
  60. /*!
  61. \brief disable CTC trim counter
  62. \param[in] none
  63. \param[out] none
  64. \retval none
  65. */
  66. void ctc_counter_disable(void)
  67. {
  68. CTC_CTL0 &= (uint32_t)(~CTC_CTL0_CNTEN);
  69. }
  70. /*!
  71. \brief configure the IRC48M trim value
  72. \param[in] ctc_trim_value: 8-bit IRC48M trim value
  73. \arg 0x00 - 0x3F
  74. \param[out] none
  75. \retval none
  76. */
  77. void ctc_irc48m_trim_value_config(uint8_t trim_value)
  78. {
  79. /* clear TRIMVALUE bits */
  80. CTC_CTL0 &= (~(uint32_t)CTC_CTL0_TRIMVALUE);
  81. /* set TRIMVALUE bits */
  82. CTC_CTL0 |= ((uint32_t)trim_value << CTC_TRIM_VALUE_OFFSET);
  83. }
  84. /*!
  85. \brief generate software reference source sync pulse
  86. \param[in] none
  87. \param[out] none
  88. \retval none
  89. */
  90. void ctc_software_refsource_pulse_generate(void)
  91. {
  92. CTC_CTL0 |= (uint32_t)CTC_CTL0_SWREFPUL;
  93. }
  94. /*!
  95. \brief configure hardware automatically trim mode
  96. \param[in] hardmode:
  97. only one parameter can be selected which is shown as below:
  98. \arg CTC_HARDWARE_TRIM_MODE_ENABLE: hardware automatically trim mode enable
  99. \arg CTC_HARDWARE_TRIM_MODE_DISABLE: hardware automatically trim mode disable
  100. \param[out] none
  101. \retval none
  102. */
  103. void ctc_hardware_trim_mode_config(uint32_t hardmode)
  104. {
  105. CTC_CTL0 &= (uint32_t)(~CTC_CTL0_AUTOTRIM);
  106. CTC_CTL0 |= (uint32_t)hardmode;
  107. }
  108. /*!
  109. \brief configure reference signal source polarity
  110. \param[in] polarity:
  111. only one parameter can be selected which is shown as below:
  112. \arg CTC_REFSOURCE_POLARITY_FALLING: reference signal source polarity is falling edge
  113. \arg CTC_REFSOURCE_POLARITY_RISING: reference signal source polarity is rising edge
  114. \param[out] none
  115. \retval none
  116. */
  117. void ctc_refsource_polarity_config(uint32_t polarity)
  118. {
  119. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPOL);
  120. CTC_CTL1 |= (uint32_t)polarity;
  121. }
  122. /*!
  123. \brief select USBFS or USBHS SOF signal
  124. \param[in] usbsof:
  125. \arg CTC_USBSOFSEL_USBHS: USBHS SOF signal is selected
  126. \arg CTC_USBSOFSEL_USBFS: USBFS SOF signal is selected
  127. \param[out] none
  128. \retval none
  129. */
  130. void ctc_usbsof_signal_select(uint32_t usbsof)
  131. {
  132. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_USBSOFSEL);
  133. CTC_CTL1 |= (uint32_t)usbsof;
  134. }
  135. /*!
  136. \brief select reference signal source
  137. \param[in] refs:
  138. only one parameter can be selected which is shown as below:
  139. \arg CTC_REFSOURCE_GPIO: GPIO is selected
  140. \arg CTC_REFSOURCE_LXTAL: LXTAL is selected
  141. \arg CTC_REFSOURCE_USBSOF: USBSOF is selected
  142. \param[out] none
  143. \retval none
  144. */
  145. void ctc_refsource_signal_select(uint32_t refs)
  146. {
  147. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL);
  148. CTC_CTL1 |= (uint32_t)refs;
  149. }
  150. /*!
  151. \brief configure reference signal source prescaler
  152. \param[in] prescaler:
  153. only one parameter can be selected which is shown as below:
  154. \arg CTC_REFSOURCE_PSC_OFF: reference signal not divided
  155. \arg CTC_REFSOURCE_PSC_DIV2: reference signal divided by 2
  156. \arg CTC_REFSOURCE_PSC_DIV4: reference signal divided by 4
  157. \arg CTC_REFSOURCE_PSC_DIV8: reference signal divided by 8
  158. \arg CTC_REFSOURCE_PSC_DIV16: reference signal divided by 16
  159. \arg CTC_REFSOURCE_PSC_DIV32: reference signal divided by 32
  160. \arg CTC_REFSOURCE_PSC_DIV64: reference signal divided by 64
  161. \arg CTC_REFSOURCE_PSC_DIV128: reference signal divided by 128
  162. \param[out] none
  163. \retval none
  164. */
  165. void ctc_refsource_prescaler_config(uint32_t prescaler)
  166. {
  167. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC);
  168. CTC_CTL1 |= (uint32_t)prescaler;
  169. }
  170. /*!
  171. \brief configure clock trim base limit value
  172. \param[in] limit_value: 8-bit clock trim base limit value
  173. \arg 0x00 - 0xFF
  174. \param[out] none
  175. \retval none
  176. */
  177. void ctc_clock_limit_value_config(uint8_t limit_value)
  178. {
  179. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM);
  180. CTC_CTL1 |= (uint32_t)((uint32_t)limit_value << CTC_LIMIT_VALUE_OFFSET);
  181. }
  182. /*!
  183. \brief configure CTC counter reload value
  184. \param[in] reload_value: 16-bit CTC counter reload value
  185. \arg 0x0000 - 0xFFFF
  186. \param[out] none
  187. \retval none
  188. */
  189. void ctc_counter_reload_value_config(uint16_t reload_value)
  190. {
  191. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE);
  192. CTC_CTL1 |= (uint32_t)reload_value;
  193. }
  194. /*!
  195. \brief read CTC counter capture value when reference sync pulse occurred
  196. \param[in] none
  197. \param[out] none
  198. \retval the 16-bit CTC counter capture value
  199. */
  200. uint16_t ctc_counter_capture_value_read(void)
  201. {
  202. uint16_t capture_value = 0U;
  203. capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP)>> CTC_REFCAP_OFFSET);
  204. return (capture_value);
  205. }
  206. /*!
  207. \brief read CTC trim counter direction when reference sync pulse occurred
  208. \param[in] none
  209. \param[out] none
  210. \retval FlagStatus: SET or RESET
  211. \arg SET: CTC trim counter direction is down-counting
  212. \arg RESET: CTC trim counter direction is up-counting
  213. */
  214. FlagStatus ctc_counter_direction_read(void)
  215. {
  216. if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){
  217. return SET;
  218. }else{
  219. return RESET;
  220. }
  221. }
  222. /*!
  223. \brief read CTC counter reload value
  224. \param[in] none
  225. \param[out] none
  226. \retval the 16-bit CTC counter reload value
  227. */
  228. uint16_t ctc_counter_reload_value_read(void)
  229. {
  230. uint16_t reload_value = 0U;
  231. reload_value = (uint16_t)(CTC_CTL1 & CTC_CTL1_RLVALUE);
  232. return (reload_value);
  233. }
  234. /*!
  235. \brief read the IRC48M trim value
  236. \param[in] none
  237. \param[out] none
  238. \retval the 8-bit IRC48M trim value
  239. */
  240. uint8_t ctc_irc48m_trim_value_read(void)
  241. {
  242. uint8_t trim_value = 0U;
  243. trim_value = (uint8_t)((CTC_CTL0 & CTC_CTL0_TRIMVALUE) >> CTC_TRIMVALUE_OFFSET);
  244. return (trim_value);
  245. }
  246. /*!
  247. \brief enable the CTC interrupt
  248. \param[in] interrupt: CTC interrupt enable
  249. one or more parameters can be selected which are shown as below:
  250. \arg CTC_INT_CKOK: clock trim OK interrupt enable
  251. \arg CTC_INT_CKWARN: clock trim warning interrupt enable
  252. \arg CTC_INT_ERR: error interrupt enable
  253. \arg CTC_INT_EREF: expect reference interrupt enable
  254. \param[out] none
  255. \retval none
  256. */
  257. void ctc_interrupt_enable(uint32_t interrupt)
  258. {
  259. CTC_CTL0 |= (uint32_t)interrupt;
  260. }
  261. /*!
  262. \brief disable the CTC interrupt
  263. \param[in] interrupt: CTC interrupt enable source
  264. one or more parameters can be selected which are shown as below:
  265. \arg CTC_INT_CKOK: clock trim OK interrupt enable
  266. \arg CTC_INT_CKWARN: clock trim warning interrupt enable
  267. \arg CTC_INT_ERR: error interrupt enable
  268. \arg CTC_INT_EREF: expect reference interrupt enable
  269. \param[out] none
  270. \retval none
  271. */
  272. void ctc_interrupt_disable(uint32_t interrupt)
  273. {
  274. CTC_CTL0 &= (uint32_t)(~interrupt);
  275. }
  276. /*!
  277. \brief get CTC interrupt flag
  278. \param[in] int_flag: the CTC interrupt flag
  279. only one parameter can be selected which is shown as below:
  280. \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt
  281. \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
  282. \arg CTC_INT_FLAG_ERR: error interrupt
  283. \arg CTC_INT_FLAG_EREF: expect reference interrupt
  284. \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
  285. \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
  286. \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
  287. \param[out] none
  288. \retval FlagStatus: SET or RESET
  289. */
  290. FlagStatus ctc_interrupt_flag_get(uint32_t int_flag)
  291. {
  292. uint32_t interrupt_flag = 0U, intenable = 0U;
  293. /* check whether the interrupt is enabled */
  294. if(RESET != (int_flag & CTC_FLAG_MASK)){
  295. intenable = CTC_CTL0 & CTC_CTL0_ERRIE;
  296. }else{
  297. intenable = CTC_CTL0 & int_flag;
  298. }
  299. /* get interrupt flag status */
  300. interrupt_flag = CTC_STAT & int_flag;
  301. if(interrupt_flag && intenable){
  302. return SET;
  303. }else{
  304. return RESET;
  305. }
  306. }
  307. /*!
  308. \brief clear CTC interrupt flag
  309. \param[in] int_flag: the CTC interrupt flag
  310. only one parameter can be selected which is shown as below:
  311. \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt
  312. \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
  313. \arg CTC_INT_FLAG_ERR: error interrupt
  314. \arg CTC_INT_FLAG_EREF: expect reference interrupt
  315. \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
  316. \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
  317. \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
  318. \param[out] none
  319. \retval none
  320. */
  321. void ctc_interrupt_flag_clear(uint32_t int_flag)
  322. {
  323. if(RESET != (int_flag & CTC_FLAG_MASK)){
  324. CTC_INTC |= CTC_INTC_ERRIC;
  325. }else{
  326. CTC_INTC |= int_flag;
  327. }
  328. }
  329. /*!
  330. \brief get CTC flag
  331. \param[in] flag: the CTC flag
  332. only one parameter can be selected which is shown as below:
  333. \arg CTC_FLAG_CKOK: clock trim OK flag
  334. \arg CTC_FLAG_CKWARN: clock trim warning flag
  335. \arg CTC_FLAG_ERR: error flag
  336. \arg CTC_FLAG_EREF: expect reference flag
  337. \arg CTC_FLAG_CKERR: clock trim error bit
  338. \arg CTC_FLAG_REFMISS: reference sync pulse miss
  339. \arg CTC_FLAG_TRIMERR: trim value error bit
  340. \param[out] none
  341. \retval FlagStatus: SET or RESET
  342. */
  343. FlagStatus ctc_flag_get(uint32_t flag)
  344. {
  345. if(RESET != (CTC_STAT & flag)){
  346. return SET;
  347. }else{
  348. return RESET;
  349. }
  350. }
  351. /*!
  352. \brief clear CTC flag
  353. \param[in] flag: the CTC flag
  354. only one parameter can be selected which is shown as below:
  355. \arg CTC_FLAG_CKOK: clock trim OK flag
  356. \arg CTC_FLAG_CKWARN: clock trim warning flag
  357. \arg CTC_FLAG_ERR: error flag
  358. \arg CTC_FLAG_EREF: expect reference flag
  359. \arg CTC_FLAG_CKERR: clock trim error bit
  360. \arg CTC_FLAG_REFMISS: reference sync pulse miss
  361. \arg CTC_FLAG_TRIMERR: trim value error bit
  362. \param[out] none
  363. \retval none
  364. */
  365. void ctc_flag_clear(uint32_t flag)
  366. {
  367. if(RESET != (flag & CTC_FLAG_MASK)){
  368. CTC_INTC |= CTC_INTC_ERRIC;
  369. }else{
  370. CTC_INTC |= flag;
  371. }
  372. }