hc32l196_sysctrl.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. /******************************************************************************
  2. *Copyright(C)2018, Huada Semiconductor Co.,Ltd All rights reserved.
  3. *
  4. * This software is owned and published by:
  5. * Huada Semiconductor Co.,Ltd("HDSC").
  6. *
  7. * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
  8. * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
  9. *
  10. * This software contains source code for use with HDSC
  11. * components. This software is licensed by HDSC to be adapted only
  12. * for use in systems utilizing HDSC components. HDSC shall not be
  13. * responsible for misuse or illegal use of this software for devices not
  14. * supported herein. HDSC is providing this software "AS IS" and will
  15. * not be responsible for issues arising from incorrect user implementation
  16. * of the software.
  17. *
  18. * Disclaimer:
  19. * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
  20. * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
  21. * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
  22. * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
  23. * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
  24. * WARRANTY OF NONINFRINGEMENT.
  25. * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
  26. * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
  27. * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
  28. * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
  29. * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
  30. * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
  31. * SAVINGS OR PROFITS,
  32. * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  33. * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
  34. * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
  35. * FROM, THE SOFTWARE.
  36. *
  37. * This software may be replicated in part or whole for the licensed use,
  38. * with the restriction that this Disclaimer and Copyright notice must be
  39. * included with each copy of this software, whether used in part or whole,
  40. * at all times.
  41. */
  42. /** \file sysctrl.c
  43. **
  44. ** Common API of sysctrl.
  45. ** @link SysctrlGroup Some description @endlink
  46. **
  47. ** - 2018-04-22 Lux
  48. **
  49. ******************************************************************************/
  50. /*******************************************************************************
  51. * Include files
  52. ******************************************************************************/
  53. #include "hc32l196_sysctrl.h"
  54. /**
  55. *******************************************************************************
  56. ** \addtogroup SysctrlGroup
  57. ******************************************************************************/
  58. //@{
  59. /*******************************************************************************
  60. * Local pre-processor symbols/macros ('#define')
  61. ******************************************************************************/
  62. #define CLK_TIMEOUT (1000000u)
  63. #define IS_VALID_SRC(x) ( ClkRCH == (x)||\
  64. ClkXTH == (x)||\
  65. ClkRCL == (x)||\
  66. ClkXTL == (x) )
  67. #define IS_VALID_FUNC(x) ( ClkFuncWkupRCH == (x)||\
  68. ClkFuncXTHEn == (x)||\
  69. ClkFuncXTLEn == (x)||\
  70. ClkFuncXTLAWSON == (x)||\
  71. ClkFuncFaultEn == (x)||\
  72. ClkFuncRtcLPWEn == (x)||\
  73. ClkFuncLockUpEn == (x)||\
  74. ClkFuncRstPinIOEn == (x)||\
  75. ClkFuncSwdPinIOEn == (x) )
  76. #define RC_TRIM_BASE_ADDR ((volatile uint16_t*) (0x00100C00ul))
  77. #define RCH_CR_TRIM_24M_VAL (*((volatile uint16_t*) (0x00100C00ul)))
  78. #define RCH_CR_TRIM_22_12M_VAL (*((volatile uint16_t*) (0x00100C02ul)))
  79. #define RCH_CR_TRIM_16M_VAL (*((volatile uint16_t*) (0x00100C04ul)))
  80. #define RCH_CR_TRIM_8M_VAL (*((volatile uint16_t*) (0x00100C06ul)))
  81. #define RCH_CR_TRIM_4M_VAL (*((volatile uint16_t*) (0x00100C08ul)))
  82. #define RCL_CR_TRIM_38400_VAL (*((volatile uint16_t*) (0x00100C20ul)))
  83. #define RCL_CR_TRIM_32768_VAL (*((volatile uint16_t*) (0x00100C22ul)))
  84. /*******************************************************************************
  85. * Global variable definitions (declared in header file with 'extern')
  86. ******************************************************************************/
  87. extern uint32_t SystemCoreClock;
  88. /*******************************************************************************
  89. * Local type definitions ('typedef')
  90. ******************************************************************************/
  91. /*******************************************************************************
  92. * Local variable definitions ('static')
  93. ******************************************************************************/
  94. /*******************************************************************************
  95. * Local function prototypes ('static')
  96. ******************************************************************************/
  97. /*******************************************************************************
  98. * Function implementation - global ('extern') and local ('static')
  99. ******************************************************************************/
  100. /**
  101. *******************************************************************************
  102. ** \brief SYSCTRL0\SYSCTRL1寄存器操作解锁
  103. **
  104. ** \retval None
  105. ******************************************************************************/
  106. static void _SysctrlUnlock(void)
  107. {
  108. M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
  109. M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
  110. }
  111. /**
  112. *******************************************************************************
  113. ** \brief 系统时钟源使能
  114. ** \param [in] enSource 目标时钟源
  115. ** \param [in] bFlag 使能1-开/0-关
  116. ** \retval Ok 设定成功
  117. ** 其他 设定失败
  118. ******************************************************************************/
  119. en_result_t Sysctrl_ClkSourceEnable(en_sysctrl_clk_source_t enSource, boolean_t bFlag)
  120. {
  121. en_result_t enRet = Ok;
  122. uint32_t u32Temp;
  123. _SysctrlUnlock();
  124. bFlag = !!bFlag;
  125. u32Temp = M0P_SYSCTRL->PERI_CLKEN0;
  126. switch (enSource)
  127. {
  128. case SysctrlClkRCH:
  129. M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = bFlag;
  130. while(bFlag && (1 != M0P_SYSCTRL->RCH_CR_f.STABLE))
  131. {
  132. ;
  133. }
  134. break;
  135. case SysctrlClkXTH:
  136. M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE;
  137. M0P_GPIO->PFADS |= 3u;
  138. M0P_SYSCTRL->SYSCTRL0_f.XTH_EN = bFlag;
  139. while(bFlag && (1 != M0P_SYSCTRL->XTH_CR_f.STABLE))
  140. {
  141. ;
  142. }
  143. break;
  144. case SysctrlClkRCL:
  145. M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = bFlag;
  146. while(bFlag && (1 != M0P_SYSCTRL->RCL_CR_f.STABLE))
  147. {
  148. ;
  149. }
  150. break;
  151. case SysctrlClkXTL:
  152. M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE;
  153. M0P_GPIO->PCADS |= 0xC000;
  154. M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = bFlag;
  155. while(bFlag && (1 != M0P_SYSCTRL->XTL_CR_f.STABLE))
  156. {
  157. ;
  158. }
  159. break;
  160. case SysctrlClkPLL:
  161. M0P_SYSCTRL->PERI_CLKEN0_f.ADC = TRUE;
  162. M0P_BGR->CR_f.BGR_EN = TRUE;
  163. delay10us(20);
  164. M0P_SYSCTRL->SYSCTRL0_f.PLL_EN = bFlag;
  165. while(bFlag && (1 != M0P_SYSCTRL->PLL_CR_f.STABLE))
  166. {
  167. ;
  168. }
  169. break;
  170. default:
  171. enRet = ErrorInvalidParameter;
  172. break;
  173. }
  174. M0P_SYSCTRL->PERI_CLKEN0 = u32Temp;
  175. return enRet;
  176. }
  177. /**
  178. *******************************************************************************
  179. ** \brief 外部高速晶振驱动配置
  180. ** \param [in] enFreq 外部高速晶振频率范围选择
  181. ** \param [in] enDriver 外部高速晶振驱动能力选择
  182. ** \retval Ok 设定成功
  183. ** 其他 设定失败
  184. ******************************************************************************/
  185. en_result_t Sysctrl_XTHDriverCfg(en_sysctrl_xtal_driver_t enDriver)
  186. {
  187. en_result_t enRet = Ok;
  188. M0P_SYSCTRL->XTH_CR_f.DRIVER = enDriver;
  189. return enRet;
  190. }
  191. /**
  192. *******************************************************************************
  193. ** \brief 外部低速晶振驱动配置
  194. ** \param [in] enFreq 外部低速晶振频率范围选择
  195. ** \param [in] enDriver 外部低速晶振驱动能力选择
  196. ** \retval Ok 设定成功
  197. ** 其他 设定失败
  198. ******************************************************************************/
  199. en_result_t Sysctrl_XTLDriverCfg(en_sysctrl_xtl_amp_t enAmp, en_sysctrl_xtal_driver_t enDriver)
  200. {
  201. en_result_t enRet = Ok;
  202. M0P_SYSCTRL->XTL_CR_f.AMP_SEL = enAmp;
  203. M0P_SYSCTRL->XTL_CR_f.DRIVER = enDriver;
  204. return enRet;
  205. }
  206. /**
  207. *******************************************************************************
  208. ** \brief 外部高速时钟稳定周期配置
  209. ** \param [in] enCycle 外部高速时钟稳定周期设置
  210. ** \retval Ok 设定成功
  211. ** 其他 设定失败
  212. ******************************************************************************/
  213. en_result_t Sysctrl_SetXTHStableTime(en_sysctrl_xth_cycle_t enCycle)
  214. {
  215. en_result_t enRet = Ok;
  216. M0P_SYSCTRL->XTH_CR_f.STARTUP = enCycle;
  217. return enRet;
  218. }
  219. /**
  220. *******************************************************************************
  221. ** \brief 内部低速时钟稳定周期配置
  222. ** \param [in] enCycle 内部低速时钟稳定周期设置
  223. ** \retval Ok 设定成功
  224. ** 其他 设定失败
  225. ******************************************************************************/
  226. en_result_t Sysctrl_SetRCLStableTime(en_sysctrl_rcl_cycle_t enCycle)
  227. {
  228. en_result_t enRet = Ok;
  229. M0P_SYSCTRL->RCL_CR_f.STARTUP = enCycle;
  230. return enRet;
  231. }
  232. /**
  233. *******************************************************************************
  234. ** \brief 外部低速时钟稳定周期配置
  235. ** \param [in] enCycle 外部低速时钟稳定周期设置
  236. ** \retval Ok 设定成功
  237. ** 其他 设定失败
  238. ******************************************************************************/
  239. en_result_t Sysctrl_SetXTLStableTime(en_sysctrl_xtl_cycle_t enCycle)
  240. {
  241. en_result_t enRet = Ok;
  242. M0P_SYSCTRL->XTL_CR_f.STARTUP = enCycle;
  243. return enRet;
  244. }
  245. /**
  246. *******************************************************************************
  247. ** \brief PLL稳定周期配置
  248. ** \param [in] enCycle PLL稳定周期设置
  249. ** \retval Ok 设定成功
  250. ** 其他 设定失败
  251. ******************************************************************************/
  252. en_result_t Sysctrl_SetPLLStableTime(en_sysctrl_pll_cycle_t enCycle)
  253. {
  254. en_result_t enRet = Ok;
  255. M0P_SYSCTRL->PLL_CR_f.STARTUP = enCycle;
  256. return enRet;
  257. }
  258. /**
  259. *******************************************************************************
  260. ** \brief 时钟源切换,该函数执行后会开启新时钟源
  261. ** \note 选择时钟源之前,需根据需要配置目标时钟源的频率/驱动参数/使能时钟源等
  262. ** \param [in] enSource 新时钟源
  263. **
  264. ** \retval Ok 设定成功
  265. ** 其他 设定失败
  266. ******************************************************************************/
  267. en_result_t Sysctrl_SysClkSwitch(en_sysctrl_clk_source_t enSource)
  268. {
  269. en_result_t enRet = Ok;
  270. en_sysctrl_clk_source_t ClkNew = enSource;
  271. _SysctrlUnlock();
  272. M0P_SYSCTRL->SYSCTRL0_f.CLKSW = ClkNew;
  273. //更新Core时钟(HCLK)
  274. SystemCoreClockUpdate();
  275. return enRet;
  276. }
  277. /**
  278. *******************************************************************************
  279. ** \brief 获得系统时钟(HCLK)频率值
  280. ** \retval uint32_t HCLK频率值
  281. **
  282. ******************************************************************************/
  283. uint32_t Sysctrl_GetHClkFreq(void)
  284. {
  285. uint32_t u32Val = 0;
  286. const uint32_t u32hcr_tbl[] = { 4000000, 8000000, 16000000, 22120000, 24000000};
  287. const uint16_t u32lcr_tbl[] = { 32768, 38400};
  288. en_sysctrl_clk_source_t enSrc;
  289. uint16_t u16Trim[5] = {0};
  290. u16Trim[4] = RCH_CR_TRIM_24M_VAL;
  291. u16Trim[3] = RCH_CR_TRIM_22_12M_VAL;
  292. u16Trim[2] = RCH_CR_TRIM_16M_VAL;
  293. u16Trim[1] = RCH_CR_TRIM_8M_VAL;
  294. u16Trim[0] = RCL_CR_TRIM_38400_VAL;
  295. //获取当前系统时钟
  296. enSrc = (en_sysctrl_clk_source_t)(M0P_SYSCTRL->SYSCTRL0_f.CLKSW);
  297. switch (enSrc)
  298. {
  299. case SysctrlClkRCH:
  300. {
  301. if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[4]))
  302. {
  303. u32Val = u32hcr_tbl[4];
  304. }
  305. else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[3]))
  306. {
  307. u32Val = u32hcr_tbl[3];
  308. }
  309. else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[2]))
  310. {
  311. u32Val = u32hcr_tbl[2];
  312. }
  313. else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[1]))
  314. {
  315. u32Val = u32hcr_tbl[1];
  316. }
  317. else
  318. {
  319. u32Val = u32hcr_tbl[0];
  320. }
  321. }
  322. break;
  323. case SysctrlClkXTH:
  324. u32Val = SYSTEM_XTH;
  325. break;
  326. case SysctrlClkRCL:
  327. {
  328. if(u16Trim[0] == (M0P_SYSCTRL->RCL_CR_f.TRIM))
  329. {
  330. u32Val = u32lcr_tbl[1];
  331. }
  332. else
  333. {
  334. u32Val = u32lcr_tbl[0];
  335. }
  336. }
  337. break;
  338. case SysctrlClkXTL:
  339. u32Val = SYSTEM_XTL;
  340. break;
  341. case SysctrlClkPLL:
  342. {
  343. if (SysctrlPllRch == M0P_SYSCTRL->PLL_CR_f.REFSEL)
  344. {
  345. if(u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM)
  346. {
  347. u32Val = u32hcr_tbl[4];
  348. }
  349. else if(u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM)
  350. {
  351. u32Val = u32hcr_tbl[3];
  352. }
  353. else if(u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM)
  354. {
  355. u32Val = u32hcr_tbl[2];
  356. }
  357. else if(u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM)
  358. {
  359. u32Val = u32hcr_tbl[1];
  360. }
  361. else
  362. {
  363. u32Val = u32hcr_tbl[0];
  364. }
  365. }
  366. else
  367. {
  368. u32Val = SYSTEM_XTH;
  369. }
  370. u32Val = (u32Val * M0P_SYSCTRL->PLL_CR_f.DIVN);
  371. }
  372. break;
  373. default:
  374. u32Val = 0u;
  375. break;
  376. }
  377. u32Val = (u32Val >> M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS);
  378. return u32Val;
  379. }
  380. /**
  381. *******************************************************************************
  382. ** \brief 获得外设时钟(PCLK)频率值
  383. ** \retval uint32_t PCLK频率值(Hz)
  384. **
  385. ******************************************************************************/
  386. uint32_t Sysctrl_GetPClkFreq(void)
  387. {
  388. uint32_t u32Val = 0;
  389. u32Val = Sysctrl_GetHClkFreq();
  390. u32Val = (u32Val >> (M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS));
  391. return u32Val;
  392. }
  393. /**
  394. *******************************************************************************
  395. ** \brief 时钟初始化函数
  396. ** \param [in] pstcCfg 初始化配置参数
  397. ** \retval Ok 设定成功
  398. ** 其他 设定失败
  399. ******************************************************************************/
  400. en_result_t Sysctrl_ClkInit(stc_sysctrl_clk_cfg_t *pstcCfg)
  401. {
  402. en_result_t enRet = Ok;
  403. //系统时钟参数配置
  404. switch(pstcCfg->enClkSrc)
  405. {
  406. case SysctrlClkRCH:
  407. break;
  408. case SysctrlClkXTH:
  409. Sysctrl_XTHDriverCfg(SysctrlXtalDriver3);
  410. Sysctrl_SetXTHStableTime(SysctrlXthStableCycle16384);
  411. break;
  412. case SysctrlClkRCL:
  413. Sysctrl_SetRCLStableTime(SysctrlRclStableCycle256);
  414. break;
  415. case SysctrlClkXTL:
  416. Sysctrl_XTLDriverCfg(SysctrlXtlAmp3, SysctrlXtalDriver3);
  417. Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384);
  418. break;
  419. case SysctrlClkPLL:
  420. Sysctrl_SetPLLStableTime(SysctrlPllStableCycle16384);
  421. break;
  422. default:
  423. enRet = ErrorInvalidParameter;
  424. break;
  425. }
  426. //时钟源使能
  427. Sysctrl_ClkSourceEnable(pstcCfg->enClkSrc, TRUE);
  428. //时钟源切换
  429. Sysctrl_SysClkSwitch(pstcCfg->enClkSrc);
  430. //时钟分频设置
  431. Sysctrl_SetHCLKDiv(pstcCfg->enHClkDiv);
  432. Sysctrl_SetPCLKDiv(pstcCfg->enPClkDiv);
  433. return enRet;
  434. }
  435. /**
  436. *******************************************************************************
  437. ** \brief 时钟去初始化函数
  438. ** \param [in]
  439. ** \retval Ok 设定成功
  440. ** 其他 设定失败
  441. ******************************************************************************/
  442. en_result_t Sysctrl_ClkDeInit(void)
  443. {
  444. en_result_t enRet = Ok;
  445. //配置RCH为内部4Hz
  446. Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz);
  447. //时钟源使能
  448. Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
  449. //时钟源切换
  450. Sysctrl_SysClkSwitch(SysctrlClkRCH);
  451. //其它时钟源使能关闭
  452. Sysctrl_ClkSourceEnable(SysctrlClkXTH, FALSE);
  453. Sysctrl_ClkSourceEnable(SysctrlClkRCL, FALSE);
  454. Sysctrl_ClkSourceEnable(SysctrlClkXTL, FALSE);
  455. Sysctrl_ClkSourceEnable(SysctrlClkPLL, FALSE);
  456. //时钟分频设置
  457. Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);
  458. Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);
  459. return enRet;
  460. }
  461. /**
  462. *******************************************************************************
  463. ** \brief 内部高速时钟频率TRIM值加载
  464. ** \param [in] enRCHFreq 设定的RCH目标频率值
  465. ** \retval Ok 设定成功
  466. ** 其他 设定失败或时钟未稳定
  467. ******************************************************************************/
  468. en_result_t Sysctrl_SetRCHTrim(en_sysctrl_rch_freq_t enRCHFreq)
  469. {
  470. //加载RCH Trim值
  471. M0P_SYSCTRL->RCH_CR_f.TRIM = *(RC_TRIM_BASE_ADDR + enRCHFreq);
  472. return Ok;
  473. }
  474. /**
  475. *******************************************************************************
  476. ** \brief 外部高速时钟频率范围设定
  477. ** \param [in] enXTHFreq 设定的频率值
  478. ** \retval Ok 设定成功
  479. ** 其他 设定失败或时钟未稳定
  480. ******************************************************************************/
  481. en_result_t Sysctrl_SetXTHFreq(en_sysctrl_xth_freq_t enXTHFreq)
  482. {
  483. en_result_t enRet = Ok;
  484. M0P_SYSCTRL->XTH_CR_f.XTH_FSEL = enXTHFreq;
  485. return enRet;
  486. }
  487. /**
  488. *******************************************************************************
  489. ** \brief PLL时钟配置
  490. ** \param [in] pstcPLLCfg PLL配置结构体指针
  491. ** \retval Ok 设定成功
  492. ** 其他 设定失败或参数值不匹配
  493. ******************************************************************************/
  494. en_result_t Sysctrl_SetPLLFreq(stc_sysctrl_pll_cfg_t *pstcPLLCfg)
  495. {
  496. en_result_t enRet = Ok;
  497. uint16_t u16Trim[5] = {0};
  498. u16Trim[4] = RCH_CR_TRIM_24M_VAL;
  499. u16Trim[3] = RCH_CR_TRIM_22_12M_VAL;
  500. u16Trim[2] = RCH_CR_TRIM_16M_VAL;
  501. u16Trim[1] = RCH_CR_TRIM_8M_VAL;
  502. ////PLL最高时钟不能超过48MHz
  503. //RCH作为PLL输入
  504. if (SysctrlPllRch == pstcPLLCfg->enPllClkSrc)
  505. {
  506. if( ((u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) ||
  507. ((u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) ||
  508. ((u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 3)) ||
  509. ((u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 6)))
  510. {
  511. return ErrorInvalidMode;
  512. }
  513. }
  514. else //XTH作为PLL输入
  515. {
  516. if ((SYSTEM_XTH * pstcPLLCfg->enPllMul) > 48*1000*1000)
  517. {
  518. return ErrorInvalidMode;
  519. }
  520. }
  521. M0P_SYSCTRL->PLL_CR_f.FRSEL = pstcPLLCfg->enInFreq;
  522. M0P_SYSCTRL->PLL_CR_f.FOSC = pstcPLLCfg->enOutFreq;
  523. M0P_SYSCTRL->PLL_CR_f.DIVN = pstcPLLCfg->enPllMul;
  524. M0P_SYSCTRL->PLL_CR_f.REFSEL = pstcPLLCfg->enPllClkSrc;
  525. return enRet;
  526. }
  527. /**
  528. *******************************************************************************
  529. ** \brief 内部低速时钟频率TRIM值加载
  530. ** \param [in] enRCLFreq 设定的RCL目标频率值
  531. ** \retval Ok 设定成功
  532. ** 其他 设定失败
  533. ******************************************************************************/
  534. en_result_t Sysctrl_SetRCLTrim(en_sysctrl_rcl_freq_t enRCLFreq)
  535. {
  536. M0P_SYSCTRL->RCL_CR_f.TRIM = *(RC_TRIM_BASE_ADDR + enRCLFreq);
  537. return Ok;
  538. }
  539. /**
  540. *******************************************************************************
  541. ** \brief 系统时钟(HCLK)分频设定
  542. ** \param [in] enHCLKDiv 分频设定值
  543. ** \retval Ok 设定成功
  544. ** 其他 设定失败
  545. ******************************************************************************/
  546. en_result_t Sysctrl_SetHCLKDiv(en_sysctrl_hclk_div_t enHCLKDiv)
  547. {
  548. _SysctrlUnlock();
  549. M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS = enHCLKDiv;
  550. return Ok;
  551. }
  552. /**
  553. *******************************************************************************
  554. ** \brief 外设时钟(PCLK)分频设定
  555. ** \param [in] enPCLKDiv 分频设定值
  556. ** \retval Ok 设定成功
  557. ** 其他 设定失败
  558. ******************************************************************************/
  559. en_result_t Sysctrl_SetPCLKDiv(en_sysctrl_pclk_div_t enPCLKDiv)
  560. {
  561. _SysctrlUnlock();
  562. M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS = enPCLKDiv;
  563. return Ok;
  564. }
  565. ///<< for Sysctrl_SetPeripheralGate() & Sysctrl_GetPeripheralGate()
  566. static volatile boolean_t bDacPeriBac = FALSE;
  567. /**
  568. *******************************************************************************
  569. ** \brief 设置外设时钟门控开关
  570. ** \param [in] enPeripheral 目标外设
  571. ** \param [in] bFlag 使能开关
  572. ** \retval Ok 设定成功
  573. ** 其他 设定失败
  574. ******************************************************************************/
  575. en_result_t Sysctrl_SetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral, boolean_t bFlag)
  576. {
  577. if(enPeripheral&0x20u)
  578. {
  579. enPeripheral &= ~0x20u;
  580. SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), enPeripheral, bFlag);
  581. if((SysctrlPeripheralDac & ~0x20u) == enPeripheral)
  582. {
  583. bDacPeriBac = bFlag;
  584. }
  585. else
  586. {
  587. SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), (SysctrlPeripheralDac & ~0x20u), bDacPeriBac);
  588. }
  589. }
  590. else
  591. {
  592. SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN0)), enPeripheral, bFlag);
  593. }
  594. return Ok;
  595. }
  596. /**
  597. *******************************************************************************
  598. ** \brief 获得外设时钟门控开关状态
  599. ** \param [in] enPeripheral 目标外设
  600. ** \retval TRUE 开
  601. ** FALSE 关
  602. ******************************************************************************/
  603. boolean_t Sysctrl_GetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral)
  604. {
  605. if(enPeripheral&0x20u)
  606. {
  607. if(SysctrlPeripheralDac == enPeripheral)
  608. {
  609. return bDacPeriBac;
  610. }
  611. else
  612. {
  613. enPeripheral &= ~0x20u;
  614. return GetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), enPeripheral);
  615. }
  616. }
  617. else
  618. {
  619. return GetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN0)), enPeripheral);
  620. }
  621. }
  622. /**
  623. *******************************************************************************
  624. ** \brief 系统功能设定
  625. ** \param [in] enFunc 系统功能枚举类型
  626. ** \param [in] bFlag 1-开/0-关
  627. ** \retval Ok 设定成功
  628. ** 其他 设定失败
  629. ******************************************************************************/
  630. en_result_t Sysctrl_SetFunc(en_sysctrl_func_t enFunc, boolean_t bFlag)
  631. {
  632. _SysctrlUnlock();
  633. SetBit((uint32_t)(&(M0P_SYSCTRL->SYSCTRL1)), enFunc, bFlag);
  634. return Ok;
  635. }
  636. /**
  637. *******************************************************************************
  638. ** \brief 设定RTC校准时钟频率
  639. ** \param [in] enRtcAdj 校准频率值
  640. ** \retval Ok 设定成功
  641. ** 其他 设定失败
  642. ******************************************************************************/
  643. en_result_t Sysctrl_SetRTCAdjustClkFreq(en_sysctrl_rtc_adjust_t enRtcAdj)
  644. {
  645. _SysctrlUnlock();
  646. M0P_SYSCTRL->SYSCTRL1_f.RTC_FREQ_ADJUST = enRtcAdj;
  647. return Ok;
  648. }
  649. //@} // SysctrlGroup
  650. /*******************************************************************************
  651. * EOF (not truncated)
  652. ******************************************************************************/