/* * mcu.c * * Created on: Feb 29, 2024 * Author: Francesco Gritti */ #include "mcu.h" #include "ftypes.h" sysclk_src get_sysclk_src (void) { return ((RCC->CFGR & RCC_CFGR_SWS_Msk) >> RCC_CFGR_SWS_Pos); } void backup_clock_init (void) { // disable PLL RCC->CR &= ~RCC_CR_PLLON; while ((RCC->CR & RCC_CR_PLLRDY) != 0); // wait until PLL is unlocked RCC->CFGR2 = PLL_PREDIV_BACKUP; RCC->CFGR = (CLK_PLLMUL_BACKUP << RCC_CFGR_PLLMUL_Pos) | (PLL_SRC_BACKUP << RCC_CFGR_PLLSRC_Pos) | (APB_SRC << RCC_CFGR_PPRE_Pos) | (AHB_SRC << RCC_CFGR_HPRE_Pos); RCC->CR |= RCC_CR_PLLON | (CSS_STATUS << RCC_CR_CSSON_Pos); // enable PLL while ((RCC->CR & RCC_CR_PLLRDY) == 0); // wait until PLL is locked and ready RCC->CFGR |= (SYSCLK_SRC << RCC_CFGR_SW_Pos); } void clock_init (void) { // disable PLL RCC->CR &= ~RCC_CR_PLLON; while ((RCC->CR & RCC_CR_PLLRDY) != 0); // wait until PLL is unlocked RCC->CR |= (HSE_STATUS << RCC_CR_HSEON_Pos); RCC->CFGR2 = PLL_PREDIV; RCC->CFGR = (CLK_PLLMUL << RCC_CFGR_PLLMUL_Pos) | (PLL_SRC << RCC_CFGR_PLLSRC_Pos) | (APB_SRC << RCC_CFGR_PPRE_Pos) | (AHB_SRC << RCC_CFGR_HPRE_Pos); RCC->CR |= RCC_CR_PLLON | (CSS_STATUS << RCC_CR_CSSON_Pos); // enable PLL while ((RCC->CR & RCC_CR_PLLRDY) == 0); // wait until PLL is locked and ready RCC->CFGR |= (SYSCLK_SRC << RCC_CFGR_SW_Pos); } // init clock in this function void SystemInit (void) { clock_init (); } #if 0 volatile systemClockTreeT systemClockTree; u32 SystemCoreClock; const u16 AHBPrescTable[16] = {1,1,1,1,1,1,1,1,2,4,8,16,64,128,256,512}; const u8 APBPrescTable[8] = {1,1,1,1,2,4,8,16}; #define HSE_FCLK 8000000U #define HSI_FCLK 8000000U #define HSI48_FCLK 48000000 void SystemCoreClockUpdate (void) { sysclk_src sysclkSrc = (RCC->CFGR & RCC_CFGR_SW_Msk) >> RCC_CFGR_SW_Pos; if (sysclkSrc == SYSCLK_SRC_HSI ) SystemCoreClock = HSI_FCLK; else if (sysclkSrc == SYSCLK_SRC_HSE) SystemCoreClock = HSE_FCLK; else if (sysclkSrc == SYSCLK_SRC_HSI48) SystemCoreClock = HSI48_FCLK; else if (sysclkSrc == SYSCLK_SRC_PLL) { pll_mul pllMul = (RCC->CFGR & RCC_CFGR_PLLMUL_Msk) >> RCC_CFGR_PLLMUL_Pos; pll_src pllSrc = (RCC->CFGR & RCC_CFGR_PLLSRC_Msk) >> RCC_CFGR_PLLSRC_Pos; u16 prediv = ((RCC->CFGR2 & RCC_CFGR2_PREDIV_Msk) >> RCC_CFGR2_PREDIV_Pos) +1; switch (pllSrc) { case PLL_SRC_HSI_2: SystemCoreClock = HSI_FCLK / 2 * (pllMul+2); break; case PLL_SRC_HSI_PREDIV: SystemCoreClock = HSI_FCLK / prediv * (pllMul+2); break; case PLL_SRC_HSE_PREDIV: SystemCoreClock = HSE_FCLK / prediv * (pllMul+2); break; case PLL_SRC_HSI48_PREDIV: SystemCoreClock = HSI48_FCLK / prediv * (pllMul+2); break; } } systemClockTree.SYS_clk = SystemCoreClock; u8 AHB_psc_idx = (RCC->CFGR & RCC_CFGR_HPRE_Msk) >> RCC_CFGR_HPRE_Pos; u16 AHB_psc = AHBPrescTable [AHB_psc_idx]; u8 APB_psc_idx = (RCC->CFGR & RCC_CFGR_PPRE_Msk) >> RCC_CFGR_PPRE_Pos; u16 APB_psc = APBPrescTable [APB_psc_idx]; systemClockTree.AHB_clk = SystemCoreClock / AHB_psc; systemClockTree.APB_clk = systemClockTree.AHB_clk / APB_psc; systemClockTree.TIM_clk = (APB_psc == 1 ? systemClockTree.APB_clk : systemClockTree.APB_clk*2); systemClockTree.sysTick_clk = systemClockTree.APB_clk; systemClockTree.USART1_clk = systemClockTree.APB_clk; systemClockTree.USART2_clk = systemClockTree.APB_clk; systemClockTree.USART3_clk = systemClockTree.APB_clk; systemClockTree.ADC_clk = systemClockTree.APB_clk; } #endif