driver_clk.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*
  2. * @File name : driver_clk.c
  3. * @Author : Bluetrum IOT Team
  4. * @Date : 2023-04-04
  5. * @Description : This file provides functions to manage the most functionalities
  6. * of the CLK peripheral.
  7. *
  8. * Copyright (c) by Bluetrum, All Rights Reserved.
  9. */
  10. #include "driver_clk.h"
  11. void clk_gate0_cmd(uint32_t clock_gate, CLK_STATE state)
  12. {
  13. if (state != CLK_DIS) {
  14. CLKGAT0 |= clock_gate;
  15. } else {
  16. CLKGAT0 &= ~clock_gate;
  17. }
  18. }
  19. void clk_gate1_cmd(uint32_t clock_gate, CLK_STATE state)
  20. {
  21. if (state != CLK_DIS) {
  22. CLKGAT1 |= clock_gate;
  23. } else {
  24. CLKGAT1 &= ~clock_gate;
  25. }
  26. }
  27. void clk_gate2_cmd(uint32_t clock_gate, CLK_STATE state)
  28. {
  29. if (state != CLK_DIS) {
  30. CLKGAT2 |= clock_gate;
  31. } else {
  32. CLKGAT2 &= ~clock_gate;
  33. }
  34. }
  35. void clk_clkout_set(CLK_CLKOUT_TYPEDEF clk_sel, uint8_t div, CLK_STATE state)
  36. {
  37. if (state != CLK_DIS) {
  38. CLKCON0 &= ~(0x0f << 13);
  39. CLKCON0 |= ((clk_sel & 0x0f) << 13);
  40. CLKDIVCON0 &= ~(0x1f << 17);
  41. CLKDIVCON0 |= ((div & 0x1f) << 17);
  42. } else {
  43. CLKCON0 &= ~(0x0f << 13);
  44. CLKDIVCON0 &= ~(0x1f << 17);
  45. }
  46. }
  47. void clk_clk32k_rtc_set(CLK_CLK32K_RTC_TYPEDEF clk_sel)
  48. {
  49. uint32_t rtccon0 = RTCCON0;
  50. if ((CLK_CLK32K_RTC_RC2M_RTC == clk_sel) || (CLK_CLK32K_RTC_SNF_RC_RTC == clk_sel)) {
  51. rtccon0 |= BIT(19); //RC2M_RTC enable
  52. }
  53. rtccon0 &= ~(0x03 << 8);
  54. rtccon0 |= ((clk_sel & 0x03) << 8);
  55. RTCCON0 = rtccon0;
  56. }
  57. uint32_t clk_clk32k_rtc_get(CLK_VALUE_MODE_TYPEDEF mode)
  58. {
  59. uint32_t rtccon0 = RTCCON0;
  60. u8 index;
  61. index = (rtccon0 >> 8) & 0x03;
  62. if (mode == CLK_VALUE_MODE_IDX) {
  63. return index;
  64. } else {
  65. switch (index) {
  66. case CLK_CLK32K_RTC_1BIT:
  67. return -1L;
  68. case CLK_CLK32K_RTC_RC2M_RTC:
  69. case CLK_CLK32K_RTC_SNF_RC_RTC:
  70. return rc2m_clk_nhz_get(1) / 64;
  71. case CLK_CLK32K_RTC_X24MDIV12_RTC:
  72. return 2000000 / 64;
  73. default:
  74. return 0;
  75. }
  76. }
  77. }
  78. void clk_hsut0_clk_set(CLK_HSUART_CLK_TYPEDEF clk_sel, uint8_t div)
  79. {
  80. uint32_t clkcon0 = CLKCON0;
  81. clkcon0 &= ~(0x03 << 17);
  82. clkcon0 |= ((clk_sel & 0x03) << 17);
  83. CLKCON0 = clkcon0;
  84. if (clk_sel >= CLK_HSUT0_CLK_PLLDIV2_CLK) {
  85. CLKDIVCON0 &= ~(0x03 << 22);
  86. CLKDIVCON0 |= ((div & 0x03) << 22);
  87. PLL0CON |= BIT(13);
  88. }
  89. }
  90. uint32_t clk_hsut0_clk_get(CLK_VALUE_MODE_TYPEDEF mode)
  91. {
  92. uint32_t clkcon0 = CLKCON0;
  93. u8 index;
  94. index = ((clkcon0 >> 17) & 0x03);
  95. if (mode == CLK_VALUE_MODE_IDX) {
  96. return index;
  97. } else {
  98. switch (index) {
  99. case CLK_HSUT0_CLK_XOSC24M_CLK:
  100. return 24000000;
  101. case CLK_HSUT0_CLK_XOSC48M:
  102. return 48000000;
  103. case CLK_HSUT0_CLK_PLLDIV2_CLK:
  104. return pll_clk_nhz_get() / 2 / (((CLKDIVCON0 >> 22) & 0x03) + 1);
  105. case CLK_HSUT0_CLK_UDET_CLKPP:
  106. return clk_udet_clk_get(CLK_VALUE_MODE_FREQ) / (((CLKDIVCON0 >> 22) & 0x03) + 1);
  107. default:
  108. return 0;
  109. }
  110. }
  111. }
  112. void clk_saradc_clk_set(CLK_SARADC_CLK_TYPEDEF clk_sel)
  113. {
  114. uint32_t clkcon0 = CLKCON0;
  115. clkcon0 &= ~(0x03 << 28);
  116. clkcon0 |= ((clk_sel & 0x03) << 28);
  117. CLKCON0 = clkcon0;
  118. }
  119. uint32_t clk_saradc_clk_get(CLK_VALUE_MODE_TYPEDEF mode)
  120. {
  121. uint32_t clkcon0 = CLKCON0;
  122. u8 index;
  123. index = ((clkcon0 >> 28) & 0x03);
  124. if (mode == CLK_VALUE_MODE_IDX) {
  125. return index;
  126. } else {
  127. switch (index) {
  128. case CLK_SARADC_CLK_RC2M_CLK:
  129. return rc2m_clk_nhz_get(0);
  130. case CLK_SARADC_CLK_X24M_CLKDIV4:
  131. return 6000000;
  132. case CLK_SARADC_CLK_X24M_CLKDIV2:
  133. return 12000000;
  134. case CLK_SARADC_CLK_X24Md32K_CLK:
  135. return 32000;
  136. default:
  137. return 0;
  138. }
  139. }
  140. }
  141. void clk_udet_clk_set(CLK_UDET_CLK_TYPEDEF clk_sel)
  142. {
  143. uint32_t clkcon1 = CLKCON1;
  144. clkcon1 &= ~(0x03 << 28);
  145. clkcon1 |= ((clk_sel & 0x03) << 28);
  146. CLKCON1 = clkcon1;
  147. }
  148. uint32_t clk_udet_clk_get(CLK_VALUE_MODE_TYPEDEF mode)
  149. {
  150. uint32_t clkcon1 = CLKCON1;
  151. u8 index;
  152. index = ((clkcon1 >> 28) & 0x03);
  153. if (mode == CLK_VALUE_MODE_IDX) {
  154. return index;
  155. } else {
  156. switch (index) {
  157. case CLK_UDET_CLK_RC2M_CLK:
  158. return rc2m_clk_nhz_get(0);
  159. case CLK_UDET_CLK_RTC_RC2M:
  160. return rc2m_clk_nhz_get(1);
  161. case XOSC24M_CLK:
  162. return 24000000;
  163. case XOSC48M:
  164. return 48000000;
  165. default:
  166. return 0;
  167. }
  168. }
  169. }
  170. void clk_tmr_inc_set(CLK_TMR_INC_TYPEDEF clk_sel)
  171. {
  172. uint32_t clkcon0 = CLKCON0;
  173. clkcon0 &= ~(0x03 << 23);
  174. clkcon0 |= ((clk_sel & 0x03) << 23);
  175. CLKCON0 = clkcon0;
  176. }
  177. uint32_t clk_tmr_inc_get(CLK_VALUE_MODE_TYPEDEF mode)
  178. {
  179. uint32_t clkcon0 = CLKCON0;
  180. u8 index;
  181. index = (clkcon0 >> 23) & 0x03;
  182. if (mode == CLK_VALUE_MODE_IDX) {
  183. return index;
  184. } else {
  185. switch (index) {
  186. case CLK_TMR_INC_OSC32K:
  187. return clk_clk32k_rtc_get(CLK_VALUE_MODE_FREQ);
  188. case CLK_TMR_INC_CLKOUOT_PIN:
  189. return -1L;
  190. case CLK_TMR_INC_X24M_DIV_CLK:
  191. return 24000000 / (((CLKDIVCON0 >> 24) & 0xff) + 1);
  192. case CLK_TMR_INC_RC2M_D0:
  193. return rc2m_clk_nhz_get(0) / 2;
  194. default:
  195. return 0;
  196. }
  197. }
  198. }
  199. void clk_uart_inc_set(CLK_UART_INC_TPYEDEF clk_sel)
  200. {
  201. uint32_t clkcon1 = CLKCON1;
  202. clkcon1 &= ~(0x01 << 14);
  203. clkcon1 |= ((clk_sel & 0x01) << 14);
  204. CLKCON1 = clkcon1;
  205. }
  206. uint32_t clk_uart_inc_get(CLK_VALUE_MODE_TYPEDEF mode)
  207. {
  208. uint32_t clkcon1 = CLKCON1;
  209. u8 index;
  210. index = (clkcon1 >> 14) & 0x01;
  211. if (mode == CLK_VALUE_MODE_IDX) {
  212. return index;
  213. } else {
  214. switch (index) {
  215. case CLK_UART_INC_X24M_DIV_CLK:
  216. return 24000000 / (((CLKDIVCON0 >> 24) & 0xff) + 1);
  217. case CLK_UART_INC_X24M_CLKDIV4:
  218. return 6000000;
  219. default:
  220. return 0;
  221. }
  222. }
  223. }
  224. void clk_clk2m_ks_set(CLK_CLK2M_KS_TYPEDEF clk_sel)
  225. {
  226. uint32_t rtccon0 = RTCCON0;
  227. rtccon0 &= ~(0x03 << 14);
  228. rtccon0 |= ((clk_sel & 0x03) << 14);
  229. RTCCON0 = rtccon0;
  230. }
  231. uint32_t clk_clk2m_ks_get(CLK_VALUE_MODE_TYPEDEF mode)
  232. {
  233. uint32_t rtccon0 = RTCCON0;
  234. u8 index;
  235. index = (rtccon0 >> 14) & 0x03;
  236. if (mode == CLK_VALUE_MODE_IDX) {
  237. return index;
  238. } else {
  239. switch (index) {
  240. case CLK_CLK2M_KS_1BIT:
  241. return -1L;
  242. case CLK_CLK2M_KS_RC2M_RTC:
  243. return rc2m_clk_nhz_get(1);
  244. case CLK_CLK2M_KS_SNF_RC_RTC:
  245. return rc2m_clk_nhz_get(1);
  246. case CLK_CLK2M_KS_X24MDIV12_RTC:
  247. return 2000000;
  248. default:
  249. return 0;
  250. }
  251. }
  252. }
  253. void clk_sdadda_clk_set(CLK_SDADDA_CLK_TYPEDEF clk_sel, uint8_t div)
  254. {
  255. u32 clkcon1 = CLKCON1;
  256. u32 clkdivcon0 = CLKDIVCON0;
  257. if (clk_sel == 4 || clk_sel > 5) {
  258. return;
  259. }
  260. clkcon1 &= ~0x07;
  261. clkcon1 |= clk_sel;
  262. CLKCON1 = clkcon1;
  263. if (clk_sel == CLK_SDADDA_CLK_ADDA_CLK24_A) {
  264. CLKGAT2 |= BIT(14);
  265. clkdivcon0 &= ~(0x0f << 4);
  266. clkdivcon0 |= ((div & 0x0f) << 4);
  267. CLKDIVCON0 = clkdivcon0;
  268. }
  269. }
  270. uint32_t clk_sdadda_clk_get(CLK_VALUE_MODE_TYPEDEF mode)
  271. {
  272. u32 clkcon1 = CLKCON1;
  273. u8 div = ((CLKDIVCON0 >> 4) & 0x0f) + 1;
  274. u8 index;
  275. index = clkcon1 & 0x07;
  276. if (mode == CLK_VALUE_MODE_IDX) {
  277. return index;
  278. } else {
  279. switch (index) {
  280. case CLK_SDADDA_CLK_ADDA_CLK24_A:
  281. return (pll_clk_nhz_get() / 2 / div / 2);
  282. case CLK_SDADDA_CLK_XOSC24M_CLK:
  283. return 24000000;
  284. case CLK_SDADDA_CLK_XOSC24M_CLK_2PLL:
  285. return 24000000;
  286. default:
  287. return 0;
  288. }
  289. }
  290. }
  291. void clk_ledc_clk_set(CLK_LEDC_CLK_TYPEDEF clk_sel)
  292. {
  293. u32 clkcon1 = CLKCON1;
  294. clkcon1 &= ~(0x01 << 27);
  295. clkcon1 |= (clk_sel & 0x01) << 27;
  296. CLKCON1 = clkcon1;
  297. }
  298. uint32_t clk_ledc_clk_get(CLK_VALUE_MODE_TYPEDEF mode)
  299. {
  300. u32 clkcon1 = CLKCON1;
  301. u8 index;
  302. index = (clkcon1 >> 27) & 0x01;
  303. if (mode == CLK_VALUE_MODE_IDX) {
  304. return index;
  305. } else {
  306. switch (index) {
  307. case CLK_LEDC_CLK_XOSC24M:
  308. return 24000000;
  309. case CLK_LEDC_CLK_X24M_CLKDIV2:
  310. return 12000000;
  311. default:
  312. return 0;
  313. }
  314. }
  315. }
  316. void clk_touch_key_clk_set(CLK_TOUCH_KEY_TYPEDEF clk_sel)
  317. {
  318. if (CLK_TOUCH_KEY_CLK_XOSC24M == clk_sel) {
  319. XOSCCON |= BIT(10); //xosc enable
  320. CLKCON4 &= ~BIT(26); //select xosc24m_p
  321. CLKGAT1 |= BIT(29); //x24m_clk enable
  322. } else if (CLK_TOUCH_KEY_RC2M == clk_sel) {
  323. RTCCON0 |= BIT(19); //RC2M_RTC EN
  324. }
  325. RTCCON0 = (RTCCON0 & ~(3 << 12)) | (clk_sel << 12);
  326. RTCCON &= ~BIT(0); //VRTC11 voltage select RTCCON4 bit26~24
  327. RTCCON4 = (RTCCON4 & ~(0x07 << 24)) | (5 << 24); //vrtc11 voltage select 0.7+0.065*5 = 1.025V
  328. }
  329. uint32_t clk_touch_key_clk_get(CLK_VALUE_MODE_TYPEDEF mode)
  330. {
  331. u32 rtccon0 = RTCCON0;
  332. u8 index;
  333. index = (rtccon0 >> 12) & 0x03;
  334. if (mode == CLK_VALUE_MODE_IDX) {
  335. return index;
  336. } else {
  337. switch (index) {
  338. case CLK_TOUCH_KEY_RC2M:
  339. return rc2m_clk_nhz_get(1);
  340. case CLK_TOUCH_KEY_CLK_XOSC24M:
  341. return 2000000;
  342. default:
  343. return 0;
  344. }
  345. }
  346. }
  347. void clk_ttmr_inc_set(CLK_TTMR_INC_TYPEDEF clk_sel)
  348. {
  349. uint32_t clkcon1 = CLKCON1;
  350. clkcon1 &= ~(0x03 << 12);
  351. clkcon1 |= ((clk_sel & 0x03) << 12);
  352. CLKCON1 = clkcon1;
  353. }
  354. uint32_t clk_ttmr_inc_get(CLK_VALUE_MODE_TYPEDEF mode)
  355. {
  356. uint32_t clkcon1 = CLKCON1;
  357. uint8_t index;
  358. index = (clkcon1 >> 12) & 0x03;
  359. if (mode == CLK_VALUE_MODE_IDX) {
  360. return index;
  361. } else {
  362. switch (index) {
  363. case CLK_TTMR_INC_OSC_32K:
  364. return clk_clk32k_rtc_get(CLK_VALUE_MODE_FREQ);
  365. case CLK_TTMR_INC_CLKOUT_PIN:
  366. /* TODO: */
  367. return -1L;
  368. case CLK_TTMR_INC_X24M_DIV_CLK:
  369. return 24000000 / (((CLKDIVCON0 >> 24) & 0xff) + 1);
  370. case CLK_TTMR_INC_RC2M_D0:
  371. return rc2m_clk_nhz_get(0) / 2;
  372. default:
  373. return 0;
  374. }
  375. }
  376. }