mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-21 14:22:33 +00:00
Add USBPHYC clock configuration for H7RS series
This commit is contained in:
parent
2f60d78ea3
commit
6d9af8304c
@ -72,8 +72,7 @@ rand_core = "0.6.3"
|
|||||||
sdio-host = "0.5.0"
|
sdio-host = "0.5.0"
|
||||||
critical-section = "1.1"
|
critical-section = "1.1"
|
||||||
#stm32-metapac = { version = "15" }
|
#stm32-metapac = { version = "15" }
|
||||||
# stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ad00827345b4b758b2453082809d6e3b634b5364" }
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-acaf04256034066bd5b3a8426224ccf3e4cb7d19" }
|
||||||
stm32-metapac = { path = "../../stm32-data/build/stm32-metapac" }
|
|
||||||
|
|
||||||
vcell = "0.1.3"
|
vcell = "0.1.3"
|
||||||
nb = "1.0.0"
|
nb = "1.0.0"
|
||||||
@ -100,8 +99,7 @@ proc-macro2 = "1.0.36"
|
|||||||
quote = "1.0.15"
|
quote = "1.0.15"
|
||||||
|
|
||||||
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
|
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
|
||||||
# stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ad00827345b4b758b2453082809d6e3b634b5364", default-features = false, features = ["metadata"] }
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-acaf04256034066bd5b3a8426224ccf3e4cb7d19", default-features = false, features = ["metadata"] }
|
||||||
stm32-metapac = { path = "../../stm32-data/build/stm32-metapac", default-features = false, features = ["metadata"] }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["rt"]
|
default = ["rt"]
|
||||||
|
@ -35,7 +35,10 @@ pub enum VoltageScale {
|
|||||||
Scale3,
|
Scale3,
|
||||||
}
|
}
|
||||||
#[cfg(any(stm32h7rs))]
|
#[cfg(any(stm32h7rs))]
|
||||||
pub use crate::pac::pwr::vals::Vos as VoltageScale;
|
pub use crate::pac::{
|
||||||
|
pwr::vals::Vos as VoltageScale,
|
||||||
|
rcc::vals::{Usbphycsel, Usbrefcksel},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||||
pub enum HseMode {
|
pub enum HseMode {
|
||||||
@ -557,6 +560,27 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
|
|
||||||
let rtc = config.ls.init();
|
let rtc = config.ls.init();
|
||||||
|
|
||||||
|
#[cfg(stm32h7rs)]
|
||||||
|
let usb_refck = match config.mux.usbphycsel {
|
||||||
|
Usbphycsel::HSE => hse,
|
||||||
|
Usbphycsel::HSE_DIV_2 => hse.map(|hse_val| hse_val / 2u8),
|
||||||
|
Usbphycsel::PLL3_Q => pll3.q,
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
#[cfg(stm32h7rs)]
|
||||||
|
let usb_refck_sel = match usb_refck {
|
||||||
|
Some(clk_val) => match clk_val {
|
||||||
|
Hertz(16_000_000) => Usbrefcksel::MHZ16,
|
||||||
|
Hertz(19_200_000) => Usbrefcksel::MHZ19_2,
|
||||||
|
Hertz(20_000_000) => Usbrefcksel::MHZ20,
|
||||||
|
Hertz(24_000_000) => Usbrefcksel::MHZ24,
|
||||||
|
Hertz(26_000_000) => Usbrefcksel::MHZ26,
|
||||||
|
Hertz(32_000_000) => Usbrefcksel::MHZ32,
|
||||||
|
_ => panic!("cannot select USBPHYC reference clock with source frequency of {} Hz, must be one of 16, 19.2, 20, 24, 26, 32 MHz", clk_val),
|
||||||
|
},
|
||||||
|
None => Usbrefcksel::MHZ24,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(stm32h7)]
|
#[cfg(stm32h7)]
|
||||||
{
|
{
|
||||||
RCC.d1cfgr().modify(|w| {
|
RCC.d1cfgr().modify(|w| {
|
||||||
@ -593,6 +617,10 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
w.set_ppre4(config.apb4_pre);
|
w.set_ppre4(config.apb4_pre);
|
||||||
w.set_ppre5(config.apb5_pre);
|
w.set_ppre5(config.apb5_pre);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RCC.ahbperckselr().modify(|w| {
|
||||||
|
w.set_usbrefcksel(usb_refck_sel);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#[cfg(stm32h5)]
|
#[cfg(stm32h5)]
|
||||||
{
|
{
|
||||||
@ -698,6 +726,8 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
#[cfg(stm32h7rs)]
|
#[cfg(stm32h7rs)]
|
||||||
clk48mohci: None, // TODO
|
clk48mohci: None, // TODO
|
||||||
#[cfg(stm32h7rs)]
|
#[cfg(stm32h7rs)]
|
||||||
|
hse_div_2: hse.map(|clk| clk / 2u32),
|
||||||
|
#[cfg(stm32h7rs)]
|
||||||
usb: Some(Hertz(48_000_000)),
|
usb: Some(Hertz(48_000_000)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,19 @@ fn common_init<T: Instance>() {
|
|||||||
// Check the USB clock is enabled and running at exactly 48 MHz.
|
// Check the USB clock is enabled and running at exactly 48 MHz.
|
||||||
// frequency() will panic if not enabled
|
// frequency() will panic if not enabled
|
||||||
let freq = T::frequency();
|
let freq = T::frequency();
|
||||||
|
|
||||||
|
// On the H7RS, the USBPHYC embeds a PLL accepting one of the input frequencies listed below and providing 48MHz to OTG_FS and 60MHz to OTG_HS internally
|
||||||
|
#[cfg(stm32h7rs)]
|
||||||
|
if ![16_000_000, 19_200_000, 20_000_000, 24_000_000, 26_000_000, 32_000_000].contains(&freq.0) {
|
||||||
|
panic!(
|
||||||
|
"USB clock should be one of 16, 19.2, 20, 24, 26, 32Mhz but is {} Hz. Please double-check your RCC settings.",
|
||||||
|
freq.0
|
||||||
|
)
|
||||||
|
}
|
||||||
// Check frequency is within the 0.25% tolerance allowed by the spec.
|
// Check frequency is within the 0.25% tolerance allowed by the spec.
|
||||||
// Clock might not be exact 48Mhz due to rounding errors in PLL calculation, or if the user
|
// Clock might not be exact 48Mhz due to rounding errors in PLL calculation, or if the user
|
||||||
// has tight clock restrictions due to something else (like audio).
|
// has tight clock restrictions due to something else (like audio).
|
||||||
|
#[cfg(not(stm32h7rs))]
|
||||||
if freq.0.abs_diff(48_000_000) > 120_000 {
|
if freq.0.abs_diff(48_000_000) > 120_000 {
|
||||||
panic!(
|
panic!(
|
||||||
"USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.",
|
"USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.",
|
||||||
|
@ -554,7 +554,7 @@ fn calculate_trdt<T: Instance>(speed: Dspd) -> u8 {
|
|||||||
match speed {
|
match speed {
|
||||||
Dspd::HIGH_SPEED => {
|
Dspd::HIGH_SPEED => {
|
||||||
// From RM0431 (F72xx), RM0090 (F429), RM0390 (F446)
|
// From RM0431 (F72xx), RM0090 (F429), RM0390 (F446)
|
||||||
if ahb_freq >= 30_000_000 {
|
if ahb_freq >= 30_000_000 || cfg!(stm32h7rs) {
|
||||||
0x9
|
0x9
|
||||||
} else {
|
} else {
|
||||||
panic!("AHB frequency is too low")
|
panic!("AHB frequency is too low")
|
||||||
|
@ -584,20 +584,27 @@ impl<'d, const MAX_EP_COUNT: usize> Bus<'d, MAX_EP_COUNT> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Applies configuration specific to
|
||||||
|
/// Core ID 0x0000_5000
|
||||||
pub fn config_v5(&mut self) {
|
pub fn config_v5(&mut self) {
|
||||||
let r = self.instance.regs;
|
let r = self.instance.regs;
|
||||||
|
let phy_type = self.instance.phy_type;
|
||||||
|
|
||||||
|
if phy_type == PhyType::InternalHighSpeed {
|
||||||
r.gccfg_v3().modify(|w| {
|
r.gccfg_v3().modify(|w| {
|
||||||
w.set_vbvaloven(true);
|
w.set_vbvaloven(!self.config.vbus_detection);
|
||||||
w.set_vbvaloval(true);
|
w.set_vbvaloval(!self.config.vbus_detection);
|
||||||
w.set_vbden(self.config.vbus_detection);
|
w.set_vbden(self.config.vbus_detection);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
// Force B-peripheral session
|
|
||||||
r.gotgctl().modify(|w| {
|
r.gotgctl().modify(|w| {
|
||||||
w.set_vbvaloen(!self.config.vbus_detection);
|
w.set_bvaloen(!self.config.vbus_detection);
|
||||||
w.set_bvaloval(true);
|
w.set_bvaloval(!self.config.vbus_detection);
|
||||||
});
|
});
|
||||||
|
r.gccfg_v3().modify(|w| {
|
||||||
|
w.set_vbden(self.config.vbus_detection);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&mut self) {
|
fn init(&mut self) {
|
||||||
|
@ -48,6 +48,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
config.rcc.apb4_pre = APBPrescaler::DIV2; // 150 MHz
|
config.rcc.apb4_pre = APBPrescaler::DIV2; // 150 MHz
|
||||||
config.rcc.apb5_pre = APBPrescaler::DIV2; // 150 MHz
|
config.rcc.apb5_pre = APBPrescaler::DIV2; // 150 MHz
|
||||||
config.rcc.voltage_scale = VoltageScale::HIGH;
|
config.rcc.voltage_scale = VoltageScale::HIGH;
|
||||||
|
config.rcc.mux.usbphycsel = mux::Usbphycsel::HSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
Loading…
Reference in New Issue
Block a user