void rcc_clock_setup_hsi(const clock_scale_t *clock) { /* Enable internal high-speed oscillator. */ rcc_osc_on(HSI); rcc_wait_for_osc_ready(HSI); /* Select HSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL (TODO: why?). */ rcc_set_hpre(clock->hpre); rcc_set_ppre1(clock->ppre1); rcc_set_ppre2(clock->ppre2); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_PWREN); pwr_set_vos_scale(clock->voltage_scale); /* I guess this should be in the settings? */ flash_64bit_enable(); flash_prefetch_enable(); /* Configure flash settings. */ flash_set_ws(clock->flash_config); /* Set the peripheral clock frequencies used. */ rcc_apb1_frequency = clock->apb1_frequency; rcc_apb2_frequency = clock->apb2_frequency; }
/** * Switch sysclock to HSI with the given parameters. * This should be usable from any point in time, but only if you have used * library functions to manage clocks. It relies on the global * @ref rcc_ahb_frequency to ensure that it reliably scales voltage up or down * as appropriate. * @param clock full struct with desired parameters */ void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock) { /* Enable internal high-speed oscillator. */ rcc_osc_on(RCC_HSI); rcc_periph_clock_enable(RCC_PWR); /* I guess this should be in the settings? */ flash_64bit_enable(); flash_prefetch_enable(); /* Don't try and go to fast for a voltage range! */ if (clock->ahb_frequency > rcc_ahb_frequency) { /* Going up, power up first */ pwr_set_vos_scale(clock->voltage_scale); rcc_set_hpre(clock->hpre); rcc_set_ppre1(clock->ppre1); rcc_set_ppre2(clock->ppre2); flash_set_ws(clock->flash_config); } else { /* going down, slow down before cutting power */ rcc_set_hpre(clock->hpre); rcc_set_ppre1(clock->ppre1); rcc_set_ppre2(clock->ppre2); flash_set_ws(clock->flash_config); pwr_set_vos_scale(clock->voltage_scale); } rcc_wait_for_osc_ready(RCC_HSI); while (PWR_CSR & PWR_CSR_VOSF) ; rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); /* Set the peripheral clock frequencies used. */ rcc_ahb_frequency = clock->ahb_frequency; rcc_apb1_frequency = clock->apb1_frequency; rcc_apb2_frequency = clock->apb2_frequency; }
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) { /* Turn on the appropriate source for the PLL */ if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) { rcc_osc_on(RCC_HSE); rcc_wait_for_osc_ready(RCC_HSE); } else { rcc_osc_on(RCC_HSI); rcc_wait_for_osc_ready(RCC_HSI); } /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL (TODO: why?). */ rcc_set_hpre(clock->hpre); rcc_set_ppre1(clock->ppre1); rcc_set_ppre2(clock->ppre2); rcc_periph_clock_enable(RCC_PWR); pwr_set_vos_scale(clock->voltage_scale); /* I guess this should be in the settings? */ flash_64bit_enable(); flash_prefetch_enable(); /* Configure flash settings. */ flash_set_ws(clock->flash_config); rcc_set_pll_configuration(clock->pll_source, clock->pll_mul, clock->pll_div); /* Enable PLL oscillator and wait for it to stabilize. */ rcc_osc_on(RCC_PLL); rcc_wait_for_osc_ready(RCC_PLL); /* Select PLL as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); /* Set the peripheral clock frequencies used. */ rcc_ahb_frequency = clock->ahb_frequency; rcc_apb1_frequency = clock->apb1_frequency; rcc_apb2_frequency = clock->apb2_frequency; }
/** * Set up sysclock with PLL from HSI16 * @param clock full struct with desired parameters */ void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) { /* Turn on the appropriate source for the PLL */ if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) { rcc_osc_on(RCC_HSE); rcc_wait_for_osc_ready(RCC_HSE); } else { rcc_osc_on(RCC_HSI16); rcc_wait_for_osc_ready(RCC_HSI16); } rcc_set_hpre(clock->hpre); rcc_set_ppre1(clock->ppre1); rcc_set_ppre2(clock->ppre2); rcc_periph_clock_enable(RCC_PWR); pwr_set_vos_scale(clock->voltage_scale); rcc_osc_off(RCC_PLL); while (rcc_is_osc_ready(RCC_PLL)); flash_prefetch_enable(); flash_set_ws(clock->flash_waitstates); /* Set up the PLL */ rcc_set_pll_multiplier(clock->pll_mul); rcc_set_pll_divider(clock->pll_div); rcc_osc_on(RCC_PLL); rcc_wait_for_osc_ready(RCC_PLL); rcc_set_sysclk_source(RCC_PLL); /* Set the peripheral clock frequencies used. */ rcc_ahb_frequency = clock->ahb_frequency; rcc_apb1_frequency = clock->apb1_frequency; rcc_apb2_frequency = clock->apb2_frequency; }
void rcc_clock_setup_msi(const struct rcc_clock_scale *clock) { /* Enable internal multi-speed oscillator. */ uint32_t reg = RCC_ICSCR; reg &= ~(RCC_ICSCR_MSIRANGE_MASK << RCC_ICSCR_MSIRANGE_SHIFT); reg |= (clock->msi_range << RCC_ICSCR_MSIRANGE_SHIFT); RCC_ICSCR = reg; rcc_osc_on(RCC_MSI); rcc_wait_for_osc_ready(RCC_MSI); /* Select MSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_MSICLK); /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL (TODO: why?). */ rcc_set_hpre(clock->hpre); rcc_set_ppre1(clock->ppre1); rcc_set_ppre2(clock->ppre2); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_PWREN); pwr_set_vos_scale(clock->voltage_scale); /* I guess this should be in the settings? */ flash_64bit_enable(); flash_prefetch_enable(); /* Configure flash settings. */ flash_set_ws(clock->flash_config); /* Set the peripheral clock frequencies used. */ rcc_apb1_frequency = clock->apb1_frequency; rcc_apb2_frequency = clock->apb2_frequency; }
void clock_setup() { /* RCC_CR |= (uint32_t)0x00000001; RCC_CFGR = 0x00000000; RCC_CR &= (uint32_t)0xFEF6FFFF; RCC_PLLCFGR = 0x24003010; RCC_CR &= (uint32_t)0xFFFBFFFF; RCC_CIR = 0x00000000; SCB_VTOR = 0x08000000; */ /* .pllm = 16, .plln = 336, .pllp = 2, .pllq = 7, .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_5WS, .apb1_frequency = 42000000, .apb2_frequency = 84000000, */ /* Enable internal high-speed oscillator. */ rcc_osc_on(RCC_HSI); rcc_wait_for_osc_ready(RCC_HSI); /* Select HSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_HSI); pwr_set_vos_scale(PWR_SCALE1); rcc_set_main_pll_hsi(16, 336, 2, 8, 0); /* Enable PLL oscillator and wait for it to stabilize. */ rcc_osc_on(RCC_PLL); rcc_wait_for_osc_ready(RCC_PLL); /* Configure flash settings. */ flash_set_ws(FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_5WS); /* Select PLL as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_PLL); rcc_set_hpre(RCC_CFGR_HPRE_DIV_NONE); rcc_set_ppre1(RCC_CFGR_PPRE_DIV_4); rcc_set_ppre2(RCC_CFGR_PPRE_DIV_2); /* Wait for PLL clock to be selected. */ rcc_wait_for_sysclk_status(RCC_PLL); rcc_ahb_frequency = 168000000; rcc_apb1_frequency = 42000000; rcc_apb2_frequency = 84000000; /* Disable internal high-speed oscillator. */ rcc_osc_off(RCC_HSI); // clock rate is 1680 to get 10uS interrupt rate systick_set_reload(168); systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); systick_counter_enable(); systick_interrupt_enable(); rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOB); rcc_periph_clock_enable(RCC_GPIOC); etk::set_tick_rate(1); }