aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerzain Mata <[email protected]>2025-07-24 16:28:59 -0700
committerGerzain Mata <[email protected]>2025-07-24 16:28:59 -0700
commita8d215ff1484cde754695b08e91663e2220c9790 (patch)
tree5dcb775578a0da34137a7e2fc821c9dd4a0d0a34
parentc5565ccc288863b7d7e5a82aa42141eb7a1cff9f (diff)
Partially working USB example
-rw-r--r--embassy-stm32/src/rcc/wba.rs14
-rw-r--r--embassy-stm32/src/usb/otg.rs26
-rw-r--r--examples/stm32wba/src/bin/usb_hs_serial.rs20
3 files changed, 37 insertions, 23 deletions
diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs
index 4ca622614..a5e6b33ff 100644
--- a/embassy-stm32/src/rcc/wba.rs
+++ b/embassy-stm32/src/rcc/wba.rs
@@ -2,7 +2,7 @@ pub use crate::pac::pwr::vals::Vos as VoltageScale;
2use crate::pac::rcc::regs::Cfgr1; 2use crate::pac::rcc::regs::Cfgr1;
3pub use crate::pac::rcc::vals::{ 3pub use crate::pac::rcc::vals::{
4 Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as Sysclk, Pllsrc as PllSource, 4 Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as Sysclk, Pllsrc as PllSource,
5 Plldiv as PllDiv, Pllm, Plln as PllMul, 5 Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul,
6}; 6};
7use crate::pac::rcc::vals::Pllrge; 7use crate::pac::rcc::vals::Pllrge;
8use crate::pac::{FLASH, RCC}; 8use crate::pac::{FLASH, RCC};
@@ -32,7 +32,7 @@ pub struct Pll {
32 /// The PLL pre-divider. 32 /// The PLL pre-divider.
33 /// 33 ///
34 /// The clock speed of the `source` divided by `m` must be between 4 and 16 MHz. 34 /// The clock speed of the `source` divided by `m` must be between 4 and 16 MHz.
35 pub pllm: Pllm, 35 pub prediv: PllPreDiv,
36 /// The PLL multiplier. 36 /// The PLL multiplier.
37 /// 37 ///
38 /// The multiplied clock – `source` divided by `m` times `n` – must be between 128 and 544 38 /// The multiplied clock – `source` divided by `m` times `n` – must be between 128 and 544
@@ -287,15 +287,18 @@ fn init_pll(config: Option<Pll>, input: &PllInput, voltage_range: VoltageScale)
287 287
288 let Some(pll) = config else { return PllOutput::default() }; 288 let Some(pll) = config else { return PllOutput::default() };
289 289
290 let src_freq = match pll.source { 290 let pre_src_freq = match pll.source {
291 PllSource::DISABLE => panic!("must not select PLL source as DISABLE"), 291 PllSource::DISABLE => panic!("must not select PLL source as DISABLE"),
292 PllSource::HSE => unwrap!(input.hse), 292 PllSource::HSE => unwrap!(input.hse),
293 PllSource::HSI => unwrap!(input.hsi), 293 PllSource::HSI => unwrap!(input.hsi),
294 PllSource::_RESERVED_1 => panic!("must not select RESERVED_1 source as DISABLE"), 294 PllSource::_RESERVED_1 => panic!("must not select RESERVED_1 source as DISABLE"),
295 }; 295 };
296 296
297 let hse_div = RCC.cr().read().hsepre();
298 let src_freq = pre_src_freq / hse_div;
299
297 // Calculate the reference clock, which is the source divided by m 300 // Calculate the reference clock, which is the source divided by m
298 let ref_freq = src_freq / pll.pllm; 301 let ref_freq = src_freq / pll.prediv;
299 // Check limits per RM0515 § 12.4.3 302 // Check limits per RM0515 § 12.4.3
300 assert!(Hertz::mhz(4) <= ref_freq && ref_freq <= Hertz::mhz(16)); 303 assert!(Hertz::mhz(4) <= ref_freq && ref_freq <= Hertz::mhz(16));
301 304
@@ -325,7 +328,6 @@ fn init_pll(config: Option<Pll>, input: &PllInput, voltage_range: VoltageScale)
325 w.set_pllp(pll.divp.unwrap_or(PllDiv::DIV1)); 328 w.set_pllp(pll.divp.unwrap_or(PllDiv::DIV1));
326 w.set_pllq(pll.divq.unwrap_or(PllDiv::DIV1)); 329 w.set_pllq(pll.divq.unwrap_or(PllDiv::DIV1));
327 w.set_pllr(pll.divr.unwrap_or(PllDiv::DIV1)); 330 w.set_pllr(pll.divr.unwrap_or(PllDiv::DIV1));
328 // w.set_pllfracn(pll.frac.unwrap_or(1));
329 }); 331 });
330 RCC.pll1fracr().write(|w| {w.set_pllfracn(pll.frac.unwrap_or(1));}); 332 RCC.pll1fracr().write(|w| {w.set_pllfracn(pll.frac.unwrap_or(1));});
331 333
@@ -340,7 +342,7 @@ fn init_pll(config: Option<Pll>, input: &PllInput, voltage_range: VoltageScale)
340 $w.set_pllqen(pll.divq.is_some()); 342 $w.set_pllqen(pll.divq.is_some());
341 $w.set_pllren(pll.divr.is_some()); 343 $w.set_pllren(pll.divr.is_some());
342 $w.set_pllfracen(pll.frac.is_some()); 344 $w.set_pllfracen(pll.frac.is_some());
343 $w.set_pllm(pll.pllm); 345 $w.set_pllm(pll.prediv);
344 $w.set_pllsrc(pll.source); 346 $w.set_pllsrc(pll.source);
345 $w.set_pllrge(input_range); 347 $w.set_pllrge(input_range);
346 }; 348 };
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs
index 02b27ed48..6b28ac980 100644
--- a/embassy-stm32/src/usb/otg.rs
+++ b/embassy-stm32/src/usb/otg.rs
@@ -315,30 +315,42 @@ impl<'d, T: Instance> Bus<'d, T> {
315 315
316 #[cfg(all(stm32u5, peri_usb_otg_hs))] 316 #[cfg(all(stm32u5, peri_usb_otg_hs))]
317 { 317 {
318 crate::pac::SYSCFG.otghsphycr().modify(|w| {
319 w.set_en(true);
320 });
321
322 critical_section::with(|_| { 318 critical_section::with(|_| {
323 crate::pac::RCC.ahb2enr1().modify(|w| { 319 crate::pac::RCC.ahb2enr1().modify(|w| {
324 w.set_usb_otg_hsen(true); 320 w.set_usb_otg_hsen(true);
325 w.set_usb_otg_hs_phyen(true); 321 w.set_usb_otg_hs_phyen(true);
326 }); 322 });
327 }); 323 });
328 }
329 324
330 #[cfg(all(stm32wba, peri_usb_otg_hs))]
331 {
332 crate::pac::SYSCFG.otghsphycr().modify(|w| { 325 crate::pac::SYSCFG.otghsphycr().modify(|w| {
333 w.set_en(true); 326 w.set_en(true);
334 }); 327 });
328 }
335 329
330 #[cfg(all(stm32wba, peri_usb_otg_hs))]
331 {
336 critical_section::with(|_| { 332 critical_section::with(|_| {
333 crate::pac::RCC.apb7enr().modify(|w| {
334 w.set_syscfgen(true);
335 });
337 crate::pac::RCC.ahb2enr().modify(|w| { 336 crate::pac::RCC.ahb2enr().modify(|w| {
338 w.set_usb_otg_hsen(true); 337 w.set_usb_otg_hsen(true);
339 w.set_usb_otg_hs_phyen(true); 338 w.set_usb_otg_hs_phyen(true);
340 }); 339 });
341 }); 340 });
341
342 // pub use crate::pac::rcc::vals::Otghssel;
343 // // select HSE
344 // crate::pac::RCC.ccipr2().modify(|w| {w.set_otghssel(Otghssel::HSE);});
345
346 crate::pac::SYSCFG.otghsphytuner2().modify(|w| {
347 w.set_compdistune(0b010);
348 w.set_sqrxtune(0b000);
349 });
350
351 crate::pac::SYSCFG.otghsphycr().modify(|w| {
352 w.set_en(true);
353 });
342 } 354 }
343 355
344 let r = T::regs(); 356 let r = T::regs();
diff --git a/examples/stm32wba/src/bin/usb_hs_serial.rs b/examples/stm32wba/src/bin/usb_hs_serial.rs
index e30f33625..bda4a5013 100644
--- a/examples/stm32wba/src/bin/usb_hs_serial.rs
+++ b/examples/stm32wba/src/bin/usb_hs_serial.rs
@@ -5,7 +5,7 @@ use defmt::{panic, *};
5use defmt_rtt as _; // global logger 5use defmt_rtt as _; // global logger
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_futures::join::join; 7use embassy_futures::join::join;
8use embassy_stm32::rcc::PllSource; 8use embassy_stm32::rcc::{PllSource, PllPreDiv, PllMul, PllDiv};
9use embassy_stm32::rcc::{mux, AHBPrescaler, APBPrescaler, Hse, HsePrescaler, Sysclk, VoltageScale}; 9use embassy_stm32::rcc::{mux, AHBPrescaler, APBPrescaler, Hse, HsePrescaler, Sysclk, VoltageScale};
10use embassy_stm32::usb::{Driver, Instance}; 10use embassy_stm32::usb::{Driver, Instance};
11use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 11use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
@@ -26,21 +26,18 @@ async fn main(_spawner: Spawner) {
26 26
27 // External HSE (32 MHz) setup 27 // External HSE (32 MHz) setup
28 config.rcc.hse = Some(Hse { 28 config.rcc.hse = Some(Hse {
29 prescaler: HsePrescaler::DIV1, 29 prescaler: HsePrescaler::DIV2,
30 }); 30 });
31 31
32 // route HSE into the USB‐OTG‐HS block
33 config.rcc.mux.otghssel = mux::Otghssel::HSE;
34 config.rcc.sys = Sysclk::HSE;
35 32
36 // Fine-tune PLL1 dividers/multipliers 33 // Fine-tune PLL1 dividers/multipliers
37 config.rcc.pll1 = Some(embassy_stm32::rcc::Pll { 34 config.rcc.pll1 = Some(embassy_stm32::rcc::Pll {
38 source: PllSource::HSE, 35 source: PllSource::HSE,
39 pllm: 2.into(), // PLLM = 2 → HSE / 2 = 16 MHz input 36 prediv: PllPreDiv::DIV2, // PLLM = 2 → HSE / 2 = 8 MHz
40 mul: 12.into(), // PLLN = 1216 MHz * 12 = 192 MHz VCO 37 mul: PllMul::MUL60, // PLLN = 608 MHz * 60 = 480 MHz VCO
41 divp: Some(2.into()), // PLLP = 2 → 96 MHz 38 divr: Some(PllDiv::DIV5), // PLLR = 5 → 96 MHz (Sysclk)
42 divq: Some(2.into()), // PLLQ = 296 MHz 39 divq: Some(PllDiv::DIV10), // PLLQ = 1048 MHz (USB)
43 divr: Some(2.into()), // PLLR = 296 MHz 40 divp: Some(PllDiv::DIV15), // PLLP = 1532 MHz (USBOTG)
44 frac: Some(4096), // Fractional part (enabled) 41 frac: Some(4096), // Fractional part (enabled)
45 }); 42 });
46 43
@@ -51,6 +48,9 @@ async fn main(_spawner: Spawner) {
51 48
52 // voltage scale for max performance 49 // voltage scale for max performance
53 config.rcc.voltage_scale = VoltageScale::RANGE1; 50 config.rcc.voltage_scale = VoltageScale::RANGE1;
51 // route PLL1_P into the USB‐OTG‐HS block
52 config.rcc.mux.otghssel = mux::Otghssel::PLL1_P;
53 config.rcc.sys = Sysclk::PLL1_R;
54 54
55 let p = embassy_stm32::init(config); 55 let p = embassy_stm32::init(config);
56 56