/** * \brief Switch into selected Power Scaling. * \param power_scaling selected Power Scaling. */ void app_switch_power_scaling(power_scaling_t power_scaling) { if (power_scaling == POWER_SCALING_PS1){ bpm_configure_power_scaling(BPM, BPM_PMCON_PS(BPM_PS_1), true); } else if (power_scaling == POWER_SCALING_PS2){ bpm_configure_power_scaling(BPM, BPM_PMCON_PS(BPM_PS_2), true); } else { bpm_configure_power_scaling(BPM, BPM_PMCON_PS(BPM_PS_0), true); } while((bpm_get_status(BPM) & BPM_SR_PSOK) == 0); }
void sysclk_init(void) { uint32_t ps_value = 0; bool is_fwu_enabled = false; #if CONFIG_HCACHE_ENABLE == 1 /* Enable HCACHE */ sysclk_enable_peripheral_clock(HCACHE); HCACHE->HCACHE_CTRL = HCACHE_CTRL_CEN_YES; while (!(HCACHE->HCACHE_SR & HCACHE_SR_CSTS_EN)); #endif /* Set up system clock dividers if different from defaults */ if ((CONFIG_SYSCLK_CPU_DIV > 0) || (CONFIG_SYSCLK_PBA_DIV > 0) || (CONFIG_SYSCLK_PBB_DIV > 0) || (CONFIG_SYSCLK_PBC_DIV > 0) || (CONFIG_SYSCLK_PBD_DIV > 0)) { sysclk_set_prescalers(CONFIG_SYSCLK_CPU_DIV, CONFIG_SYSCLK_PBA_DIV, CONFIG_SYSCLK_PBB_DIV, CONFIG_SYSCLK_PBC_DIV, CONFIG_SYSCLK_PBD_DIV ); } /* Automatically select best power scaling mode */ #ifdef CONFIG_FLASH_READ_MODE_HIGH_SPEED_ENABLE ps_value = BPM_PS_2; is_fwu_enabled = false; #elif (defined(CONFIG_PLL0_MUL) || defined(CONFIG_DFLL0_MUL) || defined(CONFIG_USBCLK_DIV)) /* USB/DFLL/PLL are not available in PS1 (BPM.PMCON.PS=1) mode */ ps_value = BPM_PS_0; is_fwu_enabled = false; #else if (sysclk_get_cpu_hz() <= FLASH_FREQ_PS1_FWS_1_MAX_FREQ) { ps_value = BPM_PS_1; if (sysclk_get_cpu_hz() > FLASH_FREQ_PS1_FWS_0_MAX_FREQ) { bpm_enable_fast_wakeup(BPM); is_fwu_enabled = true; } } else { ps_value = BPM_PS_0; } #endif /* Switch to system clock selected by user */ if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RCSYS) { /* Already running from RCSYS */ } #ifdef BOARD_OSC0_HZ else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_OSC0) { osc_enable(OSC_ID_OSC0); osc_wait_ready(OSC_ID_OSC0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_OSC0); } #endif #ifdef CONFIG_DFLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_DFLL) { dfll_enable_config_defaults(0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_DFLL); } #endif #ifdef CONFIG_PLL0_SOURCE else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLL0) { pll_enable_config_defaults(0); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_PLL0); } #endif else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC80M) { osc_enable(OSC_ID_RC80M); osc_wait_ready(OSC_ID_RC80M); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RC80M); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RCFAST) { osc_enable(OSC_ID_RCFAST); osc_wait_ready(OSC_ID_RCFAST); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RCFAST); } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC1M) { osc_enable(OSC_ID_RC1M); osc_wait_ready(OSC_ID_RC1M); // Set a flash wait state depending on the new cpu frequency. flash_set_bus_freq(sysclk_get_cpu_hz(), ps_value, is_fwu_enabled); sysclk_set_source(SYSCLK_SRC_RC1M); } else { Assert(false); } /* Automatically switch to low power mode */ bpm_configure_power_scaling(BPM, ps_value, BPM_PSCM_CPU_NOT_HALT); while ((bpm_get_status(BPM) & BPM_SR_PSOK) == 0); /* If the user has specified clock masks, enable only requested clocks */ irqflags_t const flags = cpu_irq_save(); #if defined(CONFIG_SYSCLK_INIT_CPUMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_CPUMASK - (uint32_t)PM); PM->PM_CPUMASK = SYSCLK_INIT_MINIMAL_CPUMASK | CONFIG_SYSCLK_INIT_CPUMASK; #endif #if defined(CONFIG_SYSCLK_INIT_HSBMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_HSBMASK - (uint32_t)PM); PM->PM_HSBMASK = SYSCLK_INIT_MINIMAL_HSBMASK | CONFIG_SYSCLK_INIT_HSBMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBAMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBAMASK - (uint32_t)PM); PM->PM_PBAMASK = SYSCLK_INIT_MINIMAL_PBAMASK | CONFIG_SYSCLK_INIT_PBAMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBBMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBBMASK - (uint32_t)PM); PM->PM_PBBMASK = SYSCLK_INIT_MINIMAL_PBBMASK | CONFIG_SYSCLK_INIT_PBBMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBCMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBCMASK - (uint32_t)PM); PM->PM_PBCMASK = SYSCLK_INIT_MINIMAL_PBCMASK | CONFIG_SYSCLK_INIT_PBCMASK; #endif #if defined(CONFIG_SYSCLK_INIT_PBDMASK) PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->PM_PBDMASK - (uint32_t)PM); PM->PM_PBDMASK = SYSCLK_INIT_MINIMAL_PBDMASK | CONFIG_SYSCLK_INIT_PBDMASK; #endif cpu_irq_restore(flags); #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) /* Signal that the internal frequencies are setup */ sysclk_initialized = true; #endif }