#include #include #include #include "rcc_ctrl.h" void rcc_ctrl_set_frequency(enum sysclk_freq freq) { int freqs[] = {42, 84, 168, 200, 240}; /* USB freqs: 42MHz, 42Mhz, 48MHz, 50MHz, 48MHz */ int pll_div[] = {2, 4, 7, 8, 10}; /* PLL_VCO = (HSE_VALUE / PLL_M) * PLL_N */ /* SYSCLK = PLL_VCO / PLL_P */ /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ uint32_t PLL_P = 2; uint32_t PLL_N = freqs[freq] * 2; uint32_t PLL_M = (HSE_VALUE/1000000); uint32_t PLL_Q = pll_div[freq]; RCC_DeInit(); /* Enable HSE osscilator */ RCC_HSEConfig(RCC_HSE_ON); if (RCC_WaitForHSEStartUp() == ERROR) { return; } /* Configure PLL clock M, N, P, and Q dividers */ RCC_PLLConfig(RCC_PLLSource_HSE, PLL_M, PLL_N, PLL_P, PLL_Q); /* Enable PLL clock */ RCC_PLLCmd(ENABLE); /* Wait until PLL clock is stable */ while ((RCC->CR & RCC_CR_PLLRDY) == 0); /* Set PLL_CLK as system clock source SYSCLK */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Set AHB clock divider */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* Set APBx clock dividers */ switch (freq) { /* Max freq APB1: 42MHz APB2: 84MHz */ case SYSCLK_42_MHZ: RCC_PCLK1Config(RCC_HCLK_Div1); /* 42MHz */ RCC_PCLK2Config(RCC_HCLK_Div1); /* 42MHz */ break; case SYSCLK_84_MHZ: RCC_PCLK1Config(RCC_HCLK_Div2); /* 42MHz */ RCC_PCLK2Config(RCC_HCLK_Div1); /* 84MHz */ break; case SYSCLK_168_MHZ: RCC_PCLK1Config(RCC_HCLK_Div4); /* 42MHz */ RCC_PCLK2Config(RCC_HCLK_Div2); /* 84MHz */ break; case SYSCLK_200_MHZ: RCC_PCLK1Config(RCC_HCLK_Div4); /* 50MHz */ RCC_PCLK2Config(RCC_HCLK_Div2); /* 100MHz */ break; case SYSCLK_240_MHZ: RCC_PCLK1Config(RCC_HCLK_Div4); /* 60MHz */ RCC_PCLK2Config(RCC_HCLK_Div2); /* 120MHz */ break; } /* Update SystemCoreClock variable */ SystemCoreClockUpdate(); }