diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 753f94fa6..deefb13c1 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1599,7 +1599,7 @@ fn main() { for e in rcc_registers.ir.enums { fn is_rcc_name(e: &str) -> bool { match e { - "Pllp" | "Pllq" | "Pllr" | "Plldivst" | "Pllm" | "Plln" | "Prediv1" | "Prediv2" => true, + "Pllp" | "Pllq" | "Pllr" | "Plldivst" | "Pllm" | "Plln" | "Prediv1" | "Prediv2" | "Hpre5" => true, "Timpre" | "Pllrclkpre" => false, e if e.ends_with("pre") || e.ends_with("pres") || e.ends_with("div") || e.ends_with("mul") => true, _ => false, diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index 0025d2a51..56ba7b58b 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -1,43 +1,23 @@ pub use crate::pac::pwr::vals::Vos as VoltageScale; use crate::pac::rcc::regs::Cfgr1; -use core::ops::Div; -pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as Sysclk, Pllsrc as PllSource, - Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, Hpre5 as AHB5Prescaler, Hdiv5, -}; +#[cfg(all(peri_usb_otg_hs))] +pub use crate::pac::rcc::vals::Otghssel; use crate::pac::rcc::vals::Pllrge; +pub use crate::pac::rcc::vals::{ + Hdiv5, Hpre as AHBPrescaler, Hpre5 as AHB5Prescaler, Hsepre as HsePrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, + Plln as PllMul, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, +}; +#[cfg(all(peri_usb_otg_hs))] +pub use crate::pac::{syscfg::vals::Usbrefcksel, SYSCFG}; use crate::pac::{FLASH, RCC}; use crate::rcc::LSI_FREQ; use crate::time::Hertz; -#[cfg(all(peri_usb_otg_hs))] -pub use crate::pac::rcc::vals::Otghssel; - -#[cfg(all(peri_usb_otg_hs))] -pub use crate::pac::{syscfg::vals::Usbrefcksel, SYSCFG}; - /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); // HSE speed pub const HSE_FREQ: Hertz = Hertz(32_000_000); -// Allow dividing a Hertz value by an AHB5 prescaler directly -impl Div for Hertz { - type Output = Hertz; - fn div(self, rhs: AHB5Prescaler) -> Hertz { - // Map the prescaler enum to its integer divisor - let divisor = match rhs { - AHB5Prescaler::DIV1 => 1, - AHB5Prescaler::DIV2 => 2, - AHB5Prescaler::DIV3 => 3, - AHB5Prescaler::DIV4 => 4, - AHB5Prescaler::DIV6 => 6, - _ => unreachable!("Invalid AHB5 prescaler: {:?}", rhs), - }; - Hertz(self.0 / divisor) - } -} - #[derive(Clone, Copy, Eq, PartialEq)] pub struct Hse { pub prescaler: HsePrescaler, @@ -95,8 +75,7 @@ pub struct Config { pub apb7_pre: APBPrescaler, // low speed LSI/LSE/RTC - pub lsi: super::LsConfig, - // pub lsi2: super::LsConfig, + pub ls: super::LsConfig, pub voltage_scale: VoltageScale, @@ -116,7 +95,7 @@ impl Config { apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, apb7_pre: APBPrescaler::DIV1, - lsi: crate::rcc::LsConfig::new(), + ls: crate::rcc::LsConfig::new(), // lsi2: crate::rcc::LsConfig::new(), voltage_scale: VoltageScale::RANGE2, mux: super::mux::ClockMux::default(), @@ -151,7 +130,7 @@ pub(crate) unsafe fn init(config: Config) { crate::pac::PWR.vosr().write(|w| w.set_vos(config.voltage_scale)); while !crate::pac::PWR.vosr().read().vosrdy() {} - let rtc = config.lsi.init(); + let rtc = config.ls.init(); let hsi = config.hsi.then(|| { hsi_enable(); @@ -169,7 +148,7 @@ pub(crate) unsafe fn init(config: Config) { HSE_FREQ }); - let pll_input = PllInput {hse, hsi }; + let pll_input = PllInput { hse, hsi }; let pll1 = init_pll(config.pll1, &pll_input, config.voltage_scale); @@ -250,7 +229,6 @@ pub(crate) unsafe fn init(config: Config) { let hclk5 = sys_clk / config.ahb5_pre; - #[cfg(all(stm32wba, peri_usb_otg_hs))] let usb_refck = match config.mux.otghssel { Otghssel::HSE => hse, @@ -276,7 +254,7 @@ pub(crate) unsafe fn init(config: Config) { w.set_clksel(usb_refck_sel); }); - let lsi = config.lsi.lsi.then_some(LSI_FREQ); + let lsi = config.ls.lsi.then_some(LSI_FREQ); config.mux.init(); @@ -360,7 +338,7 @@ fn init_pll(config: Option, input: &PllInput, voltage_range: VoltageScale) // let vco_freq = ref_freq * pll.mul; // Calculate VCO frequency including fractional part: FVCO = Fref_ck × (N + FRAC/2^13) let numerator = (ref_freq.0 as u64) * (((pll.mul as u64) + 1 << 13) + pll.frac.unwrap_or(0) as u64); - let vco_hz = (numerator >> 13) as u32; + let vco_hz = (numerator >> 13) as u32; let vco_freq = Hertz(vco_hz); assert!(vco_freq >= vco_min && vco_freq <= vco_max); @@ -381,7 +359,9 @@ fn init_pll(config: Option, input: &PllInput, voltage_range: VoltageScale) w.set_pllq(pll.divq.unwrap_or(PllDiv::DIV1)); w.set_pllr(pll.divr.unwrap_or(PllDiv::DIV1)); }); - RCC.pll1fracr().write(|w| {w.set_pllfracn(pll.frac.unwrap_or(0));}); + RCC.pll1fracr().write(|w| { + w.set_pllfracn(pll.frac.unwrap_or(0)); + }); let input_range = match ref_freq.0 { ..=8_000_000 => Pllrge::FREQ_4TO8MHZ, @@ -400,10 +380,12 @@ fn init_pll(config: Option, input: &PllInput, voltage_range: VoltageScale) }; } - RCC.pll1cfgr().write(|w| {write_fields!(w);}); + RCC.pll1cfgr().write(|w| { + write_fields!(w); + }); // Enable PLL pll_enable(true); - PllOutput{ p, q, r } -} \ No newline at end of file + PllOutput { p, q, r } +} diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs index d987a056d..d052934f8 100644 --- a/embassy-stm32/src/usb/mod.rs +++ b/embassy-stm32/src/usb/mod.rs @@ -110,7 +110,7 @@ fn common_init() { w.set_usv(crate::pac::pwr::vals::Usv::B_0X1); }); crate::pac::PWR.vosr().modify(|w| { - w.set_vdd11usbdis(true); + w.set_vdd11usbdis(false); }); crate::pac::PWR.vosr().modify(|w| { w.set_usbpwren(true); diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 1ddae5fee..336ea1e2e 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -9,7 +9,6 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ embassy-sync = { version = "0.7.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true } embassy-usb = { version = "0.5.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } @@ -18,7 +17,7 @@ defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -embedded-hal = "1.0.0" +embedded-hal = "0.2.6" panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } static_cell = "2" diff --git a/examples/stm32wba/src/bin/usb_hs_serial.rs b/examples/stm32wba/src/bin/usb_hs_serial.rs index 41440a940..2e17e52d1 100644 --- a/examples/stm32wba/src/bin/usb_hs_serial.rs +++ b/examples/stm32wba/src/bin/usb_hs_serial.rs @@ -2,17 +2,14 @@ #![no_main] use defmt::{panic, *}; -use defmt_rtt as _; // global logger use embassy_executor::Spawner; use embassy_futures::join::join; -use embassy_stm32::rcc::{mux, AHB5Prescaler, AHBPrescaler, APBPrescaler, Hse, HsePrescaler, Sysclk, VoltageScale}; -use embassy_stm32::rcc::{PllDiv, PllMul, PllPreDiv, PllSource}; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; -use panic_probe as _; +use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { USB_OTG_HS => usb::InterruptHandler; @@ -24,37 +21,44 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); - // External HSE (32 MHz) setup - // config.rcc.hse = Some(Hse { - // prescaler: HsePrescaler::DIV2, - // }); - // Fine-tune PLL1 dividers/multipliers - config.rcc.pll1 = Some(embassy_stm32::rcc::Pll { - source: PllSource::HSI, - prediv: PllPreDiv::DIV1, // PLLM = 1 → HSI / 1 = 16 MHz - mul: PllMul::MUL30, // PLLN = 30 → 16 MHz * 30 = 480 MHz VCO - divr: Some(PllDiv::DIV5), // PLLR = 5 → 96 MHz (Sysclk) - // divq: Some(PllDiv::DIV10), // PLLQ = 10 → 48 MHz (NOT USED) - divq: None, - divp: Some(PllDiv::DIV30), // PLLP = 30 → 16 MHz (USBOTG) - frac: Some(0), // Fractional part (enabled) - }); + { + use embassy_stm32::rcc::*; + // External HSE (32 MHz) setup + // config.rcc.hse = Some(Hse { + // prescaler: HsePrescaler::DIV2, + // }); - config.rcc.ahb_pre = AHBPrescaler::DIV1; - config.rcc.apb1_pre = APBPrescaler::DIV1; - config.rcc.apb2_pre = APBPrescaler::DIV1; - config.rcc.apb7_pre = APBPrescaler::DIV1; - config.rcc.ahb5_pre = AHB5Prescaler::DIV4; + // Fine-tune PLL1 dividers/multipliers + config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, + prediv: PllPreDiv::DIV1, // PLLM = 1 → HSI / 1 = 16 MHz + mul: PllMul::MUL30, // PLLN = 30 → 16 MHz * 30 = 480 MHz VCO + divr: Some(PllDiv::DIV5), // PLLR = 5 → 96 MHz (Sysclk) + divq: Some(PllDiv::DIV10), // PLLQ = 10 → 48 MHz (NOT USED) + // divq: None, + divp: Some(PllDiv::DIV30), // PLLP = 30 → 16 MHz (USBOTG) + frac: Some(0), // Fractional part (enabled) + }); - // voltage scale for max performance - config.rcc.voltage_scale = VoltageScale::RANGE1; - // route PLL1_P into the USB‐OTG‐HS block - config.rcc.mux.otghssel = mux::Otghssel::PLL1_P; - config.rcc.sys = Sysclk::PLL1_R; + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV1; + config.rcc.apb2_pre = APBPrescaler::DIV1; + config.rcc.apb7_pre = APBPrescaler::DIV1; + config.rcc.ahb5_pre = AHB5Prescaler::DIV4; + + config.rcc.voltage_scale = VoltageScale::RANGE1; + config.rcc.mux.otghssel = mux::Otghssel::PLL1_P; + config.rcc.sys = Sysclk::PLL1_R; + } let p = embassy_stm32::init(config); + // TRDT set to 5 + // ASVLD set to 1 + // BSVLD set to 1 + + // Create the driver, from the HAL. let mut ep_out_buffer = [0u8; 256]; let mut config = embassy_stm32::usb::Config::default();