System_ACM32F0x0.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. /*
  2. ******************************************************************************
  3. * @file System_ACM32F0x0.c
  4. * @version V1.0.0
  5. * @date 2021
  6. * @brief System Source File, includes clock management, reset management
  7. * and IO configuration, ...
  8. ******************************************************************************
  9. */
  10. #include "ACM32Fxx_HAL.h"
  11. uint32_t gu32_SystemClock;
  12. uint32_t gu32_APBClock;
  13. RESET_REASON Reset_Reason_Save;
  14. /* System count in SysTick_Handler */
  15. volatile uint32_t gu32_SystemCount;
  16. /************************* Miscellaneous Configuration ************************/
  17. /*!< Uncomment the following line if you need to relocate your vector Table in
  18. Internal SRAM. */
  19. /* #define VECT_TAB_SRAM */
  20. #define VECT_TAB_OFFSET 0x0U /*!< Vector Table base offset field.
  21. This value must be a multiple of 0x200. */
  22. /******************************************************************************/
  23. #if 0
  24. /*********************************************************************************
  25. * Function : HardFault_Handler
  26. * Description : Hard Fault handle, while(1) loop, wait for debug
  27. * Input : none
  28. * Output : none
  29. * Author : xwl
  30. **********************************************************************************/
  31. void HardFault_Handler(void)
  32. {
  33. while(1);
  34. }
  35. /*********************************************************************************
  36. * Function : SysTick_Handler
  37. * Description : System tick handler
  38. * Input : none
  39. * Output : none
  40. * Author : Chris_Kyle
  41. **********************************************************************************/
  42. void SysTick_Handler(void)
  43. {
  44. gu32_SystemCount++;
  45. }
  46. /*********************************************************************************
  47. * Function : System_SysTick_Init
  48. * Description : System Tick Init. Period is 1 ms
  49. * Input : none
  50. * Output : none
  51. * Author : Chris_Kyle
  52. **********************************************************************************/
  53. void System_SysTick_Init(void)
  54. {
  55. gu32_SystemCount = 0;
  56. SysTick_Config(gu32_SystemClock / 1000); //1ms/tick
  57. }
  58. #endif
  59. /*********************************************************************************
  60. * Function : System_SysTick_Off
  61. * Description : Turn off System Tick
  62. * Input : none
  63. * Output : none
  64. * Author : xwl
  65. **********************************************************************************/
  66. void System_SysTick_Off(void)
  67. {
  68. SysTick->CTRL = 0;
  69. }
  70. /*********************************************************************************
  71. * Function : System_Init
  72. * Description : Initialize the system clock
  73. * Input : none
  74. * Outpu : none
  75. * Author : Chris_Kyle Date : 2021
  76. **********************************************************************************/
  77. void System_Init(void)
  78. {
  79. SCU->RCR |= SCU_RCR_REMAP_EN;
  80. System_Set_Buzzer_Divider(80, FUNC_DISABLE); // disable clock out
  81. /* Configure the Vector Table location add offset address ------------------*/
  82. #ifdef VECT_TAB_SRAM
  83. /* Vector Table Relocation in Internal SRAM */
  84. SCU->VECTOROFFSET = SRAM_BASE | VECT_TAB_OFFSET | SCU_VECTOROFFSET_VOFFSETEN;
  85. #else
  86. /* Vector Table Relocation in Internal FLASH */
  87. SCU->VECTOROFFSET = EFLASH_BASE | VECT_TAB_OFFSET | SCU_VECTOROFFSET_VOFFSETEN;
  88. #endif
  89. /* Initialize the system clock */
  90. if (false == System_Clock_Init(DEFAULT_SYSTEM_CLOCK))
  91. {
  92. while(1);
  93. }
  94. #ifdef HAL_SYSTICK_ENABLED // To activate macro in ACM32Fxx_HAL.h
  95. System_SysTick_Init();
  96. #endif
  97. }
  98. /*********************************************************************************
  99. * Function : System_Clock_Init
  100. * Description : Clock init
  101. * Input : fu32_Clock: System core clock
  102. * Outpu : 0: success, other value: fail reason
  103. * Author : xwl Date : 2021
  104. **********************************************************************************/
  105. bool System_Clock_Init(uint32_t fu32_Clock)
  106. {
  107. uint32_t lu32_DIV, lu32_system_clk_source, lu32_result, lu32_timeout;
  108. lu32_system_clk_source = CLK_SRC_RC64M;
  109. SET_EFC_RD_WAIT(RD_WAIT_SET_DEFAULT)
  110. switch (fu32_Clock)
  111. {
  112. /* 64MHz */
  113. case 64000000: lu32_DIV = 1; break;
  114. /* 32MHz */
  115. case 32000000: lu32_DIV = 2; break;
  116. /* 16MHz */
  117. case 16000000: lu32_DIV = 4; break;
  118. /* 8MHz */
  119. case 8000000: lu32_DIV = 8; break;
  120. default: return false;
  121. }
  122. lu32_result = 0;
  123. if (lu32_system_clk_source == CLK_SRC_XTH_PLL)
  124. {
  125. lu32_timeout = 0;
  126. SCU->XTHCR = SCU_XTHCR_XTH_EN | SCU_XTHCR_READYTIME_32768;
  127. while (0 == (SCU->XTHCR & SCU_XTHCR_XTHRDY))
  128. {
  129. if (lu32_timeout == SYSTEM_TIMEOUT)
  130. {
  131. lu32_result = 1;
  132. break;
  133. }
  134. lu32_timeout++;
  135. }
  136. if (0 == lu32_result)
  137. {
  138. SCU->PLLCR |= SCU_PLLCR_PLL_EN;
  139. SCU->PLLCR &= ~(SCU_PLLCR_PLL_SLEEP);
  140. while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) )) {}
  141. #ifdef XTH_8M_CRYSTAL
  142. SCU->PLLCR = (SCU->PLLCR &(~(0x1FFFFU << 3))) | (15U << 3) | (1U << 12) | (0U << 16);
  143. #endif
  144. #ifdef XTH_12M_CRYSTAL
  145. SCU->PLLCR = (SCU->PLLCR &(~(0x1FFFFU << 3))) | (15U << 3) | (2U << 12) | (0U << 16);
  146. #endif
  147. SCU->PLLCR = (SCU->PLLCR & (~(0x3U << 1)) ) | (3 << 1);
  148. SCU->PLLCR |= SCU_PLLCR_PLL_UPDATE_EN;
  149. while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) ) );
  150. /* Division Config */
  151. SCU->CCR2 = (SCU->CCR2 & (~0xFF)) | APB_CLK_DIV_0 | (lu32_DIV - 1);
  152. while((SCU->CCR2 & (1UL << 31)) == 0x00);
  153. /* Clock Select PLL */
  154. SCU->CCR1 = SYS_CLK_SRC_PLLCLK;
  155. }
  156. else
  157. {
  158. SCU->XTHCR &= (~SCU_XTHCR_XTH_EN);
  159. }
  160. }
  161. if ( (lu32_system_clk_source == CLK_SRC_RC64M) || (0 != lu32_result) )
  162. {
  163. /* Division Config */
  164. SCU->CCR2 = (SCU->CCR2 & (~0xFF)) | APB_CLK_DIV_0 | (lu32_DIV - 1);
  165. while((SCU->CCR2 & (1UL << 31)) == 0x00);
  166. /* Clock Select RCH */
  167. SCU->CCR1 = SYS_CLK_SRC_RCH;
  168. }
  169. gu32_SystemClock = fu32_Clock;
  170. gu32_APBClock = fu32_Clock;
  171. /* Eflash Config */
  172. //HAL_EFlash_Init(gu32_SystemClock);
  173. return true;
  174. }
  175. /*********************************************************************************
  176. * Function : System_Get_SystemClock
  177. * Description : get AHB clock frequency
  178. * Input : none
  179. * Outpu : frequency, measured as Hz
  180. * Author : Chris_Kyle Date : 2020
  181. **********************************************************************************/
  182. uint32_t System_Get_SystemClock(void)
  183. {
  184. return gu32_SystemClock;
  185. }
  186. /*********************************************************************************
  187. * Function : System_Get_APBClock
  188. * Description : get APB clock frequency
  189. * Input : none
  190. * Outpu : frequency, measured as Hz
  191. * Author : Chris_Kyle Date : 2021
  192. **********************************************************************************/
  193. uint32_t System_Get_APBClock(void)
  194. {
  195. return gu32_APBClock;
  196. }
  197. /*********************************************************************************
  198. * Function : System_Module_Reset
  199. * Description : reset module
  200. * Input : module id
  201. * Outpu : none
  202. * Author : Chris_Kyle Date : 2021
  203. **********************************************************************************/
  204. void System_Module_Reset(enum_RST_ID_t fe_ID_Index)
  205. {
  206. SCU->IPRST &= (~(1 << fe_ID_Index));
  207. System_Delay(2);
  208. SCU->IPRST |= (1 << fe_ID_Index);
  209. }
  210. /*********************************************************************************
  211. * Function : System_Module_Enable
  212. * Description : enable module clock
  213. * Input : module id
  214. * Outpu : none
  215. * Author : Chris_Kyle Date : 2021
  216. **********************************************************************************/
  217. void System_Module_Enable(enum_Enable_ID_t fe_ID_Index)
  218. {
  219. if (fe_ID_Index > 6)
  220. {
  221. SCU->IPCKENR1 |= (1U << (fe_ID_Index - 7) );
  222. }
  223. else
  224. {
  225. SCU->IPCKENR2 |= (1U << fe_ID_Index);
  226. }
  227. System_Delay(2);
  228. }
  229. /*********************************************************************************
  230. * Function : System_Module_Disable
  231. * Description : disable module clock
  232. * Input : module id
  233. * Outpu : none
  234. * Author : Chris_Kyle Date : 2021
  235. **********************************************************************************/
  236. void System_Module_Disable(enum_Enable_ID_t fe_ID_Index)
  237. {
  238. if (fe_ID_Index > 6)
  239. {
  240. SCU->IPCKENR1 &= ~(1U << (fe_ID_Index - 7));
  241. }
  242. else
  243. {
  244. SCU->IPCKENR2 &= ~(1U << fe_ID_Index);
  245. }
  246. }
  247. /*********************************************************************************
  248. * Function : System_Delay
  249. * Description : NOP delay
  250. * Input : count
  251. * Output : none
  252. * Author : Chris_Kyle
  253. **********************************************************************************/
  254. void System_Delay(volatile uint32_t fu32_Delay)
  255. {
  256. while (fu32_Delay--);
  257. }
  258. /*********************************************************************************
  259. * Function : System_Delay_MS
  260. * Description : ms delay. Use this Function must call System_SysTick_Init()
  261. * Input : delay period, measured as ms
  262. * Output : none
  263. * Author : Chris_Kyle
  264. **********************************************************************************/
  265. void System_Delay_MS(volatile uint32_t fu32_Delay)
  266. {
  267. uint32_t lu32_SystemCountBackup;
  268. lu32_SystemCountBackup = gu32_SystemCount;
  269. while ( (gu32_SystemCount - lu32_SystemCountBackup) < fu32_Delay);
  270. }
  271. /*********************************************************************************
  272. * Function : System_Enable_RC32K
  273. * Description : Enable RC32K, make sure RTC Domain Access is allowed
  274. * Input : none
  275. * Outpu : none
  276. * Author : Chris_Kyle Date : 2021
  277. **********************************************************************************/
  278. void System_Enable_RC32K(void)
  279. {
  280. PMU->ANACR |= RPMU_ANACR_RC32K_EN;
  281. while(!(PMU->ANACR & RPMU_ANACR_RC32K_RDY));
  282. }
  283. /*********************************************************************************
  284. * Function : System_Disable_RC32K
  285. * Description : Disable RC32K
  286. * Input : none
  287. * Outpu : none
  288. * Author : CWT Date : 2021
  289. **********************************************************************************/
  290. void System_Disable_RC32K(void)
  291. {
  292. PMU->ANACR &= (~RPMU_ANACR_RC32K_EN);
  293. }
  294. /*********************************************************************************
  295. * Function : System_Enable_XTAL
  296. * Description : Enable XTAL, make sure RTC Domain Access is allowed
  297. * Input : none
  298. * Outpu : none
  299. * Author : Chris_Kyle Date : 2021
  300. **********************************************************************************/
  301. void System_Enable_XTAL(void)
  302. {
  303. PMU->ANACR = (PMU->ANACR & ~RPMU_ANACR_XTLDRV) | (RPMU_ANACR_XTLDRV_1 | RPMU_ANACR_XTLDRV_0);
  304. PMU->ANACR |= RPMU_ANACR_XTLEN;
  305. while(!(PMU->ANACR & RPMU_ANACR_XTLRDY));
  306. PMU->CR1 |= RTC_CLOCK_XTL;
  307. }
  308. /*********************************************************************************
  309. * Function : System_Disable_XTAL
  310. * Description : Disable XTAL
  311. * Input : none
  312. * Output : none
  313. * Author : CWT
  314. **********************************************************************************/
  315. void System_Disable_XTAL(void)
  316. {
  317. PMU->ANACR &= (~(RPMU_ANACR_XTLEN));
  318. }
  319. /*********************************************************************************
  320. * Function : System_Enable_Disable_RTC_Domain_Access
  321. * Description : Enable or Disable RTC Domain Access.
  322. * Input : enable or disable
  323. * Output : none
  324. * Author : CWT
  325. **********************************************************************************/
  326. void System_Enable_Disable_RTC_Domain_Access(FUNC_DISABLE_ENABLE enable_disable)
  327. {
  328. if (FUNC_DISABLE == enable_disable)
  329. {
  330. SCU->STOPCFG &= (~SCU_STOPCFG_RTC_WE);
  331. }
  332. else
  333. {
  334. SCU->STOPCFG |= SCU_STOPCFG_RTC_WE;
  335. System_Delay(1);
  336. RTC->WP = 0xCA53CA53U;
  337. }
  338. }
  339. /*********************************************************************************
  340. * Function : System_Enable_Disable_Reset
  341. * Description : Enable or Disable System Reset source.
  342. * Input : none
  343. * Output : none
  344. * Author : CWT
  345. **********************************************************************************/
  346. void System_Enable_Disable_Reset(RESET_ENABLE_SOURCE source, FUNC_DISABLE_ENABLE enable_disable)
  347. {
  348. switch(source)
  349. {
  350. /* reset source: from bit0 to bit3 */
  351. case RESET_ENABLE_SOURCE_LVD:
  352. case RESET_ENABLE_SOURCE_WDT:
  353. case RESET_ENABLE_SOURCE_IWDT:
  354. case RESET_ENABLE_SOURCE_LOCKUP:
  355. if (FUNC_DISABLE == enable_disable)
  356. {
  357. SCU->RCR &= (~(1U << source));
  358. }
  359. else
  360. {
  361. SCU->RCR |= (1U << source);
  362. }
  363. break;
  364. default: break;
  365. }
  366. }
  367. /*********************************************************************************
  368. * Function : System_Reset_MCU
  369. * Description : reset mcu
  370. * Input : reset source
  371. * Output : none
  372. * Author : xwl
  373. **********************************************************************************/
  374. void System_Reset_MCU(RESET_SOURCE source)
  375. {
  376. switch(source)
  377. {
  378. case RESET_SOURCE_EFC:
  379. {
  380. SCU->RCR &= (~BIT29);
  381. while(1);
  382. }
  383. case RESET_SOURCE_NVIC_RESET:
  384. {
  385. NVIC_SystemReset();
  386. while(1);
  387. }
  388. case RESET_SOFT_RESET:
  389. {
  390. SCU->RCR &= (~BIT30);
  391. while(1);
  392. }
  393. default: break;
  394. }
  395. }
  396. /*********************************************************************************
  397. * Function : System_Enter_Standby_Mode
  398. * Description : try to enter standby mode
  399. * Input : none
  400. * Output : none
  401. * Author : xwl Date : 2021
  402. **********************************************************************************/
  403. void System_Enter_Standby_Mode(void)
  404. {
  405. __set_PRIMASK(1); // disable interrupt
  406. SysTick->CTRL = 0; // disable systick
  407. SCU->STOPCFG |= BIT11; // set PDDS=1
  408. /* Set SLEEPDEEP bit of Cortex System Control Register */
  409. SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
  410. __WFI();
  411. CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
  412. System_Delay(100);
  413. printfS("Enter Standby Mode Failed! \n"); // should not go here
  414. }
  415. /*********************************************************************************
  416. * Function : System_Clear_Stop_Wakeup
  417. * Description : clear all stop setting and status
  418. * Input : none
  419. * Output : none
  420. * Author : CWT Date : 2021
  421. **********************************************************************************/
  422. void System_Clear_Stop_Wakeup(void)
  423. {
  424. EXTI->IENR = 0;
  425. EXTI->RTENR = 0;
  426. EXTI->FTENR = 0;
  427. EXTI->SWIER = 0;
  428. EXTI->PDR = 0x7FFFFFU;
  429. }
  430. /*********************************************************************************
  431. * Function : System_Enter_Stop_Mode
  432. * Description : try to enter stop mode
  433. * Input : STOPEntry: STOPENTRY_WFI or STOPENTRY_WFE
  434. * Output : none
  435. * Author : CWT Date : 2021
  436. **********************************************************************************/
  437. void System_Enter_Stop_Mode(uint8_t STOPEntry)
  438. {
  439. /* Set SLEEPDEEP bit of Cortex System Control Register */
  440. SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
  441. SCU->STOPCFG &= (~BIT11); // PDDS=0
  442. System_SysTick_Off();
  443. /* Select Stop mode entry */
  444. if(STOPEntry == STOPENTRY_WFI)
  445. {
  446. /* Wait For Interrupt */
  447. __WFI();
  448. }
  449. else
  450. {
  451. __SEV();
  452. __WFE();
  453. __WFE(); /* Wait For Event */
  454. }
  455. CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
  456. #ifdef HAL_SYSTICK_ENABLED // To activate macro in ACM32Fxx_HAL.h
  457. System_SysTick_Init();
  458. #endif
  459. }
  460. /*********************************************************************************
  461. * Function : System_Enter_Sleep_Mode
  462. * Description : try to enter sleep mode
  463. * Input : SleepEntry: SLEEPENTRY_WFI or SLEEPENTRY_WFE
  464. * Output : none
  465. * Author : CWT Date : 2021
  466. **********************************************************************************/
  467. void System_Enter_Sleep_Mode(uint8_t SleepEntry)
  468. {
  469. /* clear SLEEPDEEP bit of Cortex System Control Register */
  470. CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
  471. /* Select Stop mode entry */
  472. if(SleepEntry == SLEEPENTRY_WFI)
  473. {
  474. /* Wait For Interrupt */
  475. __WFI();
  476. }
  477. else
  478. {
  479. __SEV();
  480. __WFE();
  481. __WFE(); /*Wait For Event */
  482. }
  483. }
  484. /*********************************************************************************
  485. * Function : System_Return_Last_Reset_Reason
  486. * Description : Get System Last Reset Reason
  487. * Input : none
  488. * Output : RESET_REASON
  489. * Author : CWT Date : 2021
  490. **********************************************************************************/
  491. RESET_REASON System_Return_Last_Reset_Reason(void)
  492. {
  493. RESET_REASON i = RESET_REASON_POR;
  494. Reset_Reason_Save = RESET_REASON_POR;
  495. for(i = RESET_REASON_POR; i >= RESET_REASON_POR12; i--)
  496. {
  497. if ((SCU->RSR) & (1U << i))
  498. {
  499. SCU->RSR |= SCU_RSR_RSTFLAG_CLR; // clear reset reason flags
  500. Reset_Reason_Save = i;
  501. return i;
  502. }
  503. }
  504. for(i = RESET_REASON_LOW_VOLTAGE; i <= RESET_REASON_SOFT; i++)
  505. {
  506. if ((SCU->RSR) & (1U << i))
  507. {
  508. SCU->RSR |= SCU_RSR_RSTFLAG_CLR; // clear reset reason flags
  509. Reset_Reason_Save = i;
  510. return i;
  511. }
  512. }
  513. return RESET_REASON_INVALID; // this should not happen
  514. }
  515. /*********************************************************************************
  516. * Function : System_Return_Saved_Reset_Reason
  517. * Description : Get saved Reset Reason
  518. * Input : none
  519. * Output : RESET_REASON
  520. * Author : CWT Date : 2021
  521. **********************************************************************************/
  522. RESET_REASON System_Return_Saved_Reset_Reason(void)
  523. {
  524. return Reset_Reason_Save;
  525. }
  526. /*********************************************************************************
  527. * Function : System_Set_Buzzer_Divider
  528. * Description : set buzzer divide factor
  529. * Input :
  530. div: div factor, if div = 80 then output buzzer freq=HCLK/80
  531. enable: FUNC_DISABLE and FUNC_ENABLE
  532. * Output : none
  533. * Author : xwl Date : 2021
  534. **********************************************************************************/
  535. void System_Set_Buzzer_Divider(uint32_t div, FUNC_DISABLE_ENABLE enable)
  536. {
  537. if (FUNC_ENABLE == enable)
  538. {
  539. SCU->CLKOCR = (SCU->CLKOCR & (~(0x1FFFFU << 5) ) ) | (div << 5);
  540. SCU->CLKOCR |= BIT23;
  541. }
  542. else
  543. {
  544. SCU->CLKOCR &= (~BIT23);
  545. }
  546. }