STM32F042-Drivers-Pub/mcu.c

155 lines
3.5 KiB
C
Raw Normal View History

2024-05-02 10:18:04 +00:00
/*
* 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