/******************************************************************************* * File Name : system_ch32x035.c *******************************************************************************/ #include "ch32x035.h" #include "global.h" uint32_t SystemCoreClock; __I uint8_t AHBPrescTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}; void SetSysClock(uint32_t clock); static void SetSysClockToX_HSI(uint32_t div, uint8_t latency); /********************************************************************* * @fn SystemInit * * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, * update the SystemCoreClock variable. * * @return none */ void SystemInit (void) { // ensure internal oscillator is running and ready RCC->CTLR |= (uint32_t)RCC_HSION; while (!(RCC->CTLR & RCC_HSIRDY)) {}; // default to 8MHz before doing anything else // this is POR default RCC->CFGR0 = (uint32_t)RCC_HPRE_DIV6; // set user-requested startup clock SetSysClock(SYSCLK_FREQ_STARTUP); } /********************************************************************* * @fn SystemCoreClockUpdate * * @brief Update SystemCoreClock variable according to Clock Register Values. * * @return none */ void SystemCoreClockUpdate (void) { uint32_t tmp = 0; SystemCoreClock = HSI_VALUE; tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; if(((RCC->CFGR0 & RCC_HPRE) >> 4) < 8) { SystemCoreClock /= tmp; } else { SystemCoreClock >>= tmp; } } /********************************************************************* * @fn SetSysClock * * @brief Configures the System clock frequency, HCLK prescalers. * * @return none */ void SetSysClock(uint32_t clock) { switch (clock) { case SYSCLK_FREQ_48MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV1, FLASH_ACTLR_LATENCY_2); break; } case SYSCLK_FREQ_24MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV2, FLASH_ACTLR_LATENCY_1); break; } case SYSCLK_FREQ_16MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV3, FLASH_ACTLR_LATENCY_1); break; } case SYSCLK_FREQ_12MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV4, FLASH_ACTLR_LATENCY_0); break; } case SYSCLK_FREQ_3MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV16, FLASH_ACTLR_LATENCY_0); break; } default: { SetSysClockToX_HSI(RCC_HPRE_DIV6, FLASH_ACTLR_LATENCY_0); clock = 8000000; break; } } SystemCoreClock = clock; } static void SetSysClockToX_HSI(uint32_t div, uint8_t latency) { uint32_t cfgr0; // set flash access to 2 wait states (boot default is 0 at 48MHz??) FLASH->ACTLR = (uint32_t)FLASH_ACTLR_LATENCY_2; // the vendor didn't wait here. but switching from slow to high speed // often causes crashes without this. asm("nop"); asm("nop"); asm("nop"); /* HCLK = SYSCLK = APB1 */ cfgr0 = RCC->CFGR0 &= (uint32_t)~RCC_HPRE; RCC->CFGR0 = (uint32_t)(cfgr0 | (div & 0xf0)); /* Flash set wait state */ FLASH->ACTLR = (uint32_t)(latency & 0x03); }