2023-10-09 02:48:22 +02:00
|
|
|
|
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange, Plldiv, Pllm, Plln, Ppre as APBPrescaler};
|
|
|
|
|
use crate::pac::rcc::vals::{Msirgsel, Pllmboost, Pllrge, Pllsrc, Sw};
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
use crate::pac::{FLASH, PWR, RCC};
|
2021-11-08 20:27:33 +01:00
|
|
|
|
use crate::rcc::{set_freqs, Clocks};
|
2022-07-11 00:36:10 +02:00
|
|
|
|
use crate::time::Hertz;
|
2021-11-08 20:20:31 +01:00
|
|
|
|
|
2022-07-10 19:59:36 +02:00
|
|
|
|
/// HSI speed
|
|
|
|
|
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
|
|
|
|
|
|
2023-09-18 03:00:59 +02:00
|
|
|
|
pub use crate::pac::pwr::vals::Vos as VoltageScale;
|
2022-01-04 23:58:13 +01:00
|
|
|
|
|
2021-11-08 20:20:31 +01:00
|
|
|
|
#[derive(Copy, Clone)]
|
2023-10-22 22:39:55 +02:00
|
|
|
|
#[allow(non_camel_case_types)]
|
2021-11-08 20:20:31 +01:00
|
|
|
|
pub enum ClockSrc {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// Use an internal medium speed oscillator (MSIS) as the system clock.
|
2023-10-09 02:48:22 +02:00
|
|
|
|
MSI(Msirange),
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// Use the external high speed clock as the system clock.
|
|
|
|
|
///
|
|
|
|
|
/// HSE clocks faster than 25 MHz require at least `VoltageScale::RANGE3`, and HSE clocks must
|
|
|
|
|
/// never exceed 50 MHz.
|
2021-11-08 20:20:31 +01:00
|
|
|
|
HSE(Hertz),
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// Use the 16 MHz internal high speed oscillator as the system clock.
|
2023-10-22 22:39:55 +02:00
|
|
|
|
HSI,
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// Use PLL1 as the system clock.
|
2023-10-22 22:39:55 +02:00
|
|
|
|
PLL1_R(PllConfig),
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for ClockSrc {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
// The default system clock source is MSIS @ 4 MHz, per RM0456 § 11.4.9
|
2023-10-09 02:48:22 +02:00
|
|
|
|
ClockSrc::MSI(Msirange::RANGE_4MHZ)
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-09 02:48:22 +02:00
|
|
|
|
#[derive(Clone, Copy)]
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
pub struct PllConfig {
|
|
|
|
|
/// The clock source for the PLL.
|
|
|
|
|
pub source: PllSrc,
|
|
|
|
|
/// The PLL prescaler.
|
|
|
|
|
///
|
|
|
|
|
/// The clock speed of the `source` divided by `m` must be between 4 and 16 MHz.
|
2023-10-09 02:48:22 +02:00
|
|
|
|
pub m: Pllm,
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// The PLL multiplier.
|
|
|
|
|
///
|
|
|
|
|
/// The multiplied clock – `source` divided by `m` times `n` – must be between 128 and 544
|
|
|
|
|
/// MHz. The upper limit may be lower depending on the `Config { voltage_range }`.
|
2023-10-09 02:48:22 +02:00
|
|
|
|
pub n: Plln,
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// The divider for the R output.
|
|
|
|
|
///
|
|
|
|
|
/// When used to drive the system clock, `source` divided by `m` times `n` divided by `r`
|
|
|
|
|
/// must not exceed 160 MHz. System clocks above 55 MHz require a non-default
|
|
|
|
|
/// `Config { voltage_range }`.
|
2023-10-09 02:48:22 +02:00
|
|
|
|
pub r: Plldiv,
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PllConfig {
|
2023-10-22 22:39:55 +02:00
|
|
|
|
/// A configuration for HSI / 1 * 10 / 1 = 160 MHz
|
|
|
|
|
pub const fn hsi_160mhz() -> Self {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
PllConfig {
|
2023-10-22 22:39:55 +02:00
|
|
|
|
source: PllSrc::HSI,
|
2023-10-09 02:48:22 +02:00
|
|
|
|
m: Pllm::DIV1,
|
|
|
|
|
n: Plln::MUL10,
|
|
|
|
|
r: Plldiv::DIV1,
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A configuration for MSIS @ 48 MHz / 3 * 10 / 1 = 160 MHz
|
|
|
|
|
pub const fn msis_160mhz() -> Self {
|
|
|
|
|
PllConfig {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
source: PllSrc::MSIS(Msirange::RANGE_48MHZ),
|
|
|
|
|
m: Pllm::DIV3,
|
|
|
|
|
n: Plln::MUL10,
|
|
|
|
|
r: Plldiv::DIV1,
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-09 02:48:22 +02:00
|
|
|
|
#[derive(Clone, Copy)]
|
2021-11-08 20:20:31 +01:00
|
|
|
|
pub enum PllSrc {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// Use an internal medium speed oscillator as the PLL source.
|
2023-10-09 02:48:22 +02:00
|
|
|
|
MSIS(Msirange),
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// Use the external high speed clock as the system PLL source.
|
|
|
|
|
///
|
|
|
|
|
/// HSE clocks faster than 25 MHz require at least `VoltageScale::RANGE3`, and HSE clocks must
|
|
|
|
|
/// never exceed 50 MHz.
|
2021-11-08 20:20:31 +01:00
|
|
|
|
HSE(Hertz),
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// Use the 16 MHz internal high speed oscillator as the PLL source.
|
2023-10-22 22:39:55 +02:00
|
|
|
|
HSI,
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Into<Pllsrc> for PllSrc {
|
|
|
|
|
fn into(self) -> Pllsrc {
|
|
|
|
|
match self {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
PllSrc::MSIS(..) => Pllsrc::MSIS,
|
2021-11-08 20:20:31 +01:00
|
|
|
|
PllSrc::HSE(..) => Pllsrc::HSE,
|
2023-10-22 22:39:55 +02:00
|
|
|
|
PllSrc::HSI => Pllsrc::HSI,
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Into<Sw> for ClockSrc {
|
|
|
|
|
fn into(self) -> Sw {
|
|
|
|
|
match self {
|
|
|
|
|
ClockSrc::MSI(..) => Sw::MSIS,
|
|
|
|
|
ClockSrc::HSE(..) => Sw::HSE,
|
2023-10-22 22:39:55 +02:00
|
|
|
|
ClockSrc::HSI => Sw::HSI,
|
|
|
|
|
ClockSrc::PLL1_R(..) => Sw::PLL1_R,
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct Config {
|
2022-01-04 11:18:59 +01:00
|
|
|
|
pub mux: ClockSrc,
|
|
|
|
|
pub ahb_pre: AHBPrescaler,
|
|
|
|
|
pub apb1_pre: APBPrescaler,
|
|
|
|
|
pub apb2_pre: APBPrescaler,
|
|
|
|
|
pub apb3_pre: APBPrescaler,
|
2023-11-05 23:35:01 +01:00
|
|
|
|
pub hsi48: Option<super::Hsi48Config>,
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
/// The voltage range influences the maximum clock frequencies for different parts of the
|
|
|
|
|
/// device. In particular, system clocks exceeding 110 MHz require `RANGE1`, and system clocks
|
|
|
|
|
/// exceeding 55 MHz require at least `RANGE2`.
|
|
|
|
|
///
|
|
|
|
|
/// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits.
|
|
|
|
|
pub voltage_range: VoltageScale,
|
2023-10-11 03:53:27 +02:00
|
|
|
|
pub ls: super::LsConfig,
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Config {
|
2023-10-22 22:39:55 +02:00
|
|
|
|
unsafe fn init_hsi(&self) -> Hertz {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
RCC.cr().write(|w| w.set_hsion(true));
|
|
|
|
|
while !RCC.cr().read().hsirdy() {}
|
|
|
|
|
|
|
|
|
|
HSI_FREQ
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe fn init_hse(&self, frequency: Hertz) -> Hertz {
|
|
|
|
|
// Check frequency limits per RM456 § 11.4.10
|
|
|
|
|
match self.voltage_range {
|
|
|
|
|
VoltageScale::RANGE1 | VoltageScale::RANGE2 | VoltageScale::RANGE3 => {
|
|
|
|
|
assert!(frequency.0 <= 50_000_000);
|
|
|
|
|
}
|
|
|
|
|
VoltageScale::RANGE4 => {
|
|
|
|
|
assert!(frequency.0 <= 25_000_000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Enable HSE, and wait for it to stabilize
|
|
|
|
|
RCC.cr().write(|w| w.set_hseon(true));
|
|
|
|
|
while !RCC.cr().read().hserdy() {}
|
|
|
|
|
|
|
|
|
|
frequency
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-09 02:48:22 +02:00
|
|
|
|
unsafe fn init_msis(&self, range: Msirange) -> Hertz {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Check MSI output per RM0456 § 11.4.10
|
|
|
|
|
match self.voltage_range {
|
|
|
|
|
VoltageScale::RANGE4 => {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
assert!(msirange_to_hertz(range).0 <= 24_000_000);
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RM0456 § 11.8.2: spin until MSIS is off or MSIS is ready before setting its range
|
|
|
|
|
loop {
|
|
|
|
|
let cr = RCC.cr().read();
|
|
|
|
|
if cr.msison() == false || cr.msisrdy() == true {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RCC.icscr1().modify(|w| {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
w.set_msisrange(range);
|
2023-10-23 00:28:54 +02:00
|
|
|
|
w.set_msirgsel(Msirgsel::ICSCR1);
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
});
|
|
|
|
|
RCC.cr().write(|w| {
|
|
|
|
|
w.set_msipllen(false);
|
|
|
|
|
w.set_msison(true);
|
|
|
|
|
});
|
|
|
|
|
while !RCC.cr().read().msisrdy() {}
|
2023-10-09 02:48:22 +02:00
|
|
|
|
msirange_to_hertz(range)
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
}
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
2021-11-02 17:03:56 +01:00
|
|
|
|
|
2022-01-04 11:18:59 +01:00
|
|
|
|
impl Default for Config {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
mux: ClockSrc::default(),
|
2023-09-17 00:41:11 +02:00
|
|
|
|
ahb_pre: AHBPrescaler::DIV1,
|
|
|
|
|
apb1_pre: APBPrescaler::DIV1,
|
|
|
|
|
apb2_pre: APBPrescaler::DIV1,
|
|
|
|
|
apb3_pre: APBPrescaler::DIV1,
|
2023-11-05 23:35:01 +01:00
|
|
|
|
hsi48: Some(Default::default()),
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
voltage_range: VoltageScale::RANGE3,
|
2023-10-11 03:53:27 +02:00
|
|
|
|
ls: Default::default(),
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
2021-11-02 17:03:56 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-04 23:58:13 +01:00
|
|
|
|
pub(crate) unsafe fn init(config: Config) {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Ensure PWR peripheral clock is enabled
|
|
|
|
|
RCC.ahb3enr().modify(|w| {
|
|
|
|
|
w.set_pwren(true);
|
|
|
|
|
});
|
|
|
|
|
RCC.ahb3enr().read(); // synchronize
|
|
|
|
|
|
|
|
|
|
// Set the requested power mode
|
|
|
|
|
PWR.vosr().modify(|w| {
|
|
|
|
|
w.set_vos(config.voltage_range);
|
|
|
|
|
});
|
|
|
|
|
while !PWR.vosr().read().vosrdy() {}
|
|
|
|
|
|
2022-01-04 23:58:13 +01:00
|
|
|
|
let sys_clk = match config.mux {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
ClockSrc::MSI(range) => config.init_msis(range),
|
|
|
|
|
ClockSrc::HSE(freq) => config.init_hse(freq),
|
2023-10-22 22:39:55 +02:00
|
|
|
|
ClockSrc::HSI => config.init_hsi(),
|
|
|
|
|
ClockSrc::PLL1_R(pll) => {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Configure the PLL source
|
|
|
|
|
let source_clk = match pll.source {
|
|
|
|
|
PllSrc::MSIS(range) => config.init_msis(range),
|
|
|
|
|
PllSrc::HSE(hertz) => config.init_hse(hertz),
|
2023-10-22 22:39:55 +02:00
|
|
|
|
PllSrc::HSI => config.init_hsi(),
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
};
|
2021-11-08 20:20:31 +01:00
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Calculate the reference clock, which is the source divided by m
|
2023-10-09 02:48:22 +02:00
|
|
|
|
let reference_clk = source_clk / pll.m;
|
2021-11-08 20:20:31 +01:00
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Check limits per RM0456 § 11.4.6
|
|
|
|
|
assert!(Hertz::mhz(4) <= reference_clk && reference_clk <= Hertz::mhz(16));
|
2021-11-08 20:20:31 +01:00
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Calculate the PLL1 VCO clock and PLL1 R output clock
|
2023-10-09 02:48:22 +02:00
|
|
|
|
let pll1_clk = reference_clk * pll.n;
|
|
|
|
|
let pll1r_clk = pll1_clk / pll.r;
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
|
|
|
|
|
// Check system clock per RM0456 § 11.4.9
|
|
|
|
|
assert!(pll1r_clk <= Hertz::mhz(160));
|
|
|
|
|
|
|
|
|
|
// Check PLL clocks per RM0456 § 11.4.10
|
|
|
|
|
match config.voltage_range {
|
|
|
|
|
VoltageScale::RANGE1 => {
|
|
|
|
|
assert!(pll1_clk >= Hertz::mhz(128) && pll1_clk <= Hertz::mhz(544));
|
|
|
|
|
assert!(pll1r_clk <= Hertz::mhz(208));
|
2023-01-11 17:57:22 +01:00
|
|
|
|
}
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
VoltageScale::RANGE2 => {
|
|
|
|
|
assert!(pll1_clk >= Hertz::mhz(128) && pll1_clk <= Hertz::mhz(544));
|
|
|
|
|
assert!(pll1r_clk <= Hertz::mhz(110));
|
2023-01-11 17:57:22 +01:00
|
|
|
|
}
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
VoltageScale::RANGE3 => {
|
|
|
|
|
assert!(pll1_clk >= Hertz::mhz(128) && pll1_clk <= Hertz::mhz(330));
|
|
|
|
|
assert!(pll1r_clk <= Hertz::mhz(55));
|
|
|
|
|
}
|
|
|
|
|
VoltageScale::RANGE4 => {
|
|
|
|
|
panic!("PLL is unavailable in voltage range 4");
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-11 17:57:22 +01:00
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// § 10.5.4: if we're targeting >= 55 MHz, we must configure PLL1MBOOST to a prescaler
|
|
|
|
|
// value that results in an output between 4 and 16 MHz for the PWR EPOD boost
|
|
|
|
|
let mboost = if pll1r_clk >= Hertz::mhz(55) {
|
|
|
|
|
// source_clk can be up to 50 MHz, so there's just a few cases:
|
|
|
|
|
if source_clk > Hertz::mhz(32) {
|
|
|
|
|
// Divide by 4, giving EPOD 8-12.5 MHz
|
|
|
|
|
Pllmboost::DIV4
|
|
|
|
|
} else if source_clk > Hertz::mhz(16) {
|
|
|
|
|
// Divide by 2, giving EPOD 8-16 MHz
|
|
|
|
|
Pllmboost::DIV2
|
|
|
|
|
} else {
|
|
|
|
|
// Bypass, giving EPOD 4-16 MHz
|
2023-10-09 02:48:22 +02:00
|
|
|
|
Pllmboost::DIV1
|
2023-01-11 17:57:22 +01:00
|
|
|
|
}
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
} else {
|
|
|
|
|
// Nothing to do
|
2023-10-09 02:48:22 +02:00
|
|
|
|
Pllmboost::DIV1
|
2022-01-04 23:58:13 +01:00
|
|
|
|
};
|
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Disable the PLL, and wait for it to disable
|
2022-01-04 23:58:13 +01:00
|
|
|
|
RCC.cr().modify(|w| w.set_pllon(0, false));
|
|
|
|
|
while RCC.cr().read().pllrdy(0) {}
|
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Configure the PLL
|
2022-01-04 23:58:13 +01:00
|
|
|
|
RCC.pll1cfgr().write(|w| {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Configure PLL1 source and prescaler
|
|
|
|
|
w.set_pllsrc(pll.source.into());
|
2023-10-09 02:48:22 +02:00
|
|
|
|
w.set_pllm(pll.m);
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
|
|
|
|
|
// Configure PLL1 input frequncy range
|
|
|
|
|
let input_range = if reference_clk <= Hertz::mhz(8) {
|
|
|
|
|
Pllrge::FREQ_4TO8MHZ
|
|
|
|
|
} else {
|
|
|
|
|
Pllrge::FREQ_8TO16MHZ
|
|
|
|
|
};
|
|
|
|
|
w.set_pllrge(input_range);
|
|
|
|
|
|
|
|
|
|
// Set the prescaler for PWR EPOD
|
|
|
|
|
w.set_pllmboost(mboost);
|
|
|
|
|
|
2023-10-22 22:39:55 +02:00
|
|
|
|
// Enable PLL1_R output
|
2023-01-11 17:57:22 +01:00
|
|
|
|
w.set_pllren(true);
|
2021-11-08 20:20:31 +01:00
|
|
|
|
});
|
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Configure the PLL divisors
|
2022-01-04 23:58:13 +01:00
|
|
|
|
RCC.pll1divr().modify(|w| {
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Set the VCO multiplier
|
2023-10-09 02:48:22 +02:00
|
|
|
|
w.set_plln(pll.n);
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Set the R output divisor
|
2023-10-09 02:48:22 +02:00
|
|
|
|
w.set_pllr(pll.r);
|
2021-11-08 20:20:31 +01:00
|
|
|
|
});
|
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Do we need the EPOD booster to reach the target clock speed per § 10.5.4?
|
|
|
|
|
if pll1r_clk >= Hertz::mhz(55) {
|
|
|
|
|
// Enable the booster
|
|
|
|
|
PWR.vosr().modify(|w| {
|
|
|
|
|
w.set_boosten(true);
|
|
|
|
|
});
|
|
|
|
|
while !PWR.vosr().read().boostrdy() {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Enable the PLL
|
2022-01-04 23:58:13 +01:00
|
|
|
|
RCC.cr().modify(|w| w.set_pllon(0, true));
|
|
|
|
|
while !RCC.cr().read().pllrdy(0) {}
|
2021-11-08 20:20:31 +01:00
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
pll1r_clk
|
2022-01-04 23:58:13 +01:00
|
|
|
|
}
|
2023-10-09 02:48:22 +02:00
|
|
|
|
};
|
2022-01-04 23:58:13 +01:00
|
|
|
|
|
2023-11-05 23:35:01 +01:00
|
|
|
|
let _hsi48 = config.hsi48.map(super::init_hsi48);
|
2023-01-11 17:57:22 +01:00
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// The clock source is ready
|
|
|
|
|
// Calculate and set the flash wait states
|
|
|
|
|
let wait_states = match config.voltage_range {
|
2023-09-18 03:00:59 +02:00
|
|
|
|
// VOS 1 range VCORE 1.26V - 1.40V
|
|
|
|
|
VoltageScale::RANGE1 => {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
if sys_clk.0 < 32_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
0
|
2023-10-09 02:48:22 +02:00
|
|
|
|
} else if sys_clk.0 < 64_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
1
|
2023-10-09 02:48:22 +02:00
|
|
|
|
} else if sys_clk.0 < 96_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
2
|
2023-10-09 02:48:22 +02:00
|
|
|
|
} else if sys_clk.0 < 128_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
3
|
|
|
|
|
} else {
|
|
|
|
|
4
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
2022-01-04 23:58:13 +01:00
|
|
|
|
}
|
2023-09-18 03:00:59 +02:00
|
|
|
|
// VOS 2 range VCORE 1.15V - 1.26V
|
|
|
|
|
VoltageScale::RANGE2 => {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
if sys_clk.0 < 30_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
0
|
2023-10-09 02:48:22 +02:00
|
|
|
|
} else if sys_clk.0 < 60_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
1
|
2023-10-09 02:48:22 +02:00
|
|
|
|
} else if sys_clk.0 < 90_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
2
|
|
|
|
|
} else {
|
|
|
|
|
3
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
2022-01-04 23:58:13 +01:00
|
|
|
|
}
|
2023-09-18 03:00:59 +02:00
|
|
|
|
// VOS 3 range VCORE 1.05V - 1.15V
|
|
|
|
|
VoltageScale::RANGE3 => {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
if sys_clk.0 < 24_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
0
|
2023-10-09 02:48:22 +02:00
|
|
|
|
} else if sys_clk.0 < 48_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
1
|
|
|
|
|
} else {
|
|
|
|
|
2
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
2022-01-04 23:58:13 +01:00
|
|
|
|
}
|
2023-09-18 03:00:59 +02:00
|
|
|
|
// VOS 4 range VCORE 0.95V - 1.05V
|
|
|
|
|
VoltageScale::RANGE4 => {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
if sys_clk.0 < 12_000_000 {
|
2022-01-04 23:58:13 +01:00
|
|
|
|
0
|
|
|
|
|
} else {
|
|
|
|
|
1
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-04 23:58:13 +01:00
|
|
|
|
};
|
|
|
|
|
FLASH.acr().modify(|w| {
|
|
|
|
|
w.set_latency(wait_states);
|
|
|
|
|
});
|
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// Switch the system clock source
|
2022-01-04 23:58:13 +01:00
|
|
|
|
RCC.cfgr1().modify(|w| {
|
|
|
|
|
w.set_sw(config.mux.into());
|
|
|
|
|
});
|
|
|
|
|
|
stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.
On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.
STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.
This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.
STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.
The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.
STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-06 05:05:05 +02:00
|
|
|
|
// RM0456 § 11.4.9 specifies maximum bus frequencies per voltage range, but the maximum bus
|
|
|
|
|
// frequency for each voltage range exactly matches the maximum permitted PLL output frequency.
|
|
|
|
|
// Given that:
|
|
|
|
|
//
|
|
|
|
|
// 1. Any bus frequency can never exceed the system clock frequency;
|
|
|
|
|
// 2. We checked the PLL output frequency if we're using it as a system clock;
|
|
|
|
|
// 3. The maximum HSE frequencies at each voltage range are lower than the bus limits, and
|
|
|
|
|
// we checked the HSE frequency if configured as a system clock; and
|
|
|
|
|
// 4. The maximum frequencies from the other clock sources are lower than the lowest bus
|
|
|
|
|
// frequency limit
|
|
|
|
|
//
|
|
|
|
|
// ...then we do not need to perform additional bus-related frequency checks.
|
|
|
|
|
|
|
|
|
|
// Configure the bus prescalers
|
2022-01-04 23:58:13 +01:00
|
|
|
|
RCC.cfgr2().modify(|w| {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
w.set_hpre(config.ahb_pre);
|
|
|
|
|
w.set_ppre1(config.apb1_pre);
|
|
|
|
|
w.set_ppre2(config.apb2_pre);
|
2022-01-04 23:58:13 +01:00
|
|
|
|
});
|
|
|
|
|
RCC.cfgr3().modify(|w| {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
w.set_ppre3(config.apb3_pre);
|
2022-01-04 23:58:13 +01:00
|
|
|
|
});
|
|
|
|
|
|
2023-10-09 02:48:22 +02:00
|
|
|
|
let ahb_freq = sys_clk / config.ahb_pre;
|
2022-01-04 23:58:13 +01:00
|
|
|
|
|
|
|
|
|
let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
|
2023-09-17 00:41:11 +02:00
|
|
|
|
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
|
2022-01-04 23:58:13 +01:00
|
|
|
|
pre => {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
let freq = ahb_freq / pre;
|
|
|
|
|
(freq, freq * 2u32)
|
2022-01-04 23:58:13 +01:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
|
2023-09-17 00:41:11 +02:00
|
|
|
|
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
|
2022-01-04 23:58:13 +01:00
|
|
|
|
pre => {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
let freq = ahb_freq / pre;
|
|
|
|
|
(freq, freq * 2u32)
|
2022-01-04 23:58:13 +01:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let (apb3_freq, _apb3_tim_freq) = match config.apb3_pre {
|
2023-09-17 00:41:11 +02:00
|
|
|
|
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
|
2022-01-04 23:58:13 +01:00
|
|
|
|
pre => {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
let freq = ahb_freq / pre;
|
|
|
|
|
(freq, freq * 2u32)
|
2022-01-04 23:58:13 +01:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2023-10-11 03:53:27 +02:00
|
|
|
|
let rtc = config.ls.init();
|
|
|
|
|
|
2022-01-04 23:58:13 +01:00
|
|
|
|
set_freqs(Clocks {
|
2023-10-09 02:48:22 +02:00
|
|
|
|
sys: sys_clk,
|
2023-10-16 02:51:35 +02:00
|
|
|
|
hclk1: ahb_freq,
|
|
|
|
|
hclk2: ahb_freq,
|
|
|
|
|
hclk3: ahb_freq,
|
|
|
|
|
pclk1: apb1_freq,
|
|
|
|
|
pclk2: apb2_freq,
|
|
|
|
|
pclk3: apb3_freq,
|
|
|
|
|
pclk1_tim: apb1_tim_freq,
|
|
|
|
|
pclk2_tim: apb2_tim_freq,
|
2023-10-11 03:53:27 +02:00
|
|
|
|
rtc,
|
2022-01-04 23:58:13 +01:00
|
|
|
|
});
|
2021-11-08 20:20:31 +01:00
|
|
|
|
}
|
2023-10-09 02:48:22 +02:00
|
|
|
|
|
|
|
|
|
fn msirange_to_hertz(range: Msirange) -> Hertz {
|
|
|
|
|
match range {
|
|
|
|
|
Msirange::RANGE_48MHZ => Hertz(48_000_000),
|
|
|
|
|
Msirange::RANGE_24MHZ => Hertz(24_000_000),
|
|
|
|
|
Msirange::RANGE_16MHZ => Hertz(16_000_000),
|
|
|
|
|
Msirange::RANGE_12MHZ => Hertz(12_000_000),
|
|
|
|
|
Msirange::RANGE_4MHZ => Hertz(4_000_000),
|
|
|
|
|
Msirange::RANGE_2MHZ => Hertz(2_000_000),
|
|
|
|
|
Msirange::RANGE_1_33MHZ => Hertz(1_330_000),
|
|
|
|
|
Msirange::RANGE_1MHZ => Hertz(1_000_000),
|
|
|
|
|
Msirange::RANGE_3_072MHZ => Hertz(3_072_000),
|
|
|
|
|
Msirange::RANGE_1_536MHZ => Hertz(1_536_000),
|
|
|
|
|
Msirange::RANGE_1_024MHZ => Hertz(1_024_000),
|
|
|
|
|
Msirange::RANGE_768KHZ => Hertz(768_000),
|
|
|
|
|
Msirange::RANGE_400KHZ => Hertz(400_000),
|
|
|
|
|
Msirange::RANGE_200KHZ => Hertz(200_000),
|
|
|
|
|
Msirange::RANGE_133KHZ => Hertz(133_000),
|
|
|
|
|
Msirange::RANGE_100KHZ => Hertz(100_000),
|
|
|
|
|
}
|
|
|
|
|
}
|