/** * \brief Test power scaling switch. * * \param test Current test case. */ static void run_ps_test(const struct test_case *test) { uint32_t timeout = sysclk_get_cpu_hz() / 1000 * 10; /* Wait 10ms */ bool b_psok; b_psok = bpm_power_scaling_cpu_failsafe(BPM, BPM_PMCON_PS(BPM_PS_1), timeout); test_assert_true(test, b_psok, "Switch to PS1: PSOK not ready"); wait_test_assert_idle(); b_psok = bpm_power_scaling_cpu_failsafe(BPM, BPM_PMCON_PS(BPM_PS_0), timeout); test_assert_true(test, b_psok, "Switch to PS0: PSOK not ready"); wait_test_assert_idle(); }
/** * \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 bpm_power_scaling_cpu(Bpm *bpm, uint32_t ps_value) { uint32_t pmcon = 0; /* Read last PM_CON value */ pmcon = bpm->BPM_PMCON; /* Clear last PS Value */ pmcon &= ~BPM_PMCON_PS_Msk; /* Write new PS Value */ pmcon |= BPM_PMCON_PS(ps_value); /* PSCM: without CPU halt */ pmcon |= BPM_PMCON_PSCM; /* Power Scaling Change Request */ pmcon |= BPM_PMCON_PSCREQ; /* Unlock PMCON register */ BPM_UNLOCK(PMCON); /* Write back PM_CON value */ bpm->BPM_PMCON = pmcon; }
bool bpm_power_scaling_cpu_failsafe(Bpm *bpm, uint32_t ps_value, uint32_t timeout) { uint32_t pmcon = 0; /* Read last PM_CON value */ pmcon = bpm->BPM_PMCON; /* Clear last PS Value & Write new one */ pmcon &= ~BPM_PMCON_PS_Msk; pmcon |= BPM_PMCON_PS(ps_value); /* Set PSCM Value: PS change no halt */ pmcon |= BPM_PMCON_PSCM; /* Power Scaling Change Request */ pmcon |= BPM_PMCON_PSCREQ; /* Execute power scaling no halt in RAM */ irqflags_t flags; bool b_psok; uint32_t ctrl, load, val; /* Avoid interrupt while flash halt */ flags = cpu_irq_save(); /* Save SysTick */ val = SysTick->VAL; ctrl = SysTick->CTRL; load = SysTick->LOAD; /* Setup SysTick & start counting */ SysTick->LOAD = timeout; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; b_psok = bpm_ps_no_halt_exec(bpm, pmcon); /* Restore SysTick */ SysTick->CTRL = 0; SysTick->LOAD = load; SysTick->VAL = val; SysTick->CTRL = ctrl; cpu_irq_restore(flags); return b_psok; }