gd32f30x_ctc.c 13 KB

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