gd32f30x_ctc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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. \version 2020-09-30, V2.1.0, firmware for GD32F30x
  8. */
  9. /*
  10. Copyright (c) 2020, GigaDevice Semiconductor Inc.
  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] trim_value: 6-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. \param[out] none
  130. \retval none
  131. */
  132. void ctc_refsource_signal_select(uint32_t refs)
  133. {
  134. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL);
  135. CTC_CTL1 |= (uint32_t)refs;
  136. }
  137. /*!
  138. \brief configure reference signal source prescaler
  139. \param[in] prescaler:
  140. only one parameter can be selected which is shown as below:
  141. \arg CTC_REFSOURCE_PSC_OFF: reference signal not divided
  142. \arg CTC_REFSOURCE_PSC_DIV2: reference signal divided by 2
  143. \arg CTC_REFSOURCE_PSC_DIV4: reference signal divided by 4
  144. \arg CTC_REFSOURCE_PSC_DIV8: reference signal divided by 8
  145. \arg CTC_REFSOURCE_PSC_DIV16: reference signal divided by 16
  146. \arg CTC_REFSOURCE_PSC_DIV32: reference signal divided by 32
  147. \arg CTC_REFSOURCE_PSC_DIV64: reference signal divided by 64
  148. \arg CTC_REFSOURCE_PSC_DIV128: reference signal divided by 128
  149. \param[out] none
  150. \retval none
  151. */
  152. void ctc_refsource_prescaler_config(uint32_t prescaler)
  153. {
  154. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC);
  155. CTC_CTL1 |= (uint32_t)prescaler;
  156. }
  157. /*!
  158. \brief configure clock trim base limit value
  159. \param[in] limit_value: 8-bit clock trim base limit value
  160. \arg 0x00 - 0xFF
  161. \param[out] none
  162. \retval none
  163. */
  164. void ctc_clock_limit_value_config(uint8_t limit_value)
  165. {
  166. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM);
  167. CTC_CTL1 |= (uint32_t)((uint32_t)limit_value << CTC_LIMIT_VALUE_OFFSET);
  168. }
  169. /*!
  170. \brief configure CTC counter reload value
  171. \param[in] reload_value: 16-bit CTC counter reload value
  172. \arg 0x0000 - 0xFFFF
  173. \param[out] none
  174. \retval none
  175. */
  176. void ctc_counter_reload_value_config(uint16_t reload_value)
  177. {
  178. CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE);
  179. CTC_CTL1 |= (uint32_t)reload_value;
  180. }
  181. /*!
  182. \brief read CTC counter capture value when reference sync pulse occurred
  183. \param[in] none
  184. \param[out] none
  185. \retval the 16-bit CTC counter capture value
  186. */
  187. uint16_t ctc_counter_capture_value_read(void)
  188. {
  189. uint16_t capture_value = 0U;
  190. capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP)>> CTC_REFCAP_OFFSET);
  191. return (capture_value);
  192. }
  193. /*!
  194. \brief read CTC trim counter direction when reference sync pulse occurred
  195. \param[in] none
  196. \param[out] none
  197. \retval FlagStatus: SET or RESET
  198. \arg SET: CTC trim counter direction is down-counting
  199. \arg RESET: CTC trim counter direction is up-counting
  200. */
  201. FlagStatus ctc_counter_direction_read(void)
  202. {
  203. if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){
  204. return SET;
  205. }else{
  206. return RESET;
  207. }
  208. }
  209. /*!
  210. \brief read CTC counter reload value
  211. \param[in] none
  212. \param[out] none
  213. \retval the 16-bit CTC counter reload value
  214. */
  215. uint16_t ctc_counter_reload_value_read(void)
  216. {
  217. uint16_t reload_value = 0U;
  218. reload_value = (uint16_t)(CTC_CTL1 & CTC_CTL1_RLVALUE);
  219. return (reload_value);
  220. }
  221. /*!
  222. \brief read the IRC48M trim value
  223. \param[in] none
  224. \param[out] none
  225. \retval the 6-bit IRC48M trim value
  226. */
  227. uint8_t ctc_irc48m_trim_value_read(void)
  228. {
  229. uint8_t trim_value = 0U;
  230. trim_value = (uint8_t)((CTC_CTL0 & CTC_CTL0_TRIMVALUE) >> CTC_TRIMVALUE_OFFSET);
  231. return (trim_value);
  232. }
  233. /*!
  234. \brief get CTC flag
  235. \param[in] flag: the CTC flag
  236. only one parameter can be selected which is shown as below:
  237. \arg CTC_FLAG_CKOK: clock trim OK flag
  238. \arg CTC_FLAG_CKWARN: clock trim warning flag
  239. \arg CTC_FLAG_ERR: error flag
  240. \arg CTC_FLAG_EREF: expect reference flag
  241. \arg CTC_FLAG_CKERR: clock trim error bit
  242. \arg CTC_FLAG_REFMISS: reference sync pulse miss
  243. \arg CTC_FLAG_TRIMERR: trim value error bit
  244. \param[out] none
  245. \retval FlagStatus: SET or RESET
  246. */
  247. FlagStatus ctc_flag_get(uint32_t flag)
  248. {
  249. if(RESET != (CTC_STAT & flag)){
  250. return SET;
  251. }else{
  252. return RESET;
  253. }
  254. }
  255. /*!
  256. \brief clear CTC flag
  257. \param[in] flag: the CTC flag
  258. only one parameter can be selected which is shown as below:
  259. \arg CTC_FLAG_CKOK: clock trim OK flag
  260. \arg CTC_FLAG_CKWARN: clock trim warning flag
  261. \arg CTC_FLAG_ERR: error flag
  262. \arg CTC_FLAG_EREF: expect reference flag
  263. \arg CTC_FLAG_CKERR: clock trim error bit
  264. \arg CTC_FLAG_REFMISS: reference sync pulse miss
  265. \arg CTC_FLAG_TRIMERR: trim value error bit
  266. \param[out] none
  267. \retval none
  268. */
  269. void ctc_flag_clear(uint32_t flag)
  270. {
  271. if(RESET != (flag & CTC_FLAG_MASK)){
  272. CTC_INTC |= CTC_INTC_ERRIC;
  273. }else{
  274. CTC_INTC |= flag;
  275. }
  276. }
  277. /*!
  278. \brief enable the CTC interrupt
  279. \param[in] interrupt: CTC interrupt enable
  280. one or more parameters can be selected which are shown as below:
  281. \arg CTC_INT_CKOK: clock trim OK interrupt enable
  282. \arg CTC_INT_CKWARN: clock trim warning interrupt enable
  283. \arg CTC_INT_ERR: error interrupt enable
  284. \arg CTC_INT_EREF: expect reference interrupt enable
  285. \param[out] none
  286. \retval none
  287. */
  288. void ctc_interrupt_enable(uint32_t interrupt)
  289. {
  290. CTC_CTL0 |= (uint32_t)interrupt;
  291. }
  292. /*!
  293. \brief disable the CTC interrupt
  294. \param[in] interrupt: CTC interrupt enable source
  295. one or more parameters can be selected which are shown as below:
  296. \arg CTC_INT_CKOK: clock trim OK interrupt enable
  297. \arg CTC_INT_CKWARN: clock trim warning interrupt enable
  298. \arg CTC_INT_ERR: error interrupt enable
  299. \arg CTC_INT_EREF: expect reference interrupt enable
  300. \param[out] none
  301. \retval none
  302. */
  303. void ctc_interrupt_disable(uint32_t interrupt)
  304. {
  305. CTC_CTL0 &= (uint32_t)(~interrupt);
  306. }
  307. /*!
  308. \brief get 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 FlagStatus: SET or RESET
  320. */
  321. FlagStatus ctc_interrupt_flag_get(uint32_t int_flag)
  322. {
  323. uint32_t interrupt_flag = 0U, intenable = 0U;
  324. /* check whether the interrupt is enabled */
  325. if(RESET != (int_flag & CTC_FLAG_MASK)){
  326. intenable = CTC_CTL0 & CTC_CTL0_ERRIE;
  327. }else{
  328. intenable = CTC_CTL0 & int_flag;
  329. }
  330. /* get interrupt flag status */
  331. interrupt_flag = CTC_STAT & int_flag;
  332. if(interrupt_flag && intenable){
  333. return SET;
  334. }else{
  335. return RESET;
  336. }
  337. }
  338. /*!
  339. \brief clear CTC interrupt flag
  340. \param[in] int_flag: the CTC interrupt flag
  341. only one parameter can be selected which is shown as below:
  342. \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt
  343. \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
  344. \arg CTC_INT_FLAG_ERR: error interrupt
  345. \arg CTC_INT_FLAG_EREF: expect reference interrupt
  346. \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
  347. \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
  348. \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
  349. \param[out] none
  350. \retval none
  351. */
  352. void ctc_interrupt_flag_clear(uint32_t int_flag)
  353. {
  354. if(RESET != (int_flag & CTC_FLAG_MASK)){
  355. CTC_INTC |= CTC_INTC_ERRIC;
  356. }else{
  357. CTC_INTC |= int_flag;
  358. }
  359. }