gd32f30x_ctc.c 12 KB

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