mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-28 04:40:39 +00:00
Working USB_OTG_HS example
This commit is contained in:
parent
0545353ec1
commit
1d3c48cf45
@ -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,
|
||||
|
@ -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<AHB5Prescaler> 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();
|
||||
@ -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();
|
||||
|
||||
@ -381,7 +359,9 @@ fn init_pll(config: Option<Pll>, 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,7 +380,9 @@ fn init_pll(config: Option<Pll>, input: &PllInput, voltage_range: VoltageScale)
|
||||
};
|
||||
}
|
||||
|
||||
RCC.pll1cfgr().write(|w| {write_fields!(w);});
|
||||
RCC.pll1cfgr().write(|w| {
|
||||
write_fields!(w);
|
||||
});
|
||||
|
||||
// Enable PLL
|
||||
pll_enable(true);
|
||||
|
@ -110,7 +110,7 @@ fn common_init<T: Instance>() {
|
||||
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);
|
||||
|
@ -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"
|
||||
|
@ -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<peripherals::USB_OTG_HS>;
|
||||
@ -24,19 +21,22 @@ async fn main(_spawner: Spawner) {
|
||||
|
||||
let mut config = Config::default();
|
||||
|
||||
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
// 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 {
|
||||
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,
|
||||
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)
|
||||
});
|
||||
@ -47,14 +47,18 @@ async fn main(_spawner: Spawner) {
|
||||
config.rcc.apb7_pre = APBPrescaler::DIV1;
|
||||
config.rcc.ahb5_pre = AHB5Prescaler::DIV4;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user