155 lines
3.5 KiB
C
155 lines
3.5 KiB
C
/*
|
|
* 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
|
|
|
|
|
|
|