From a402aed3d1738a2afee4b78d01344cba636f6a1d Mon Sep 17 00:00:00 2001 From: Matt Spencer Date: Tue, 19 Sep 2023 15:42:26 +0100 Subject: [PATCH 01/95] Add async interface for CDC control changes Signed-off-by: Matt Spencer --- embassy-usb/src/class/cdc_acm.rs | 70 +++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index a341e10d..0c708464 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs @@ -1,10 +1,13 @@ //! CDC-ACM class implementation, aka Serial over USB. -use core::cell::Cell; +use core::cell::{Cell, RefCell}; +use core::future::poll_fn; use core::mem::{self, MaybeUninit}; use core::sync::atomic::{AtomicBool, Ordering}; +use core::task::Poll; use embassy_sync::blocking_mutex::CriticalSectionMutex; +use embassy_sync::waitqueue::WakerRegistration; use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType}; use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; @@ -76,6 +79,9 @@ struct ControlShared { line_coding: CriticalSectionMutex>, dtr: AtomicBool, rts: AtomicBool, + + waker: RefCell, + changed: AtomicBool, } impl Default for ControlShared { @@ -89,10 +95,28 @@ impl Default for ControlShared { parity_type: ParityType::None, data_rate: 8_000, })), + waker: RefCell::new(WakerRegistration::new()), + changed: AtomicBool::new(false), } } } +impl ControlShared { + async fn changed(&self) { + poll_fn(|cx| match self.changed.load(Ordering::Relaxed) { + true => { + self.changed.store(false, Ordering::Relaxed); + Poll::Ready(()) + } + false => { + self.waker.borrow_mut().register(cx.waker()); + Poll::Pending + } + }) + .await + } +} + impl<'a> Control<'a> { fn shared(&mut self) -> &'a ControlShared { self.shared @@ -105,6 +129,9 @@ impl<'d> Handler for Control<'d> { shared.line_coding.lock(|x| x.set(LineCoding::default())); shared.dtr.store(false, Ordering::Relaxed); shared.rts.store(false, Ordering::Relaxed); + + shared.changed.store(true, Ordering::Relaxed); + shared.waker.borrow_mut().wake(); } fn control_out(&mut self, req: control::Request, data: &[u8]) -> Option { @@ -127,9 +154,13 @@ impl<'d> Handler for Control<'d> { parity_type: data[5].into(), data_bits: data[6], }; - self.shared().line_coding.lock(|x| x.set(coding)); + let shared = self.shared(); + shared.line_coding.lock(|x| x.set(coding)); debug!("Set line coding to: {:?}", coding); + shared.changed.store(true, Ordering::Relaxed); + shared.waker.borrow_mut().wake(); + Some(OutResponse::Accepted) } REQ_SET_CONTROL_LINE_STATE => { @@ -141,6 +172,9 @@ impl<'d> Handler for Control<'d> { shared.rts.store(rts, Ordering::Relaxed); debug!("Set dtr {}, rts {}", dtr, rts); + shared.changed.store(true, Ordering::Relaxed); + shared.waker.borrow_mut().wake(); + Some(OutResponse::Accepted) } _ => Some(OutResponse::Rejected), @@ -292,6 +326,38 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { }, ) } + + /// Split the class into sender, receiver and control + /// + /// Allows concurrently sending and receiving packets whilst monitoring for + /// control changes (dtr, rts) + pub fn split_with_control(self) -> (Sender<'d, D>, Receiver<'d, D>, ControlChanged<'d>) { + ( + Sender { + write_ep: self.write_ep, + control: self.control, + }, + Receiver { + read_ep: self.read_ep, + control: self.control, + }, + ControlChanged { control: self.control }, + ) + } +} + +/// CDC ACM Control status change monitor +/// +/// You can obtain a `ControlChanged` with [`CdcAcmClass::split_with_control`] +pub struct ControlChanged<'d> { + control: &'d ControlShared, +} + +impl<'d> ControlChanged<'d> { + /// Return a future for when the control settings change + pub async fn control_changed(&self) { + self.control.changed().await + } } /// CDC ACM class packet sender. From 2008030a8b50204289fa72b7951aa67ed9761a9d Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 1 Oct 2023 23:01:35 +0200 Subject: [PATCH 02/95] ci: add all stm32f4 --- ci.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ci.sh b/ci.sh index af98d6ed..7c6e4ac4 100755 --- a/ci.sh +++ b/ci.sh @@ -80,10 +80,23 @@ cargo batch \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f412zg,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f415zg,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f417zg,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f423zh,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f427zi,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f437zi,log,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f439zi,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f446ze,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f469zi,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f479zi,defmt,exti,time-driver-any,unstable-traits,embedded-sdmmc \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits \ From 2af97e7595ae5d703b5e798a0eeb625fd16036b0 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 1 Oct 2023 23:01:58 +0200 Subject: [PATCH 03/95] rcc/f4: fix build on stm32f446 fixes #1989 --- embassy-stm32/src/rcc/f4.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index ebf78d0e..edc5ff52 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -52,7 +52,7 @@ fn setup_i2s_pll(_vco_in: u32, _plli2s: Option) -> Option { None } -#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] +#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423)))] fn calculate_sai_i2s_pll_values(vco_in: u32, max_div: u32, target: Option) -> Option<(u32, u32, u32)> { let min_div = 2; let target = match target { From f98c8886b21099072b9373e7b194e6495291008e Mon Sep 17 00:00:00 2001 From: Jonathan Dickinson Date: Sun, 1 Oct 2023 21:47:50 -0400 Subject: [PATCH 04/95] feat: allow schmitt, slew, and drive strength be set from Flex, Input, Output Allows the schmitt, slew and drive strength to be set from Flex. Input and Output[OpenDrain] also expose the appropriate setters. --- embassy-rp/src/gpio.rs | 38 +++++++++++++++++++++++++ examples/rp/src/bin/usb_hid_keyboard.rs | 3 ++ 2 files changed, 41 insertions(+) diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index ad9d4262..33bc58a0 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -97,6 +97,12 @@ impl<'d, T: Pin> Input<'d, T> { Self { pin } } + /// Set the pin's Schmitt trigger. + #[inline] + pub fn set_schmitt(&mut self, enable: bool) { + self.pin.set_schmitt(enable) + } + #[inline] pub fn is_high(&self) -> bool { self.pin.is_high() @@ -326,6 +332,18 @@ impl<'d, T: Pin> Output<'d, T> { Self { pin } } + /// Set the pin's drive strength. + #[inline] + pub fn set_drive_strength(&mut self, strength: Drive) { + self.pin.set_drive_strength(strength) + } + + // Set the pin's slew rate. + #[inline] + pub fn set_slew_rate(&mut self, slew_rate: SlewRate) { + self.pin.set_slew_rate(slew_rate) + } + /// Set the output as high. #[inline] pub fn set_high(&mut self) { @@ -386,6 +404,18 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> { Self { pin } } + /// Set the pin's drive strength. + #[inline] + pub fn set_drive_strength(&mut self, strength: Drive) { + self.pin.set_drive_strength(strength) + } + + // Set the pin's slew rate. + #[inline] + pub fn set_slew_rate(&mut self, slew_rate: SlewRate) { + self.pin.set_slew_rate(slew_rate) + } + /// Set the output as high. #[inline] pub fn set_high(&mut self) { @@ -541,6 +571,14 @@ impl<'d, T: Pin> Flex<'d, T> { }); } + /// Set the pin's Schmitt trigger. + #[inline] + pub fn set_schmitt(&mut self, enable: bool) { + self.pin.pad_ctrl().modify(|w| { + w.set_schmitt(enable); + }); + } + /// Put the pin into input mode. /// /// The pull setting is left unchanged. diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs index 99af1f02..cc2090d2 100644 --- a/examples/rp/src/bin/usb_hid_keyboard.rs +++ b/examples/rp/src/bin/usb_hid_keyboard.rs @@ -78,6 +78,9 @@ async fn main(_spawner: Spawner) { // Set up the signal pin that will be used to trigger the keyboard. let mut signal_pin = Input::new(p.PIN_16, Pull::None); + // Enable the schmitt trigger to slightly debounce. + signal_pin.set_schmitt(true); + let (reader, mut writer) = hid.split(); // Do stuff with the class! From 729338875ccb1acd9f991dd2fec47ed33a66e415 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Thu, 31 Aug 2023 10:53:51 +0200 Subject: [PATCH 05/95] support QSPI BK2 --- embassy-stm32/build.rs | 16 ++++++--- embassy-stm32/src/qspi/mod.rs | 67 +++++++++++++++++++++++++++++------ 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 76db0a76..6fa10c7e 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -719,18 +719,24 @@ fn main() { (("sdmmc", "D6"), quote!(crate::sdmmc::D6Pin)), (("sdmmc", "D6"), quote!(crate::sdmmc::D7Pin)), (("sdmmc", "D8"), quote!(crate::sdmmc::D8Pin)), - (("quadspi", "BK1_IO0"), quote!(crate::qspi::D0Pin)), - (("quadspi", "BK1_IO1"), quote!(crate::qspi::D1Pin)), - (("quadspi", "BK1_IO2"), quote!(crate::qspi::D2Pin)), - (("quadspi", "BK1_IO3"), quote!(crate::qspi::D3Pin)), + (("quadspi", "BK1_IO0"), quote!(crate::qspi::BK1D0Pin)), + (("quadspi", "BK1_IO1"), quote!(crate::qspi::BK1D1Pin)), + (("quadspi", "BK1_IO2"), quote!(crate::qspi::BK1D2Pin)), + (("quadspi", "BK1_IO3"), quote!(crate::qspi::BK1D3Pin)), + (("quadspi", "BK1_NCS"), quote!(crate::qspi::BK1NSSPin)), + (("quadspi", "BK2_IO0"), quote!(crate::qspi::BK2D0Pin)), + (("quadspi", "BK2_IO1"), quote!(crate::qspi::BK2D1Pin)), + (("quadspi", "BK2_IO2"), quote!(crate::qspi::BK2D2Pin)), + (("quadspi", "BK2_IO3"), quote!(crate::qspi::BK2D3Pin)), + (("quadspi", "BK2_NCS"), quote!(crate::qspi::BK2NSSPin)), (("quadspi", "CLK"), quote!(crate::qspi::SckPin)), - (("quadspi", "BK1_NCS"), quote!(crate::qspi::NSSPin)), ].into(); for p in METADATA.peripherals { if let Some(regs) = &p.registers { for pin in p.pins { let key = (regs.kind, pin.signal); + eprintln!("key: {:#?}", &key); if let Some(tr) = signals.get(&key) { let mut peri = format_ident!("{}", p.name); diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 32382fb2..9ca40f8f 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -83,14 +83,53 @@ pub struct Qspi<'d, T: Instance, Dma> { } impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { - pub fn new( + pub fn new_bk1( peri: impl Peripheral

+ 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, + d0: impl Peripheral

> + 'd, + d1: impl Peripheral

> + 'd, + d2: impl Peripheral

> + 'd, + d3: impl Peripheral

> + 'd, sck: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + nss: impl Peripheral

> + 'd, + dma: impl Peripheral

+ 'd, + config: Config, + ) -> Self { + into_ref!(peri, d0, d1, d2, d3, sck, nss); + + sck.set_as_af(sck.af_num(), AFType::OutputPushPull); + sck.set_speed(crate::gpio::Speed::VeryHigh); + nss.set_as_af(nss.af_num(), AFType::OutputPushPull); + nss.set_speed(crate::gpio::Speed::VeryHigh); + d0.set_as_af(d0.af_num(), AFType::OutputPushPull); + d0.set_speed(crate::gpio::Speed::VeryHigh); + d1.set_as_af(d1.af_num(), AFType::OutputPushPull); + d1.set_speed(crate::gpio::Speed::VeryHigh); + d2.set_as_af(d2.af_num(), AFType::OutputPushPull); + d2.set_speed(crate::gpio::Speed::VeryHigh); + d3.set_as_af(d3.af_num(), AFType::OutputPushPull); + d3.set_speed(crate::gpio::Speed::VeryHigh); + + Self::new_inner( + peri, + Some(d0.map_into()), + Some(d1.map_into()), + Some(d2.map_into()), + Some(d3.map_into()), + Some(sck.map_into()), + Some(nss.map_into()), + dma, + config, + ) + } + + pub fn new_bk2( + peri: impl Peripheral

+ 'd, + d0: impl Peripheral

> + 'd, + d1: impl Peripheral

> + 'd, + d2: impl Peripheral

> + 'd, + d3: impl Peripheral

> + 'd, + sck: impl Peripheral

> + 'd, + nss: impl Peripheral

> + 'd, dma: impl Peripheral

+ 'd, config: Config, ) -> Self { @@ -313,11 +352,17 @@ pub(crate) mod sealed { pub trait Instance: Peripheral

+ sealed::Instance + RccPeripheral {} pin_trait!(SckPin, Instance); -pin_trait!(D0Pin, Instance); -pin_trait!(D1Pin, Instance); -pin_trait!(D2Pin, Instance); -pin_trait!(D3Pin, Instance); -pin_trait!(NSSPin, Instance); +pin_trait!(BK1D0Pin, Instance); +pin_trait!(BK1D1Pin, Instance); +pin_trait!(BK1D2Pin, Instance); +pin_trait!(BK1D3Pin, Instance); +pin_trait!(BK1NSSPin, Instance); + +pin_trait!(BK2D0Pin, Instance); +pin_trait!(BK2D1Pin, Instance); +pin_trait!(BK2D2Pin, Instance); +pin_trait!(BK2D3Pin, Instance); +pin_trait!(BK2NSSPin, Instance); dma_trait!(QuadDma, Instance); From 81da9ca6215ff156f1055762f47efce6fc03d004 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:06:50 +0200 Subject: [PATCH 06/95] Bump stm32-metapac, add flash selection --- embassy-stm32/src/qspi/enums.rs | 16 ++++++++++++ embassy-stm32/src/qspi/mod.rs | 44 ++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/embassy-stm32/src/qspi/enums.rs b/embassy-stm32/src/qspi/enums.rs index 2dbe2b06..0412d991 100644 --- a/embassy-stm32/src/qspi/enums.rs +++ b/embassy-stm32/src/qspi/enums.rs @@ -38,6 +38,22 @@ impl Into for QspiWidth { } } +#[allow(dead_code)] +#[derive(Copy, Clone)] +pub enum FlashSelection { + Flash1, + Flash2, +} + +impl Into for FlashSelection { + fn into(self) -> bool { + match self { + FlashSelection::Flash1 => false, + FlashSelection::Flash2 => true, + } + } +} + #[derive(Copy, Clone)] pub enum MemorySize { _1KiB, diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 9ca40f8f..64131506 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -4,6 +4,7 @@ pub mod enums; use embassy_hal_internal::{into_ref, PeripheralRef}; use enums::*; +use stm32_metapac::quadspi::regs::Cr; use crate::dma::Transfer; use crate::gpio::sealed::AFType; @@ -119,6 +120,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { Some(nss.map_into()), dma, config, + FlashSelection::Flash2, ) } @@ -139,13 +141,13 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { sck.set_speed(crate::gpio::Speed::VeryHigh); nss.set_as_af(nss.af_num(), AFType::OutputPushPull); nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af(d0.af_num(), AFType::OutputPushPull); + d0.set_as_af(d0.af_num(), AFType::OutputOpenDrain); d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af(d1.af_num(), AFType::OutputPushPull); + d1.set_as_af(d1.af_num(), AFType::OutputOpenDrain); d1.set_speed(crate::gpio::Speed::VeryHigh); - d2.set_as_af(d2.af_num(), AFType::OutputPushPull); + d2.set_as_af(d2.af_num(), AFType::OutputOpenDrain); d2.set_speed(crate::gpio::Speed::VeryHigh); - d3.set_as_af(d3.af_num(), AFType::OutputPushPull); + d3.set_as_af(d3.af_num(), AFType::OutputOpenDrain); d3.set_speed(crate::gpio::Speed::VeryHigh); Self::new_inner( @@ -158,6 +160,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { Some(nss.map_into()), dma, config, + FlashSelection::Flash2, ) } @@ -171,24 +174,42 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { nss: Option>, dma: impl Peripheral

+ 'd, config: Config, + fsel: FlashSelection, ) -> Self { into_ref!(peri, dma); T::enable(); - T::REGS.cr().write(|w| w.set_fthres(config.fifo_threshold.into())); + T::reset(); while T::REGS.sr().read().busy() {} - T::REGS.cr().write(|w| { - w.set_prescaler(config.prescaler); + // Apply precautionary steps according to the errata... + T::REGS.cr().write_value(Cr(0)); + while T::REGS.sr().read().busy() {} + T::REGS.cr().write_value(Cr(0xFF000001)); + T::REGS.ccr().write(|w| w.set_frcm(true)); + T::REGS.ccr().write(|w| w.set_frcm(true)); + T::REGS.cr().write_value(Cr(0)); + while T::REGS.sr().read().busy() {} + + T::REGS.cr().modify(|w| { w.set_en(true); + //w.set_tcen(false); + w.set_sshift(false); + w.set_fthres(config.fifo_threshold.into()); + w.set_prescaler(config.prescaler); + w.set_fsel(fsel.into()); }); - T::REGS.dcr().write(|w| { + T::REGS.dcr().modify(|w| { w.set_fsize(config.memory_size.into()); w.set_csht(config.cs_high_time.into()); - w.set_ckmode(false); + w.set_ckmode(true); }); + // FOR TESTING ONLY + //T::REGS.ccr().write(|w| w.set_frcm(true)); + // END FOR TESTING ONLY + Self { _peri: peri, sck, @@ -203,6 +224,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { } pub fn command(&mut self, transaction: TransferConfig) { + #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(false)); self.setup_transaction(QspiMode::IndirectWrite, &transaction); @@ -211,6 +233,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { } pub fn blocking_read(&mut self, buf: &mut [u8], transaction: TransferConfig) { + #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(false)); self.setup_transaction(QspiMode::IndirectWrite, &transaction); @@ -234,6 +257,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { } pub fn blocking_write(&mut self, buf: &[u8], transaction: TransferConfig) { + #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(false)); self.setup_transaction(QspiMode::IndirectWrite, &transaction); @@ -277,6 +301,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { ) }; + #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(true)); transfer.blocking_wait(); @@ -303,6 +328,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { ) }; + #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(true)); transfer.blocking_wait(); From 8c13126cff826a20268f695a7b4d0c2588c69252 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Thu, 7 Sep 2023 20:22:33 +0200 Subject: [PATCH 07/95] make push/pull settings for pins explicit --- embassy-stm32/src/qspi/mod.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 64131506..92219e01 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -8,7 +8,7 @@ use stm32_metapac::quadspi::regs::Cr; use crate::dma::Transfer; use crate::gpio::sealed::AFType; -use crate::gpio::AnyPin; +use crate::gpio::{AnyPin, Pull}; use crate::pac::quadspi::Quadspi as Regs; use crate::rcc::RccPeripheral; use crate::{peripherals, Peripheral}; @@ -97,17 +97,17 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { ) -> Self { into_ref!(peri, d0, d1, d2, d3, sck, nss); - sck.set_as_af(sck.af_num(), AFType::OutputPushPull); + sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af(nss.af_num(), AFType::OutputPushPull); + nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af(d0.af_num(), AFType::OutputPushPull); + d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af(d1.af_num(), AFType::OutputPushPull); + d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); d1.set_speed(crate::gpio::Speed::VeryHigh); - d2.set_as_af(d2.af_num(), AFType::OutputPushPull); + d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); d2.set_speed(crate::gpio::Speed::VeryHigh); - d3.set_as_af(d3.af_num(), AFType::OutputPushPull); + d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); d3.set_speed(crate::gpio::Speed::VeryHigh); Self::new_inner( @@ -137,17 +137,17 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { ) -> Self { into_ref!(peri, d0, d1, d2, d3, sck, nss); - sck.set_as_af(sck.af_num(), AFType::OutputPushPull); + sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, Pull::None); sck.set_speed(crate::gpio::Speed::VeryHigh); - nss.set_as_af(nss.af_num(), AFType::OutputPushPull); + nss.set_as_af_pull(nss.af_num(), AFType::OutputPushPull, Pull::Up); nss.set_speed(crate::gpio::Speed::VeryHigh); - d0.set_as_af(d0.af_num(), AFType::OutputOpenDrain); + d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::None); d0.set_speed(crate::gpio::Speed::VeryHigh); - d1.set_as_af(d1.af_num(), AFType::OutputOpenDrain); + d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::None); d1.set_speed(crate::gpio::Speed::VeryHigh); - d2.set_as_af(d2.af_num(), AFType::OutputOpenDrain); + d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::None); d2.set_speed(crate::gpio::Speed::VeryHigh); - d3.set_as_af(d3.af_num(), AFType::OutputOpenDrain); + d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::None); d3.set_speed(crate::gpio::Speed::VeryHigh); Self::new_inner( From 6ea5aa347db40a0f50b82ff9bc39f2f2c73fb04e Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Sun, 10 Sep 2023 11:05:10 +0200 Subject: [PATCH 08/95] feature-gate errata workaround for h7 --- embassy-stm32/src/qspi/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 92219e01..900dfa83 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -183,14 +183,17 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { while T::REGS.sr().read().busy() {} - // Apply precautionary steps according to the errata... - T::REGS.cr().write_value(Cr(0)); - while T::REGS.sr().read().busy() {} - T::REGS.cr().write_value(Cr(0xFF000001)); - T::REGS.ccr().write(|w| w.set_frcm(true)); - T::REGS.ccr().write(|w| w.set_frcm(true)); - T::REGS.cr().write_value(Cr(0)); - while T::REGS.sr().read().busy() {} + #[cfg(stm32h7)] + { + // Apply precautionary steps according to the errata... + T::REGS.cr().write_value(Cr(0)); + while T::REGS.sr().read().busy() {} + T::REGS.cr().write_value(Cr(0xFF000001)); + T::REGS.ccr().write(|w| w.set_frcm(true)); + T::REGS.ccr().write(|w| w.set_frcm(true)); + T::REGS.cr().write_value(Cr(0)); + while T::REGS.sr().read().busy() {} + } T::REGS.cr().modify(|w| { w.set_en(true); From f3aa0cfe5a7ff98e2fc8a004ea8a2268112d54f3 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:33:10 +0200 Subject: [PATCH 09/95] remove debug code, add some comments --- embassy-stm32/src/qspi/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 900dfa83..7d2ae579 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -209,10 +209,6 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { w.set_ckmode(true); }); - // FOR TESTING ONLY - //T::REGS.ccr().write(|w| w.set_frcm(true)); - // END FOR TESTING ONLY - Self { _peri: peri, sck, @@ -260,8 +256,10 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { } pub fn blocking_write(&mut self, buf: &[u8], transaction: TransferConfig) { + // STM32H7 does not have dmaen #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(false)); + self.setup_transaction(QspiMode::IndirectWrite, &transaction); if let Some(len) = transaction.data_len { @@ -304,6 +302,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { ) }; + // STM32H7 does not have dmaen #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(true)); @@ -331,6 +330,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { ) }; + // STM32H7 does not have dmaen #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(true)); From bd267a647963d38d9865f7876b0e7617cf2b899e Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:34:59 +0200 Subject: [PATCH 10/95] move stm32h7 specific import --- embassy-stm32/src/qspi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 7d2ae579..8fb7df64 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -4,7 +4,6 @@ pub mod enums; use embassy_hal_internal::{into_ref, PeripheralRef}; use enums::*; -use stm32_metapac::quadspi::regs::Cr; use crate::dma::Transfer; use crate::gpio::sealed::AFType; @@ -185,6 +184,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { #[cfg(stm32h7)] { + use stm32_metapac::quadspi::regs::Cr; // Apply precautionary steps according to the errata... T::REGS.cr().write_value(Cr(0)); while T::REGS.sr().read().busy() {} From 923f1851ee02f697989fd25b6e93d22f30cb6b28 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:36:11 +0200 Subject: [PATCH 11/95] remove debug logging in build.rs --- embassy-stm32/build.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 6fa10c7e..ed5fa84d 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -736,7 +736,6 @@ fn main() { if let Some(regs) = &p.registers { for pin in p.pins { let key = (regs.kind, pin.signal); - eprintln!("key: {:#?}", &key); if let Some(tr) = signals.get(&key) { let mut peri = format_ident!("{}", p.name); From 4b252586e58224a7137a6a6bfecb7c23a4036f1d Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 2 Oct 2023 13:51:13 +0200 Subject: [PATCH 12/95] Update Nightly. --- rust-toolchain.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 7b34afa2..755a9207 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,8 +1,8 @@ # Before upgrading check that everything is available on all tier1 targets here: # https://rust-lang.github.io/rustup-components-history [toolchain] -channel = "nightly-2023-08-19" -components = [ "rust-src", "rustfmt", "llvm-tools-preview" ] +channel = "nightly-2023-10-02" +components = [ "rust-src", "rustfmt", "llvm-tools" ] targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", From eb121143458cb3ecc67da2bdfc6a0aa564ae39d8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 2 Oct 2023 14:00:49 +0200 Subject: [PATCH 13/95] Remove impl_trait_projections. --- embassy-embedded-hal/src/lib.rs | 2 +- embassy-lora/src/lib.rs | 2 +- embassy-net/src/lib.rs | 2 +- embassy-nrf/src/lib.rs | 2 +- embassy-rp/src/lib.rs | 2 +- embassy-stm32/src/lib.rs | 2 +- embassy-sync/src/lib.rs | 2 +- examples/std/src/bin/net_ppp.rs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/embassy-embedded-hal/src/lib.rs b/embassy-embedded-hal/src/lib.rs index 8872b3d6..ee964e40 100644 --- a/embassy-embedded-hal/src/lib.rs +++ b/embassy-embedded-hal/src/lib.rs @@ -1,5 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections, try_blocks))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, try_blocks))] #![warn(missing_docs)] //! Utilities to use `embedded-hal` traits with Embassy. diff --git a/embassy-lora/src/lib.rs b/embassy-lora/src/lib.rs index c23d1d0d..0a9cea16 100644 --- a/embassy-lora/src/lib.rs +++ b/embassy-lora/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![feature(async_fn_in_trait, impl_trait_projections)] +#![feature(async_fn_in_trait)] //! embassy-lora holds LoRa-specific functionality. pub(crate) mod fmt; diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 0d7ac47a..c55f1b1a 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -1,5 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] #![warn(missing_docs)] #![doc = include_str!("../README.md")] diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 9c4b6569..2cc83d74 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] #![doc = include_str!("../README.md")] #![warn(missing_docs)] diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index c3561bbe..e8f818bc 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 9dd2f616..bd77fae4 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -1,5 +1,5 @@ #![cfg_attr(not(test), no_std)] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] //! ## Feature flags #![doc = document_features::document_features!(feature_label = r#"{feature}"#)] diff --git a/embassy-sync/src/lib.rs b/embassy-sync/src/lib.rs index 8a9f841e..aca6ff38 100644 --- a/embassy-sync/src/lib.rs +++ b/embassy-sync/src/lib.rs @@ -1,5 +1,5 @@ #![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] #![allow(clippy::new_without_default)] #![doc = include_str!("../README.md")] #![warn(missing_docs)] diff --git a/examples/std/src/bin/net_ppp.rs b/examples/std/src/bin/net_ppp.rs index 9cf6e19d..9ea07b29 100644 --- a/examples/std/src/bin/net_ppp.rs +++ b/examples/std/src/bin/net_ppp.rs @@ -8,7 +8,7 @@ //! nc 192.168.7.10 1234 #![feature(type_alias_impl_trait)] -#![feature(async_fn_in_trait, impl_trait_projections)] +#![feature(async_fn_in_trait)] #[path = "../serial_port.rs"] mod serial_port; From bf6e06060bd9777facea738c84ddf9d9d2f93664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Damien?= Date: Mon, 2 Oct 2023 17:20:58 +0200 Subject: [PATCH 14/95] stm32: avoid useless endian conversion in rng --- embassy-stm32/src/rng.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 0979dce8..5080cf03 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -164,7 +164,7 @@ impl<'d, T: Instance> Rng<'d, T> { return Err(Error::SeedError); } // write bytes to chunk - for (dest, src) in chunk.iter_mut().zip(random_word.to_be_bytes().iter()) { + for (dest, src) in chunk.iter_mut().zip(random_word.to_ne_bytes().iter()) { *dest = *src } } @@ -195,7 +195,7 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> { fn fill_bytes(&mut self, dest: &mut [u8]) { for chunk in dest.chunks_mut(4) { let rand = self.next_u32(); - for (slot, num) in chunk.iter_mut().zip(rand.to_be_bytes().iter()) { + for (slot, num) in chunk.iter_mut().zip(rand.to_ne_bytes().iter()) { *slot = *num } } From 3c9dfbbc9d49100de5d6f442d9f724101ca4b1ed Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 2 Oct 2023 19:05:41 +0200 Subject: [PATCH 15/95] enable wifi_esp_hosted_perf test, disable stm32f4 stop test. --- ci.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index 7c6e4ac4..7e688a51 100755 --- a/ci.sh +++ b/ci.sh @@ -196,7 +196,8 @@ cargo batch \ --- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \ $BUILD_EXTRA -rm out/tests/nrf52840-dk/wifi_esp_hosted_perf +# temporarily disabled: broken by nightly update and/or clock settings update. +rm out/tests/stm32f429zi/stop if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests From eff61648fef3c50b144bbf9611ef7ee893e2c5f7 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 28 Sep 2023 05:16:41 +0200 Subject: [PATCH 16/95] tests/stm32: add eth test. --- tests/stm32/Cargo.toml | 14 ++++- tests/stm32/src/bin/eth.rs | 113 +++++++++++++++++++++++++++++++++++++ tests/stm32/src/common.rs | 35 ++++++++++++ 3 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 tests/stm32/src/bin/eth.rs diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index bfe5bc82..2b01def5 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -7,13 +7,13 @@ autobins = false [features] stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill -stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" +stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo -stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma", "dac-adc-pin"] # Nucleo +stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo -stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo +stm32h563zi = ["embassy-stm32/stm32h563zi", "eth"] # Nucleo stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo stm32l152re = ["embassy-stm32/stm32l152re", "not-gpdma"] # Nucleo @@ -21,6 +21,7 @@ stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "not-gpdma"] # Nucleo stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "not-gpdma"] # Nucleo stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo +eth = [] sdmmc = [] stop = ["embassy-stm32/low-power"] chrono = ["embassy-stm32/chrono", "dep:chrono"] @@ -40,6 +41,8 @@ embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["de embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-any"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } +embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } +perf-client = { path = "../perf-client" } defmt = "0.3.0" defmt-rtt = "0.4" @@ -69,6 +72,11 @@ name = "dac" path = "src/bin/dac.rs" required-features = [ "dac-adc-pin",] +[[bin]] +name = "eth" +path = "src/bin/eth.rs" +required-features = [ "eth",] + [[bin]] name = "gpio" path = "src/bin/gpio.rs" diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs new file mode 100644 index 00000000..0b32b60b --- /dev/null +++ b/tests/stm32/src/bin/eth.rs @@ -0,0 +1,113 @@ +// required-features: eth +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[path = "../common.rs"] +mod common; +use common::*; +use embassy_executor::Spawner; +use embassy_net::{Stack, StackResources}; +use embassy_stm32::eth::generic_smi::GenericSMI; +use embassy_stm32::eth::{Ethernet, PacketQueue}; +use embassy_stm32::peripherals::ETH; +use embassy_stm32::rng::Rng; +use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; +use rand_core::RngCore; +use static_cell::make_static; +use {defmt_rtt as _, panic_probe as _}; + +teleprobe_meta::timeout!(120); + +#[cfg(not(feature = "stm32h563zi"))] +bind_interrupts!(struct Irqs { + ETH => eth::InterruptHandler; + HASH_RNG => rng::InterruptHandler; +}); +#[cfg(feature = "stm32h563zi")] +bind_interrupts!(struct Irqs { + ETH => eth::InterruptHandler; + RNG => rng::InterruptHandler; +}); + +type Device = Ethernet<'static, ETH, GenericSMI>; + +#[embassy_executor::task] +async fn net_task(stack: &'static Stack) -> ! { + stack.run().await +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_stm32::init(config()); + info!("Hello World!"); + + // Generate random seed. + let mut rng = Rng::new(p.RNG, Irqs); + let mut seed = [0; 8]; + rng.fill_bytes(&mut seed); + let seed = u64::from_le_bytes(seed); + + // Ensure different boards get different MAC + // so running tests concurrently doesn't break (they're all in the same LAN) + #[cfg(feature = "stm32f429zi")] + let n = 1; + #[cfg(feature = "stm32h755zi")] + let n = 2; + #[cfg(feature = "stm32h563zi")] + let n = 3; + + let mac_addr = [0x00, n, 0xDE, 0xAD, 0xBE, 0xEF]; + + let device = Ethernet::new( + make_static!(PacketQueue::<4, 4>::new()), + p.ETH, + Irqs, + p.PA1, + p.PA2, + p.PC1, + p.PA7, + p.PC4, + p.PC5, + p.PG13, + #[cfg(not(feature = "stm32h563zi"))] + p.PB13, + #[cfg(feature = "stm32h563zi")] + p.PB15, + p.PG11, + GenericSMI::new(), + mac_addr, + 0, + ); + + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { + // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), + // dns_servers: Vec::new(), + // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), + //}); + + // Init network stack + let stack = &*make_static!(Stack::new( + device, + config, + make_static!(StackResources::<2>::new()), + seed + )); + + // Launch network task + unwrap!(spawner.spawn(net_task(&stack))); + + perf_client::run( + stack, + perf_client::Expected { + down_kbps: 1000, + up_kbps: 1000, + updown_kbps: 1000, + }, + ) + .await; + + info!("Test OK"); + cortex_m::asm::bkpt(); +} diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 9c0b8c39..6bf5c36e 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -154,11 +154,46 @@ pub fn config() -> Config { #[allow(unused_mut)] let mut config = Config::default(); + #[cfg(feature = "stm32f429zi")] + { + // TODO: stm32f429zi can do up to 180mhz, but that makes tests fail. + // perhaps we have some bug w.r.t overdrive. + config.rcc.sys_ck = Some(Hertz(168_000_000)); + config.rcc.pclk1 = Some(Hertz(42_000_000)); + config.rcc.pclk2 = Some(Hertz(84_000_000)); + } + + #[cfg(feature = "stm32h563zi")] + { + use embassy_stm32::rcc::*; + config.rcc.hsi = None; + config.rcc.hsi48 = true; // needed for rng + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::BypassDigital, + }); + config.rcc.pll1 = Some(Pll { + source: PllSource::Hse, + prediv: 2, + mul: 125, + divp: Some(2), + divq: Some(2), + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV1; + config.rcc.apb2_pre = APBPrescaler::DIV1; + config.rcc.apb3_pre = APBPrescaler::DIV1; + config.rcc.sys = Sysclk::Pll1P; + config.rcc.voltage_scale = VoltageScale::Scale0; + } + #[cfg(feature = "stm32h755zi")] { use embassy_stm32::rcc::*; config.rcc.hsi = Some(Hsi::Mhz64); config.rcc.csi = true; + config.rcc.hsi48 = true; // needed for RNG config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { prediv: 4, From a931dfd9ad67ef68b47ffa334910e550e84fb35f Mon Sep 17 00:00:00 2001 From: KingCol13 <48412633+KingCol13@users.noreply.github.com> Date: Mon, 2 Oct 2023 20:10:45 +0100 Subject: [PATCH 17/95] Update firmware size in rp wifi examples --- examples/rp/src/bin/wifi_ap_tcp_server.rs | 2 +- examples/rp/src/bin/wifi_blinky.rs | 2 +- examples/rp/src/bin/wifi_scan.rs | 2 +- examples/rp/src/bin/wifi_tcp_server.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs index cd61ad78..98cae53f 100644 --- a/examples/rp/src/bin/wifi_ap_tcp_server.rs +++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs @@ -52,7 +52,7 @@ async fn main(spawner: Spawner) { // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: // probe-rs download 43439A0.bin --format bin --chip RP2040 --base-address 0x10100000 // probe-rs download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x10140000 - //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 224190) }; + //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) }; //let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; let pwr = Output::new(p.PIN_23, Level::Low); diff --git a/examples/rp/src/bin/wifi_blinky.rs b/examples/rp/src/bin/wifi_blinky.rs index 33d43788..14ace74e 100644 --- a/examples/rp/src/bin/wifi_blinky.rs +++ b/examples/rp/src/bin/wifi_blinky.rs @@ -38,7 +38,7 @@ async fn main(spawner: Spawner) { // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: // probe-rs download 43439A0.bin --format bin --chip RP2040 --base-address 0x10100000 // probe-rs download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x10140000 - //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 224190) }; + //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) }; //let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; let pwr = Output::new(p.PIN_23, Level::Low); diff --git a/examples/rp/src/bin/wifi_scan.rs b/examples/rp/src/bin/wifi_scan.rs index 743fab61..dbbbf6c8 100644 --- a/examples/rp/src/bin/wifi_scan.rs +++ b/examples/rp/src/bin/wifi_scan.rs @@ -49,7 +49,7 @@ async fn main(spawner: Spawner) { // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: // probe-rs download 43439A0.bin --format bin --chip RP2040 --base-address 0x10100000 // probe-rs download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x10140000 - //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 224190) }; + //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) }; //let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; let pwr = Output::new(p.PIN_23, Level::Low); diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 55fcb4a6..20a92b6e 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs @@ -55,7 +55,7 @@ async fn main(spawner: Spawner) { // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: // probe-rs download 43439A0.bin --format bin --chip RP2040 --base-address 0x10100000 // probe-rs download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x10140000 - //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 224190) }; + //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) }; //let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; let pwr = Output::new(p.PIN_23, Level::Low); From 90ade1b311646f0ed83f3f2264537bccca2258d5 Mon Sep 17 00:00:00 2001 From: KingCol13 <48412633+KingCol13@users.noreply.github.com> Date: Mon, 2 Oct 2023 20:10:52 +0100 Subject: [PATCH 18/95] Add wait for DHCP in rp wifi_tcp_server --- examples/rp/src/bin/wifi_tcp_server.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 20a92b6e..64cf9517 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs @@ -18,7 +18,7 @@ use embassy_rp::bind_interrupts; use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; use embassy_rp::pio::{InterruptHandler, Pio}; -use embassy_time::Duration; +use embassy_time::{Duration, Timer}; use embedded_io_async::Write; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; @@ -102,6 +102,13 @@ async fn main(spawner: Spawner) { } } + // Wait for DHCP, not necessary when using static IP + info!("waiting for DHCP..."); + while !stack.is_config_up() { + Timer::after(Duration::from_millis(100)).await; + } + info!("DHCP is now up!"); + // And now we can use it! let mut rx_buffer = [0; 4096]; From b856d760f4e47bc2b6176eb6ef3b5cb9cf7eee3d Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 2 Oct 2023 22:03:18 +0200 Subject: [PATCH 19/95] stm32/rcc: reset backup domain before enabling LSE. --- embassy-stm32/src/rcc/bd.rs | 93 +++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index de27130f..026c89d6 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -88,6 +88,12 @@ impl BackupDomain { ))] #[allow(dead_code, unused_variables)] pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option) { + match clock_source { + RtcClockSource::LSI => assert!(lsi), + RtcClockSource::LSE => assert!(&lse.is_some()), + _ => {} + }; + if lsi { #[cfg(rtc_v3u5)] let csr = crate::pac::RCC.bdcr(); @@ -111,6 +117,40 @@ impl BackupDomain { while !csr.read().lsi1rdy() {} } + // backup domain configuration (LSEON, RTCEN, RTCSEL) is kept across resets. + // once set, changing it requires a backup domain reset. + // first check if the configuration matches what we want. + + // check if it's already enabled and in the source we want. + let reg = Self::read(); + let mut ok = true; + ok &= reg.rtcsel() == clock_source; + #[cfg(not(rcc_wba))] + { + ok &= reg.rtcen() == (clock_source != RtcClockSource::NOCLOCK); + } + ok &= reg.lseon() == lse.is_some(); + #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] + if let Some(lse_drive) = lse { + ok &= reg.lsedrv() == lse_drive.into(); + } + + // if configuration is OK, we're done. + if ok { + // RTC code assumes backup domain is unlocked + Self::modify(|w| {}); + + trace!("BDCR ok: {:08x}", Self::read().0); + return; + } + + // If not OK, reset backup domain and configure it. + #[cfg(not(any(rcc_l0, rcc_l1)))] + { + Self::modify(|w| w.set_bdrst(true)); + Self::modify(|w| w.set_bdrst(false)); + } + if let Some(lse_drive) = lse { Self::modify(|w| { #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] @@ -121,56 +161,17 @@ impl BackupDomain { while !Self::read().lserdy() {} } - match clock_source { - RtcClockSource::LSI => assert!(lsi), - RtcClockSource::LSE => assert!(&lse.is_some()), - _ => {} - }; - - if clock_source == RtcClockSource::NOCLOCK { - // disable it + if clock_source != RtcClockSource::NOCLOCK { Self::modify(|w| { + #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] + assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet."); + #[cfg(not(rcc_wba))] - w.set_rtcen(false); + w.set_rtcen(true); w.set_rtcsel(clock_source); }); - } else { - // check if it's already enabled and in the source we want. - let reg = Self::read(); - let ok = reg.rtcsel() == clock_source; - #[cfg(not(rcc_wba))] - let ok = ok & reg.rtcen(); - - // if not, configure it. - if !ok { - #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] - assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); - - #[cfg(not(any(rcc_l0, rcc_l1)))] - Self::modify(|w| w.set_bdrst(true)); - - Self::modify(|w| { - // Reset - #[cfg(not(any(rcc_l0, rcc_l1)))] - w.set_bdrst(false); - - #[cfg(not(rcc_wba))] - w.set_rtcen(true); - w.set_rtcsel(clock_source); - - // Restore bcdr - #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] - w.set_lscosel(reg.lscosel()); - #[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] - w.set_lscoen(reg.lscoen()); - - w.set_lseon(reg.lseon()); - - #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] - w.set_lsedrv(reg.lsedrv()); - w.set_lsebyp(reg.lsebyp()); - }); - } } + + trace!("BDCR configured: {:08x}", Self::read().0); } } From e042b3056d64564f7ed738883253372914847fbc Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 2 Oct 2023 18:11:03 -0500 Subject: [PATCH 20/95] stm32: fix stop --- ci.sh | 2 -- embassy-stm32/src/low_power.rs | 26 +++++++++++--------------- embassy-stm32/src/rcc/mod.rs | 3 +-- embassy-stm32/src/rtc/v2.rs | 31 ++++++++++++++++--------------- embassy-stm32/src/time_driver.rs | 6 +++++- 5 files changed, 33 insertions(+), 35 deletions(-) diff --git a/ci.sh b/ci.sh index 7e688a51..de46d898 100755 --- a/ci.sh +++ b/ci.sh @@ -196,8 +196,6 @@ cargo batch \ --- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \ $BUILD_EXTRA -# temporarily disabled: broken by nightly update and/or clock settings update. -rm out/tests/stm32f429zi/stop if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index ce8afb57..bb714b8c 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -1,6 +1,7 @@ use core::arch::asm; use core::marker::PhantomData; +use atomic_polyfill::{compiler_fence, Ordering}; use cortex_m::peripheral::SCB; use embassy_executor::*; @@ -67,10 +68,8 @@ impl Executor { } unsafe fn on_wakeup_irq(&mut self) { - trace!("low power: on wakeup irq"); - self.time_driver.resume_time(); - trace!("low power: resume time"); + trace!("low power: resume"); } pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) { @@ -82,21 +81,18 @@ impl Executor { } fn configure_pwr(&mut self) { - trace!("low power: configure_pwr"); - self.scb.clear_sleepdeep(); + + compiler_fence(Ordering::SeqCst); + if !low_power_ready() { - trace!("low power: configure_pwr: low power not ready"); - return; + trace!("low power: not ready to stop"); + } else if self.time_driver.pause_time().is_err() { + trace!("low power: failed to pause time"); + } else { + trace!("low power: stop"); + self.scb.set_sleepdeep(); } - - if self.time_driver.pause_time().is_err() { - trace!("low power: configure_pwr: time driver failed to pause"); - return; - } - - trace!("low power: enter stop..."); - self.scb.set_sleepdeep(); } /// Run the executor. diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 9ccf2ac4..ac967383 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -111,8 +111,7 @@ static CLOCK_REFCOUNT: AtomicU32 = AtomicU32::new(0); #[cfg(feature = "low-power")] pub fn low_power_ready() -> bool { - trace!("clock refcount: {}", CLOCK_REFCOUNT.load(Ordering::SeqCst)); - + // trace!("clock refcount: {}", CLOCK_REFCOUNT.load(Ordering::SeqCst)); CLOCK_REFCOUNT.load(Ordering::SeqCst) == 0 } diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 4608d311..4974f6ee 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs @@ -112,25 +112,26 @@ impl super::Rtc { pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option { use crate::interrupt::typelevel::Interrupt; - trace!("rtc: stop wakeup alarm at {}", self.instant()); + if RTC::regs().cr().read().wute() { + trace!("rtc: stop wakeup alarm at {}", self.instant()); - self.write(false, |regs| { - regs.cr().modify(|w| w.set_wutie(false)); - regs.cr().modify(|w| w.set_wute(false)); - regs.isr().modify(|w| w.set_wutf(false)); + self.write(false, |regs| { + regs.cr().modify(|w| w.set_wutie(false)); + regs.cr().modify(|w| w.set_wute(false)); + regs.isr().modify(|w| w.set_wutf(false)); - crate::pac::EXTI - .pr(0) - .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); + crate::pac::EXTI + .pr(0) + .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); - ::WakeupInterrupt::unpend(); - }); - - if let Some(stop_time) = self.stop_time.borrow(cs).take() { - Some(self.instant() - stop_time) - } else { - None + ::WakeupInterrupt::unpend(); + }); } + + self.stop_time + .borrow(cs) + .take() + .map(|stop_time| self.instant() - stop_time) } #[cfg(feature = "low-power")] diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 5b01937f..91750241 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -340,7 +340,11 @@ impl RtcDriver { #[cfg(feature = "low-power")] /// Set the rtc but panic if it's already been set pub(crate) fn set_rtc(&self, rtc: &'static Rtc) { - critical_section::with(|cs| assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none())); + critical_section::with(|cs| { + rtc.stop_wakeup_alarm(cs); + + assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none()) + }); } #[cfg(feature = "low-power")] From adf9ffb1095a65a375b7426086e6b99ccda3abc1 Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 2 Oct 2023 18:51:59 -0500 Subject: [PATCH 21/95] tests/stm32: use default clock config --- tests/stm32/src/bin/stop.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 48d59b79..55c4aa90 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs @@ -14,6 +14,7 @@ use embassy_stm32::low_power::{stop_with_rtc, Executor}; use embassy_stm32::rcc::RtcClockSource; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::time::Hertz; +use embassy_stm32::Config; use embassy_time::{Duration, Timer}; use static_cell::make_static; @@ -45,7 +46,9 @@ async fn task_2() { #[embassy_executor::task] async fn async_main(spawner: Spawner) { - let mut config = config(); + let _ = config(); + + let mut config = Config::default(); config.rcc.lse = Some(Hertz(32_768)); config.rcc.rtc = Some(RtcClockSource::LSE); From 00824af82ba8bfa5cd8226ee057719595d8d10af Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 2 Oct 2023 18:55:31 -0500 Subject: [PATCH 22/95] ci: remove wpan tests --- ci.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci.sh b/ci.sh index de46d898..318c6cc0 100755 --- a/ci.sh +++ b/ci.sh @@ -197,6 +197,9 @@ cargo batch \ $BUILD_EXTRA +rm out/tests/stm32wb55rg/wpan_mac +rm out/tests/stm32wb55rg/wpan_ble + if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests exit From c0a6c78a146a6e0ec57a03e64ff83a3fa87b4bdd Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 3 Oct 2023 01:42:46 +0200 Subject: [PATCH 23/95] stm32/hil: add f2, f3, f7, l49 --- ci.sh | 4 +++ tests/perf-client/src/lib.rs | 9 ++--- tests/stm32/Cargo.toml | 4 +++ tests/stm32/src/bin/eth.rs | 16 +++++++-- tests/stm32/src/common.rs | 65 ++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 7 deletions(-) diff --git a/ci.sh b/ci.sh index 318c6cc0..f2a686c7 100755 --- a/ci.sh +++ b/ci.sh @@ -191,6 +191,10 @@ cargo batch \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4a6zg --out-dir out/tests/stm32l4a6zg \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r5zi --out-dir out/tests/stm32l4r5zi \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze --out-dir out/tests/stm32l552ze \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f767zi --out-dir out/tests/stm32f767zi \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f207zg --out-dir out/tests/stm32f207zg \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303ze --out-dir out/tests/stm32f303ze \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l496zg --out-dir out/tests/stm32l496zg \ --- build --release --manifest-path tests/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/tests/rpi-pico \ --- build --release --manifest-path tests/nrf/Cargo.toml --target thumbv7em-none-eabi --out-dir out/tests/nrf52840-dk \ --- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \ diff --git a/tests/perf-client/src/lib.rs b/tests/perf-client/src/lib.rs index a36147db..d709c7bd 100644 --- a/tests/perf-client/src/lib.rs +++ b/tests/perf-client/src/lib.rs @@ -30,6 +30,7 @@ pub async fn run(stack: &Stack, expected: Expected) { } const TEST_DURATION: usize = 10; +const IO_BUFFER_SIZE: usize = 1024; const RX_BUFFER_SIZE: usize = 4096; const TX_BUFFER_SIZE: usize = 4096; const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2); @@ -52,7 +53,7 @@ async fn test_download(stack: &Stack) -> usize { } info!("connected, testing..."); - let mut rx_buf = [0; 4096]; + let mut rx_buf = [0; IO_BUFFER_SIZE]; let mut total: usize = 0; with_timeout(Duration::from_secs(TEST_DURATION as _), async { loop { @@ -92,7 +93,7 @@ async fn test_upload(stack: &Stack) -> usize { } info!("connected, testing..."); - let buf = [0; 4096]; + let buf = [0; IO_BUFFER_SIZE]; let mut total: usize = 0; with_timeout(Duration::from_secs(TEST_DURATION as _), async { loop { @@ -134,8 +135,8 @@ async fn test_upload_download(stack: &Stack) -> usize { let (mut reader, mut writer) = socket.split(); - let tx_buf = [0; 4096]; - let mut rx_buf = [0; 4096]; + let tx_buf = [0; IO_BUFFER_SIZE]; + let mut rx_buf = [0; IO_BUFFER_SIZE]; let mut total: usize = 0; let tx_fut = async { loop { diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 2b01def5..c1addcd9 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -20,6 +20,10 @@ stm32l152re = ["embassy-stm32/stm32l152re", "not-gpdma"] # Nucleo stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "not-gpdma"] # Nucleo stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "not-gpdma"] # Nucleo stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo +stm32f767zi = ["embassy-stm32/stm32f767zi", "not-gpdma", "eth"] # Nucleo +stm32f207zg = ["embassy-stm32/stm32f207zg", "not-gpdma", "eth"] # Nucleo +stm32f303ze = ["embassy-stm32/stm32f303ze", "not-gpdma"] # Nucleo +stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma"] # Nucleo eth = [] sdmmc = [] diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index 0b32b60b..13919238 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs @@ -19,12 +19,12 @@ use {defmt_rtt as _, panic_probe as _}; teleprobe_meta::timeout!(120); -#[cfg(not(feature = "stm32h563zi"))] +#[cfg(not(any(feature = "stm32h563zi", feature = "stm32f767zi", feature = "stm32f207zg")))] bind_interrupts!(struct Irqs { ETH => eth::InterruptHandler; HASH_RNG => rng::InterruptHandler; }); -#[cfg(feature = "stm32h563zi")] +#[cfg(any(feature = "stm32h563zi", feature = "stm32f767zi", feature = "stm32f207zg"))] bind_interrupts!(struct Irqs { ETH => eth::InterruptHandler; RNG => rng::InterruptHandler; @@ -56,11 +56,21 @@ async fn main(spawner: Spawner) { let n = 2; #[cfg(feature = "stm32h563zi")] let n = 3; + #[cfg(feature = "stm32f767zi")] + let n = 4; + #[cfg(feature = "stm32f207zg")] + let n = 5; let mac_addr = [0x00, n, 0xDE, 0xAD, 0xBE, 0xEF]; + // F2 runs out of RAM + #[cfg(feature = "stm32f207zg")] + const PACKET_QUEUE_SIZE: usize = 2; + #[cfg(not(feature = "stm32f207zg"))] + const PACKET_QUEUE_SIZE: usize = 4; + let device = Ethernet::new( - make_static!(PacketQueue::<4, 4>::new()), + make_static!(PacketQueue::::new()), p.ETH, Irqs, p.PA1, diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 6bf5c36e..32ba03e4 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -34,6 +34,14 @@ teleprobe_meta::target!(b"nucleo-stm32l4a6zg"); teleprobe_meta::target!(b"nucleo-stm32l4r5zi"); #[cfg(feature = "stm32l552ze")] teleprobe_meta::target!(b"nucleo-stm32l552ze"); +#[cfg(feature = "stm32f767zi")] +teleprobe_meta::target!(b"nucleo-stm32f767zi"); +#[cfg(feature = "stm32f207zg")] +teleprobe_meta::target!(b"nucleo-stm32f207zg"); +#[cfg(feature = "stm32f303ze")] +teleprobe_meta::target!(b"nucleo-stm32f303ze"); +#[cfg(feature = "stm32l496zg")] +teleprobe_meta::target!(b"nucleo-stm32l496zg"); macro_rules! define_peris { ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { @@ -119,6 +127,12 @@ define_peris!( SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2, @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler;}, ); +#[cfg(feature = "stm32l496zg")] +define_peris!( + UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, + @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler;}, +); #[cfg(feature = "stm32l4a6zg")] define_peris!( UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, @@ -149,11 +163,57 @@ define_peris!( SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2, @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler;}, ); +#[cfg(feature = "stm32f767zi")] +define_peris!( + UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, + @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler;}, +); +#[cfg(feature = "stm32f207zg")] +define_peris!( + UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, + @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler;}, +); +#[cfg(feature = "stm32f303ze")] +define_peris!( + UART = USART1, UART_TX = PC4, UART_RX = PC5, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, + @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler;}, +); pub fn config() -> Config { #[allow(unused_mut)] let mut config = Config::default(); + #[cfg(feature = "stm32f207zg")] + { + use embassy_stm32::rcc::*; + // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) + config.rcc.hse = Some(HSEConfig { + frequency: Hertz(8_000_000), + source: HSESrc::Bypass, + }); + // PLL uses HSE as the clock source + config.rcc.pll_mux = PLLSrc::HSE; + config.rcc.pll = PLLConfig { + // 8 MHz clock source / 8 = 1 MHz PLL input + pre_div: unwrap!(PLLPreDiv::try_from(8)), + // 1 MHz PLL input * 240 = 240 MHz PLL VCO + mul: unwrap!(PLLMul::try_from(240)), + // 240 MHz PLL VCO / 2 = 120 MHz main PLL output + main_div: PLLMainDiv::Div2, + // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output + pll48_div: unwrap!(PLL48Div::try_from(5)), + }; + // System clock comes from PLL (= the 120 MHz main PLL output) + config.rcc.mux = ClockSrc::PLL; + // 120 MHz / 4 = 30 MHz APB1 frequency + config.rcc.apb1_pre = APBPrescaler::DIV4; + // 120 MHz / 2 = 60 MHz APB2 frequency + config.rcc.apb2_pre = APBPrescaler::DIV2; + } + #[cfg(feature = "stm32f429zi")] { // TODO: stm32f429zi can do up to 180mhz, but that makes tests fail. @@ -163,6 +223,11 @@ pub fn config() -> Config { config.rcc.pclk2 = Some(Hertz(84_000_000)); } + #[cfg(feature = "stm32f767zi")] + { + config.rcc.sys_ck = Some(Hertz(200_000_000)); + } + #[cfg(feature = "stm32h563zi")] { use embassy_stm32::rcc::*; From 80a740bc72430a9be6f7da9d94916984530838e0 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 3 Oct 2023 21:35:31 +0200 Subject: [PATCH 24/95] docs: minor doc improvements and cleanup --- docs/modules/ROOT/nav.adoc | 4 ++-- docs/modules/ROOT/pages/getting_started.adoc | 7 +++++-- docs/modules/ROOT/pages/hal.adoc | 4 +++- docs/modules/ROOT/pages/index.adoc | 17 +++++++++++++++-- docs/modules/ROOT/pages/layer_by_layer.adoc | 5 ++--- docs/modules/ROOT/pages/nrf.adoc | 6 +++++- docs/modules/ROOT/pages/runtime.adoc | 2 +- 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 261a3c19..ee559a82 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -1,6 +1,6 @@ * xref:getting_started.adoc[Getting started] ** xref:basic_application.adoc[Basic application] -** xref:layer_by_layer.adoc[Layer by Layer] +* xref:layer_by_layer.adoc[Bare metal to async] * xref:runtime.adoc[Executor] * xref:hal.adoc[HAL] ** xref:nrf.adoc[nRF] @@ -9,4 +9,4 @@ * xref:examples.adoc[Examples] * xref:developer.adoc[Developer] -** xref:developer_stm32.adoc[Developer: STM32] \ No newline at end of file +** xref:developer_stm32.adoc[Developer: STM32] diff --git a/docs/modules/ROOT/pages/getting_started.adoc b/docs/modules/ROOT/pages/getting_started.adoc index 881e449b..2c6f4b1e 100644 --- a/docs/modules/ROOT/pages/getting_started.adoc +++ b/docs/modules/ROOT/pages/getting_started.adoc @@ -3,7 +3,7 @@ So you want to try Embassy, great! To get started, there are a few tools you need to install: * link:https://rustup.rs/[rustup] - the Rust toolchain is needed to compile Rust code. -* link:https://crates.io/crates/probe-run[probe-run] - to flash the firmware on your device. If you already have other tools like `OpenOCD` setup, you can use that as well. +* link:https://crates.io/crates/probe-rs[probe-rs] - to flash the firmware on your device. If you already have other tools like `OpenOCD` setup, you can use that as well. If you don't have any supported board, don't worry: you can also run embassy on your PC using the `std` examples. @@ -30,6 +30,10 @@ Embassy supports many microcontroller families, but the easiest ways to get star * link:https://www.raspberrypi.com/products/raspberry-pi-pico/[Raspberry Pi Pico] +=== ESP32 + +* link:https://github.com/esp-rs/esp-rust-board[ESP32C3] + == Running an example First you need to clone the [github repository]; @@ -38,7 +42,6 @@ First you need to clone the [github repository]; ---- git clone https://github.com/embassy-rs/embassy.git cd embassy -git submodule update --init ---- You can run an example by opening a terminal and entering the following commands: diff --git a/docs/modules/ROOT/pages/hal.adoc b/docs/modules/ROOT/pages/hal.adoc index de4ab33b..b1382e8e 100644 --- a/docs/modules/ROOT/pages/hal.adoc +++ b/docs/modules/ROOT/pages/hal.adoc @@ -7,4 +7,6 @@ Embassy provides HALs for several microcontroller families: * `embassy-rp` for the Raspberry Pi RP2040 microcontrollers These HALs implement async/await functionality for most peripherals while also implementing the -async traits in `embedded-hal-async`. You can also use these HALs with another executor. +async traits in `embedded-hal` and `embedded-hal-async`. You can also use these HALs with another executor. + +For the ESP32 series, there is an link:https://github.com/esp-rs/esp-hal[esp-hal] which you can use. diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index 805a1e70..c6dead46 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -17,13 +17,26 @@ The Embassy project consists of several crates that you can use together or inde * **Hardware Abstraction Layers** - HALs implement safe, idiomatic Rust APIs to use the hardware capabilities, so raw register manipulation is not needed. The Embassy project maintains HALs for select hardware, but you can still use HALs from other projects with Embassy. ** link:https://docs.embassy.dev/embassy-stm32/[embassy-stm32], for all STM32 microcontroller families. ** link:https://docs.embassy.dev/embassy-nrf/[embassy-nrf], for the Nordic Semiconductor nRF52, nRF53, nRF91 series. +** link:https://docs.embassy.dev/embassy-rp/[embassy-rp], for the Raspberry Pi RP2040 microcontroller. +** link:https://github.com/esp-rs[esp-rs], for the Espressif Systems ESP32 series of chips. ++ +NOTE: A common question is if one can use the Embassy HALs standalone. Yes, it is possible! There are no dependency on the executor within the HALs. You can even use them without async, +as they implement both the link:https://github.com/rust-embedded/embedded-hal[Embedded HAL] blocking and async traits. -* **Networking** - The link:https://docs.embassy.dev/embassy-net/[embassy-net] network stack implements extensive networking functionality, including Ethernet, IP, TCP, UDP, ICMP and DHCP. Async drastically simplifies managing timeouts and serving multiple connections concurrently. +* **Networking** - The link:https://docs.embassy.dev/embassy-net/[embassy-net] network stack implements extensive networking functionality, including Ethernet, IP, TCP, UDP, ICMP and DHCP. Async drastically simplifies managing timeouts and serving multiple connections concurrently. Several drivers for WiFi and Ethernet chips can be found. * **Bluetooth** - The link:https://github.com/embassy-rs/nrf-softdevice[nrf-softdevice] crate provides Bluetooth Low Energy 4.x and 5.x support for nRF52 microcontrollers. -* **LoRa** - link:https://docs.embassy.dev/embassy-lora/[embassy-lora] supports LoRa networking on STM32WL wireless microcontrollers and Semtech SX127x transceivers. +* **LoRa** - link:https://github.com/embassy-rs/lora-phy[lora-phy] and link:https://docs.embassy.dev/embassy-lora/[embassy-lora] supports LoRa networking on a wide range of LoRa radios, fully integrated with a Rust link:https://github.com/ivajloip/rust-lorawan[LoRaWAN] implementation. * **USB** - link:https://docs.embassy.dev/embassy-usb/[embassy-usb] implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own. * **Bootloader and DFU** - link:https://github.com/embassy-rs/embassy/tree/master/embassy-boot[embassy-boot] is a lightweight bootloader supporting firmware application upgrades in a power-fail-safe way, with trial boots and rollbacks. + +== Resources + +For more reading material on async Rust and Embassy: + +* link:https://tweedegolf.nl/en/blog/65/async-rust-vs-rtos-showdown[Comparsion of FreeRTOS and Embassy] +* link:https://dev.to/apollolabsbin/series/20707[Tutorials] +* link:https://blog.drogue.io/firmware-updates-part-1/[Firmware Updates with Embassy] diff --git a/docs/modules/ROOT/pages/layer_by_layer.adoc b/docs/modules/ROOT/pages/layer_by_layer.adoc index a78a64a9..1d7bdc89 100644 --- a/docs/modules/ROOT/pages/layer_by_layer.adoc +++ b/docs/modules/ROOT/pages/layer_by_layer.adoc @@ -1,4 +1,4 @@ -= Embassy layer by layer += From bare metal to async Rust If you're new to Embassy, it can be overwhelming to grasp all the terminology and concepts. This guide aims to clarify the different layers in Embassy, which problem each layer solves for the application writer. @@ -8,8 +8,7 @@ The application we'll write is a simple 'push button, blink led' application, wh == PAC version -The PAC is the lowest API for accessing peripherals and registers, if you don't count reading/writing directly to memory addresses. It provides distinct types -to make accessing peripheral registers easier, but it does not prevent you from writing unsafe code. +The PAC is the lowest API for accessing peripherals and registers, if you don't count reading/writing directly to memory addresses. It provides distinct types to make accessing peripheral registers easier, but it does not prevent you from writing unsafe code. Writing an application using the PAC directly is therefore not recommended, but if the functionality you want to use is not exposed in the upper layers, that's what you need to use. diff --git a/docs/modules/ROOT/pages/nrf.adoc b/docs/modules/ROOT/pages/nrf.adoc index 10fe54b4..1706087a 100644 --- a/docs/modules/ROOT/pages/nrf.adoc +++ b/docs/modules/ROOT/pages/nrf.adoc @@ -8,7 +8,7 @@ The nRF timer driver operates at 32768 Hz by default. == Peripherals -The following peripherals have a HAL implementation at present: +The following peripherals have a HAL implementation at present * PWM * SPIM @@ -23,3 +23,7 @@ The following peripherals have a HAL implementation at present: * UARTE * TWIM * SAADC + +== Bluetooth + +For bluetooth, you can use the link:https://github.com/embassy-rs/nrf-softdevice[nrf-softdevice] crate. diff --git a/docs/modules/ROOT/pages/runtime.adoc b/docs/modules/ROOT/pages/runtime.adoc index 5096f5a4..cb8afef2 100644 --- a/docs/modules/ROOT/pages/runtime.adoc +++ b/docs/modules/ROOT/pages/runtime.adoc @@ -10,7 +10,7 @@ The Embassy executor is an async/await executor designed for embedded usage alon * No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`. * Efficient polling: a wake will only poll the woken task, not all of them. * Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time. -* Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks. +* Creating multiple executor instances is supported, to run tasks at different priority levels. This allows higher-priority tasks to preempt lower-priority tasks. == Executor From 40f30fa4cd1d1273c1fe6c6520042d21e73a348e Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 3 Oct 2023 22:22:16 +0200 Subject: [PATCH 25/95] Remove a few ultra-verbose logs. They're heavily spamming logs for HIL tests, and I don't believe they're valuable now that the thing they helped debug in their young age is now solid and mature. --- embassy-rp/src/gpio.rs | 10 +--------- embassy-rp/src/uart/buffered.rs | 2 -- tests/stm32/src/bin/dac.rs | 2 +- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index 33bc58a0..ee7e03e9 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -222,7 +222,6 @@ fn IO_IRQ_QSPI() { #[must_use = "futures do nothing unless you `.await` or poll them"] struct InputFuture<'a, T: Pin> { pin: PeripheralRef<'a, T>, - level: InterruptTrigger, } impl<'d, T: Pin> InputFuture<'d, T> { @@ -249,7 +248,6 @@ impl<'d, T: Pin> InputFuture<'d, T> { .inte((pin.pin() / 8) as usize) .write_set(|w| match level { InterruptTrigger::LevelHigh => { - trace!("InputFuture::new enable LevelHigh for pin {}", pin.pin()); w.set_level_high(pin_group, true); } InterruptTrigger::LevelLow => { @@ -267,7 +265,7 @@ impl<'d, T: Pin> InputFuture<'d, T> { } }); - Self { pin, level } + Self { pin } } } @@ -303,14 +301,8 @@ impl<'d, T: Pin> Future for InputFuture<'d, T> { && !inte.level_high(pin_group) && !inte.level_low(pin_group) { - trace!( - "{:?} for pin {} was cleared, return Poll::Ready", - self.level, - self.pin.pin() - ); return Poll::Ready(()); } - trace!("InputFuture::poll return Poll::Pending"); Poll::Pending } } diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index e57b7259..645d703d 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs @@ -490,8 +490,6 @@ impl interrupt::typelevel::Handler for BufferedInterr w.set_oeic(ris.oeris()); }); - trace!("on_interrupt ris={:#X}", ris.0); - // Errors if ris.feris() { warn!("Framing error"); diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs index 67a7d5b5..fb7a84b1 100644 --- a/tests/stm32/src/bin/dac.rs +++ b/tests/stm32/src/bin/dac.rs @@ -54,7 +54,7 @@ async fn main(_spawner: Spawner) { // Calibrate and normalize the measurement to get close to the dac_output_val let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16; - info!("value / measured: {} / {}", dac_output_val, measured_normalized); + //info!("value / measured: {} / {}", dac_output_val, measured_normalized); // The deviations are quite enormous but that does not matter since this is only a quick test assert!((dac_output_val as i16 - measured_normalized).abs() < 15); From bb8a1b7f1f8728e09435a8ee89b393533f813e85 Mon Sep 17 00:00:00 2001 From: xoviat Date: Tue, 3 Oct 2023 15:53:22 -0500 Subject: [PATCH 26/95] wpan: re-enable HIL tests --- ci.sh | 2 -- embassy-stm32/src/rcc/bd.rs | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ci.sh b/ci.sh index f2a686c7..714056f1 100755 --- a/ci.sh +++ b/ci.sh @@ -201,8 +201,6 @@ cargo batch \ $BUILD_EXTRA -rm out/tests/stm32wb55rg/wpan_mac -rm out/tests/stm32wb55rg/wpan_ble if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index 026c89d6..cec2ea01 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -88,6 +88,8 @@ impl BackupDomain { ))] #[allow(dead_code, unused_variables)] pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option) { + use atomic_polyfill::{compiler_fence, Ordering}; + match clock_source { RtcClockSource::LSI => assert!(lsi), RtcClockSource::LSE => assert!(&lse.is_some()), @@ -173,5 +175,7 @@ impl BackupDomain { } trace!("BDCR configured: {:08x}", Self::read().0); + + compiler_fence(Ordering::SeqCst); } } From e561e673c2ad6ef403f808ffa8ad33a6c74a86b7 Mon Sep 17 00:00:00 2001 From: xoviat Date: Tue, 3 Oct 2023 16:34:13 -0500 Subject: [PATCH 27/95] stm32: add opamp mod and update pac --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/build.rs | 14 +++ embassy-stm32/src/lib.rs | 2 + embassy-stm32/src/opamp.rs | 133 ++++++++++++++++++++++++++++ examples/stm32f334/src/bin/opamp.rs | 59 ++++++++++++ 5 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 embassy-stm32/src/opamp.rs create mode 100644 examples/stm32f334/src/bin/opamp.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 87f9083b..ab1cae89 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8ee2862086886cd8ebaf5fd5e3bd6cfbe5baa840" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-06d13dfd245cc9bf86fd88c35b401bdb84c079c4" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8ee2862086886cd8ebaf5fd5e3bd6cfbe5baa840", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-06d13dfd245cc9bf86fd88c35b401bdb84c079c4", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index ed5fa84d..f825dbee 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -810,6 +810,20 @@ fn main() { } } + if regs.kind == "opamp" { + if !pin.signal.starts_with("VP") { + continue; + } + + let peri = format_ident!("{}", p.name); + let pin_name = format_ident!("{}", pin.pin); + let ch: u8 = pin.signal.strip_prefix("VP").unwrap().parse().unwrap(); + + g.extend(quote! { + impl_opamp_pin!( #peri, #pin_name, #ch); + }) + } + // DAC is special if regs.kind == "dac" { let peri = format_ident!("{}", p.name); diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index bd77fae4..e883678b 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -49,6 +49,8 @@ pub mod i2s; pub mod ipcc; #[cfg(feature = "low-power")] pub mod low_power; +#[cfg(opamp)] +pub mod opamp; #[cfg(quadspi)] pub mod qspi; #[cfg(rng)] diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs new file mode 100644 index 00000000..7b388aef --- /dev/null +++ b/embassy-stm32/src/opamp.rs @@ -0,0 +1,133 @@ +#![macro_use] + +use embassy_hal_internal::{into_ref, PeripheralRef}; + +use crate::Peripheral; + +#[cfg(opamp_f3)] +pub struct OpAmpOutput<'d, 'p, T: Instance, P: NonInvertingPin> { + _inner: &'d OpAmp<'d, T>, + _input: &'p mut P, +} + +pub struct OpAmp<'d, T: Instance> { + _inner: PeripheralRef<'d, T>, +} + +impl<'d, T: Instance> OpAmp<'d, T> { + pub fn new(opamp: impl Peripheral

+ 'd) -> Self { + Self::new_inner(opamp) + } + + fn new_inner(opamp: impl Peripheral

+ 'd) -> Self { + into_ref!(opamp); + + #[cfg(opamp_f3)] + T::regs().opampcsr().modify(|w| { + w.set_opampen(true); + }); + + #[cfg(opamp_g4)] + T::regs().opamp_csr().modify(|w| { + w.set_opaen(true); + }); + + Self { _inner: opamp } + } + + #[cfg(opamp_f3)] + pub fn buffer_for<'a, 'b, P>(&'a mut self, pin: &'b mut P) -> OpAmpOutput<'a, 'b, T, P> + where + P: NonInvertingPin, + { + #[cfg(opamp_f3)] + T::regs().opampcsr().modify(|w| { + w.set_vp_sel(pin.channel()); + }); + + OpAmpOutput { + _inner: self, + _input: pin, + } + } +} + +pub trait Instance: sealed::Instance + 'static {} + +pub(crate) mod sealed { + pub trait Instance { + fn regs() -> crate::pac::opamp::Opamp; + } + + pub trait NonInvertingPin { + fn channel(&self) -> u8; + } + + pub trait InvertingPin { + fn channel(&self) -> u8; + } +} + +pub trait NonInvertingPin: sealed::NonInvertingPin {} + +pub trait InvertingPin: sealed::InvertingPin {} + +#[cfg(opamp_f3)] +macro_rules! impl_opamp_output { + ($inst:ident, $adc:ident, $ch:expr) => { + impl<'d, 'p, P: NonInvertingPin> crate::adc::sealed::AdcPin + for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> + { + fn channel(&self) -> u8 { + $ch + } + } + + impl<'d, 'p, P: NonInvertingPin> crate::adc::AdcPin + for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> + { + } + }; +} + +#[cfg(opamp_f3)] +foreach_peripheral!( + (opamp, OPAMP1) => { + impl_opamp_output!(OPAMP1, ADC1, 3); + }; + (opamp, OPAMP2) => { + impl_opamp_output!(OPAMP2, ADC2, 3); + }; + (opamp, OPAMP3) => { + impl_opamp_output!(OPAMP3, ADC3, 1); + }; + (opamp, OPAMP4) => { + impl_opamp_output!(OPAMP4, ADC4, 3); + }; +); + +foreach_peripheral! { + (opamp, $inst:ident) => { + impl sealed::Instance for crate::peripherals::$inst { + fn regs() -> crate::pac::opamp::Opamp { + crate::pac::$inst + } + } + + impl Instance for crate::peripherals::$inst { + + } + }; +} + +#[allow(unused_macros)] +macro_rules! impl_opamp_pin { + ($inst:ident, $pin:ident, $ch:expr) => { + impl crate::opamp::NonInvertingPin for crate::peripherals::$pin {} + impl crate::opamp::sealed::NonInvertingPin for crate::peripherals::$pin { + fn channel(&self) -> u8 { + $ch + } + } + }; +} diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs new file mode 100644 index 00000000..72263bab --- /dev/null +++ b/examples/stm32f334/src/bin/opamp.rs @@ -0,0 +1,59 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_stm32::adc::{Adc, SampleTime}; +use embassy_stm32::opamp::OpAmp; +use embassy_stm32::peripherals::ADC2; +use embassy_stm32::rcc::AdcClockSource; +use embassy_stm32::time::mhz; +use embassy_stm32::{adc, bind_interrupts, Config}; +use embassy_time::{Delay, Duration, Timer}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + ADC1_2 => adc::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + let mut config = Config::default(); + config.rcc.sysclk = Some(mhz(64)); + config.rcc.hclk = Some(mhz(64)); + config.rcc.pclk1 = Some(mhz(32)); + config.rcc.pclk2 = Some(mhz(64)); + config.rcc.adc = Some(AdcClockSource::PllDiv1); + + let mut p = embassy_stm32::init(config); + + info!("create adc..."); + + let mut adc = Adc::new(p.ADC2, Irqs, &mut Delay); + let mut opamp = OpAmp::new(p.OPAMP2); + + adc.set_sample_time(SampleTime::Cycles601_5); + + info!("enable vrefint..."); + + let mut vrefint = adc.enable_vref(&mut Delay); + let mut temperature = adc.enable_temperature(); + let mut buffer = opamp.buffer_for(&mut p.PA7); + + loop { + let vref = adc.read(&mut vrefint).await; + info!("read vref: {} (should be {})", vref, vrefint.value()); + + let temp = adc.read(&mut temperature).await; + info!("read temperature: {}", temp); + + let buffer = adc.read(&mut buffer).await; + info!("read buffer: {}", buffer); + + let pin_mv = (buffer as u32 * vrefint.value() as u32 / vref as u32) * 3300 / 4095; + info!("computed pin mv: {}", pin_mv); + + Timer::after(Duration::from_millis(500)).await; + } +} From e7ab044935246d0d98926f84ab1e5abd42d0be9b Mon Sep 17 00:00:00 2001 From: xoviat Date: Tue, 3 Oct 2023 16:59:18 -0500 Subject: [PATCH 28/95] ci: remove wpan tests again --- ci.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci.sh b/ci.sh index 714056f1..d8bbb785 100755 --- a/ci.sh +++ b/ci.sh @@ -201,6 +201,9 @@ cargo batch \ $BUILD_EXTRA +rm out/tests/stm32wb55rg/wpan_mac +rm out/tests/stm32wb55rg/wpan_ble + if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests From 0324cee0ca9caf40a43583367fe7ff0448d0f35f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 3 Oct 2023 22:15:02 +0200 Subject: [PATCH 29/95] update embedded-io, embedded-nal-async. --- embassy-net-ppp/Cargo.toml | 2 +- embassy-net-ppp/src/lib.rs | 17 +++-------------- embassy-net/Cargo.toml | 4 ++-- embassy-nrf/Cargo.toml | 4 ++-- embassy-rp/Cargo.toml | 4 ++-- embassy-stm32/Cargo.toml | 4 ++-- embassy-sync/Cargo.toml | 2 +- examples/nrf52840/Cargo.toml | 4 ++-- examples/nrf5340/Cargo.toml | 2 +- examples/rp/Cargo.toml | 2 +- examples/std/Cargo.toml | 4 ++-- examples/stm32f4/Cargo.toml | 4 ++-- examples/stm32f7/Cargo.toml | 2 +- examples/stm32h5/Cargo.toml | 4 ++-- examples/stm32h7/Cargo.toml | 4 ++-- examples/stm32l0/Cargo.toml | 4 ++-- examples/stm32l4/Cargo.toml | 4 ++-- examples/stm32l5/Cargo.toml | 2 +- tests/nrf/Cargo.toml | 2 +- tests/rp/Cargo.toml | 2 +- 20 files changed, 33 insertions(+), 44 deletions(-) diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml index da09f780..453da436 100644 --- a/embassy-net-ppp/Cargo.toml +++ b/embassy-net-ppp/Cargo.toml @@ -15,7 +15,7 @@ log = ["dep:log", "ppproto/log"] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -embedded-io-async = { version = "0.5.0" } +embedded-io-async = { version = "0.6.0" } embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } ppproto = { version = "0.1.2"} diff --git a/embassy-net-ppp/src/lib.rs b/embassy-net-ppp/src/lib.rs index 66496ee0..54a98c95 100644 --- a/embassy-net-ppp/src/lib.rs +++ b/embassy-net-ppp/src/lib.rs @@ -11,7 +11,7 @@ use core::mem::MaybeUninit; use embassy_futures::select::{select, Either}; use embassy_net_driver_channel as ch; use embassy_net_driver_channel::driver::LinkState; -use embedded_io_async::{BufRead, Write, WriteAllError}; +use embedded_io_async::{BufRead, Write}; use ppproto::pppos::{BufferFullError, PPPoS, PPPoSAction}; pub use ppproto::{Config, Ipv4Status}; @@ -49,23 +49,12 @@ pub enum RunError { Read(E), /// Writing to the serial port failed. Write(E), - /// Writing to the serial port wrote zero bytes, indicating it can't accept more data. - WriteZero, /// Writing to the serial got EOF. Eof, /// PPP protocol was terminated by the peer Terminated, } -impl From> for RunError { - fn from(value: WriteAllError) -> Self { - match value { - WriteAllError::Other(e) => Self::Write(e), - WriteAllError::WriteZero => Self::WriteZero, - } - } -} - impl<'d> Runner<'d> { /// You must call this in a background task for the driver to operate. /// @@ -125,7 +114,7 @@ impl<'d> Runner<'d> { buf[..pkt.len()].copy_from_slice(pkt); rx_chan.rx_done(pkt.len()); } - PPPoSAction::Transmit(n) => rw.write_all(&tx_buf[..n]).await?, + PPPoSAction::Transmit(n) => rw.write_all(&tx_buf[..n]).await.map_err(RunError::Write)?, } let status = ppp.status(); @@ -148,7 +137,7 @@ impl<'d> Runner<'d> { } Either::Second(pkt) => { match ppp.send(pkt, &mut tx_buf) { - Ok(n) => rw.write_all(&tx_buf[..n]).await?, + Ok(n) => rw.write_all(&tx_buf[..n]).await.map_err(RunError::Write)?, Err(BufferFullError) => unreachable!(), } tx_chan.tx_done(); diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 8aca92a6..89582dee 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -53,7 +53,7 @@ smoltcp = { version = "0.10.0", default-features = false, features = [ embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } embassy-time = { version = "0.1.3", path = "../embassy-time" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embedded-io-async = { version = "0.5.0", optional = true } +embedded-io-async = { version = "0.6.0", optional = true } managed = { version = "0.8.0", default-features = false, features = [ "map" ] } heapless = { version = "0.7.5", default-features = false } @@ -62,5 +62,5 @@ generic-array = { version = "0.14.4", default-features = false } stable_deref_trait = { version = "1.2.0", default-features = false } futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } atomic-pool = "1.0" -embedded-nal-async = { version = "0.5.0", optional = true } +embedded-nal-async = { version = "0.6.0", optional = true } atomic-polyfill = { version = "1.0" } diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 3c706b47..7ef18306 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -103,8 +103,8 @@ embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optiona embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = true} embedded-hal-async = { version = "=1.0.0-rc.1", optional = true} -embedded-io = { version = "0.5.0" } -embedded-io-async = { version = "0.5.0", optional = true } +embedded-io = { version = "0.6.0" } +embedded-io-async = { version = "0.6.0", optional = true } defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 1147286f..26ff0ce8 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -75,8 +75,8 @@ cortex-m = "0.7.6" critical-section = "1.1" futures = { version = "0.3.17", default-features = false, features = ["async-await"] } chrono = { version = "0.4", default-features = false, optional = true } -embedded-io = { version = "0.5.0" } -embedded-io-async = { version = "0.5.0", optional = true } +embedded-io = { version = "0.6.0" } +embedded-io-async = { version = "0.6.0", optional = true } embedded-storage = { version = "0.3" } embedded-storage-async = { version = "0.4.0", optional = true } rand_core = "0.6.4" diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index ab1cae89..d43252ad 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -66,8 +66,8 @@ nb = "1.0.0" stm32-fmc = "0.3.0" seq-macro = "0.3.0" cfg-if = "1.0.0" -embedded-io = { version = "0.5.0" } -embedded-io-async = { version = "0.5.0", optional = true } +embedded-io = { version = "0.6.0" } +embedded-io-async = { version = "0.6.0", optional = true } chrono = { version = "^0.4", default-features = false, optional = true} bit_field = "0.10.2" document-features = "0.2.7" diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index f7739f30..7d3d2c58 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml @@ -35,7 +35,7 @@ futures-util = { version = "0.3.17", default-features = false } critical-section = "1.1" heapless = "0.7.5" cfg-if = "1.0.0" -embedded-io-async = { version = "0.5.0", optional = true } +embedded-io-async = { version = "0.6.0", optional = true } [dev-dependencies] futures-executor = { version = "0.3.17", features = [ "thread-pool" ] } diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index d45e006c..ce68935f 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -35,8 +35,8 @@ embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["de embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "msos-descriptor",], optional = true } -embedded-io = { version = "0.5.0", features = ["defmt-03"] } -embedded-io-async = { version = "0.5.0", optional = true, features = ["defmt-03"] } +embedded-io = { version = "0.6.0", features = ["defmt-03"] } +embedded-io-async = { version = "0.6.0", optional = true, features = ["defmt-03"] } embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["time", "defmt"], optional = true } lora-phy = { version = "2", optional = true } lorawan-device = { version = "0.11.0", default-features = false, features = ["async", "external-lora-phy"], optional = true } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 86d969ed..9d9400c2 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -37,7 +37,7 @@ embassy-net = { version = "0.1.0", path = "../../embassy-net", features = [ embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = [ "defmt", ] } -embedded-io-async = { version = "0.5.0" } +embedded-io-async = { version = "0.6.0" } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 2677e040..c998a3dc 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -45,7 +45,7 @@ usbd-hid = "0.6.1" embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } embedded-hal-async = "1.0.0-rc.1" embedded-hal-bus = { version = "0.1.0-rc.1", features = ["async"] } -embedded-io-async = { version = "0.5.0", features = ["defmt-03"] } +embedded-io-async = { version = "0.6.0", features = ["defmt-03"] } embedded-storage = { version = "0.3" } static_cell = { version = "1.1", features = ["nightly"]} log = "0.4" diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index e54f3698..52e68381 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -11,8 +11,8 @@ embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["lo embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" } embassy-net-ppp = { version = "0.1.0", path = "../../embassy-net-ppp", features = ["log"]} -embedded-io-async = { version = "0.5.0" } -embedded-io-adapters = { version = "0.5.0", features = ["futures-03"] } +embedded-io-async = { version = "0.6.0" } +embedded-io-adapters = { version = "0.6.0", features = ["futures-03"] } critical-section = { version = "1.1", features = ["std"] } smoltcp = { version = "0.10.0", features = ["dns-max-server-count-4"] } diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 4b4fb479..6ffa223b 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -19,8 +19,8 @@ defmt-rtt = "0.4" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -embedded-io = { version = "0.5.0" } -embedded-io-async = { version = "0.5.0" } +embedded-io = { version = "0.6.0" } +embedded-io-async = { version = "0.6.0" } panic-probe = { version = "0.3", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index bf8f413d..19d08a8b 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -11,7 +11,7 @@ embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } -embedded-io-async = { version = "0.5.0" } +embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } defmt = "0.3" diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index 42a42618..a69de965 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -11,7 +11,7 @@ embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } -embedded-io-async = { version = "0.5.0" } +embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } defmt = "0.3" @@ -22,7 +22,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } -embedded-nal-async = { version = "0.5.0" } +embedded-nal-async = { version = "0.6.0" } panic-probe = { version = "0.3", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index c1d49963..3a3927a9 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -11,7 +11,7 @@ embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } -embedded-io-async = { version = "0.5.0" } +embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } defmt = "0.3" @@ -22,7 +22,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } -embedded-nal-async = { version = "0.5.0" } +embedded-nal-async = { version = "0.6.0" } panic-probe = { version = "0.3", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index 502ebfc8..0aff9dbd 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -24,8 +24,8 @@ defmt = "0.3" defmt-rtt = "0.4" embedded-storage = "0.3.0" -embedded-io = { version = "0.5.0" } -embedded-io-async = { version = "0.5.0", optional = true } +embedded-io = { version = "0.6.0" } +embedded-io-async = { version = "0.6.0", optional = true } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 59e89c53..07fcbed6 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -15,8 +15,8 @@ embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defm embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "udp", "tcp", "dhcpv4", "medium-ethernet"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embedded-io-async = { version = "0.5.0", features = ["defmt-03"] } -embedded-io = { version = "0.5.0", features = ["defmt-03"] } +embedded-io-async = { version = "0.6.0", features = ["defmt-03"] } +embedded-io = { version = "0.6.0", features = ["defmt-03"] } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 583e1a77..a82cdc61 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -25,7 +25,7 @@ embedded-hal = "0.2.6" futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } rand_core = { version = "0.6.3", default-features = false } -embedded-io-async = { version = "0.5.0" } +embedded-io-async = { version = "0.6.0" } static_cell = { version = "1.1", features = ["nightly"]} [profile.release] diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 08fe1a4b..2b265fc4 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -12,7 +12,7 @@ embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nightly", "unstable-traits", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } -embedded-io-async = { version = "0.5.0" } +embedded-io-async = { version = "0.6.0" } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 8bb0de6c..9751fe8c 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -29,7 +29,7 @@ embedded-hal-async = { version = "=1.0.0-rc.1" } embedded-hal-bus = { version = "=0.1.0-rc.1", features = ["async"] } panic-probe = { version = "0.3.0", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } -embedded-io-async = { version = "0.5.0" } +embedded-io-async = { version = "0.6.0" } embedded-storage = { version = "0.3" } static_cell = { version = "1.1", features = ["nightly"]} pio = "0.2" From ba7d74ac16f818eef25070f88556fc14df3f6b0c Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 4 Oct 2023 00:17:33 +0200 Subject: [PATCH 30/95] tests/stm32: increase tickrate for better precision. --- tests/stm32/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index c1addcd9..e11e585d 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -41,7 +41,7 @@ teleprobe-meta = "1" embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "tick-hz-32_768", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-any"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } From c6513f93fe8198cfcb49adc9d8b61e27090578fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20G=C3=B3rski?= Date: Wed, 4 Oct 2023 18:20:25 +0200 Subject: [PATCH 31/95] stm32/gpio: Implement `eh1::digital::InputPin` for `OutputOpenDrain` Pins in open-drain mode are outputs and inputs simultaneously. --- embassy-stm32/src/gpio.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index c709d46d..58d17f12 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -974,6 +974,18 @@ mod eh1 { type Error = Infallible; } + impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> { + #[inline] + fn is_high(&self) -> Result { + Ok(self.is_high()) + } + + #[inline] + fn is_low(&self) -> Result { + Ok(self.is_low()) + } + } + impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> { #[inline] fn set_high(&mut self) -> Result<(), Self::Error> { From e1a0635ca302b0a4009e305f170c906bb0d56949 Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 4 Oct 2023 16:15:08 -0500 Subject: [PATCH 32/95] stm32: update metapac and fix opamp ch --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/src/opamp.rs | 32 ++++++++++++++++++++++++++--- examples/stm32f334/src/bin/opamp.rs | 4 ++-- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index d43252ad..1b688eca 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-06d13dfd245cc9bf86fd88c35b401bdb84c079c4" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-172c5ea18824d7cd38decb210e4af441fa3816cb" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-06d13dfd245cc9bf86fd88c35b401bdb84c079c4", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-172c5ea18824d7cd38decb210e4af441fa3816cb", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index 7b388aef..e0fad26e 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -4,7 +4,15 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; use crate::Peripheral; -#[cfg(opamp_f3)] +#[derive(Clone, Copy)] +pub enum OpAmpGain { + Mul1, + Mul2, + Mul4, + Mul8, + Mul16, +} + pub struct OpAmpOutput<'d, 'p, T: Instance, P: NonInvertingPin> { _inner: &'d OpAmp<'d, T>, _input: &'p mut P, @@ -35,14 +43,32 @@ impl<'d, T: Instance> OpAmp<'d, T> { Self { _inner: opamp } } - #[cfg(opamp_f3)] - pub fn buffer_for<'a, 'b, P>(&'a mut self, pin: &'b mut P) -> OpAmpOutput<'a, 'b, T, P> + pub fn buffer_for<'a, 'b, P>(&'a mut self, pin: &'b mut P, gain: OpAmpGain) -> OpAmpOutput<'a, 'b, T, P> where P: NonInvertingPin, { + let (vm_sel, pga_gain) = match gain { + OpAmpGain::Mul1 => (0b11, 0b00), + OpAmpGain::Mul2 => (0b10, 0b00), + OpAmpGain::Mul4 => (0b10, 0b01), + OpAmpGain::Mul8 => (0b10, 0b10), + OpAmpGain::Mul16 => (0b10, 0b11), + }; + #[cfg(opamp_f3)] T::regs().opampcsr().modify(|w| { w.set_vp_sel(pin.channel()); + w.set_vm_sel(vm_sel); + w.set_pga_gain(pga_gain); + }); + + #[cfg(opamp_g4)] + T::regs().opamp_csr().modify(|w| { + use crate::pac::opamp::vals::*; + + w.set_vp_sel(OpampCsrVpSel::from_bits(pin.channel())); + w.set_vm_sel(OpampCsrVmSel::from_bits(vm_sel)); + w.set_pga_gain(OpampCsrPgaGain::from_bits(pga_gain)); }); OpAmpOutput { diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index 72263bab..3fffcfb1 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs @@ -5,7 +5,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; -use embassy_stm32::opamp::OpAmp; +use embassy_stm32::opamp::{OpAmp, OpAmpGain}; use embassy_stm32::peripherals::ADC2; use embassy_stm32::rcc::AdcClockSource; use embassy_stm32::time::mhz; @@ -39,7 +39,7 @@ async fn main(_spawner: Spawner) -> ! { let mut vrefint = adc.enable_vref(&mut Delay); let mut temperature = adc.enable_temperature(); - let mut buffer = opamp.buffer_for(&mut p.PA7); + let mut buffer = opamp.buffer_for(&mut p.PA7, OpAmpGain::Mul1); loop { let vref = adc.read(&mut vrefint).await; From be9c05fbc904fd7c62f4ae1b90c021ee403cc0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 5 Oct 2023 17:02:25 +0200 Subject: [PATCH 33/95] Reexport IpListenEndpoint for TCP --- embassy-net/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 0d7ac47a..c5fe08ab 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -39,7 +39,7 @@ use smoltcp::socket::dhcpv4::{self, RetryConfig}; pub use smoltcp::wire::EthernetAddress; #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154", feature = "medium-ip"))] pub use smoltcp::wire::HardwareAddress; -#[cfg(feature = "udp")] +#[cfg(any(feature = "udp", feature = "tcp"))] pub use smoltcp::wire::IpListenEndpoint; #[cfg(feature = "medium-ieee802154")] pub use smoltcp::wire::{Ieee802154Address, Ieee802154Frame}; From 38e7709a24982231a6a68dca4dddb75eb934c6bf Mon Sep 17 00:00:00 2001 From: Will Glynn Date: Thu, 5 Oct 2023 22:05:05 -0500 Subject: [PATCH 34/95] 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. --- embassy-stm32/src/rcc/u5.rs | 360 ++++++++++++++++++------- examples/stm32u5/src/bin/usb_serial.rs | 7 +- 2 files changed, 274 insertions(+), 93 deletions(-) diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index d9a53128..14b8577d 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -1,7 +1,7 @@ -use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllsrc, Sw}; +use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllmboost, Pllrge, Pllsrc, Sw}; pub use super::bus::{AHBPrescaler, APBPrescaler}; -use crate::pac::{FLASH, RCC}; +use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -15,23 +15,86 @@ pub use crate::pac::pwr::vals::Vos as VoltageScale; #[derive(Copy, Clone)] pub enum ClockSrc { + /// Use an internal medium speed oscillator (MSIS) as the system clock. MSI(MSIRange), + /// 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. HSE(Hertz), + /// Use the 16 MHz internal high speed oscillator as the system clock. HSI16, - PLL1R(PllSrc, PllM, PllN, PllClkDiv), + /// Use PLL1 as the system clock. + PLL1R(PllConfig), +} + +impl Default for ClockSrc { + fn default() -> Self { + // The default system clock source is MSIS @ 4 MHz, per RM0456 § 11.4.9 + ClockSrc::MSI(MSIRange::Range4mhz) + } +} + +#[derive(Clone, Copy, Debug)] +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. + pub m: PllM, + /// 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 }`. + pub n: PllN, + /// 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 }`. + pub r: PllClkDiv, +} + +impl PllConfig { + /// A configuration for HSI16 / 1 * 10 / 1 = 160 MHz + pub const fn hsi16_160mhz() -> Self { + PllConfig { + source: PllSrc::HSI16, + m: PllM::NotDivided, + n: PllN::Mul10, + r: PllClkDiv::NotDivided, + } + } + + /// A configuration for MSIS @ 48 MHz / 3 * 10 / 1 = 160 MHz + pub const fn msis_160mhz() -> Self { + PllConfig { + source: PllSrc::MSIS(MSIRange::Range48mhz), + m: PllM::Div3, + n: PllN::Mul10, + r: PllClkDiv::NotDivided, + } + } } #[derive(Clone, Copy, Debug)] pub enum PllSrc { - MSI(MSIRange), + /// Use an internal medium speed oscillator as the PLL source. + MSIS(MSIRange), + /// 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. HSE(Hertz), + /// Use the 16 MHz internal high speed oscillator as the PLL source. HSI16, } impl Into for PllSrc { fn into(self) -> Pllsrc { match self { - PllSrc::MSI(..) => Pllsrc::MSIS, + PllSrc::MSIS(..) => Pllsrc::MSIS, PllSrc::HSE(..) => Pllsrc::HSE, PllSrc::HSI16 => Pllsrc::HSI16, } @@ -41,57 +104,45 @@ impl Into for PllSrc { seq_macro::seq!(N in 2..=128 { #[derive(Copy, Clone, Debug)] pub enum PllClkDiv { - NotDivided, + NotDivided = 1, #( - Div~N = (N-1), + Div~N = N, )* } impl PllClkDiv { fn to_div(&self) -> u8 { match self { - PllClkDiv::NotDivided => 1, + PllClkDiv::NotDivided => 0, #( - PllClkDiv::Div~N => N + 1, + PllClkDiv::Div~N => N - 1, )* } } } }); -impl Into for PllClkDiv { - fn into(self) -> u8 { - (self as u8) + 1 - } -} - seq_macro::seq!(N in 4..=512 { #[derive(Copy, Clone, Debug)] pub enum PllN { - NotMultiplied, + NotMultiplied = 1, #( - Mul~N = N-1, + Mul~N = N, )* } impl PllN { fn to_mul(&self) -> u16 { match self { - PllN::NotMultiplied => 1, + PllN::NotMultiplied => 0, #( - PllN::Mul~N => N + 1, + PllN::Mul~N => N - 1, )* } } } }); -impl Into for PllN { - fn into(self) -> u16 { - (self as u16) + 1 - } -} - // Pre-division #[derive(Copy, Clone, Debug)] pub enum PllM { @@ -132,6 +183,7 @@ impl Into for ClockSrc { #[derive(Debug, Copy, Clone)] pub enum MSIRange { + /// The 48 MHz MSI speed is unavailable in `VoltageScale::RANGE4`. Range48mhz = 48_000_000, Range24mhz = 24_000_000, Range16mhz = 16_000_000, @@ -179,12 +231,6 @@ impl Into for MSIRange { } } -impl Default for MSIRange { - fn default() -> Self { - MSIRange::Range4mhz - } -} - #[derive(Copy, Clone)] pub struct Config { pub mux: ClockSrc, @@ -193,103 +239,220 @@ pub struct Config { pub apb2_pre: APBPrescaler, pub apb3_pre: APBPrescaler, pub hsi48: bool, + /// 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, +} + +impl Config { + unsafe fn init_hsi16(&self) -> Hertz { + 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 + } + + unsafe fn init_msis(&self, range: MSIRange) -> Hertz { + // Check MSI output per RM0456 § 11.4.10 + match self.voltage_range { + VoltageScale::RANGE4 => { + assert!(range as u32 <= 24_000_000); + } + _ => {} + } + + // 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| { + let bits: Msirange = range.into(); + w.set_msisrange(bits); + w.set_msirgsel(Msirgsel::RCC_ICSCR1); + }); + RCC.cr().write(|w| { + w.set_msipllen(false); + w.set_msison(true); + }); + while !RCC.cr().read().msisrdy() {} + Hertz(range as u32) + } } impl Default for Config { fn default() -> Self { Self { - mux: ClockSrc::MSI(MSIRange::default()), + mux: ClockSrc::default(), ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, apb3_pre: APBPrescaler::DIV1, hsi48: false, + voltage_range: VoltageScale::RANGE3, } } } pub(crate) unsafe fn init(config: Config) { + // 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() {} + let sys_clk = match config.mux { - ClockSrc::MSI(range) => { - RCC.icscr1().modify(|w| { - let bits: Msirange = range.into(); - w.set_msisrange(bits); - w.set_msirgsel(Msirgsel::RCC_ICSCR1); - }); - RCC.cr().write(|w| { - w.set_msipllen(false); - w.set_msison(true); - }); - while !RCC.cr().read().msisrdy() {} - - range.into() - } - ClockSrc::HSE(freq) => { - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - - freq.0 - } - ClockSrc::HSI16 => { - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - HSI_FREQ.0 - } - ClockSrc::PLL1R(src, m, n, div) => { - let freq = match src { - PllSrc::MSI(_) => { - // TODO: enable MSI - MSIRange::default().into() - } - PllSrc::HSE(hertz) => { - // TODO: enable HSE - hertz.0 - } - PllSrc::HSI16 => { - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - HSI_FREQ.0 - } + ClockSrc::MSI(range) => config.init_msis(range), + ClockSrc::HSE(freq) => config.init_hse(freq), + ClockSrc::HSI16 => config.init_hsi16(), + ClockSrc::PLL1R(pll) => { + // Configure the PLL source + let source_clk = match pll.source { + PllSrc::MSIS(range) => config.init_msis(range), + PllSrc::HSE(hertz) => config.init_hse(hertz), + PllSrc::HSI16 => config.init_hsi16(), }; - // disable + // Calculate the reference clock, which is the source divided by m + let reference_clk = source_clk / (pll.m as u8 as u32 + 1); + + // Check limits per RM0456 § 11.4.6 + assert!(Hertz::mhz(4) <= reference_clk && reference_clk <= Hertz::mhz(16)); + + // Calculate the PLL1 VCO clock and PLL1 R output clock + let pll1_clk = reference_clk * (pll.n as u8 as u32); + let pll1r_clk = pll1_clk / (pll.r as u8 as u32); + + // 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)); + } + VoltageScale::RANGE2 => { + assert!(pll1_clk >= Hertz::mhz(128) && pll1_clk <= Hertz::mhz(544)); + assert!(pll1r_clk <= Hertz::mhz(110)); + } + 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"); + } + } + + // § 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 + Pllmboost::BYPASS + } + } else { + // Nothing to do + Pllmboost::BYPASS + }; + + // Disable the PLL, and wait for it to disable RCC.cr().modify(|w| w.set_pllon(0, false)); while RCC.cr().read().pllrdy(0) {} - let vco = freq * n as u8 as u32; - let pll_ck = vco / (div as u8 as u32 + 1); - + // Configure the PLL RCC.pll1cfgr().write(|w| { - w.set_pllm(m.into()); - w.set_pllsrc(src.into()); + // Configure PLL1 source and prescaler + w.set_pllsrc(pll.source.into()); + w.set_pllm(pll.m.into()); + + // 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); + + // Enable PLL1R output w.set_pllren(true); }); + // Configure the PLL divisors RCC.pll1divr().modify(|w| { - w.set_pllr(div.to_div()); - w.set_plln(n.to_mul()); + // Set the VCO multiplier + w.set_plln(pll.n.to_mul()); + // Set the R output divisor + w.set_pllr(pll.r.to_div()); }); - // Enable PLL + // 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 RCC.cr().modify(|w| w.set_pllon(0, true)); while !RCC.cr().read().pllrdy(0) {} - pll_ck + pll1r_clk } - }; + } + .0; if config.hsi48 { RCC.cr().modify(|w| w.set_hsi48on(true)); while !RCC.cr().read().hsi48rdy() {} } - // TODO make configurable - let power_vos = VoltageScale::RANGE3; - - // states and programming delay - let wait_states = match power_vos { + // The clock source is ready + // Calculate and set the flash wait states + let wait_states = match config.voltage_range { // VOS 1 range VCORE 1.26V - 1.40V VoltageScale::RANGE1 => { if sys_clk < 32_000_000 { @@ -335,21 +498,34 @@ pub(crate) unsafe fn init(config: Config) { } } }; - FLASH.acr().modify(|w| { w.set_latency(wait_states); }); + // Switch the system clock source RCC.cfgr1().modify(|w| { w.set_sw(config.mux.into()); }); + // 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 RCC.cfgr2().modify(|w| { w.set_hpre(config.ahb_pre.into()); w.set_ppre1(config.apb1_pre.into()); w.set_ppre2(config.apb2_pre.into()); }); - RCC.cfgr3().modify(|w| { w.set_ppre3(config.apb3_pre.into()); }); diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index 9e47fb18..278bd30f 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -23,7 +23,12 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL1R(PllSrc::HSI16, PllM::Div2, PllN::Mul10, PllClkDiv::NotDivided); + config.rcc.mux = ClockSrc::PLL1R(PllConfig { + source: PllSrc::HSI16, + m: PllM::Div2, + n: PllN::Mul10, + r: PllClkDiv::NotDivided, + }); //config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz); config.rcc.hsi48 = true; From 930b8f34953596c550ca47bb35d8ab1d19d8feed Mon Sep 17 00:00:00 2001 From: James Munns Date: Fri, 6 Oct 2023 17:45:35 +0200 Subject: [PATCH 35/95] Add some uncontroversial derives to Error types --- embassy-embedded-hal/src/flash/partition/mod.rs | 2 +- embassy-rp/src/i2c.rs | 2 +- embassy-rp/src/i2c_slave.rs | 2 +- embassy-stm32/src/dac/mod.rs | 2 +- embassy-stm32/src/i2c/mod.rs | 2 +- embassy-stm32/src/rng.rs | 1 + embassy-stm32/src/sai/mod.rs | 2 +- embassy-stm32/src/spi/mod.rs | 2 +- examples/stm32h7/src/bin/camera.rs | 2 +- examples/stm32l4/src/bin/spe_adin1110_http_server.rs | 2 +- 10 files changed, 10 insertions(+), 9 deletions(-) diff --git a/embassy-embedded-hal/src/flash/partition/mod.rs b/embassy-embedded-hal/src/flash/partition/mod.rs index a12e49ce..42c8a308 100644 --- a/embassy-embedded-hal/src/flash/partition/mod.rs +++ b/embassy-embedded-hal/src/flash/partition/mod.rs @@ -11,7 +11,7 @@ pub use asynch::Partition; pub use blocking::BlockingPartition; /// Partition error -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { /// The requested flash area is outside the partition diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index c358682c..ea077335 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs @@ -27,7 +27,7 @@ pub enum AbortReason { } /// I2C error -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { /// I2C abort with error diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs index 6136d69c..30e78925 100644 --- a/embassy-rp/src/i2c_slave.rs +++ b/embassy-rp/src/i2c_slave.rs @@ -10,7 +10,7 @@ use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::{pac, Peripheral}; /// I2C error -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[non_exhaustive] pub enum Error { diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index a2040b85..7658dce4 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -11,7 +11,7 @@ use crate::{peripherals, Peripheral}; #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Curstom Errors +/// Custom Errors pub enum Error { UnconfiguredChannel, InvalidValue, diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index b35678ed..62d13e90 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -14,7 +14,7 @@ pub use timeout::*; use crate::peripherals; -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { Bus, diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 5080cf03..2d7ffc62 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -13,6 +13,7 @@ use crate::{interrupt, pac, peripherals, Peripheral}; static RNG_WAKER: AtomicWaker = AtomicWaker::new(); +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { SeedError, diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 5eecb637..4c3604e5 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs @@ -11,7 +11,7 @@ use crate::pac::sai::{vals, Sai as Regs}; use crate::rcc::RccPeripheral; use crate::{peripherals, Peripheral}; -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { NotATransmitter, diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 14333ba2..bd70342c 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -15,7 +15,7 @@ use crate::rcc::RccPeripheral; use crate::time::Hertz; use crate::{peripherals, Peripheral}; -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { Framing, diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index de8ddc29..c22ce4e0 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs @@ -184,7 +184,7 @@ mod ov7725 { const CAM_ADDR: u8 = 0x21; - #[derive(Format)] + #[derive(Format, PartialEq, Eq)] pub enum Error { I2c(I2cError), } diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 28752158..ba4a9d23 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -366,7 +366,7 @@ pub struct ADT7422<'d, BUS: I2cBus> { bus: BUS, } -#[derive(Debug, Format)] +#[derive(Debug, Format, PartialEq, Eq)] pub enum Error { I2c(I2cError), Address, From f01609036ff757ef3f04e568c646a467289d5440 Mon Sep 17 00:00:00 2001 From: Matt Ickstadt Date: Tue, 3 Oct 2023 16:45:05 -0500 Subject: [PATCH 36/95] h7: implement RTC and LSE clock configuration --- embassy-stm32/Cargo.toml | 4 +-- embassy-stm32/src/dac/mod.rs | 4 +-- embassy-stm32/src/rcc/bd.rs | 47 +++++++++++++++++-------- embassy-stm32/src/rcc/f4.rs | 2 +- embassy-stm32/src/rcc/h.rs | 57 ++++++++++++++++++++++++++++-- embassy-stm32/src/rcc/l4.rs | 2 +- embassy-stm32/src/rcc/mod.rs | 59 +++++++++++++++++++++++++------ embassy-stm32/src/rcc/wl.rs | 2 +- embassy-stm32/src/rtc/mod.rs | 61 ++++++++++++++++++++++++--------- embassy-stm32/src/rtc/v2.rs | 2 ++ examples/stm32h7/Cargo.toml | 3 +- examples/stm32h7/src/bin/rtc.rs | 39 +++++++++++++++++++++ 12 files changed, 231 insertions(+), 51 deletions(-) create mode 100644 examples/stm32h7/src/bin/rtc.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 1b688eca..5258e4c7 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-172c5ea18824d7cd38decb210e4af441fa3816cb" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f0f06b4c95bd9e185e4aa5f2e1d4b76ba84f1594" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-172c5ea18824d7cd38decb210e4af441fa3816cb", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f0f06b4c95bd9e185e4aa5f2e1d4b76ba84f1594", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index a2040b85..976aa3ee 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -564,7 +564,7 @@ pub trait DacPin: crate::gpio::Pin + 'static {} foreach_peripheral!( (dac, $inst:ident) => { // H7 uses single bit for both DAC1 and DAC2, this is a hack until a proper fix is implemented - #[cfg(rcc_h7)] + #[cfg(any(rcc_h7, rcc_h7rm0433))] impl crate::rcc::sealed::RccPeripheral for peripherals::$inst { fn frequency() -> crate::time::Hertz { critical_section::with(|_| unsafe { crate::rcc::get_freqs().apb1 }) @@ -590,7 +590,7 @@ foreach_peripheral!( } } - #[cfg(rcc_h7)] + #[cfg(any(rcc_h7, rcc_h7rm0433))] impl crate::rcc::RccPeripheral for peripherals::$inst {} impl crate::dac::sealed::Instance for peripherals::$inst { diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index cec2ea01..9c784c3a 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -1,26 +1,36 @@ +#[allow(dead_code)] +#[derive(Clone, Copy)] +pub enum LseCfg { + Oscillator(LseDrive), + Bypass, +} + +impl Default for LseCfg { + fn default() -> Self { + Self::Oscillator(Default::default()) + } +} + #[allow(dead_code)] #[derive(Default, Clone, Copy)] pub enum LseDrive { - #[cfg(any(rtc_v2f7, rtc_v2l4))] Low = 0, MediumLow = 0x01, #[default] MediumHigh = 0x02, - #[cfg(any(rtc_v2f7, rtc_v2l4))] High = 0x03, } -#[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] +// All families but these have the LSEDRV register +#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] impl From for crate::pac::rcc::vals::Lsedrv { fn from(value: LseDrive) -> Self { use crate::pac::rcc::vals::Lsedrv; match value { - #[cfg(any(rtc_v2f7, rtc_v2l4))] LseDrive::Low => Lsedrv::LOW, LseDrive::MediumLow => Lsedrv::MEDIUMLOW, LseDrive::MediumHigh => Lsedrv::MEDIUMHIGH, - #[cfg(any(rtc_v2f7, rtc_v2l4))] LseDrive::High => Lsedrv::HIGH, } } @@ -87,14 +97,19 @@ impl BackupDomain { rtc_v3u5 ))] #[allow(dead_code, unused_variables)] - pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option) { + pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option) { use atomic_polyfill::{compiler_fence, Ordering}; match clock_source { RtcClockSource::LSI => assert!(lsi), - RtcClockSource::LSE => assert!(&lse.is_some()), + RtcClockSource::LSE => assert!(lse.is_some()), _ => {} }; + let (lse_en, lse_byp, lse_drv) = match lse { + Some(LseCfg::Oscillator(lse_drv)) => (true, false, Some(lse_drv)), + Some(LseCfg::Bypass) => (true, true, None), + None => (false, false, None), + }; if lsi { #[cfg(rtc_v3u5)] @@ -131,10 +146,11 @@ impl BackupDomain { { ok &= reg.rtcen() == (clock_source != RtcClockSource::NOCLOCK); } - ok &= reg.lseon() == lse.is_some(); - #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] - if let Some(lse_drive) = lse { - ok &= reg.lsedrv() == lse_drive.into(); + ok &= reg.lseon() == lse_en; + ok &= reg.lsebyp() == lse_byp; + #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] + if let Some(lse_drv) = lse_drv { + ok &= reg.lsedrv() == lse_drv.into(); } // if configuration is OK, we're done. @@ -153,10 +169,13 @@ impl BackupDomain { Self::modify(|w| w.set_bdrst(false)); } - if let Some(lse_drive) = lse { + if lse_en { Self::modify(|w| { - #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] - w.set_lsedrv(lse_drive.into()); + #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] + if let Some(lse_drv) = lse_drv { + w.set_lsedrv(lse_drv.into()); + } + w.set_lsebyp(lse_byp); w.set_lseon(true); }); diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index edc5ff52..5ba958a0 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -540,7 +540,7 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pllsai: plls.pllsaiclk.map(Hertz), - rtc: rtc, + rtc, rtc_hse: None, }); } diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 43e8db22..5f9cc1c8 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -9,6 +9,8 @@ pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; pub use crate::pac::rcc::vals::Ckpersel as PerClockSource; use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre}; use crate::pac::{FLASH, PWR, RCC}; +#[cfg(stm32h7)] +use crate::rcc::bd::{BackupDomain, LseCfg, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -46,9 +48,9 @@ pub enum VoltageScale { pub enum HseMode { /// crystal/ceramic oscillator (HSEBYP=0) Oscillator, - /// external analog clock (low swing) (HSEBYP=1, HSEEXT=0) + /// external analog clock (low swing) (HSEBYP=1, HSEEXT=0) Bypass, - /// external digital clock (full swing) (HSEBYP=1, HSEEXT=1) + /// external digital clock (full swing) (HSEBYP=1, HSEEXT=1) #[cfg(any(rcc_h5, rcc_h50))] BypassDigital, } @@ -61,6 +63,15 @@ pub struct Hse { pub mode: HseMode, } +#[cfg(stm32h7)] +#[derive(Clone, Copy, Eq, PartialEq)] +pub enum Lse { + /// 32.768 kHz crystal/ceramic oscillator (LSEBYP=0) + Oscillator, + /// external clock input up to 1MHz (LSEBYP=1) + Bypass(Hertz), +} + #[derive(Clone, Copy, Eq, PartialEq)] pub enum Hsi { /// 64Mhz @@ -157,6 +168,10 @@ impl From for Timpre { pub struct Config { pub hsi: Option, pub hse: Option, + #[cfg(stm32h7)] + pub lse: Option, + #[cfg(stm32h7)] + pub lsi: bool, pub csi: bool, pub hsi48: bool, pub sys: Sysclk, @@ -181,6 +196,8 @@ pub struct Config { pub adc_clock_source: AdcClockSource, pub timer_prescaler: TimerPrescaler, pub voltage_scale: VoltageScale, + #[cfg(stm32h7)] + pub rtc_mux: Option, } impl Default for Config { @@ -188,6 +205,10 @@ impl Default for Config { Self { hsi: Some(Hsi::Mhz64), hse: None, + #[cfg(stm32h7)] + lse: None, + #[cfg(stm32h7)] + lsi: false, csi: false, hsi48: false, sys: Sysclk::HSI, @@ -210,6 +231,8 @@ impl Default for Config { adc_clock_source: AdcClockSource::from_bits(0), // PLL2_P on H7, HCLK on H5 timer_prescaler: TimerPrescaler::DefaultX2, voltage_scale: VoltageScale::Scale0, + #[cfg(stm32h7)] + rtc_mux: None, } } } @@ -448,6 +471,19 @@ pub(crate) unsafe fn init(config: Config) { flash_setup(hclk, config.voltage_scale); + #[cfg(stm32h7)] + { + let lsecfg = config.lse.map(|lse| match lse { + Lse::Bypass(freq) => { + assert!(freq <= Hertz(1_000_000)); + LseCfg::Bypass + } + Lse::Oscillator => LseCfg::Oscillator(Default::default()), + }); + + BackupDomain::configure_ls(config.rtc_mux.unwrap_or(RtcClockSource::NOCLOCK), config.lsi, lsecfg); + } + #[cfg(stm32h7)] { RCC.d1cfgr().modify(|w| { @@ -512,6 +548,17 @@ pub(crate) unsafe fn init(config: Config) { while !pac::SYSCFG.cccsr().read().ready() {} } + #[cfg(stm32h7)] + let rtc_clk = match config.rtc_mux { + Some(RtcClockSource::LSI) => Some(LSI_FREQ), + Some(RtcClockSource::LSE) => Some(match config.lse { + Some(Lse::Oscillator) => Hertz(32768), + Some(Lse::Bypass(freq)) => freq, + None => panic!("LSE not configured"), + }), + _ => None, + }; + set_freqs(Clocks { sys, ahb1: hclk, @@ -525,7 +572,11 @@ pub(crate) unsafe fn init(config: Config) { apb4, apb1_tim, apb2_tim, - adc: adc, + adc, + #[cfg(stm32h7)] + rtc: rtc_clk, + #[cfg(stm32h7)] + rtc_hse: None, }); } diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 6f1f7458..3a24eca8 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -420,7 +420,7 @@ pub(crate) unsafe fn init(config: Config) { w.set_msirgsel(true); w.set_msion(true); - if let RtcClockSource::LSE = config.rtc_mux { + if config.rtc_mux == RtcClockSource::LSE { // If LSE is enabled, enable calibration of MSI w.set_msipllen(true); } else { diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index ac967383..bf497ca1 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -21,7 +21,7 @@ pub use mco::*; #[cfg_attr(rcc_c0, path = "c0.rs")] #[cfg_attr(rcc_g0, path = "g0.rs")] #[cfg_attr(rcc_g4, path = "g4.rs")] -#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7ab), path = "h.rs")] +#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] #[cfg_attr(rcc_l0, path = "l0.rs")] #[cfg_attr(rcc_l1, path = "l1.rs")] #[cfg_attr(rcc_l4, path = "l4.rs")] @@ -57,9 +57,9 @@ pub struct Clocks { pub apb2: Hertz, #[cfg(not(any(rcc_c0, rcc_g0)))] pub apb2_tim: Hertz, - #[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_u5))] + #[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_u5))] pub apb3: Hertz, - #[cfg(any(rcc_h7, rcc_h7ab))] + #[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab))] pub apb4: Hertz, #[cfg(any(rcc_wba))] pub apb7: Hertz, @@ -67,16 +67,44 @@ pub struct Clocks { // AHB pub ahb1: Hertz, #[cfg(any( - rcc_l4, rcc_l5, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_g4, rcc_u5, rcc_wb, - rcc_wba, rcc_wl5, rcc_wle + rcc_l4, + rcc_l5, + rcc_f2, + rcc_f4, + rcc_f410, + rcc_f7, + rcc_h5, + rcc_h50, + rcc_h7, + rcc_h7rm0433, + rcc_h7ab, + rcc_g4, + rcc_u5, + rcc_wb, + rcc_wba, + rcc_wl5, + rcc_wle ))] pub ahb2: Hertz, #[cfg(any( - rcc_l4, rcc_l5, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_u5, rcc_wb, rcc_wl5, + rcc_l4, + rcc_l5, + rcc_f2, + rcc_f4, + rcc_f410, + rcc_f7, + rcc_h5, + rcc_h50, + rcc_h7, + rcc_h7rm0433, + rcc_h7ab, + rcc_u5, + rcc_wb, + rcc_wl5, rcc_wle ))] pub ahb3: Hertz, - #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_wba))] + #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_wba))] pub ahb4: Hertz, #[cfg(any(rcc_f2, rcc_f4, rcc_f410, rcc_f7))] @@ -88,7 +116,18 @@ pub struct Clocks { #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pub pllsai: Option, - #[cfg(any(rcc_f1, rcc_f100, rcc_f1cl, rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_f3, rcc_g4))] + #[cfg(any( + rcc_f1, + rcc_f100, + rcc_f1cl, + rcc_h5, + rcc_h50, + rcc_h7, + rcc_h7rm0433, + rcc_h7ab, + rcc_f3, + rcc_g4 + ))] pub adc: Option, #[cfg(any(rcc_f3, rcc_g4))] @@ -97,11 +136,11 @@ pub struct Clocks { #[cfg(stm32f334)] pub hrtim: Option, - #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_f7))] + #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_f7, rcc_h7, rcc_h7rm0433, rcc_h7ab))] /// Set only if the lsi or lse is configured, indicates stop is supported pub rtc: Option, - #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] + #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h7, rcc_h7rm0433, rcc_h7ab))] /// Set if the hse is configured, indicates stop is not supported pub rtc_hse: Option, } diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 6643d278..937f5550 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -261,7 +261,7 @@ pub(crate) unsafe fn init(config: Config) { w.set_msirange(range.into()); w.set_msion(true); - if let RtcClockSource::LSE = config.rtc_mux { + if config.rtc_mux == RtcClockSource::LSE { // If LSE is enabled, enable calibration of MSI w.set_msipllen(true); } else { diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 73b78f25..28dde2eb 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -93,21 +93,50 @@ impl RtcTimeProvider { /// /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. pub fn now(&self) -> Result { - let r = RTC::regs(); - let tr = r.tr().read(); - let second = bcd2_to_byte((tr.st(), tr.su())); - let minute = bcd2_to_byte((tr.mnt(), tr.mnu())); - let hour = bcd2_to_byte((tr.ht(), tr.hu())); - // Reading either RTC_SSR or RTC_TR locks the values in the higher-order - // calendar shadow registers until RTC_DR is read. - let dr = r.dr().read(); + // For RM0433 we use BYPSHAD=1 to work around errata ES0392 2.19.1 + #[cfg(rcc_h7rm0433)] + loop { + let r = RTC::regs(); + let ss = r.ssr().read().ss(); + let dr = r.dr().read(); + let tr = r.tr().read(); - let weekday = dr.wdu(); - let day = bcd2_to_byte((dr.dt(), dr.du())); - let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); - let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; + // If an RTCCLK edge occurs during read we may see inconsistent values + // so read ssr again and see if it has changed. (see RM0433 Rev 7 46.3.9) + let ss_after = r.ssr().read().ss(); + if ss == ss_after { + let second = bcd2_to_byte((tr.st(), tr.su())); + let minute = bcd2_to_byte((tr.mnt(), tr.mnu())); + let hour = bcd2_to_byte((tr.ht(), tr.hu())); - self::datetime::datetime(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) + let weekday = dr.wdu(); + let day = bcd2_to_byte((dr.dt(), dr.du())); + let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); + let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; + + return self::datetime::datetime(year, month, day, weekday, hour, minute, second) + .map_err(RtcError::InvalidDateTime); + } + } + + #[cfg(not(rcc_h7rm0433))] + { + let r = RTC::regs(); + let tr = r.tr().read(); + let second = bcd2_to_byte((tr.st(), tr.su())); + let minute = bcd2_to_byte((tr.mnt(), tr.mnu())); + let hour = bcd2_to_byte((tr.ht(), tr.hu())); + // Reading either RTC_SSR or RTC_TR locks the values in the higher-order + // calendar shadow registers until RTC_DR is read. + let dr = r.dr().read(); + + let weekday = dr.wdu(); + let day = bcd2_to_byte((dr.dt(), dr.du())); + let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); + let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; + + self::datetime::datetime(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) + } } } @@ -175,18 +204,18 @@ impl Rtc { } fn frequency() -> Hertz { - #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] + #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))] let freqs = unsafe { crate::rcc::get_freqs() }; // Load the clock frequency from the rcc mod, if supported - #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] + #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))] match freqs.rtc { Some(hertz) => hertz, None => freqs.rtc_hse.unwrap(), } // Assume the default value, if not supported - #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410)))] + #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab)))] Hertz(32_768) } diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 4974f6ee..eeb23e1f 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs @@ -157,6 +157,8 @@ impl super::Rtc { w.set_fmt(stm32_metapac::rtc::vals::Fmt::TWENTY_FOUR_HOUR); w.set_osel(Osel::DISABLED); w.set_pol(Pol::HIGH); + #[cfg(rcc_h7rm0433)] + w.set_bypshad(true); }); rtc.prer().modify(|w| { diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 3a3927a9..7bcdf2b3 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32h743bi to your chip name, if necessary. -embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "unstable-traits"] } +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "unstable-traits", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } @@ -32,6 +32,7 @@ micromath = "2.0.0" stm32-fmc = "0.3.0" embedded-storage = "0.3.0" static_cell = { version = "1.1", features = ["nightly"]} +chrono = { version = "^0.4", default-features = false } # cargo build/run [profile.dev] diff --git a/examples/stm32h7/src/bin/rtc.rs b/examples/stm32h7/src/bin/rtc.rs new file mode 100644 index 00000000..eeb94073 --- /dev/null +++ b/examples/stm32h7/src/bin/rtc.rs @@ -0,0 +1,39 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use chrono::{NaiveDate, NaiveDateTime}; +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::rcc::Lse; +use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; +use embassy_stm32::Config; +use embassy_time::{Duration, Timer}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = { + let mut config = Config::default(); + config.rcc.lse = Some(Lse::Oscillator); + config.rcc.rtc_mux = Some(RtcClockSource::LSE); + embassy_stm32::init(config) + }; + info!("Hello World!"); + + let now = NaiveDate::from_ymd_opt(2020, 5, 15) + .unwrap() + .and_hms_opt(10, 30, 15) + .unwrap(); + + let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); + info!("Got RTC! {:?}", now.timestamp()); + + rtc.set_datetime(now.into()).expect("datetime not set"); + + // In reality the delay would be much longer + Timer::after(Duration::from_millis(20000)).await; + + let then: NaiveDateTime = rtc.now().unwrap().into(); + info!("Got RTC! {:?}", then.timestamp()); +} From 4075ac84e14cbf970e773ba4a178ef4f82267c48 Mon Sep 17 00:00:00 2001 From: Matt Ickstadt Date: Fri, 6 Oct 2023 14:09:11 -0500 Subject: [PATCH 37/95] h7: enable rtc test --- tests/stm32/Cargo.toml | 2 +- tests/stm32/src/bin/rtc.rs | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index e11e585d..ef835eed 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -11,7 +11,7 @@ stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo -stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo +stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo stm32h563zi = ["embassy-stm32/stm32h563zi", "eth"] # Nucleo stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs index 22be6fac..1f0d630c 100644 --- a/tests/stm32/src/bin/rtc.rs +++ b/tests/stm32/src/bin/rtc.rs @@ -12,15 +12,24 @@ use defmt::assert; use embassy_executor::Spawner; use embassy_stm32::rcc::RtcClockSource; use embassy_stm32::rtc::{Rtc, RtcConfig}; -use embassy_stm32::time::Hertz; use embassy_time::{Duration, Timer}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = config(); - config.rcc.lse = Some(Hertz(32_768)); - config.rcc.rtc = Some(RtcClockSource::LSE); + #[cfg(feature = "stm32h755zi")] + { + use embassy_stm32::rcc::Lse; + config.rcc.lse = Some(Lse::Oscillator); + config.rcc.rtc_mux = Some(RtcClockSource::LSE); + } + #[cfg(not(feature = "stm32h755zi"))] + { + use embassy_stm32::time::Hertz; + config.rcc.lse = Some(Hertz(32_768)); + config.rcc.rtc = Some(RtcClockSource::LSE); + } let p = embassy_stm32::init(config); info!("Hello World!"); @@ -40,7 +49,7 @@ async fn main(_spawner: Spawner) { let then: NaiveDateTime = rtc.now().unwrap().into(); let seconds = (then - now).num_seconds(); - defmt::info!("measured = {}", seconds); + info!("measured = {}", seconds); assert!(seconds > 3 && seconds < 7); From 75c1a9a3aa695fc8c0c1ab9712e99ecb22eb8ae4 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 6 Oct 2023 23:25:39 +0200 Subject: [PATCH 38/95] disable flaky f2 eth test --- ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index d8bbb785..46a48f6b 100755 --- a/ci.sh +++ b/ci.sh @@ -203,7 +203,7 @@ cargo batch \ rm out/tests/stm32wb55rg/wpan_mac rm out/tests/stm32wb55rg/wpan_ble - +rm out/tests/stm32f207zg/eth if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests From 68c4820ddecce77c2cbf67d20f5643f5d5ca18fc Mon Sep 17 00:00:00 2001 From: shakencodes Date: Fri, 6 Oct 2023 14:36:16 -0700 Subject: [PATCH 39/95] Add MCO support for stm32wl family --- embassy-stm32/build.rs | 31 ++++++------------------------- embassy-stm32/src/rcc/mco.rs | 24 +++++++++++++++++------- embassy-stm32/src/rcc/mod.rs | 4 ++-- 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index f825dbee..a6a83088 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -50,12 +50,10 @@ fn main() { // We *shouldn't* have singletons for these, but the HAL currently requires // singletons, for using with RccPeripheral to enable/disable clocks to them. "rcc" => { - if r.version.starts_with("h5") || r.version.starts_with("h7") || r.version.starts_with("f4") { - singletons.push("MCO1".to_string()); - singletons.push("MCO2".to_string()); - } - if r.version.starts_with("l4") { - singletons.push("MCO".to_string()); + for pin in p.pins { + if pin.signal.starts_with("MCO") { + singletons.push(pin.signal.replace('_', "").to_string()); + } } singletons.push(p.name.to_string()); } @@ -751,25 +749,8 @@ fn main() { let af = pin.af.unwrap_or(0); // MCO is special - if pin.signal.starts_with("MCO_") { - // Supported in H7 only for now - if regs.version.starts_with("h5") - || regs.version.starts_with("h7") - || regs.version.starts_with("f4") - { - peri = format_ident!("{}", pin.signal.replace('_', "")); - } else { - continue; - } - } - - if pin.signal == "MCO" { - // Supported in H7 only for now - if regs.version.starts_with("l4") { - peri = format_ident!("MCO"); - } else { - continue; - } + if pin.signal.starts_with("MCO") { + peri = format_ident!("{}", pin.signal.replace('_', "")); } g.extend(quote! { diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index 2453ed82..85665fd2 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs @@ -4,14 +4,18 @@ use embassy_hal_internal::into_ref; use crate::gpio::sealed::AFType; use crate::gpio::Speed; +#[cfg(not(stm32wl))] pub use crate::pac::rcc::vals::{Mco1 as Mco1Source, Mco2 as Mco2Source}; +#[cfg(stm32wl)] +pub use crate::pac::rcc::vals::{Mcopre, Mcosel}; use crate::pac::RCC; use crate::{peripherals, Peripheral}; pub(crate) mod sealed { pub trait McoInstance { type Source; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8); + type Prescaler; + unsafe fn apply_clock_settings(source: Self::Source, prescaler: Self::Prescaler); } } @@ -20,11 +24,12 @@ pub trait McoInstance: sealed::McoInstance + 'static {} pin_trait!(McoPin, McoInstance); macro_rules! impl_peri { - ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { + ($peri:ident, $source:ident, $prescaler:ident, $set_source:ident, $set_prescaler:ident) => { impl sealed::McoInstance for peripherals::$peri { type Source = $source; + type Prescaler = $prescaler; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8) { + unsafe fn apply_clock_settings(source: Self::Source, prescaler: Self::Prescaler) { RCC.cfgr().modify(|w| { w.$set_source(source); w.$set_prescaler(prescaler); @@ -36,8 +41,12 @@ macro_rules! impl_peri { }; } -impl_peri!(MCO1, Mco1Source, set_mco1, set_mco1pre); -impl_peri!(MCO2, Mco2Source, set_mco2, set_mco2pre); +#[cfg(not(stm32wl))] +impl_peri!(MCO1, Mco1Source, u8, set_mco1, set_mco1pre); +#[cfg(not(stm32wl))] +impl_peri!(MCO2, Mco2Source, u8, set_mco2, set_mco2pre); +#[cfg(stm32wl)] +impl_peri!(MCO, Mcosel, Mcopre, set_mcosel, set_mcopre); pub struct Mco<'d, T: McoInstance> { phantom: PhantomData<&'d mut T>, @@ -46,15 +55,16 @@ pub struct Mco<'d, T: McoInstance> { impl<'d, T: McoInstance> Mco<'d, T> { /// Create a new MCO instance. /// - /// `prescaler` must be between 1 and 15. + /// `prescaler` must be between 1 and 15 for implementations not using Presel enum. pub fn new( _peri: impl Peripheral

+ 'd, pin: impl Peripheral

> + 'd, source: T::Source, - prescaler: u8, + prescaler: T::Prescaler, ) -> Self { into_ref!(pin); + #[cfg(not(stm32wl))] assert!( 1 <= prescaler && prescaler <= 15, "Mco prescaler must be between 1 and 15. Refer to the reference manual for more information." diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index bf497ca1..f7e3ecdb 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -7,9 +7,9 @@ use crate::time::Hertz; pub(crate) mod bd; mod bus; -#[cfg(any(stm32h5, stm32h7))] +#[cfg(any(stm32h5, stm32h7, stm32wl))] mod mco; -#[cfg(any(stm32h5, stm32h7))] +#[cfg(any(stm32h5, stm32h7, stm32wl))] pub use mco::*; #[cfg_attr(rcc_f0, path = "f0.rs")] From b217d147deab67a988df0d5e58a15eb9260dd6fa Mon Sep 17 00:00:00 2001 From: randi Date: Sat, 7 Oct 2023 11:57:19 +1300 Subject: [PATCH 40/95] Implemented Pwm trait from embedded_hal --- embassy-stm32/src/timer/mod.rs | 28 ++++++++++++++++++++ embassy-stm32/src/timer/simple_pwm.rs | 38 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index d88fbcfd..1e0999ed 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -70,6 +70,16 @@ pub(crate) mod sealed { fn set_autoreload_preload(&mut self, enable: vals::Arpe) { Self::regs().cr1().modify(|r| r.set_arpe(enable)); } + + fn get_frequency(&self) -> Hertz { + let timer_f = Self::frequency(); + + let regs = Self::regs(); + let arr = regs.arr().read().arr(); + let psc = regs.psc().read().psc(); + + timer_f / arr / (psc + 1) + } } pub trait GeneralPurpose16bitInstance: Basic16bitInstance { @@ -103,6 +113,16 @@ pub(crate) mod sealed { regs.egr().write(|r| r.set_ug(true)); regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT)); } + + fn get_frequency(&self) -> Hertz { + let timer_f = Self::frequency(); + + let regs = Self::regs_gp32(); + let arr = regs.arr().read().arr(); + let psc = regs.psc().read().psc(); + + timer_f / arr / (psc + 1) + } } pub trait AdvancedControlInstance: GeneralPurpose16bitInstance { @@ -183,6 +203,10 @@ pub(crate) mod sealed { fn get_max_compare_value(&self) -> u16 { Self::regs_gp16().arr().read().arr() } + + fn get_compare_value(&self, channel: Channel) -> u16 { + Self::regs_gp16().ccr(channel.raw()).read().ccr() + } } pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance + AdvancedControlInstance { @@ -219,6 +243,10 @@ pub(crate) mod sealed { fn get_max_compare_value(&self) -> u32 { Self::regs_gp32().arr().read().arr() } + + fn get_compare_value(&self, channel: Channel) -> u32 { + Self::regs_gp32().ccr(channel.raw()).read().ccr() + } } } diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 9e28878b..2b3a069a 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -109,3 +109,41 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { self.inner.set_output_polarity(channel, polarity); } } + +impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { + type Channel = Channel; + type Time = Hertz; + type Duty = u16; + + fn disable(&mut self, channel: Self::Channel) { + self.inner.enable_channel(channel, false); + } + + fn enable(&mut self, channel: Self::Channel) { + self.inner.enable_channel(channel, true); + } + + fn get_period(&self) -> Self::Time { + self.inner.get_frequency().into() + } + + fn get_duty(&self, channel: Self::Channel) -> Self::Duty { + self.inner.get_compare_value(channel) + } + + fn get_max_duty(&self) -> Self::Duty { + self.inner.get_max_compare_value() + 1 + } + + fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { + assert!(duty <= self.get_max_duty()); + self.inner.set_compare_value(channel, duty) + } + + fn set_period

(&mut self, period: P) + where + P: Into, + { + self.inner.set_frequency(period.into()); + } +} From 3a8e0d4a279f750e82689ce362c898f66cc81486 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 7 Oct 2023 01:15:24 +0200 Subject: [PATCH 41/95] stm32: implement MCO for all chips. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/build.rs | 6 +- embassy-stm32/src/rcc/f4.rs | 166 ----------------------------- embassy-stm32/src/rcc/l4.rs | 132 ----------------------- embassy-stm32/src/rcc/mco.rs | 58 +++++----- embassy-stm32/src/rcc/mod.rs | 2 - examples/stm32f4/src/bin/mco.rs | 6 +- examples/stm32h7/src/bin/camera.rs | 4 +- examples/stm32h7/src/bin/mco.rs | 4 +- examples/stm32l4/src/bin/mco.rs | 4 +- 10 files changed, 48 insertions(+), 338 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 5258e4c7..20c5155a 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f0f06b4c95bd9e185e4aa5f2e1d4b76ba84f1594" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-a7bf7f02d1e0bc720c24dbb8881677a298890365" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f0f06b4c95bd9e185e4aa5f2e1d4b76ba84f1594", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-a7bf7f02d1e0bc720c24dbb8881677a298890365", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index a6a83088..3f85d9e6 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -52,7 +52,11 @@ fn main() { "rcc" => { for pin in p.pins { if pin.signal.starts_with("MCO") { - singletons.push(pin.signal.replace('_', "").to_string()); + let name = pin.signal.replace('_', "").to_string(); + if !singletons.contains(&name) { + println!("cargo:rustc-cfg={}", name.to_ascii_lowercase()); + singletons.push(name); + } } } singletons.push(p.name.to_string()); diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index 5ba958a0..ad106ce3 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -1,16 +1,8 @@ -use core::marker::PhantomData; - -use embassy_hal_internal::into_ref; -use stm32_metapac::rcc::vals::{Mco1, Mco2, Mcopre}; - -use crate::gpio::sealed::AFType; -use crate::gpio::Speed; use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; -use crate::{peripherals, Peripheral}; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); @@ -197,164 +189,6 @@ fn setup_pll( } } -pub enum McoClock { - DIV1, - DIV2, - DIV3, - DIV4, - DIV5, -} - -impl McoClock { - fn into_raw(&self) -> Mcopre { - match self { - McoClock::DIV1 => Mcopre::DIV1, - McoClock::DIV2 => Mcopre::DIV2, - McoClock::DIV3 => Mcopre::DIV3, - McoClock::DIV4 => Mcopre::DIV4, - McoClock::DIV5 => Mcopre::DIV5, - } - } -} - -#[derive(Copy, Clone)] -pub enum Mco1Source { - Hsi, - Lse, - Hse, - Pll, -} - -impl Default for Mco1Source { - fn default() -> Self { - Self::Hsi - } -} - -pub trait McoSource { - type Raw; - - fn into_raw(&self) -> Self::Raw; -} - -impl McoSource for Mco1Source { - type Raw = Mco1; - fn into_raw(&self) -> Self::Raw { - match self { - Mco1Source::Hsi => Mco1::HSI, - Mco1Source::Lse => Mco1::LSE, - Mco1Source::Hse => Mco1::HSE, - Mco1Source::Pll => Mco1::PLL, - } - } -} - -#[derive(Copy, Clone)] -pub enum Mco2Source { - SysClk, - Plli2s, - Hse, - Pll, -} - -impl Default for Mco2Source { - fn default() -> Self { - Self::SysClk - } -} - -impl McoSource for Mco2Source { - type Raw = Mco2; - fn into_raw(&self) -> Self::Raw { - match self { - Mco2Source::SysClk => Mco2::SYSCLK, - Mco2Source::Plli2s => Mco2::PLLI2S, - Mco2Source::Hse => Mco2::HSE, - Mco2Source::Pll => Mco2::PLL, - } - } -} - -pub(crate) mod sealed { - use stm32_metapac::rcc::vals::Mcopre; - pub trait McoInstance { - type Source; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre); - } -} - -pub trait McoInstance: sealed::McoInstance + 'static {} - -pin_trait!(McoPin, McoInstance); - -impl sealed::McoInstance for peripherals::MCO1 { - type Source = Mco1; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre) { - RCC.cfgr().modify(|w| { - w.set_mco1(source); - w.set_mco1pre(prescaler); - }); - match source { - Mco1::PLL => { - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - } - Mco1::HSI => { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - } - _ => {} - } - } -} -impl McoInstance for peripherals::MCO1 {} - -impl sealed::McoInstance for peripherals::MCO2 { - type Source = Mco2; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre) { - RCC.cfgr().modify(|w| { - w.set_mco2(source); - w.set_mco2pre(prescaler); - }); - match source { - Mco2::PLL => { - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - } - #[cfg(not(stm32f410))] - Mco2::PLLI2S => { - RCC.cr().modify(|w| w.set_plli2son(true)); - while !RCC.cr().read().plli2srdy() {} - } - _ => {} - } - } -} -impl McoInstance for peripherals::MCO2 {} - -pub struct Mco<'d, T: McoInstance> { - phantom: PhantomData<&'d mut T>, -} - -impl<'d, T: McoInstance> Mco<'d, T> { - pub fn new( - _peri: impl Peripheral

+ 'd, - pin: impl Peripheral

> + 'd, - source: impl McoSource, - prescaler: McoClock, - ) -> Self { - into_ref!(pin); - - critical_section::with(|_| unsafe { - T::apply_clock_settings(source.into_raw(), prescaler.into_raw()); - pin.set_as_af(pin.af_num(), AFType::OutputPushPull); - pin.set_speed(Speed::VeryHigh); - }); - - Self { phantom: PhantomData } - } -} - fn flash_setup(sysclk: u32) { use crate::pac::flash::vals::Latency; diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 3a24eca8..2fbb9920 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -1,18 +1,11 @@ -use core::marker::PhantomData; - -use embassy_hal_internal::into_ref; use stm32_metapac::rcc::regs::Cfgr; -use stm32_metapac::rcc::vals::{Mcopre, Mcosel}; pub use super::bus::{AHBPrescaler, APBPrescaler}; -use crate::gpio::sealed::AFType; -use crate::gpio::Speed; use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; -use crate::{peripherals, Peripheral}; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); @@ -263,131 +256,6 @@ impl Default for Config { } } -pub enum McoClock { - DIV1, - DIV2, - DIV4, - DIV8, - DIV16, -} - -impl McoClock { - fn into_raw(&self) -> Mcopre { - match self { - McoClock::DIV1 => Mcopre::DIV1, - McoClock::DIV2 => Mcopre::DIV2, - McoClock::DIV4 => Mcopre::DIV4, - McoClock::DIV8 => Mcopre::DIV8, - McoClock::DIV16 => Mcopre::DIV16, - } - } -} - -#[derive(Copy, Clone)] -pub enum Mco1Source { - Disabled, - Lse, - Lsi, - Hse, - Hsi16, - PllClk, - SysClk, - Msi, - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - Hsi48, -} - -impl Default for Mco1Source { - fn default() -> Self { - Self::Hsi16 - } -} - -pub trait McoSource { - type Raw; - - fn into_raw(&self) -> Self::Raw; -} - -impl McoSource for Mco1Source { - type Raw = Mcosel; - fn into_raw(&self) -> Self::Raw { - match self { - Mco1Source::Disabled => Mcosel::NOCLOCK, - Mco1Source::Lse => Mcosel::LSE, - Mco1Source::Lsi => Mcosel::LSI, - Mco1Source::Hse => Mcosel::HSE, - Mco1Source::Hsi16 => Mcosel::HSI16, - Mco1Source::PllClk => Mcosel::PLL, - Mco1Source::SysClk => Mcosel::SYSCLK, - Mco1Source::Msi => Mcosel::MSI, - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - Mco1Source::Hsi48 => Mcosel::HSI48, - } - } -} - -pub(crate) mod sealed { - use stm32_metapac::rcc::vals::Mcopre; - pub trait McoInstance { - type Source; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre); - } -} - -pub trait McoInstance: sealed::McoInstance + 'static {} - -pin_trait!(McoPin, McoInstance); - -impl sealed::McoInstance for peripherals::MCO { - type Source = Mcosel; - - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Mcopre) { - RCC.cfgr().modify(|w| { - w.set_mcosel(source); - w.set_mcopre(prescaler); - }); - - match source { - Mcosel::HSI16 => { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - } - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - Mcosel::HSI48 => { - RCC.crrcr().modify(|w| w.set_hsi48on(true)); - while !RCC.crrcr().read().hsi48rdy() {} - } - _ => {} - } - } -} - -impl McoInstance for peripherals::MCO {} - -pub struct Mco<'d, T: McoInstance> { - phantom: PhantomData<&'d mut T>, -} - -impl<'d, T: McoInstance> Mco<'d, T> { - pub fn new( - _peri: impl Peripheral

+ 'd, - pin: impl Peripheral

> + 'd, - source: impl McoSource, - prescaler: McoClock, - ) -> Self { - into_ref!(pin); - - critical_section::with(|_| unsafe { - T::apply_clock_settings(source.into_raw(), prescaler.into_raw()); - pin.set_as_af(pin.af_num(), AFType::OutputPushPull); - pin.set_speed(Speed::VeryHigh); - }); - - Self { phantom: PhantomData } - } -} - pub(crate) unsafe fn init(config: Config) { // Switch to MSI to prevent problems with PLL configuration. if !RCC.cr().read().msion() { diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index 85665fd2..eaaf8071 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs @@ -4,18 +4,19 @@ use embassy_hal_internal::into_ref; use crate::gpio::sealed::AFType; use crate::gpio::Speed; -#[cfg(not(stm32wl))] -pub use crate::pac::rcc::vals::{Mco1 as Mco1Source, Mco2 as Mco2Source}; -#[cfg(stm32wl)] -pub use crate::pac::rcc::vals::{Mcopre, Mcosel}; +#[cfg(not(stm32f1))] +pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; +#[cfg(not(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))] +pub use crate::pac::rcc::vals::Mcosel as McoSource; +#[cfg(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7))] +pub use crate::pac::rcc::vals::{Mco1sel as Mco1Source, Mco2sel as Mco2Source}; use crate::pac::RCC; use crate::{peripherals, Peripheral}; pub(crate) mod sealed { pub trait McoInstance { type Source; - type Prescaler; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Self::Prescaler); + unsafe fn apply_clock_settings(source: Self::Source, #[cfg(not(stm32f1))] prescaler: super::McoPrescaler); } } @@ -24,14 +25,19 @@ pub trait McoInstance: sealed::McoInstance + 'static {} pin_trait!(McoPin, McoInstance); macro_rules! impl_peri { - ($peri:ident, $source:ident, $prescaler:ident, $set_source:ident, $set_prescaler:ident) => { + ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { impl sealed::McoInstance for peripherals::$peri { type Source = $source; - type Prescaler = $prescaler; - unsafe fn apply_clock_settings(source: Self::Source, prescaler: Self::Prescaler) { - RCC.cfgr().modify(|w| { + unsafe fn apply_clock_settings(source: Self::Source, #[cfg(not(stm32f1))] prescaler: McoPrescaler) { + #[cfg(not(any(stm32u5, stm32wba)))] + let r = RCC.cfgr(); + #[cfg(any(stm32u5, stm32wba))] + let r = RCC.cfgr1(); + + r.modify(|w| { w.$set_source(source); + #[cfg(not(stm32f1))] w.$set_prescaler(prescaler); }); } @@ -41,12 +47,16 @@ macro_rules! impl_peri { }; } -#[cfg(not(stm32wl))] -impl_peri!(MCO1, Mco1Source, u8, set_mco1, set_mco1pre); -#[cfg(not(stm32wl))] -impl_peri!(MCO2, Mco2Source, u8, set_mco2, set_mco2pre); -#[cfg(stm32wl)] -impl_peri!(MCO, Mcosel, Mcopre, set_mcosel, set_mcopre); +#[cfg(any(rcc_c0, rcc_g0))] +#[allow(unused_imports)] +use self::{McoSource as Mco1Source, McoSource as Mco2Source}; + +#[cfg(mco)] +impl_peri!(MCO, McoSource, set_mcosel, set_mcopre); +#[cfg(mco1)] +impl_peri!(MCO1, Mco1Source, set_mco1sel, set_mco1pre); +#[cfg(mco2)] +impl_peri!(MCO2, Mco2Source, set_mco2sel, set_mco2pre); pub struct Mco<'d, T: McoInstance> { phantom: PhantomData<&'d mut T>, @@ -54,24 +64,20 @@ pub struct Mco<'d, T: McoInstance> { impl<'d, T: McoInstance> Mco<'d, T> { /// Create a new MCO instance. - /// - /// `prescaler` must be between 1 and 15 for implementations not using Presel enum. pub fn new( _peri: impl Peripheral

+ 'd, pin: impl Peripheral

> + 'd, source: T::Source, - prescaler: T::Prescaler, + #[cfg(not(stm32f1))] prescaler: McoPrescaler, ) -> Self { into_ref!(pin); - #[cfg(not(stm32wl))] - assert!( - 1 <= prescaler && prescaler <= 15, - "Mco prescaler must be between 1 and 15. Refer to the reference manual for more information." - ); - critical_section::with(|_| unsafe { - T::apply_clock_settings(source, prescaler); + T::apply_clock_settings( + source, + #[cfg(not(stm32f1))] + prescaler, + ); pin.set_as_af(pin.af_num(), AFType::OutputPushPull); pin.set_speed(Speed::VeryHigh); }); diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index f7e3ecdb..a3299089 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -7,9 +7,7 @@ use crate::time::Hertz; pub(crate) mod bd; mod bus; -#[cfg(any(stm32h5, stm32h7, stm32wl))] mod mco; -#[cfg(any(stm32h5, stm32h7, stm32wl))] pub use mco::*; #[cfg_attr(rcc_f0, path = "f0.rs")] diff --git a/examples/stm32f4/src/bin/mco.rs b/examples/stm32f4/src/bin/mco.rs index 2b9ceebc..5144a78c 100644 --- a/examples/stm32f4/src/bin/mco.rs +++ b/examples/stm32f4/src/bin/mco.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_stm32::rcc::{Mco, Mco1Source, Mco2Source, McoClock}; +use embassy_stm32::rcc::{Mco, Mco1Source, Mco2Source, McoPrescaler}; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -14,8 +14,8 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let _mco1 = Mco::new(p.MCO1, p.PA8, Mco1Source::Hsi, McoClock::DIV1); - let _mco2 = Mco::new(p.MCO2, p.PC9, Mco2Source::Pll, McoClock::DIV4); + let _mco1 = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV1); + let _mco2 = Mco::new(p.MCO2, p.PC9, Mco2Source::PLL, McoPrescaler::DIV4); let mut led = Output::new(p.PB7, Level::High, Speed::Low); loop { diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index de8ddc29..0ea8b449 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs @@ -6,7 +6,7 @@ use embassy_executor::Spawner; use embassy_stm32::dcmi::{self, *}; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::i2c::I2c; -use embassy_stm32::rcc::{Mco, Mco1Source}; +use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; use embassy_stm32::time::khz; use embassy_stm32::{bind_interrupts, i2c, peripherals, Config}; use embassy_time::{Duration, Timer}; @@ -49,7 +49,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(config); defmt::info!("Hello World!"); - let mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, 3); + let mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV3); let mut led = Output::new(p.PE3, Level::High, Speed::Low); let cam_i2c = I2c::new( diff --git a/examples/stm32h7/src/bin/mco.rs b/examples/stm32h7/src/bin/mco.rs index 9d6d805a..de89aee2 100644 --- a/examples/stm32h7/src/bin/mco.rs +++ b/examples/stm32h7/src/bin/mco.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_stm32::rcc::{Mco, Mco1Source}; +use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) { let mut led = Output::new(p.PB14, Level::High, Speed::Low); - let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, 8); + let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV8); loop { info!("high"); diff --git a/examples/stm32l4/src/bin/mco.rs b/examples/stm32l4/src/bin/mco.rs index dea0c66e..8d35af78 100644 --- a/examples/stm32l4/src/bin/mco.rs +++ b/examples/stm32l4/src/bin/mco.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_stm32::rcc::{Mco, Mco1Source, McoClock}; +use embassy_stm32::rcc::{Mco, McoPrescaler, McoSource}; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let _mco = Mco::new(p.MCO, p.PA8, Mco1Source::Hsi16, McoClock::DIV1); + let _mco = Mco::new(p.MCO, p.PA8, McoSource::HSI16, McoPrescaler::DIV1); let mut led = Output::new(p.PB14, Level::High, Speed::Low); From 710874021a783768f5d2d3f712e095eba3bc1627 Mon Sep 17 00:00:00 2001 From: randi Date: Sat, 7 Oct 2023 12:22:31 +1300 Subject: [PATCH 42/95] Implemented Pwm trait for complementary pwm from embedded_hal --- embassy-stm32/src/timer/complementary_pwm.rs | 40 ++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 4f033e3a..0ab72734 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -122,6 +122,46 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { } } +impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { + type Channel = Channel; + type Time = Hertz; + type Duty = u16; + + fn disable(&mut self, channel: Self::Channel) { + self.inner.enable_complementary_channel(channel, false); + self.inner.enable_channel(channel, false); + } + + fn enable(&mut self, channel: Self::Channel) { + self.inner.enable_channel(channel, true); + self.inner.enable_complementary_channel(channel, true); + } + + fn get_period(&self) -> Self::Time { + self.inner.get_frequency().into() + } + + fn get_duty(&self, channel: Self::Channel) -> Self::Duty { + self.inner.get_compare_value(channel) + } + + fn get_max_duty(&self) -> Self::Duty { + self.inner.get_max_compare_value() + 1 + } + + fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { + assert!(duty <= self.get_max_duty()); + self.inner.set_compare_value(channel, duty) + } + + fn set_period

(&mut self, period: P) + where + P: Into, + { + self.inner.set_frequency(period.into()); + } +} + fn compute_dead_time_value(value: u16) -> (Ckd, u8) { /* Dead-time = T_clk * T_dts * T_dtg From 534eb960e9f7c9bb28cbd6ffe10b6cc43fd55ff7 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 6 Oct 2023 20:47:31 +0200 Subject: [PATCH 43/95] net: add support for dhcp hostname option. --- ci.sh | 2 +- embassy-net/Cargo.toml | 1 + embassy-net/src/lib.rs | 44 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index 46a48f6b..9038a066 100755 --- a/ci.sh +++ b/ci.sh @@ -36,7 +36,7 @@ cargo batch \ --- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \ - --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly,dhcpv4-hostname \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ieee802154 \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,medium-ieee802154 \ diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 89582dee..c2fffba8 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -33,6 +33,7 @@ udp = ["smoltcp/socket-udp"] tcp = ["smoltcp/socket-tcp"] dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"] dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"] +dhcpv4-hostname = ["dhcpv4"] proto-ipv4 = ["smoltcp/proto-ipv4"] proto-ipv6 = ["smoltcp/proto-ipv6"] medium-ethernet = ["smoltcp/medium-ethernet"] diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 297f0467..ef67935e 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -56,12 +56,22 @@ const LOCAL_PORT_MIN: u16 = 1025; const LOCAL_PORT_MAX: u16 = 65535; #[cfg(feature = "dns")] const MAX_QUERIES: usize = 4; +#[cfg(feature = "dhcpv4-hostname")] +const MAX_HOSTNAME_LEN: usize = 32; /// Memory resources needed for a network stack. pub struct StackResources { sockets: [SocketStorage<'static>; SOCK], #[cfg(feature = "dns")] queries: [Option; MAX_QUERIES], + #[cfg(feature = "dhcpv4-hostname")] + hostname: core::cell::UnsafeCell, +} + +#[cfg(feature = "dhcpv4-hostname")] +struct HostnameResources { + option: smoltcp::wire::DhcpOption<'static>, + data: [u8; MAX_HOSTNAME_LEN], } impl StackResources { @@ -73,6 +83,11 @@ impl StackResources { sockets: [SocketStorage::EMPTY; SOCK], #[cfg(feature = "dns")] queries: [INIT; MAX_QUERIES], + #[cfg(feature = "dhcpv4-hostname")] + hostname: core::cell::UnsafeCell::new(HostnameResources { + option: smoltcp::wire::DhcpOption { kind: 0, data: &[] }, + data: [0; MAX_HOSTNAME_LEN], + }), } } } @@ -104,6 +119,7 @@ pub struct StaticConfigV6 { /// DHCP configuration. #[cfg(feature = "dhcpv4")] #[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] pub struct DhcpConfig { /// Maximum lease duration. /// @@ -120,6 +136,9 @@ pub struct DhcpConfig { pub server_port: u16, /// Client port. This is almost always 68. Do not change unless you know what you're doing. pub client_port: u16, + /// Our hostname. This will be sent to the DHCP server as Option 12. + #[cfg(feature = "dhcpv4-hostname")] + pub hostname: Option>, } #[cfg(feature = "dhcpv4")] @@ -131,6 +150,8 @@ impl Default for DhcpConfig { ignore_naks: Default::default(), server_port: smoltcp::wire::DHCP_SERVER_PORT, client_port: smoltcp::wire::DHCP_CLIENT_PORT, + #[cfg(feature = "dhcpv4-hostname")] + hostname: None, } } } @@ -232,6 +253,8 @@ struct Inner { dns_socket: SocketHandle, #[cfg(feature = "dns")] dns_waker: WakerRegistration, + #[cfg(feature = "dhcpv4-hostname")] + hostname: &'static mut core::cell::UnsafeCell, } pub(crate) struct SocketStack { @@ -307,6 +330,8 @@ impl Stack { )), #[cfg(feature = "dns")] dns_waker: WakerRegistration::new(), + #[cfg(feature = "dhcpv4-hostname")] + hostname: &mut resources.hostname, }; #[cfg(feature = "proto-ipv4")] @@ -673,6 +698,25 @@ impl Inner { socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp)); socket.set_ports(c.server_port, c.client_port); socket.set_retry_config(c.retry_config); + + socket.set_outgoing_options(&[]); + #[cfg(feature = "dhcpv4-hostname")] + if let Some(h) = c.hostname { + // safety: we just did set_outgoing_options([]) so we know the socket is no longer holding a reference. + let hostname = unsafe { &mut *self.hostname.get() }; + + // create data + // safety: we know the buffer lives forever, new borrows the StackResources for 'static. + // also we won't modify it until next call to this function. + hostname.data[..h.len()].copy_from_slice(h.as_bytes()); + let data: &[u8] = &hostname.data[..h.len()]; + let data: &'static [u8] = unsafe { core::mem::transmute(data) }; + + // set the option. + hostname.option = smoltcp::wire::DhcpOption { data, kind: 12 }; + socket.set_outgoing_options(core::slice::from_ref(&hostname.option)); + } + socket.reset(); } _ => { From 022d870d616575805ace9b37ea87bae1fd90cb84 Mon Sep 17 00:00:00 2001 From: James Munns Date: Sat, 7 Oct 2023 01:33:43 +0200 Subject: [PATCH 44/95] Add missing derive --- embassy-rp/src/i2c.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index ea077335..77777ad3 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs @@ -12,7 +12,7 @@ use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::{interrupt, pac, peripherals, Peripheral}; /// I2C error abort reason -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum AbortReason { /// A bus operation was not acknowledged, e.g. due to the addressed device From 9090a78df4c3838ee8fdfd6641f5fea7d8e9906e Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 7 Oct 2023 01:33:43 +0200 Subject: [PATCH 45/95] ci: set target dir if not specified. --- ci.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index 9038a066..33222298 100755 --- a/ci.sh +++ b/ci.sh @@ -1,9 +1,12 @@ #!/bin/bash -set -euo pipefail +set -eo pipefail export RUSTFLAGS=-Dwarnings export DEFMT_LOG=trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info +if [[ -z "${CARGO_TARGET_DIR}" ]]; then + export CARGO_TARGET_DIR=target_ci +fi TARGET=$(rustc -vV | sed -n 's|host: ||p') From c6d53e7bce9a9f04b2d479a150c4e1aee1bb4ea8 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sat, 23 Sep 2023 17:34:08 +1200 Subject: [PATCH 46/95] rp2040: move in_ram helper outside of Flash's impl Allow it to be called from other modules. --- embassy-rp/src/flash.rs | 78 ++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 1c1c2449..8fb5542f 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs @@ -131,7 +131,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI let len = to - from; - unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len))? }; + unsafe { in_ram(|| ram_helpers::flash_range_erase(from, len))? }; Ok(()) } @@ -156,7 +156,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI let unaligned_offset = offset as usize - start; - unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } + unsafe { in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } } let remaining_len = bytes.len() - start_padding; @@ -174,12 +174,12 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI if bytes.as_ptr() as usize >= 0x2000_0000 { let aligned_data = &bytes[start_padding..end_padding]; - unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? } + unsafe { in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? } } else { for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) { let mut ram_buf = [0xFF_u8; PAGE_SIZE]; ram_buf.copy_from_slice(chunk); - unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? } + unsafe { in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? } aligned_offset += PAGE_SIZE; } } @@ -194,47 +194,15 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset); - unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } + unsafe { in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } } Ok(()) } - /// Make sure to uphold the contract points with rp2040-flash. - /// - interrupts must be disabled - /// - DMA must not access flash memory - unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> { - // Make sure we're running on CORE0 - let core_id: u32 = pac::SIO.cpuid().read(); - if core_id != 0 { - return Err(Error::InvalidCore); - } - - // Make sure CORE1 is paused during the entire duration of the RAM function - crate::multicore::pause_core1(); - - critical_section::with(|_| { - // Wait for all DMA channels in flash to finish before ram operation - const SRAM_LOWER: u32 = 0x2000_0000; - for n in 0..crate::dma::CHANNEL_COUNT { - let ch = crate::pac::DMA.ch(n); - while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {} - } - // Wait for completion of any background reads - while pac::XIP_CTRL.stream_ctr().read().0 > 0 {} - - // Run our flash operation in RAM - operation(); - }); - - // Resume CORE1 execution - crate::multicore::resume_core1(); - Ok(()) - } - /// Read SPI flash unique ID pub fn blocking_unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> { - unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid))? }; + unsafe { in_ram(|| ram_helpers::flash_unique_id(uid))? }; Ok(()) } @@ -242,7 +210,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI pub fn blocking_jedec_id(&mut self) -> Result { let mut jedec = None; unsafe { - self.in_ram(|| { + in_ram(|| { jedec.replace(ram_helpers::flash_jedec_id()); })?; }; @@ -871,6 +839,38 @@ mod ram_helpers { } } +/// Make sure to uphold the contract points with rp2040-flash. +/// - interrupts must be disabled +/// - DMA must not access flash memory +pub(crate) unsafe fn in_ram(operation: impl FnOnce()) -> Result<(), Error> { + // Make sure we're running on CORE0 + let core_id: u32 = pac::SIO.cpuid().read(); + if core_id != 0 { + return Err(Error::InvalidCore); + } + + // Make sure CORE1 is paused during the entire duration of the RAM function + crate::multicore::pause_core1(); + + critical_section::with(|_| { + // Wait for all DMA channels in flash to finish before ram operation + const SRAM_LOWER: u32 = 0x2000_0000; + for n in 0..crate::dma::CHANNEL_COUNT { + let ch = crate::pac::DMA.ch(n); + while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {} + } + // Wait for completion of any background reads + while pac::XIP_CTRL.stream_ctr().read().0 > 0 {} + + // Run our flash operation in RAM + operation(); + }); + + // Resume CORE1 execution + crate::multicore::resume_core1(); + Ok(()) +} + mod sealed { pub trait Instance {} pub trait Mode {} From 3e054a6f0d3ba018315f7cb7f0a373221e15737a Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sat, 23 Sep 2023 17:34:47 +1200 Subject: [PATCH 47/95] rp2040: implement BOOTSEL button support --- embassy-rp/src/bootsel.rs | 81 +++++++++++++++++++++++++++++++++++++++ embassy-rp/src/lib.rs | 1 + 2 files changed, 82 insertions(+) create mode 100644 embassy-rp/src/bootsel.rs diff --git a/embassy-rp/src/bootsel.rs b/embassy-rp/src/bootsel.rs new file mode 100644 index 00000000..69d620e8 --- /dev/null +++ b/embassy-rp/src/bootsel.rs @@ -0,0 +1,81 @@ +//! Boot Select button +//! +//! The RP2040 rom supports a BOOTSEL button that is used to enter the USB bootloader +//! if held during reset. To avoid wasting GPIO pins, the button is multiplexed onto +//! the CS pin of the QSPI flash, but that makes it somewhat expensive and complicated +//! to utilize outside of the rom's bootloader. +//! +//! This module provides functionality to poll BOOTSEL from an embassy application. + +use crate::flash::in_ram; + +/// Polls the BOOTSEL button. Returns true if the button is pressed. +/// +/// Polling isn't cheap, as this function waits for core 1 to finish it's current +/// task and for any DMAs from flash to complete +pub fn poll_bootsel() -> bool { + let mut cs_status = Default::default(); + + unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0"); + + // bootsel is active low, so invert + !cs_status.infrompad() +} + +mod ram_helpers { + use rp_pac::io::regs::GpioStatus; + + /// Temporally reconfigures the CS gpio and returns the GpioStatus. + + /// This function runs from RAM so it can disable flash XIP. + /// + /// # Safety + /// + /// The caller must ensure flash is idle and will remain idle. + /// This function must live in ram. It uses inline asm to avoid any + /// potential calls to ABI functions that might be in flash. + #[inline(never)] + #[link_section = ".data.ram_func"] + #[cfg(target_arch = "arm")] + pub unsafe fn read_cs_status() -> GpioStatus { + let result: u32; + + // Magic value, used as both OEOVER::DISABLE and delay loop counter + let magic = 0x2000; + + core::arch::asm!( + ".equiv GPIO_STATUS, 0x0", + ".equiv GPIO_CTRL, 0x4", + + "ldr {orig_ctrl}, [{cs_gpio}, $GPIO_CTRL]", + + // The BOOTSEL pulls the flash's CS line low though a 1K resistor. + // this is weak enough to avoid disrupting normal operation. + // But, if we disable CS's output drive and allow it to float... + "str {val}, [{cs_gpio}, $GPIO_CTRL]", + + // ...then wait for the state to settle... + "1:", // ~4000 cycle delay loop + "subs {val}, #8", + "bne 1b", + + // ...we can read the current state of bootsel + "ldr {val}, [{cs_gpio}, $GPIO_STATUS]", + + // Finally, restore CS to normal operation so XIP can continue + "str {orig_ctrl}, [{cs_gpio}, $GPIO_CTRL]", + + cs_gpio = in(reg) rp_pac::IO_QSPI.gpio(1).as_ptr(), + orig_ctrl = out(reg) _, + val = inout(reg) magic => result, + options(nostack), + ); + + core::mem::transmute(result) + } + + #[cfg(not(target_arch = "arm"))] + pub unsafe fn read_cs_status() -> GpioStatus { + unimplemented!() + } +} diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index e8f818bc..fb918920 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -10,6 +10,7 @@ mod critical_section_impl; mod intrinsics; pub mod adc; +pub mod bootsel; pub mod clocks; pub mod dma; pub mod flash; From d4ed8e5779d5e09ea57728a48fc8654d93b786f8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 7 Oct 2023 01:46:57 +0200 Subject: [PATCH 48/95] rp/bootsel: change it to a method on the peripheral. --- embassy-rp/src/bootsel.rs | 20 +++++++++++--------- embassy-rp/src/lib.rs | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/embassy-rp/src/bootsel.rs b/embassy-rp/src/bootsel.rs index 69d620e8..540255ae 100644 --- a/embassy-rp/src/bootsel.rs +++ b/embassy-rp/src/bootsel.rs @@ -9,17 +9,19 @@ use crate::flash::in_ram; -/// Polls the BOOTSEL button. Returns true if the button is pressed. -/// -/// Polling isn't cheap, as this function waits for core 1 to finish it's current -/// task and for any DMAs from flash to complete -pub fn poll_bootsel() -> bool { - let mut cs_status = Default::default(); +impl crate::peripherals::BOOTSEL { + /// Polls the BOOTSEL button. Returns true if the button is pressed. + /// + /// Polling isn't cheap, as this function waits for core 1 to finish it's current + /// task and for any DMAs from flash to complete + pub fn is_pressed(&mut self) -> bool { + let mut cs_status = Default::default(); - unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0"); + unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0"); - // bootsel is active low, so invert - !cs_status.infrompad() + // bootsel is active low, so invert + !cs_status.infrompad() + } } mod ram_helpers { diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index fb918920..2728395b 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -194,6 +194,7 @@ embassy_hal_internal::peripherals! { PIO1, WATCHDOG, + BOOTSEL, } macro_rules! select_bootloader { From b67b179933806f270465dcf5f246c605eba15dd9 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 7 Oct 2023 01:47:25 +0200 Subject: [PATCH 49/95] rp/bootsel: add test. --- tests/rp/src/bin/bootsel.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/rp/src/bin/bootsel.rs diff --git a/tests/rp/src/bin/bootsel.rs b/tests/rp/src/bin/bootsel.rs new file mode 100644 index 00000000..df1ed8d2 --- /dev/null +++ b/tests/rp/src/bin/bootsel.rs @@ -0,0 +1,26 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] +teleprobe_meta::target!(b"rpi-pico"); + +use defmt::{assert_eq, *}; +use embassy_executor::Spawner; +use embassy_time::{Duration, Timer}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut p = embassy_rp::init(Default::default()); + info!("Hello World!"); + + // add some delay to give an attached debug probe time to parse the + // defmt RTT header. Reading that header might touch flash memory, which + // interferes with flash write operations. + // https://github.com/knurling-rs/defmt/pull/683 + Timer::after(Duration::from_millis(10)).await; + + assert_eq!(p.BOOTSEL.is_pressed(), false); + + info!("Test OK"); + cortex_m::asm::bkpt(); +} From 2e5ab7981ef5d7681be91b0c29f830872c77eeb0 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 8 Oct 2023 18:27:36 -0500 Subject: [PATCH 50/95] stm32: update metapac --- embassy-stm32/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 20c5155a..18010fb9 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-a7bf7f02d1e0bc720c24dbb8881677a298890365" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-eecd80c34d4a3035be31404857e6c6e115376f41" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -78,7 +78,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-a7bf7f02d1e0bc720c24dbb8881677a298890365", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-eecd80c34d4a3035be31404857e6c6e115376f41", default-features = false, features = ["metadata"]} [features] From 6186fe08070c5f497d72586640db287193b41894 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 9 Oct 2023 02:48:22 +0200 Subject: [PATCH 51/95] stm32/rcc: use PLL enums from PAC. --- embassy-stm32/Cargo.toml | 5 +- embassy-stm32/build.rs | 99 +++++ embassy-stm32/src/rcc/bus.rs | 56 --- embassy-stm32/src/rcc/c0.rs | 2 +- embassy-stm32/src/rcc/f2.rs | 161 +------- embassy-stm32/src/rcc/f4.rs | 10 +- embassy-stm32/src/rcc/f7.rs | 10 +- embassy-stm32/src/rcc/g0.rs | 165 ++------ embassy-stm32/src/rcc/g4.rs | 197 +--------- embassy-stm32/src/rcc/h.rs | 53 ++- embassy-stm32/src/rcc/l0.rs | 2 +- embassy-stm32/src/rcc/l1.rs | 2 +- embassy-stm32/src/rcc/l4.rs | 334 ++++------------- embassy-stm32/src/rcc/l5.rs | 351 ++++++------------ embassy-stm32/src/rcc/mod.rs | 1 - embassy-stm32/src/rcc/u5.rs | 276 ++++---------- embassy-stm32/src/rcc/wb.rs | 2 +- embassy-stm32/src/rcc/wl.rs | 2 +- examples/stm32f2/src/bin/pll.rs | 6 +- examples/stm32g4/src/bin/adc.rs | 6 +- examples/stm32g4/src/bin/pll.rs | 6 +- examples/stm32g4/src/bin/usb_serial.rs | 8 +- examples/stm32h5/src/bin/eth.rs | 12 +- examples/stm32h5/src/bin/usb_serial.rs | 10 +- examples/stm32h7/src/bin/adc.rs | 14 +- examples/stm32h7/src/bin/camera.rs | 8 +- examples/stm32h7/src/bin/dac.rs | 14 +- examples/stm32h7/src/bin/dac_dma.rs | 14 +- examples/stm32h7/src/bin/eth.rs | 6 +- examples/stm32h7/src/bin/eth_client.rs | 6 +- examples/stm32h7/src/bin/fmc.rs | 8 +- .../stm32h7/src/bin/low_level_timer_api.rs | 8 +- examples/stm32h7/src/bin/pwm.rs | 6 +- examples/stm32h7/src/bin/sdmmc.rs | 8 +- examples/stm32h7/src/bin/spi.rs | 8 +- examples/stm32h7/src/bin/spi_dma.rs | 8 +- examples/stm32h7/src/bin/usb_serial.rs | 6 +- examples/stm32l4/src/bin/rng.rs | 10 +- examples/stm32l4/src/bin/rtc.rs | 8 +- .../src/bin/spe_adin1110_http_server.rs | 8 +- examples/stm32l4/src/bin/usb_serial.rs | 2 +- examples/stm32l5/src/bin/rng.rs | 10 +- examples/stm32l5/src/bin/usb_ethernet.rs | 2 +- examples/stm32l5/src/bin/usb_hid_mouse.rs | 2 +- examples/stm32l5/src/bin/usb_serial.rs | 2 +- examples/stm32u5/src/bin/usb_serial.rs | 6 +- tests/stm32/src/common.rs | 42 +-- 47 files changed, 599 insertions(+), 1383 deletions(-) delete mode 100644 embassy-stm32/src/rcc/bus.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 18010fb9..70e8f2e2 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,12 +59,11 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-eecd80c34d4a3035be31404857e6c6e115376f41" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e89b8cfc30e480036aaf502f34c874ee42d68026" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" stm32-fmc = "0.3.0" -seq-macro = "0.3.0" cfg-if = "1.0.0" embedded-io = { version = "0.6.0" } embedded-io-async = { version = "0.6.0", optional = true } @@ -78,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-eecd80c34d4a3035be31404857e6c6e115376f41", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e89b8cfc30e480036aaf502f34c874ee42d68026", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 3f85d9e6..643f1b6e 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -893,6 +893,105 @@ fn main() { } } + // ======== + // Generate Div/Mul impls for RCC prescalers/dividers/multipliers. + let rcc_registers = METADATA + .peripherals + .iter() + .filter_map(|p| p.registers.as_ref()) + .find(|r| r.kind == "rcc") + .unwrap() + .ir; + + for e in rcc_registers.enums { + fn is_rcc_name(e: &str) -> bool { + match e { + "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true, + "Timpre" | "Pllrclkpre" => false, + e if e.ends_with("pre") || e.ends_with("div") || e.ends_with("mul") => true, + _ => false, + } + } + + #[derive(Copy, Clone, Debug)] + struct Frac { + num: u32, + denom: u32, + } + + impl Frac { + fn simplify(self) -> Self { + let d = gcd(self.num, self.denom); + Self { + num: self.num / d, + denom: self.denom / d, + } + } + } + + fn gcd(a: u32, b: u32) -> u32 { + if b == 0 { + return a; + } + gcd(b, a % b) + } + + fn parse_num(n: &str) -> Result { + for prefix in ["DIV", "MUL"] { + if let Some(n) = n.strip_prefix(prefix) { + let exponent = n.find('_').map(|e| n.len() - 1 - e).unwrap_or(0) as u32; + let mantissa = n.replace('_', "").parse().map_err(|_| ())?; + let f = Frac { + num: mantissa, + denom: 10u32.pow(exponent), + }; + return Ok(f.simplify()); + } + } + Err(()) + } + + if is_rcc_name(e.name) { + let enum_name = format_ident!("{}", e.name); + let mut muls = Vec::new(); + let mut divs = Vec::new(); + for v in e.variants { + let Ok(val) = parse_num(v.name) else { + panic!("could not parse mul/div. enum={} variant={}", e.name, v.name) + }; + let variant_name = format_ident!("{}", v.name); + let variant = quote!(crate::pac::rcc::vals::#enum_name::#variant_name); + let num = val.num; + let denom = val.denom; + muls.push(quote!(#variant => self * #num / #denom,)); + divs.push(quote!(#variant => self * #denom / #num,)); + } + + g.extend(quote! { + impl core::ops::Div for crate::time::Hertz { + type Output = crate::time::Hertz; + fn div(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output { + match rhs { + #(#divs)* + #[allow(unreachable_patterns)] + _ => unreachable!(), + } + } + } + impl core::ops::Mul for crate::time::Hertz { + type Output = crate::time::Hertz; + fn mul(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output { + match rhs { + #(#muls)* + #[allow(unreachable_patterns)] + _ => unreachable!(), + } + } + } + }); + } + } + // ======== // Write foreach_foo! macrotables diff --git a/embassy-stm32/src/rcc/bus.rs b/embassy-stm32/src/rcc/bus.rs deleted file mode 100644 index 495cf7fe..00000000 --- a/embassy-stm32/src/rcc/bus.rs +++ /dev/null @@ -1,56 +0,0 @@ -use core::ops::Div; - -#[allow(unused_imports)] -use crate::pac::rcc; -pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; -use crate::time::Hertz; - -impl Div for Hertz { - type Output = Hertz; - - fn div(self, rhs: AHBPrescaler) -> Self::Output { - let divisor = match rhs { - AHBPrescaler::DIV1 => 1, - AHBPrescaler::DIV2 => 2, - #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] - AHBPrescaler::DIV3 => 3, - AHBPrescaler::DIV4 => 4, - #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] - AHBPrescaler::DIV5 => 5, - #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] - AHBPrescaler::DIV6 => 6, - AHBPrescaler::DIV8 => 8, - #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] - AHBPrescaler::DIV10 => 10, - AHBPrescaler::DIV16 => 16, - #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] - AHBPrescaler::DIV32 => 32, - #[cfg(not(rcc_wba))] - AHBPrescaler::DIV64 => 64, - #[cfg(not(rcc_wba))] - AHBPrescaler::DIV128 => 128, - #[cfg(not(rcc_wba))] - AHBPrescaler::DIV256 => 256, - #[cfg(not(rcc_wba))] - AHBPrescaler::DIV512 => 512, - _ => unreachable!(), - }; - Hertz(self.0 / divisor) - } -} - -impl Div for Hertz { - type Output = Hertz; - - fn div(self, rhs: APBPrescaler) -> Self::Output { - let divisor = match rhs { - APBPrescaler::DIV1 => 1, - APBPrescaler::DIV2 => 2, - APBPrescaler::DIV4 => 4, - APBPrescaler::DIV8 => 8, - APBPrescaler::DIV16 => 16, - _ => unreachable!(), - }; - Hertz(self.0 / divisor) - } -} diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index 8f45e7c0..efa56de7 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -1,5 +1,5 @@ -pub use super::bus::{AHBPrescaler, APBPrescaler}; use crate::pac::flash::vals::Latency; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 44de5bf1..07b816bf 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -1,9 +1,9 @@ -use core::convert::TryFrom; -use core::ops::{Div, Mul}; - -pub use super::bus::{AHBPrescaler, APBPrescaler}; use crate::pac::flash::vals::Latency; -use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw}; +use crate::pac::rcc::vals::Sw; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Pllm as PLLPreDiv, Plln as PLLMul, Pllp as PLLPDiv, Pllq as PLLQDiv, Pllsrc as PLLSrc, + Ppre as APBPrescaler, +}; use crate::pac::{FLASH, RCC}; use crate::rcc::bd::BackupDomain; use crate::rcc::{set_freqs, Clocks}; @@ -43,17 +43,17 @@ pub enum HSESrc { pub struct PLLConfig { pub pre_div: PLLPreDiv, pub mul: PLLMul, - pub main_div: PLLMainDiv, - pub pll48_div: PLL48Div, + pub p_div: PLLPDiv, + pub q_div: PLLQDiv, } impl Default for PLLConfig { fn default() -> Self { PLLConfig { - pre_div: PLLPreDiv(16), - mul: PLLMul(192), - main_div: PLLMainDiv::Div2, - pll48_div: PLL48Div(4), + pre_div: PLLPreDiv::DIV16, + mul: PLLMul::MUL192, + p_div: PLLPDiv::DIV2, + q_div: PLLQDiv::DIV4, } } } @@ -61,9 +61,9 @@ impl Default for PLLConfig { impl PLLConfig { pub fn clocks(&self, src_freq: Hertz) -> PLLClocks { let in_freq = src_freq / self.pre_div; - let vco_freq = Hertz((src_freq.0 as u64 * self.mul.0 as u64 / self.pre_div.0 as u64) as u32); - let main_freq = vco_freq / self.main_div; - let pll48_freq = vco_freq / self.pll48_div; + let vco_freq = src_freq / self.pre_div * self.mul; + let main_freq = vco_freq / self.p_div; + let pll48_freq = vco_freq / self.q_div; PLLClocks { in_freq, vco_freq, @@ -72,129 +72,6 @@ impl PLLConfig { } } } - -/// Clock source for both main PLL and PLLI2S -#[derive(Clone, Copy, PartialEq)] -pub enum PLLSrc { - HSE, - HSI, -} - -impl Into for PLLSrc { - fn into(self) -> Pllsrc { - match self { - PLLSrc::HSE => Pllsrc::HSE, - PLLSrc::HSI => Pllsrc::HSI, - } - } -} - -/// Division factor for both main PLL and PLLI2S -#[derive(Clone, Copy, PartialEq)] -#[repr(transparent)] -pub struct PLLPreDiv(u8); - -impl TryFrom for PLLPreDiv { - type Error = &'static str; - - fn try_from(value: u8) -> Result { - match value { - 2..=63 => Ok(PLLPreDiv(value)), - _ => Err("PLLPreDiv must be within range 2..=63"), - } - } -} - -impl Div for Hertz { - type Output = Hertz; - - fn div(self, rhs: PLLPreDiv) -> Self::Output { - Hertz(self.0 / u32::from(rhs.0)) - } -} - -/// Multiplication factor for main PLL -#[derive(Clone, Copy, PartialEq)] -#[repr(transparent)] -pub struct PLLMul(u16); - -impl Mul for Hertz { - type Output = Hertz; - - fn mul(self, rhs: PLLMul) -> Self::Output { - Hertz(self.0 * u32::from(rhs.0)) - } -} - -impl TryFrom for PLLMul { - type Error = &'static str; - - fn try_from(value: u16) -> Result { - match value { - 192..=432 => Ok(PLLMul(value)), - _ => Err("PLLMul must be within range 192..=432"), - } - } -} - -/// PLL division factor for the main system clock -#[derive(Clone, Copy, PartialEq)] -pub enum PLLMainDiv { - Div2, - Div4, - Div6, - Div8, -} - -impl Into for PLLMainDiv { - fn into(self) -> Pllp { - match self { - PLLMainDiv::Div2 => Pllp::DIV2, - PLLMainDiv::Div4 => Pllp::DIV4, - PLLMainDiv::Div6 => Pllp::DIV6, - PLLMainDiv::Div8 => Pllp::DIV8, - } - } -} - -impl Div for Hertz { - type Output = Hertz; - - fn div(self, rhs: PLLMainDiv) -> Self::Output { - let divisor = match rhs { - PLLMainDiv::Div2 => 2, - PLLMainDiv::Div4 => 4, - PLLMainDiv::Div6 => 6, - PLLMainDiv::Div8 => 8, - }; - Hertz(self.0 / divisor) - } -} - -/// PLL division factor for USB OTG FS / SDIO / RNG -#[derive(Clone, Copy, PartialEq)] -#[repr(transparent)] -pub struct PLL48Div(u8); - -impl Div for Hertz { - type Output = Hertz; - - fn div(self, rhs: PLL48Div) -> Self::Output { - Hertz(self.0 / u32::from(rhs.0)) - } -} - -impl TryFrom for PLL48Div { - type Error = &'static str; - - fn try_from(value: u8) -> Result { - match value { - 2..=15 => Ok(PLL48Div(value)), - _ => Err("PLL48Div must be within range 2..=15"), - } - } -} - #[derive(Clone, Copy, PartialEq)] pub struct PLLClocks { pub in_freq: Hertz, @@ -367,11 +244,11 @@ pub(crate) unsafe fn init(config: Config) { assert!(pll_clocks.pll48_freq <= Hertz(48_000_000)); RCC.pllcfgr().write(|w| { - w.set_pllsrc(config.pll_mux.into()); - w.set_pllm(config.pll.pre_div.0); - w.set_plln(config.pll.mul.0); - w.set_pllp(config.pll.main_div.into()); - w.set_pllq(config.pll.pll48_div.0); + w.set_pllsrc(config.pll_mux); + w.set_pllm(config.pll.pre_div); + w.set_plln(config.pll.mul); + w.set_pllp(config.pll.p_div); + w.set_pllq(config.pll.q_div); }); let (sys_clk, sw) = match config.mux { diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index ad106ce3..754a0d57 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -1,3 +1,5 @@ +use stm32_metapac::rcc::vals::{Pllm, Plln, Pllq, Pllr}; + use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; @@ -170,12 +172,12 @@ fn setup_pll( let real_pll48clk = vco_in * plln / pllq; RCC.pllcfgr().modify(|w| { - w.set_pllm(pllm as u8); - w.set_plln(plln as u16); + w.set_pllm(Pllm::from_bits(pllm as u8)); + w.set_plln(Plln::from_bits(plln as u16)); w.set_pllp(Pllp::from_bits(pllp as u8)); - w.set_pllq(pllq as u8); + w.set_pllq(Pllq::from_bits(pllq as u8)); w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); - w.set_pllr(0); + w.set_pllr(Pllr::from_bits(0)); }); let real_pllsysclk = vco_in * plln / sysclk_div; diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs index f32559e2..565f6aa9 100644 --- a/embassy-stm32/src/rcc/f7.rs +++ b/embassy-stm32/src/rcc/f7.rs @@ -1,5 +1,5 @@ use crate::pac::pwr::vals::Vos; -use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; +use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; @@ -29,8 +29,6 @@ pub struct Config { } fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option, pll48clk: bool) -> PllResults { - use crate::pac::rcc::vals::{Pllp, Pllsrc}; - let sysclk = pllsysclk.unwrap_or(pllsrcclk); if pllsysclk.is_none() && !pll48clk { RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc::from_bits(use_hse as u8))); @@ -84,10 +82,10 @@ fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option, pll48clk: bo let real_pll48clk = vco_in * plln / pllq; RCC.pllcfgr().modify(|w| { - w.set_pllm(pllm as u8); - w.set_plln(plln as u16); + w.set_pllm(Pllm::from_bits(pllm as u8)); + w.set_plln(Plln::from_bits(plln as u16)); w.set_pllp(Pllp::from_bits(pllp as u8)); - w.set_pllq(pllq as u8); + w.set_pllq(Pllq::from_bits(pllq as u8)); w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); }); diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 7f0a2c7f..5ac40911 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -1,6 +1,6 @@ -pub use super::bus::{AHBPrescaler, APBPrescaler}; use crate::pac::flash::vals::Latency; -use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw}; +use crate::pac::rcc::vals::{self, Hsidiv, Sw}; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -60,15 +60,15 @@ pub struct PllConfig { /// The initial divisor of that clock signal pub m: Pllm, /// The PLL VCO multiplier, which must be in the range `8..=86`. - pub n: u8, + pub n: Plln, /// The final divisor for `PLLRCLK` output which drives the system clock pub r: Pllr, /// The divisor for the `PLLQCLK` output, if desired - pub q: Option, + pub q: Option, /// The divisor for the `PLLPCLK` output, if desired - pub p: Option, + pub p: Option, } impl Default for PllConfig { @@ -77,9 +77,9 @@ impl Default for PllConfig { // HSI16 / 1 * 8 / 2 = 64 MHz PllConfig { source: PllSrc::HSI16, - m: Pllm::Div1, - n: 8, - r: Pllr::Div2, + m: Pllm::DIV1, + n: Plln::MUL8, + r: Pllr::DIV2, q: None, p: None, } @@ -92,87 +92,6 @@ pub enum PllSrc { HSE(Hertz), } -#[derive(Clone, Copy)] -pub enum Pllm { - Div1, - Div2, - Div3, - Div4, - Div5, - Div6, - Div7, - Div8, -} - -impl From for u8 { - fn from(v: Pllm) -> Self { - match v { - Pllm::Div1 => 0b000, - Pllm::Div2 => 0b001, - Pllm::Div3 => 0b010, - Pllm::Div4 => 0b011, - Pllm::Div5 => 0b100, - Pllm::Div6 => 0b101, - Pllm::Div7 => 0b110, - Pllm::Div8 => 0b111, - } - } -} - -impl From for u32 { - fn from(v: Pllm) -> Self { - match v { - Pllm::Div1 => 1, - Pllm::Div2 => 2, - Pllm::Div3 => 3, - Pllm::Div4 => 4, - Pllm::Div5 => 5, - Pllm::Div6 => 6, - Pllm::Div7 => 7, - Pllm::Div8 => 8, - } - } -} - -#[derive(Clone, Copy)] -pub enum Pllr { - Div2, - Div3, - Div4, - Div5, - Div6, - Div7, - Div8, -} - -impl From for u8 { - fn from(v: Pllr) -> Self { - match v { - Pllr::Div2 => 0b000, - Pllr::Div3 => 0b001, - Pllr::Div4 => 0b010, - Pllr::Div5 => 0b011, - Pllr::Div6 => 0b101, - Pllr::Div7 => 0b110, - Pllr::Div8 => 0b111, - } - } -} - -impl From for u32 { - fn from(v: Pllr) -> Self { - match v { - Pllr::Div2 => 2, - Pllr::Div3 => 3, - Pllr::Div4 => 4, - Pllr::Div5 => 5, - Pllr::Div6 => 6, - Pllr::Div7 => 7, - Pllr::Div8 => 8, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -194,29 +113,28 @@ impl Default for Config { } impl PllConfig { - pub(crate) fn init(self) -> u32 { - assert!(self.n >= 8 && self.n <= 86); + pub(crate) fn init(self) -> Hertz { let (src, input_freq) = match self.source { - PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ.0), - PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq.0), + PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ), + PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq), }; - let m_freq = input_freq / u32::from(self.m); + let m_freq = input_freq / self.m; // RM0454 § 5.4.4: // > Caution: The software must set these bits so that the PLL input frequency after the // > /M divider is between 2.66 and 16 MHz. - debug_assert!(m_freq >= 2_660_000 && m_freq <= 16_000_000); + debug_assert!(m_freq.0 >= 2_660_000 && m_freq.0 <= 16_000_000); let n_freq = m_freq * self.n as u32; // RM0454 § 5.4.4: // > Caution: The software must set these bits so that the VCO output frequency is between // > 64 and 344 MHz. - debug_assert!(n_freq >= 64_000_000 && n_freq <= 344_000_000); + debug_assert!(n_freq.0 >= 64_000_000 && n_freq.0 <= 344_000_000); - let r_freq = n_freq / u32::from(self.r); + let r_freq = n_freq / self.r; // RM0454 § 5.4.4: // > Caution: The software must set this bitfield so as not to exceed 64 MHz on this clock. - debug_assert!(r_freq <= 64_000_000); + debug_assert!(r_freq.0 <= 64_000_000); // RM0454 § 5.2.3: // > To modify the PLL configuration, proceed as follows: @@ -239,25 +157,16 @@ impl PllConfig { } } - // Configure PLLSYSCFGR - RCC.pllsyscfgr().modify(|w| { - w.set_pllr(u8::from(self.r)); + // Configure PLLCFGR + RCC.pllcfgr().modify(|w| { + w.set_pllr(self.r); w.set_pllren(false); - - if let Some(q) = self.q { - w.set_pllq(u8::from(q)); - } + w.set_pllq(self.q.unwrap_or(Pllq::DIV2)); w.set_pllqen(false); - - if let Some(p) = self.p { - w.set_pllp(u8::from(p)); - } + w.set_pllp(self.p.unwrap_or(Pllp::DIV2)); w.set_pllpen(false); - w.set_plln(self.n); - - w.set_pllm(self.m as u8); - + w.set_pllm(self.m); w.set_pllsrc(src) }); @@ -269,7 +178,7 @@ impl PllConfig { // > 5. Enable the desired PLL outputs by configuring PLLPEN, PLLQEN, and PLLREN in PLL // > configuration register (RCC_PLLCFGR). - RCC.pllsyscfgr().modify(|w| { + RCC.pllcfgr().modify(|w| { // We'll use R for system clock, so enable that unconditionally w.set_pllren(true); @@ -293,14 +202,14 @@ pub(crate) unsafe fn init(config: Config) { }); while !RCC.cr().read().hsirdy() {} - (HSI_FREQ.0 >> div.to_bits(), Sw::HSI) + (HSI_FREQ / div, Sw::HSI) } ClockSrc::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - (freq.0, Sw::HSE) + (freq, Sw::HSE) } ClockSrc::PLL(pll) => { let freq = pll.init(); @@ -310,15 +219,15 @@ pub(crate) unsafe fn init(config: Config) { // Enable LSI RCC.csr().write(|w| w.set_lsion(true)); while !RCC.csr().read().lsirdy() {} - (LSI_FREQ.0, Sw::LSI) + (LSI_FREQ, Sw::LSI) } }; // Determine the flash latency implied by the target clock speed // RM0454 § 3.3.4: - let target_flash_latency = if sys_clk <= 24_000_000 { + let target_flash_latency = if sys_clk.0 <= 24_000_000 { Latency::WS0 - } else if sys_clk <= 48_000_000 { + } else if sys_clk.0 <= 48_000_000 { Latency::WS1 } else { Latency::WS2 @@ -374,27 +283,25 @@ pub(crate) unsafe fn init(config: Config) { FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); } - let ahb_freq = Hertz(sys_clk) / config.ahb_pre; + let ahb_freq = sys_clk / config.ahb_pre; let (apb_freq, apb_tim_freq) = match config.apb_pre { - APBPrescaler::DIV1 => (ahb_freq.0, ahb_freq.0), + APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq.0 / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; if config.low_power_run { - assert!(sys_clk <= 2_000_000); + assert!(sys_clk.0 <= 2_000_000); PWR.cr1().modify(|w| w.set_lpr(true)); } set_freqs(Clocks { - sys: Hertz(sys_clk), + sys: sys_clk, ahb1: ahb_freq, - apb1: Hertz(apb_freq), - apb1_tim: Hertz(apb_tim_freq), + apb1: apb_freq, + apb1_tim: apb_tim_freq, }); } diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 41bebc91..08ccc5fe 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -2,7 +2,9 @@ use stm32_metapac::flash::vals::Latency; use stm32_metapac::rcc::vals::{Adcsel, Pllsrc, Sw}; use stm32_metapac::FLASH; -pub use super::bus::{AHBPrescaler, APBPrescaler}; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Pllm as PllM, Plln as PllN, Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler, +}; use crate::pac::{PWR, RCC}; use crate::rcc::sealed::RccPeripheral; use crate::rcc::{set_freqs, Clocks}; @@ -61,181 +63,6 @@ impl Into for PllSrc { } } -seq_macro::seq!(P in 2..=31 { - /// Output divider for the PLL P output. - #[derive(Clone, Copy)] - pub enum PllP { - // Note: If PLL P is set to 0 the PLLP bit controls the output division. There does not seem to - // a good reason to do this so the API does not support it. - // Div1 is invalid - #( - Div~P, - )* - } - - impl From for u8 { - /// Returns the register value for the P output divider. - fn from(val: PllP) -> u8 { - match val { - #( - PllP::Div~P => P, - )* - } - } - } -}); - -impl PllP { - /// Returns the numeric value of the P output divider. - pub fn to_div(self) -> u32 { - let val: u8 = self.into(); - val as u32 - } -} - -/// Output divider for the PLL Q output. -#[derive(Clone, Copy)] -pub enum PllQ { - Div2, - Div4, - Div6, - Div8, -} - -impl PllQ { - /// Returns the numeric value of the Q output divider. - pub fn to_div(self) -> u32 { - let val: u8 = self.into(); - (val as u32 + 1) * 2 - } -} - -impl From for u8 { - /// Returns the register value for the Q output divider. - fn from(val: PllQ) -> u8 { - match val { - PllQ::Div2 => 0b00, - PllQ::Div4 => 0b01, - PllQ::Div6 => 0b10, - PllQ::Div8 => 0b11, - } - } -} - -/// Output divider for the PLL R output. -#[derive(Clone, Copy)] -pub enum PllR { - Div2, - Div4, - Div6, - Div8, -} - -impl PllR { - /// Returns the numeric value of the R output divider. - pub fn to_div(self) -> u32 { - let val: u8 = self.into(); - (val as u32 + 1) * 2 - } -} - -impl From for u8 { - /// Returns the register value for the R output divider. - fn from(val: PllR) -> u8 { - match val { - PllR::Div2 => 0b00, - PllR::Div4 => 0b01, - PllR::Div6 => 0b10, - PllR::Div8 => 0b11, - } - } -} - -seq_macro::seq!(N in 8..=127 { - /// Multiplication factor for the PLL VCO input clock. - #[derive(Clone, Copy)] - pub enum PllN { - #( - Mul~N, - )* - } - - impl From for u8 { - /// Returns the register value for the N multiplication factor. - fn from(val: PllN) -> u8 { - match val { - #( - PllN::Mul~N => N, - )* - } - } - } - - impl PllN { - /// Returns the numeric value of the N multiplication factor. - pub fn to_mul(self) -> u32 { - match self { - #( - PllN::Mul~N => N, - )* - } - } - } -}); - -/// PLL Pre-division. This must be set such that the PLL input is between 2.66 MHz and 16 MHz. -#[derive(Copy, Clone)] -pub enum PllM { - Div1, - Div2, - Div3, - Div4, - Div5, - Div6, - Div7, - Div8, - Div9, - Div10, - Div11, - Div12, - Div13, - Div14, - Div15, - Div16, -} - -impl PllM { - /// Returns the numeric value of the M pre-division. - pub fn to_div(self) -> u32 { - let val: u8 = self.into(); - val as u32 + 1 - } -} - -impl From for u8 { - /// Returns the register value for the M pre-division. - fn from(val: PllM) -> u8 { - match val { - PllM::Div1 => 0b0000, - PllM::Div2 => 0b0001, - PllM::Div3 => 0b0010, - PllM::Div4 => 0b0011, - PllM::Div5 => 0b0100, - PllM::Div6 => 0b0101, - PllM::Div7 => 0b0110, - PllM::Div8 => 0b0111, - PllM::Div9 => 0b1000, - PllM::Div10 => 0b1001, - PllM::Div11 => 0b1010, - PllM::Div12 => 0b1011, - PllM::Div13 => 0b1100, - PllM::Div14 => 0b1101, - PllM::Div15 => 0b1110, - PllM::Div16 => 0b1111, - } - } -} - /// PLL Configuration /// /// Use this struct to configure the PLL source, input frequency, multiplication factor, and output @@ -360,12 +187,12 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - HSI_FREQ.0 + HSI_FREQ } PllSrc::HSE(freq) => { RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - freq.0 + freq } }; @@ -373,7 +200,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_pllon(false)); while RCC.cr().read().pllrdy() {} - let internal_freq = src_freq / pll_config.prediv_m.to_div() * pll_config.mul_n.to_mul(); + let internal_freq = src_freq / pll_config.prediv_m * pll_config.mul_n; RCC.pllcfgr().write(|w| { w.set_plln(pll_config.mul_n.into()); @@ -383,26 +210,26 @@ pub(crate) unsafe fn init(config: Config) { let pll_p_freq = pll_config.div_p.map(|div_p| { RCC.pllcfgr().modify(|w| { - w.set_pllpdiv(div_p.into()); + w.set_pllp(div_p); w.set_pllpen(true); }); - Hertz(internal_freq / div_p.to_div()) + internal_freq / div_p }); let pll_q_freq = pll_config.div_q.map(|div_q| { RCC.pllcfgr().modify(|w| { - w.set_pllq(div_q.into()); + w.set_pllq(div_q); w.set_pllqen(true); }); - Hertz(internal_freq / div_q.to_div()) + internal_freq / div_q }); let pll_r_freq = pll_config.div_r.map(|div_r| { RCC.pllcfgr().modify(|w| { - w.set_pllr(div_r.into()); + w.set_pllr(div_r); w.set_pllren(true); }); - Hertz(internal_freq / div_r.to_div()) + internal_freq / div_r }); // Enable the PLL diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 5f9cc1c8..a11fd473 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -6,8 +6,8 @@ use crate::pac::pwr::vals::Vos; pub use crate::pac::rcc::vals::Adcdacsel as AdcClockSource; #[cfg(stm32h7)] pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; -pub use crate::pac::rcc::vals::Ckpersel as PerClockSource; use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre}; +pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul}; use crate::pac::{FLASH, PWR, RCC}; #[cfg(stm32h7)] use crate::rcc::bd::{BackupDomain, LseCfg, RtcClockSource}; @@ -34,7 +34,7 @@ const VCO_WIDE_RANGE: RangeInclusive = 192_000_000..=836_000_000; #[cfg(any(pwr_h7rm0399, pwr_h7rm0433))] const VCO_WIDE_RANGE: RangeInclusive = 192_000_000..=960_000_000; -pub use super::bus::{AHBPrescaler, APBPrescaler}; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; #[derive(Clone, Copy, Eq, PartialEq)] pub enum VoltageScale { @@ -109,19 +109,19 @@ pub struct Pll { #[cfg(stm32h5)] pub source: PllSource, - /// PLL pre-divider (DIVM). Must be between 1 and 63. - pub prediv: u8, + /// PLL pre-divider (DIVM). + pub prediv: PllPreDiv, - /// PLL multiplication factor. Must be between 4 and 512. - pub mul: u16, + /// PLL multiplication factor. + pub mul: PllMul, - /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128. + /// PLL P division factor. If None, PLL P output is disabled. /// On PLL1, it must be even (in particular, it cannot be 1.) - pub divp: Option, - /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128. - pub divq: Option, - /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128. - pub divr: Option, + pub divp: Option, + /// PLL Q division factor. If None, PLL Q output is disabled. + pub divq: Option, + /// PLL R division factor. If None, PLL R output is disabled. + pub divr: Option, } fn apb_div_tim(apb: &APBPrescaler, clk: Hertz, tim: TimerPrescaler) -> Hertz { @@ -604,9 +604,9 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { // "To save power when PLL1 is not used, the value of PLL1M must be set to 0."" #[cfg(stm32h7)] - RCC.pllckselr().write(|w| w.set_divm(num, 0)); + RCC.pllckselr().write(|w| w.set_divm(num, PllPreDiv::from_bits(0))); #[cfg(stm32h5)] - RCC.pllcfgr(num).write(|w| w.set_divm(0)); + RCC.pllcfgr(num).write(|w| w.set_divm(PllPreDiv::from_bits(0))); return PllOutput { p: None, @@ -615,9 +615,6 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { }; }; - assert!(1 <= config.prediv && config.prediv <= 63); - assert!(4 <= config.mul && config.mul <= 512); - #[cfg(stm32h5)] let source = config.source; #[cfg(stm32h7)] @@ -653,22 +650,16 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { }; let p = config.divp.map(|div| { - assert!(1 <= div && div <= 128); if num == 0 { // on PLL1, DIVP must be even. - assert!(div % 2 == 0); + // The enum value is 1 less than the divider, so check it's odd. + assert!(div.to_bits() % 2 == 1); } vco_clk / div }); - let q = config.divq.map(|div| { - assert!(1 <= div && div <= 128); - vco_clk / div - }); - let r = config.divr.map(|div| { - assert!(1 <= div && div <= 128); - vco_clk / div - }); + let q = config.divq.map(|div| vco_clk / div); + let r = config.divr.map(|div| vco_clk / div); #[cfg(stm32h5)] RCC.pllcfgr(num).write(|w| { @@ -699,10 +690,10 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { } RCC.plldivr(num).write(|w| { - w.set_plln(config.mul - 1); - w.set_pllp((config.divp.unwrap_or(1) - 1) as u8); - w.set_pllq((config.divq.unwrap_or(1) - 1) as u8); - w.set_pllr((config.divr.unwrap_or(1) - 1) as u8); + w.set_plln(config.mul); + w.set_pllp(config.divp.unwrap_or(PllDiv::DIV2)); + w.set_pllq(config.divq.unwrap_or(PllDiv::DIV2)); + w.set_pllr(config.divr.unwrap_or(PllDiv::DIV2)); }); RCC.cr().modify(|w| w.set_pllon(num, true)); diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index 7358be31..b4236126 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs @@ -1,8 +1,8 @@ use super::bd::BackupDomain; -pub use super::bus::{AHBPrescaler, APBPrescaler}; use super::RtcClockSource; pub use crate::pac::pwr::vals::Vos as VoltageScale; use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; #[cfg(crs)] use crate::pac::{crs, CRS, SYSCFG}; use crate::pac::{FLASH, PWR, RCC}; diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs index 90524fb3..e445a716 100644 --- a/embassy-stm32/src/rcc/l1.rs +++ b/embassy-stm32/src/rcc/l1.rs @@ -1,5 +1,5 @@ -pub use super::bus::{AHBPrescaler, APBPrescaler}; use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 2fbb9920..0e35b42e 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -1,7 +1,9 @@ -use stm32_metapac::rcc::regs::Cfgr; - -pub use super::bus::{AHBPrescaler, APBPrescaler}; -use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; +use crate::pac::rcc::regs::Cfgr; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, + Pllr as PllRDiv, Ppre as APBPrescaler, +}; +use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; @@ -17,62 +19,11 @@ pub const LSI_FREQ: Hertz = Hertz(32_000); #[derive(Clone, Copy)] pub enum ClockSrc { MSI(MSIRange), - PLL(PLLSource, PLLClkDiv, PLLSrcDiv, PLLMul, Option), + PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option), HSE(Hertz), HSI16, } -/// MSI Clock Range -/// -/// These ranges control the frequency of the MSI. Internally, these ranges map -/// to the `MSIRANGE` bits in the `RCC_ICSCR` register. -#[derive(Clone, Copy)] -pub enum MSIRange { - /// Around 100 kHz - Range0, - /// Around 200 kHz - Range1, - /// Around 400 kHz - Range2, - /// Around 800 kHz - Range3, - /// Around 1 MHz - Range4, - /// Around 2 MHz - Range5, - /// Around 4 MHz (reset value) - Range6, - /// Around 8 MHz - Range7, - /// Around 16 MHz - Range8, - /// Around 24 MHz - Range9, - /// Around 32 MHz - Range10, - /// Around 48 MHz - Range11, -} - -impl Default for MSIRange { - fn default() -> MSIRange { - MSIRange::Range6 - } -} - -pub type PLL48Div = PLLClkDiv; -pub type PLLSAI1RDiv = PLLClkDiv; -pub type PLLSAI1QDiv = PLLClkDiv; -pub type PLLSAI1PDiv = PLLClkDiv; - -/// PLL divider -#[derive(Clone, Copy)] -pub enum PLLDiv { - Div2, - Div3, - Div4, -} - /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { @@ -81,95 +32,6 @@ pub enum PLLSource { MSI(MSIRange), } -seq_macro::seq!(N in 8..=86 { - #[derive(Clone, Copy)] - pub enum PLLMul { - #( - Mul~N, - )* - } - - impl From for u8 { - fn from(val: PLLMul) -> u8 { - match val { - #( - PLLMul::Mul~N => N, - )* - } - } - } - - impl PLLMul { - pub fn to_mul(self) -> u32 { - match self { - #( - PLLMul::Mul~N => N, - )* - } - } - } -}); - -#[derive(Clone, Copy)] -pub enum PLLClkDiv { - Div2, - Div4, - Div6, - Div8, -} - -impl PLLClkDiv { - pub fn to_div(self) -> u32 { - let val: u8 = self.into(); - (val as u32 + 1) * 2 - } -} - -impl From for u8 { - fn from(val: PLLClkDiv) -> u8 { - match val { - PLLClkDiv::Div2 => 0b00, - PLLClkDiv::Div4 => 0b01, - PLLClkDiv::Div6 => 0b10, - PLLClkDiv::Div8 => 0b11, - } - } -} - -#[derive(Clone, Copy)] -pub enum PLLSrcDiv { - Div1, - Div2, - Div3, - Div4, - Div5, - Div6, - Div7, - Div8, -} - -impl PLLSrcDiv { - pub fn to_div(self) -> u32 { - let val: u8 = self.into(); - val as u32 + 1 - } -} - -impl From for u8 { - fn from(val: PLLSrcDiv) -> u8 { - match val { - PLLSrcDiv::Div1 => 0b000, - PLLSrcDiv::Div2 => 0b001, - PLLSrcDiv::Div3 => 0b010, - PLLSrcDiv::Div4 => 0b011, - PLLSrcDiv::Div5 => 0b100, - PLLSrcDiv::Div6 => 0b101, - PLLSrcDiv::Div7 => 0b110, - PLLSrcDiv::Div8 => 0b111, - } - } -} - impl From for Pllsrc { fn from(val: PLLSource) -> Pllsrc { match val { @@ -180,57 +42,13 @@ impl From for Pllsrc { } } -impl From for Msirange { - fn from(val: MSIRange) -> Msirange { - match val { - MSIRange::Range0 => Msirange::RANGE100K, - MSIRange::Range1 => Msirange::RANGE200K, - MSIRange::Range2 => Msirange::RANGE400K, - MSIRange::Range3 => Msirange::RANGE800K, - MSIRange::Range4 => Msirange::RANGE1M, - MSIRange::Range5 => Msirange::RANGE2M, - MSIRange::Range6 => Msirange::RANGE4M, - MSIRange::Range7 => Msirange::RANGE8M, - MSIRange::Range8 => Msirange::RANGE16M, - MSIRange::Range9 => Msirange::RANGE24M, - MSIRange::Range10 => Msirange::RANGE32M, - MSIRange::Range11 => Msirange::RANGE48M, - } - } -} - -impl From for u32 { - fn from(val: MSIRange) -> u32 { - match val { - MSIRange::Range0 => 100_000, - MSIRange::Range1 => 200_000, - MSIRange::Range2 => 400_000, - MSIRange::Range3 => 800_000, - MSIRange::Range4 => 1_000_000, - MSIRange::Range5 => 2_000_000, - MSIRange::Range6 => 4_000_000, - MSIRange::Range7 => 8_000_000, - MSIRange::Range8 => 16_000_000, - MSIRange::Range9 => 24_000_000, - MSIRange::Range10 => 32_000_000, - MSIRange::Range11 => 48_000_000, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, - pub pllsai1: Option<( - PLLMul, - PLLSrcDiv, - Option, - Option, - Option, - )>, + pub pllsai1: Option<(PllMul, PllPreDiv, Option, Option, Option)>, #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] pub hsi48: bool, pub rtc_mux: RtcClockSource, @@ -242,7 +60,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::MSI(MSIRange::Range6), + mux: ClockSrc::MSI(MSIRange::RANGE4M), ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, @@ -262,7 +80,7 @@ pub(crate) unsafe fn init(config: Config) { // Turn on MSI and configure it to 4MHz. RCC.cr().modify(|w| { w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0]. - w.set_msirange(MSIRange::default().into()); + w.set_msirange(MSIRange::RANGE4M); w.set_msipllen(false); w.set_msion(true) }); @@ -298,40 +116,40 @@ pub(crate) unsafe fn init(config: Config) { while !RCC.cr().read().msirdy() {} // Enable as clock source for USB, RNG if running at 48 MHz - if let MSIRange::Range11 = range { + if range == MSIRange::RANGE48M { RCC.ccipr().modify(|w| { w.set_clk48sel(0b11); }); } - (range.into(), Sw::MSI) + (msirange_to_hertz(range), Sw::MSI) } ClockSrc::HSI16 => { // Enable HSI16 RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - (HSI_FREQ.0, Sw::HSI16) + (HSI_FREQ, Sw::HSI16) } ClockSrc::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - (freq.0, Sw::HSE) + (freq, Sw::HSE) } - ClockSrc::PLL(src, div, prediv, mul, pll48div) => { + ClockSrc::PLL(src, divr, prediv, mul, divq) => { let src_freq = match src { PLLSource::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - freq.0 + freq } PLLSource::HSI16 => { // Enable HSI RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - HSI_FREQ.0 + HSI_FREQ } PLLSource::MSI(range) => { // Enable MSI @@ -343,7 +161,8 @@ pub(crate) unsafe fn init(config: Config) { w.set_msion(true); }); while !RCC.cr().read().msirdy() {} - range.into() + + msirange_to_hertz(range) } }; @@ -351,28 +170,28 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_pllon(false)); while RCC.cr().read().pllrdy() {} - let freq = (src_freq / prediv.to_div() * mul.to_mul()) / div.to_div(); + let freq = src_freq / prediv * mul / divr; #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] - assert!(freq <= 120_000_000); + assert!(freq.0 <= 120_000_000); #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))] - assert!(freq <= 80_000_000); + assert!(freq.0 <= 80_000_000); RCC.pllcfgr().write(move |w| { - w.set_plln(mul.into()); - w.set_pllm(prediv.into()); - w.set_pllr(div.into()); - if let Some(pll48div) = pll48div { - w.set_pllq(pll48div.into()); + w.set_plln(mul); + w.set_pllm(prediv); + w.set_pllr(divr); + if let Some(divq) = divq { + w.set_pllq(divq); w.set_pllqen(true); } w.set_pllsrc(src.into()); }); // Enable as clock source for USB, RNG if PLL48 divisor is provided - if let Some(pll48div) = pll48div { - let freq = (src_freq / prediv.to_div() * mul.to_mul()) / pll48div.to_div(); - assert!(freq == 48_000_000); + if let Some(divq) = divq { + let freq = src_freq / prediv * mul / divq; + assert!(freq.0 == 48_000_000); RCC.ccipr().modify(|w| { w.set_clk48sel(0b10); }); @@ -380,25 +199,25 @@ pub(crate) unsafe fn init(config: Config) { if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { RCC.pllsai1cfgr().write(move |w| { - w.set_pllsai1n(mul.into()); - w.set_pllsai1m(prediv.into()); + w.set_plln(mul); + w.set_pllm(prediv); if let Some(r_div) = r_div { - w.set_pllsai1r(r_div.into()); - w.set_pllsai1ren(true); + w.set_pllr(r_div); + w.set_pllren(true); } if let Some(q_div) = q_div { - w.set_pllsai1q(q_div.into()); - w.set_pllsai1qen(true); - let freq = (src_freq / prediv.to_div() * mul.to_mul()) / q_div.to_div(); - if freq == 48_000_000 { + w.set_pllq(q_div); + w.set_pllqen(true); + let freq = src_freq / prediv * mul / q_div; + if freq.0 == 48_000_000 { RCC.ccipr().modify(|w| { w.set_clk48sel(0b1); }); } } if let Some(p_div) = p_div { - w.set_pllsai1pdiv(p_div.into()); - w.set_pllsai1pen(true); + w.set_pllp(p_div); + w.set_pllpen(true); } }); @@ -425,17 +244,13 @@ pub(crate) unsafe fn init(config: Config) { // Set flash wait states FLASH.acr().modify(|w| { - w.set_latency(if sys_clk <= 16_000_000 { - 0b000 - } else if sys_clk <= 32_000_000 { - 0b001 - } else if sys_clk <= 48_000_000 { - 0b010 - } else if sys_clk <= 64_000_000 { - 0b011 - } else { - 0b100 - }); + w.set_latency(match sys_clk.0 { + 0..=16_000_000 => 0, + 0..=32_000_000 => 1, + 0..=48_000_000 => 2, + 0..=64_000_000 => 3, + _ => 4, + }) }); RCC.cfgr().modify(|w| { @@ -445,43 +260,50 @@ pub(crate) unsafe fn init(config: Config) { w.set_ppre2(config.apb2_pre.into()); }); - let ahb_freq: u32 = match config.ahb_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: Hpre = pre.into(); - let pre = 1 << (pre.to_bits() as u32 - 7); - sys_clk / pre - } - }; + let ahb_freq = sys_clk / config.ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - ahb2: Hertz(ahb_freq), - ahb3: Hertz(ahb_freq), - apb1: Hertz(apb1_freq), - apb2: Hertz(apb2_freq), - apb1_tim: Hertz(apb1_tim_freq), - apb2_tim: Hertz(apb2_tim_freq), + sys: sys_clk, + ahb1: ahb_freq, + ahb2: ahb_freq, + ahb3: ahb_freq, + apb1: apb1_freq, + apb2: apb2_freq, + apb1_tim: apb1_tim_freq, + apb2_tim: apb2_tim_freq, }); } + +fn msirange_to_hertz(range: Msirange) -> Hertz { + match range { + MSIRange::RANGE100K => Hertz(100_000), + MSIRange::RANGE200K => Hertz(200_000), + MSIRange::RANGE400K => Hertz(400_000), + MSIRange::RANGE800K => Hertz(800_000), + MSIRange::RANGE1M => Hertz(1_000_000), + MSIRange::RANGE2M => Hertz(2_000_000), + MSIRange::RANGE4M => Hertz(4_000_000), + MSIRange::RANGE8M => Hertz(8_000_000), + MSIRange::RANGE16M => Hertz(16_000_000), + MSIRange::RANGE24M => Hertz(24_000_000), + MSIRange::RANGE32M => Hertz(32_000_000), + MSIRange::RANGE48M => Hertz(48_000_000), + _ => unreachable!(), + } +} diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index 652bdcb7..d9b3ee28 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs @@ -1,8 +1,11 @@ -use stm32_metapac::PWR; - -pub use super::bus::{AHBPrescaler, APBPrescaler}; -use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; -use crate::pac::{FLASH, RCC}; +use crate::pac::rcc::regs::Cfgr; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, + Pllr as PllRDiv, Ppre as APBPrescaler, +}; +use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; +use crate::pac::{FLASH, PWR, RCC}; +use crate::rcc::bd::RtcClockSource; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -16,62 +19,11 @@ pub const LSI_FREQ: Hertz = Hertz(32_000); #[derive(Clone, Copy)] pub enum ClockSrc { MSI(MSIRange), - PLL(PLLSource, PLLClkDiv, PLLSrcDiv, PLLMul, Option), + PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option), HSE(Hertz), HSI16, } -/// MSI Clock Range -/// -/// These ranges control the frequency of the MSI. Internally, these ranges map -/// to the `MSIRANGE` bits in the `RCC_ICSCR` register. -#[derive(Clone, Copy)] -pub enum MSIRange { - /// Around 100 kHz - Range0, - /// Around 200 kHz - Range1, - /// Around 400 kHz - Range2, - /// Around 800 kHz - Range3, - /// Around 1 MHz - Range4, - /// Around 2 MHz - Range5, - /// Around 4 MHz (reset value) - Range6, - /// Around 8 MHz - Range7, - /// Around 16 MHz - Range8, - /// Around 24 MHz - Range9, - /// Around 32 MHz - Range10, - /// Around 48 MHz - Range11, -} - -impl Default for MSIRange { - fn default() -> MSIRange { - MSIRange::Range6 - } -} - -pub type PLL48Div = PLLClkDiv; -pub type PLLSAI1RDiv = PLLClkDiv; -pub type PLLSAI1QDiv = PLLClkDiv; -pub type PLLSAI1PDiv = PLLClkDiv; - -/// PLL divider -#[derive(Clone, Copy)] -pub enum PLLDiv { - Div2, - Div3, - Div4, -} - /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { @@ -80,95 +32,6 @@ pub enum PLLSource { MSI(MSIRange), } -seq_macro::seq!(N in 8..=86 { - #[derive(Clone, Copy)] - pub enum PLLMul { - #( - Mul~N, - )* - } - - impl From for u8 { - fn from(val: PLLMul) -> u8 { - match val { - #( - PLLMul::Mul~N => N, - )* - } - } - } - - impl PLLMul { - pub fn to_mul(self) -> u32 { - match self { - #( - PLLMul::Mul~N => N, - )* - } - } - } -}); - -#[derive(Clone, Copy)] -pub enum PLLClkDiv { - Div2, - Div4, - Div6, - Div8, -} - -impl PLLClkDiv { - pub fn to_div(self) -> u32 { - let val: u8 = self.into(); - (val as u32 + 1) * 2 - } -} - -impl From for u8 { - fn from(val: PLLClkDiv) -> u8 { - match val { - PLLClkDiv::Div2 => 0b00, - PLLClkDiv::Div4 => 0b01, - PLLClkDiv::Div6 => 0b10, - PLLClkDiv::Div8 => 0b11, - } - } -} - -#[derive(Clone, Copy)] -pub enum PLLSrcDiv { - Div1, - Div2, - Div3, - Div4, - Div5, - Div6, - Div7, - Div8, -} - -impl PLLSrcDiv { - pub fn to_div(self) -> u32 { - let val: u8 = self.into(); - val as u32 + 1 - } -} - -impl From for u8 { - fn from(val: PLLSrcDiv) -> u8 { - match val { - PLLSrcDiv::Div1 => 0b000, - PLLSrcDiv::Div2 => 0b001, - PLLSrcDiv::Div3 => 0b010, - PLLSrcDiv::Div4 => 0b011, - PLLSrcDiv::Div5 => 0b100, - PLLSrcDiv::Div6 => 0b101, - PLLSrcDiv::Div7 => 0b110, - PLLSrcDiv::Div8 => 0b111, - } - } -} - impl From for Pllsrc { fn from(val: PLLSource) -> Pllsrc { match val { @@ -179,75 +42,59 @@ impl From for Pllsrc { } } -impl From for Msirange { - fn from(val: MSIRange) -> Msirange { - match val { - MSIRange::Range0 => Msirange::RANGE100K, - MSIRange::Range1 => Msirange::RANGE200K, - MSIRange::Range2 => Msirange::RANGE400K, - MSIRange::Range3 => Msirange::RANGE800K, - MSIRange::Range4 => Msirange::RANGE1M, - MSIRange::Range5 => Msirange::RANGE2M, - MSIRange::Range6 => Msirange::RANGE4M, - MSIRange::Range7 => Msirange::RANGE8M, - MSIRange::Range8 => Msirange::RANGE16M, - MSIRange::Range9 => Msirange::RANGE24M, - MSIRange::Range10 => Msirange::RANGE32M, - MSIRange::Range11 => Msirange::RANGE48M, - } - } -} - -impl From for u32 { - fn from(val: MSIRange) -> u32 { - match val { - MSIRange::Range0 => 100_000, - MSIRange::Range1 => 200_000, - MSIRange::Range2 => 400_000, - MSIRange::Range3 => 800_000, - MSIRange::Range4 => 1_000_000, - MSIRange::Range5 => 2_000_000, - MSIRange::Range6 => 4_000_000, - MSIRange::Range7 => 8_000_000, - MSIRange::Range8 => 16_000_000, - MSIRange::Range9 => 24_000_000, - MSIRange::Range10 => 32_000_000, - MSIRange::Range11 => 48_000_000, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, - pub pllsai1: Option<( - PLLMul, - PLLSrcDiv, - Option, - Option, - Option, - )>, + pub pllsai1: Option<(PllMul, PllPreDiv, Option, Option, Option)>, pub hsi48: bool, + pub rtc_mux: RtcClockSource, + pub lse: Option, + pub lsi: bool, } impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::MSI(MSIRange::Range6), + mux: ClockSrc::MSI(MSIRange::RANGE4M), ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, pllsai1: None, hsi48: false, + rtc_mux: RtcClockSource::LSI, + lsi: true, + lse: None, } } } pub(crate) unsafe fn init(config: Config) { + // Switch to MSI to prevent problems with PLL configuration. + if !RCC.cr().read().msion() { + // Turn on MSI and configure it to 4MHz. + RCC.cr().modify(|w| { + w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0]. + w.set_msirange(MSIRange::RANGE4M); + w.set_msipllen(false); + w.set_msion(true) + }); + + // Wait until MSI is running + while !RCC.cr().read().msirdy() {} + } + if RCC.cfgr().read().sws() != Sw::MSI { + // Set MSI as a clock source, reset prescalers. + RCC.cfgr().write_value(Cfgr::default()); + // Wait for clock switch status bits to change. + while RCC.cfgr().read().sws() != Sw::MSI {} + } + + //BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); + PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0)); let (sys_clk, sw) = match config.mux { ClockSrc::MSI(range) => { @@ -255,47 +102,53 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().write(|w| { let bits: Msirange = range.into(); w.set_msirange(bits); - w.set_msipllen(false); w.set_msirgsel(true); w.set_msion(true); + + if config.rtc_mux == RtcClockSource::LSE { + // If LSE is enabled, enable calibration of MSI + w.set_msipllen(true); + } else { + w.set_msipllen(false); + } }); while !RCC.cr().read().msirdy() {} // Enable as clock source for USB, RNG if running at 48 MHz - if let MSIRange::Range11 = range { + if range == MSIRange::RANGE48M { RCC.ccipr1().modify(|w| { w.set_clk48msel(0b11); }); } - (range.into(), Sw::MSI) + (msirange_to_hertz(range), Sw::MSI) } ClockSrc::HSI16 => { // Enable HSI16 RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - (HSI_FREQ.0, Sw::HSI16) + (HSI_FREQ, Sw::HSI16) } ClockSrc::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - (freq.0, Sw::HSE) + (freq, Sw::HSE) } - ClockSrc::PLL(src, div, prediv, mul, pll48div) => { + ClockSrc::PLL(src, divr, prediv, mul, divq) => { let src_freq = match src { PLLSource::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - freq.0 + freq } PLLSource::HSI16 => { // Enable HSI RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - HSI_FREQ.0 + HSI_FREQ } PLLSource::MSI(range) => { // Enable MSI @@ -307,7 +160,8 @@ pub(crate) unsafe fn init(config: Config) { w.set_msion(true); }); while !RCC.cr().read().msirdy() {} - range.into() + + msirange_to_hertz(range) } }; @@ -315,23 +169,23 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_pllon(false)); while RCC.cr().read().pllrdy() {} - let freq = (src_freq / prediv.to_div() * mul.to_mul()) / div.to_div(); + let freq = src_freq / prediv * mul / divr; RCC.pllcfgr().write(move |w| { - w.set_plln(mul.into()); - w.set_pllm(prediv.into()); - w.set_pllr(div.into()); - if let Some(pll48div) = pll48div { - w.set_pllq(pll48div.into()); + w.set_plln(mul); + w.set_pllm(prediv); + w.set_pllr(divr); + if let Some(divq) = divq { + w.set_pllq(divq); w.set_pllqen(true); } w.set_pllsrc(src.into()); }); // Enable as clock source for USB, RNG if PLL48 divisor is provided - if let Some(pll48div) = pll48div { - let freq = (src_freq / prediv.to_div() * mul.to_mul()) / pll48div.to_div(); - assert!(freq == 48_000_000); + if let Some(divq) = divq { + let freq = src_freq / prediv * mul / divq; + assert!(freq.0 == 48_000_000); RCC.ccipr1().modify(|w| { w.set_clk48msel(0b10); }); @@ -339,25 +193,25 @@ pub(crate) unsafe fn init(config: Config) { if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { RCC.pllsai1cfgr().write(move |w| { - w.set_pllsai1n(mul.into()); - w.set_pllsai1m(prediv.into()); + w.set_plln(mul); + w.set_pllm(prediv); if let Some(r_div) = r_div { - w.set_pllsai1r(r_div.into()); - w.set_pllsai1ren(true); + w.set_pllr(r_div); + w.set_pllren(true); } if let Some(q_div) = q_div { - w.set_pllsai1q(q_div.into()); - w.set_pllsai1qen(true); - let freq = (src_freq / prediv.to_div() * mul.to_mul()) / q_div.to_div(); - if freq == 48_000_000 { + w.set_pllq(q_div); + w.set_pllqen(true); + let freq = src_freq / prediv * mul / q_div; + if freq.0 == 48_000_000 { RCC.ccipr1().modify(|w| { w.set_clk48msel(0b1); }); } } if let Some(p_div) = p_div { - w.set_pllsai1pdiv(p_div.into()); - w.set_pllsai1pen(true); + w.set_pllp(p_div); + w.set_pllpen(true); } }); @@ -384,7 +238,7 @@ pub(crate) unsafe fn init(config: Config) { // Set flash wait states // VCORE Range 0 (performance), others TODO FLASH.acr().modify(|w| { - w.set_latency(match sys_clk { + w.set_latency(match sys_clk.0 { 0..=20_000_000 => 0, 0..=40_000_000 => 1, 0..=60_000_000 => 2, @@ -401,43 +255,50 @@ pub(crate) unsafe fn init(config: Config) { w.set_ppre2(config.apb2_pre.into()); }); - let ahb_freq: u32 = match config.ahb_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: Hpre = pre.into(); - let pre = 1 << (pre.to_bits() as u32 - 7); - sys_clk / pre - } - }; + let ahb_freq = sys_clk / config.ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - ahb2: Hertz(ahb_freq), - ahb3: Hertz(ahb_freq), - apb1: Hertz(apb1_freq), - apb2: Hertz(apb2_freq), - apb1_tim: Hertz(apb1_tim_freq), - apb2_tim: Hertz(apb2_tim_freq), + sys: sys_clk, + ahb1: ahb_freq, + ahb2: ahb_freq, + ahb3: ahb_freq, + apb1: apb1_freq, + apb2: apb2_freq, + apb1_tim: apb1_tim_freq, + apb2_tim: apb2_tim_freq, }); } + +fn msirange_to_hertz(range: Msirange) -> Hertz { + match range { + MSIRange::RANGE100K => Hertz(100_000), + MSIRange::RANGE200K => Hertz(200_000), + MSIRange::RANGE400K => Hertz(400_000), + MSIRange::RANGE800K => Hertz(800_000), + MSIRange::RANGE1M => Hertz(1_000_000), + MSIRange::RANGE2M => Hertz(2_000_000), + MSIRange::RANGE4M => Hertz(4_000_000), + MSIRange::RANGE8M => Hertz(8_000_000), + MSIRange::RANGE16M => Hertz(16_000_000), + MSIRange::RANGE24M => Hertz(24_000_000), + MSIRange::RANGE32M => Hertz(32_000_000), + MSIRange::RANGE48M => Hertz(48_000_000), + _ => unreachable!(), + } +} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index a3299089..52dc386b 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -6,7 +6,6 @@ pub use crate::rcc::bd::RtcClockSource; use crate::time::Hertz; pub(crate) mod bd; -mod bus; mod mco; pub use mco::*; diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 14b8577d..d8fb1730 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -1,6 +1,5 @@ -use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllmboost, Pllrge, Pllsrc, Sw}; - -pub use super::bus::{AHBPrescaler, APBPrescaler}; +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}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -16,7 +15,7 @@ pub use crate::pac::pwr::vals::Vos as VoltageScale; #[derive(Copy, Clone)] pub enum ClockSrc { /// Use an internal medium speed oscillator (MSIS) as the system clock. - MSI(MSIRange), + MSI(Msirange), /// 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 @@ -31,29 +30,29 @@ pub enum ClockSrc { impl Default for ClockSrc { fn default() -> Self { // The default system clock source is MSIS @ 4 MHz, per RM0456 § 11.4.9 - ClockSrc::MSI(MSIRange::Range4mhz) + ClockSrc::MSI(Msirange::RANGE_4MHZ) } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy)] 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. - pub m: PllM, + pub m: Pllm, /// 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 }`. - pub n: PllN, + pub n: Plln, /// 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 }`. - pub r: PllClkDiv, + pub r: Plldiv, } impl PllConfig { @@ -61,27 +60,27 @@ impl PllConfig { pub const fn hsi16_160mhz() -> Self { PllConfig { source: PllSrc::HSI16, - m: PllM::NotDivided, - n: PllN::Mul10, - r: PllClkDiv::NotDivided, + m: Pllm::DIV1, + n: Plln::MUL10, + r: Plldiv::DIV1, } } /// A configuration for MSIS @ 48 MHz / 3 * 10 / 1 = 160 MHz pub const fn msis_160mhz() -> Self { PllConfig { - source: PllSrc::MSIS(MSIRange::Range48mhz), - m: PllM::Div3, - n: PllN::Mul10, - r: PllClkDiv::NotDivided, + source: PllSrc::MSIS(Msirange::RANGE_48MHZ), + m: Pllm::DIV3, + n: Plln::MUL10, + r: Plldiv::DIV1, } } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy)] pub enum PllSrc { /// Use an internal medium speed oscillator as the PLL source. - MSIS(MSIRange), + MSIS(Msirange), /// 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 @@ -101,75 +100,6 @@ impl Into for PllSrc { } } -seq_macro::seq!(N in 2..=128 { - #[derive(Copy, Clone, Debug)] - pub enum PllClkDiv { - NotDivided = 1, - #( - Div~N = N, - )* - } - - impl PllClkDiv { - fn to_div(&self) -> u8 { - match self { - PllClkDiv::NotDivided => 0, - #( - PllClkDiv::Div~N => N - 1, - )* - } - } - } -}); - -seq_macro::seq!(N in 4..=512 { - #[derive(Copy, Clone, Debug)] - pub enum PllN { - NotMultiplied = 1, - #( - Mul~N = N, - )* - } - - impl PllN { - fn to_mul(&self) -> u16 { - match self { - PllN::NotMultiplied => 0, - #( - PllN::Mul~N => N - 1, - )* - } - } - } -}); - -// Pre-division -#[derive(Copy, Clone, Debug)] -pub enum PllM { - NotDivided = 0b0000, - Div2 = 0b0001, - Div3 = 0b0010, - Div4 = 0b0011, - Div5 = 0b0100, - Div6 = 0b0101, - Div7 = 0b0110, - Div8 = 0b0111, - Div9 = 0b1000, - Div10 = 0b1001, - Div11 = 0b1010, - Div12 = 0b1011, - Div13 = 0b1100, - Div14 = 0b1101, - Div15 = 0b1110, - Div16 = 0b1111, -} - -impl Into for PllM { - fn into(self) -> Pllm { - Pllm::from_bits(self as u8) - } -} - impl Into for ClockSrc { fn into(self) -> Sw { match self { @@ -181,56 +111,6 @@ impl Into for ClockSrc { } } -#[derive(Debug, Copy, Clone)] -pub enum MSIRange { - /// The 48 MHz MSI speed is unavailable in `VoltageScale::RANGE4`. - Range48mhz = 48_000_000, - Range24mhz = 24_000_000, - Range16mhz = 16_000_000, - Range12mhz = 12_000_000, - Range4mhz = 4_000_000, - Range2mhz = 2_000_000, - Range1_33mhz = 1_330_000, - Range1mhz = 1_000_000, - Range3_072mhz = 3_072_000, - Range1_536mhz = 1_536_000, - Range1_024mhz = 1_024_000, - Range768khz = 768_000, - Range400khz = 400_000, - Range200khz = 200_000, - Range133khz = 133_000, - Range100khz = 100_000, -} - -impl Into for MSIRange { - fn into(self) -> u32 { - self as u32 - } -} - -impl Into for MSIRange { - fn into(self) -> Msirange { - match self { - MSIRange::Range48mhz => Msirange::RANGE_48MHZ, - MSIRange::Range24mhz => Msirange::RANGE_24MHZ, - MSIRange::Range16mhz => Msirange::RANGE_16MHZ, - MSIRange::Range12mhz => Msirange::RANGE_12MHZ, - MSIRange::Range4mhz => Msirange::RANGE_4MHZ, - MSIRange::Range2mhz => Msirange::RANGE_2MHZ, - MSIRange::Range1_33mhz => Msirange::RANGE_1_33MHZ, - MSIRange::Range1mhz => Msirange::RANGE_1MHZ, - MSIRange::Range3_072mhz => Msirange::RANGE_3_072MHZ, - MSIRange::Range1_536mhz => Msirange::RANGE_1_536MHZ, - MSIRange::Range1_024mhz => Msirange::RANGE_1_024MHZ, - MSIRange::Range768khz => Msirange::RANGE_768KHZ, - MSIRange::Range400khz => Msirange::RANGE_400KHZ, - MSIRange::Range200khz => Msirange::RANGE_200KHZ, - MSIRange::Range133khz => Msirange::RANGE_133KHZ, - MSIRange::Range100khz => Msirange::RANGE_100KHZ, - } - } -} - #[derive(Copy, Clone)] pub struct Config { pub mux: ClockSrc, @@ -273,11 +153,11 @@ impl Config { frequency } - unsafe fn init_msis(&self, range: MSIRange) -> Hertz { + unsafe fn init_msis(&self, range: Msirange) -> Hertz { // Check MSI output per RM0456 § 11.4.10 match self.voltage_range { VoltageScale::RANGE4 => { - assert!(range as u32 <= 24_000_000); + assert!(msirange_to_hertz(range).0 <= 24_000_000); } _ => {} } @@ -291,8 +171,7 @@ impl Config { } RCC.icscr1().modify(|w| { - let bits: Msirange = range.into(); - w.set_msisrange(bits); + w.set_msisrange(range); w.set_msirgsel(Msirgsel::RCC_ICSCR1); }); RCC.cr().write(|w| { @@ -300,7 +179,7 @@ impl Config { w.set_msison(true); }); while !RCC.cr().read().msisrdy() {} - Hertz(range as u32) + msirange_to_hertz(range) } } @@ -344,14 +223,14 @@ pub(crate) unsafe fn init(config: Config) { }; // Calculate the reference clock, which is the source divided by m - let reference_clk = source_clk / (pll.m as u8 as u32 + 1); + let reference_clk = source_clk / pll.m; // Check limits per RM0456 § 11.4.6 assert!(Hertz::mhz(4) <= reference_clk && reference_clk <= Hertz::mhz(16)); // Calculate the PLL1 VCO clock and PLL1 R output clock - let pll1_clk = reference_clk * (pll.n as u8 as u32); - let pll1r_clk = pll1_clk / (pll.r as u8 as u32); + let pll1_clk = reference_clk * pll.n; + let pll1r_clk = pll1_clk / pll.r; // Check system clock per RM0456 § 11.4.9 assert!(pll1r_clk <= Hertz::mhz(160)); @@ -387,11 +266,11 @@ pub(crate) unsafe fn init(config: Config) { Pllmboost::DIV2 } else { // Bypass, giving EPOD 4-16 MHz - Pllmboost::BYPASS + Pllmboost::DIV1 } } else { // Nothing to do - Pllmboost::BYPASS + Pllmboost::DIV1 }; // Disable the PLL, and wait for it to disable @@ -402,7 +281,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.pll1cfgr().write(|w| { // Configure PLL1 source and prescaler w.set_pllsrc(pll.source.into()); - w.set_pllm(pll.m.into()); + w.set_pllm(pll.m); // Configure PLL1 input frequncy range let input_range = if reference_clk <= Hertz::mhz(8) { @@ -422,9 +301,9 @@ pub(crate) unsafe fn init(config: Config) { // Configure the PLL divisors RCC.pll1divr().modify(|w| { // Set the VCO multiplier - w.set_plln(pll.n.to_mul()); + w.set_plln(pll.n); // Set the R output divisor - w.set_pllr(pll.r.to_div()); + w.set_pllr(pll.r); }); // Do we need the EPOD booster to reach the target clock speed per § 10.5.4? @@ -442,8 +321,7 @@ pub(crate) unsafe fn init(config: Config) { pll1r_clk } - } - .0; + }; if config.hsi48 { RCC.cr().modify(|w| w.set_hsi48on(true)); @@ -455,13 +333,13 @@ pub(crate) unsafe fn init(config: Config) { let wait_states = match config.voltage_range { // VOS 1 range VCORE 1.26V - 1.40V VoltageScale::RANGE1 => { - if sys_clk < 32_000_000 { + if sys_clk.0 < 32_000_000 { 0 - } else if sys_clk < 64_000_000 { + } else if sys_clk.0 < 64_000_000 { 1 - } else if sys_clk < 96_000_000 { + } else if sys_clk.0 < 96_000_000 { 2 - } else if sys_clk < 128_000_000 { + } else if sys_clk.0 < 128_000_000 { 3 } else { 4 @@ -469,11 +347,11 @@ pub(crate) unsafe fn init(config: Config) { } // VOS 2 range VCORE 1.15V - 1.26V VoltageScale::RANGE2 => { - if sys_clk < 30_000_000 { + if sys_clk.0 < 30_000_000 { 0 - } else if sys_clk < 60_000_000 { + } else if sys_clk.0 < 60_000_000 { 1 - } else if sys_clk < 90_000_000 { + } else if sys_clk.0 < 90_000_000 { 2 } else { 3 @@ -481,9 +359,9 @@ pub(crate) unsafe fn init(config: Config) { } // VOS 3 range VCORE 1.05V - 1.15V VoltageScale::RANGE3 => { - if sys_clk < 24_000_000 { + if sys_clk.0 < 24_000_000 { 0 - } else if sys_clk < 48_000_000 { + } else if sys_clk.0 < 48_000_000 { 1 } else { 2 @@ -491,7 +369,7 @@ pub(crate) unsafe fn init(config: Config) { } // VOS 4 range VCORE 0.95V - 1.05V VoltageScale::RANGE4 => { - if sys_clk < 12_000_000 { + if sys_clk.0 < 12_000_000 { 0 } else { 1 @@ -522,62 +400,70 @@ pub(crate) unsafe fn init(config: Config) { // Configure the bus prescalers RCC.cfgr2().modify(|w| { - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); RCC.cfgr3().modify(|w| { - w.set_ppre3(config.apb3_pre.into()); + w.set_ppre3(config.apb3_pre); }); - let ahb_freq: u32 = match config.ahb_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: u8 = pre.into(); - let pre = 1 << (pre as u32 - 7); - sys_clk / pre - } - }; + let ahb_freq = sys_clk / config.ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; let (apb3_freq, _apb3_tim_freq) = match config.apb3_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - ahb2: Hertz(ahb_freq), - ahb3: Hertz(ahb_freq), - apb1: Hertz(apb1_freq), - apb2: Hertz(apb2_freq), - apb3: Hertz(apb3_freq), - apb1_tim: Hertz(apb1_tim_freq), - apb2_tim: Hertz(apb2_tim_freq), + sys: sys_clk, + ahb1: ahb_freq, + ahb2: ahb_freq, + ahb3: ahb_freq, + apb1: apb1_freq, + apb2: apb2_freq, + apb3: apb3_freq, + apb1_tim: apb1_tim_freq, + apb2_tim: apb2_tim_freq, }); } + +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), + } +} diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index ee45a342..ee2a8ae1 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -1,4 +1,4 @@ -pub use super::bus::{AHBPrescaler, APBPrescaler}; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::Clocks; use crate::time::{khz, mhz, Hertz}; diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 937f5550..7baedfcd 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -1,6 +1,6 @@ -pub use super::bus::{AHBPrescaler, APBPrescaler}; pub use crate::pac::pwr::vals::Vos as VoltageScale; use crate::pac::rcc::vals::Adcsel; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; use crate::pac::{FLASH, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs index 89493761..62aaa980 100644 --- a/examples/stm32f2/src/bin/pll.rs +++ b/examples/stm32f2/src/bin/pll.rs @@ -7,7 +7,7 @@ use core::convert::TryFrom; use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rcc::{ - APBPrescaler, ClockSrc, HSEConfig, HSESrc, PLL48Div, PLLConfig, PLLMainDiv, PLLMul, PLLPreDiv, PLLSrc, + APBPrescaler, ClockSrc, HSEConfig, HSESrc, PLLConfig, PLLMul, PLLPDiv, PLLPreDiv, PLLQDiv, PLLSrc, }; use embassy_stm32::time::Hertz; use embassy_stm32::Config; @@ -32,9 +32,9 @@ async fn main(_spawner: Spawner) { // 1 MHz PLL input * 240 = 240 MHz PLL VCO mul: unwrap!(PLLMul::try_from(240)), // 240 MHz PLL VCO / 2 = 120 MHz main PLL output - main_div: PLLMainDiv::Div2, + p_div: PLLPDiv::DIV2, // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - pll48_div: unwrap!(PLL48Div::try_from(5)), + q_div: PLLQDiv::DIV5, }; // System clock comes from PLL (= the 120 MHz main PLL output) config.rcc.mux = ClockSrc::PLL; diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index a792748b..da9b18a0 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -16,12 +16,12 @@ async fn main(_spawner: Spawner) { config.rcc.pll = Some(Pll { source: PllSrc::HSI16, - prediv_m: PllM::Div4, - mul_n: PllN::Mul85, + prediv_m: PllM::DIV4, + mul_n: PllN::MUL85, div_p: None, div_q: None, // Main system clock at 170 MHz - div_r: Some(PllR::Div2), + div_r: Some(PllR::DIV2), }); config.rcc.adc12_clock_source = AdcClockSource::SysClk; diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs index ef7d4800..f8159cb5 100644 --- a/examples/stm32g4/src/bin/pll.rs +++ b/examples/stm32g4/src/bin/pll.rs @@ -15,12 +15,12 @@ async fn main(_spawner: Spawner) { config.rcc.pll = Some(Pll { source: PllSrc::HSI16, - prediv_m: PllM::Div4, - mul_n: PllN::Mul85, + prediv_m: PllM::DIV4, + mul_n: PllN::MUL85, div_p: None, div_q: None, // Main system clock at 170 MHz - div_r: Some(PllR::Div2), + div_r: Some(PllR::DIV2), }); config.rcc.mux = ClockSrc::PLL; diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index 77cfa67d..9099b609 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs @@ -25,16 +25,16 @@ async fn main(_spawner: Spawner) { // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE. const USE_HSI48: bool = true; - let pllq_div = if USE_HSI48 { None } else { Some(PllQ::Div6) }; + let pllq_div = if USE_HSI48 { None } else { Some(PllQ::DIV6) }; config.rcc.pll = Some(Pll { source: PllSrc::HSE(Hertz(8_000_000)), - prediv_m: PllM::Div2, - mul_n: PllN::Mul72, + prediv_m: PllM::DIV2, + mul_n: PllN::MUL72, div_p: None, div_q: pllq_div, // Main system clock at 144 MHz - div_r: Some(PllR::Div2), + div_r: Some(PllR::DIV2), }); config.rcc.mux = ClockSrc::PLL; diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 4e92d064..2f445476 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -9,7 +9,9 @@ use embassy_net::{Ipv4Address, Stack, StackResources}; use embassy_stm32::eth::generic_smi::GenericSMI; use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; -use embassy_stm32::rcc::{AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllSource, Sysclk, VoltageScale}; +use embassy_stm32::rcc::{ + AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllDiv, PllMul, PllPreDiv, PllSource, Sysclk, VoltageScale, +}; use embassy_stm32::rng::Rng; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; @@ -42,10 +44,10 @@ async fn main(spawner: Spawner) -> ! { }); config.rcc.pll1 = Some(Pll { source: PllSource::Hse, - prediv: 2, - mul: 125, - divp: Some(2), - divq: Some(2), + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL125, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV2), divr: None, }); config.rcc.ahb_pre = AHBPrescaler::DIV1; diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index cbe540a0..3b3c38e1 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs @@ -4,7 +4,9 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::rcc::{AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllSource, Sysclk, VoltageScale}; +use embassy_stm32::rcc::{ + AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllDiv, PllMul, PllPreDiv, PllSource, Sysclk, VoltageScale, +}; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config}; @@ -29,9 +31,9 @@ async fn main(_spawner: Spawner) { }); config.rcc.pll1 = Some(Pll { source: PllSource::Hse, - prediv: 2, - mul: 125, - divp: Some(2), // 250mhz + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL125, + divp: Some(PllDiv::DIV2), // 250mhz divq: None, divr: None, }); diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs index 77922d4b..7859b86d 100644 --- a/examples/stm32h7/src/bin/adc.rs +++ b/examples/stm32h7/src/bin/adc.rs @@ -18,16 +18,16 @@ async fn main(_spawner: Spawner) { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(8), // SPI1 cksel defaults to pll1_q + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // SPI1 cksel defaults to pll1_q divr: None, }); config.rcc.pll2 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(8), // 100mhz + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index 64ca65a0..40ef16cf 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs @@ -32,10 +32,10 @@ async fn main(_spawner: Spawner) { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(8), // 100mhz + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); config.rcc.sys = Sysclk::Pll1P; // 400 Mhz diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index 93df7a31..82122189 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs @@ -20,16 +20,16 @@ fn main() -> ! { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(8), // SPI1 cksel defaults to pll1_q + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); config.rcc.pll2 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(8), // 100mhz + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 8c921abc..933641ae 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -28,16 +28,16 @@ async fn main(spawner: Spawner) { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(8), // SPI1 cksel defaults to pll1_q + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); config.rcc.pll2 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(8), // 100mhz + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 1b5d71ed..a6603d50 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -39,9 +39,9 @@ async fn main(spawner: Spawner) -> ! { config.rcc.hsi48 = true; // needed for RNG config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), divq: None, divr: None, }); diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 3abd31c7..596de2f4 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -40,9 +40,9 @@ async fn main(spawner: Spawner) -> ! { config.rcc.hsi48 = true; // needed for RNG config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), divq: None, divr: None, }); diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs index de0b351d..7ae87b02 100644 --- a/examples/stm32h7/src/bin/fmc.rs +++ b/examples/stm32h7/src/bin/fmc.rs @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(8), // 100mhz + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); config.rcc.sys = Sysclk::Pll1P; // 400 Mhz diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index a1e955c3..f4fa0690 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -22,10 +22,10 @@ async fn main(_spawner: Spawner) { config.rcc.hsi48 = true; // needed for RNG config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(8), // 100 Mhz + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); config.rcc.sys = Sysclk::Pll1P; // 400 Mhz diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs index 5c8e57aa..37e4c92c 100644 --- a/examples/stm32h7/src/bin/pwm.rs +++ b/examples/stm32h7/src/bin/pwm.rs @@ -21,9 +21,9 @@ async fn main(_spawner: Spawner) { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), divq: None, divr: None, }); diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs index 752aefdf..ecb8d654 100644 --- a/examples/stm32h7/src/bin/sdmmc.rs +++ b/examples/stm32h7/src/bin/sdmmc.rs @@ -22,10 +22,10 @@ async fn main(_spawner: Spawner) -> ! { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(4), // default clock chosen by SDMMCSEL. 200 Mhz + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV4), // default clock chosen by SDMMCSEL. 200 Mhz divr: None, }); config.rcc.sys = Sysclk::Pll1P; // 400 Mhz diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index 9fe46f03..f128d4a5 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs @@ -44,10 +44,10 @@ fn main() -> ! { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(4), // used by SPI3. 100Mhz. + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz. divr: None, }); config.rcc.sys = Sysclk::Pll1P; // 400 Mhz diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index 88d65d5b..d4c0bcdb 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs @@ -40,10 +40,10 @@ fn main() -> ! { config.rcc.csi = true; config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(4), // used by SPI3. 100Mhz. + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz. divr: None, }); config.rcc.sys = Sysclk::Pll1P; // 400 Mhz diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index 14de4356..c1e5144b 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs @@ -28,9 +28,9 @@ async fn main(_spawner: Spawner) { config.rcc.hsi48 = true; // needed for USB config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), divq: None, divr: None, }); diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index 806e49f5..d0208d8a 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; +use embassy_stm32::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -19,10 +19,10 @@ async fn main(_spawner: Spawner) { // 72Mhz clock (16 / 1 * 18 / 4) config.rcc.mux = ClockSrc::PLL( PLLSource::HSI16, - PLLClkDiv::Div4, - PLLSrcDiv::Div1, - PLLMul::Mul18, - Some(PLLClkDiv::Div6), // 48Mhz (16 / 1 * 18 / 6) + PllRDiv::DIV4, + PllPreDiv::DIV1, + PllMul::MUL18, + Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) ); let p = embassy_stm32::init(config); diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index eb1eed01..7e2b8c78 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -5,7 +5,7 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{self, ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; +use embassy_stm32::rcc::{self, ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; @@ -18,9 +18,9 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.mux = ClockSrc::PLL( PLLSource::HSE(Hertz::mhz(8)), - PLLClkDiv::Div2, - PLLSrcDiv::Div1, - PLLMul::Mul20, + PllRDiv::DIV2, + PllPreDiv::DIV1, + PllMul::MUL20, None, ); config.rcc.lse = Some(Hertz(32_768)); diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index ba4a9d23..8db89be2 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -49,7 +49,7 @@ use embassy_net_adin1110::{self, Device, Runner, ADIN1110}; use embedded_hal_bus::spi::ExclusiveDevice; use hal::gpio::Pull; use hal::i2c::Config as I2C_Config; -use hal::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; +use hal::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv}; use hal::spi::{Config as SPI_Config, Spi}; use hal::time::Hertz; @@ -80,9 +80,9 @@ async fn main(spawner: Spawner) { // 80MHz highest frequency for flash 0 wait. config.rcc.mux = ClockSrc::PLL( PLLSource::HSE(Hertz(8_000_000)), - PLLClkDiv::Div2, - PLLSrcDiv::Div1, - PLLMul::Mul20, + PllRDiv::DIV2, + PllPreDiv::DIV1, + PllMul::MUL20, None, ); config.rcc.hsi48 = true; // needed for rng diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 410d6891..dc0d98ad 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PLLClkDiv::Div2, PLLSrcDiv::Div1, PLLMul::Mul10, None); + config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); config.rcc.hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index 9549d64d..cc3c99b5 100644 --- a/examples/stm32l5/src/bin/rng.rs +++ b/examples/stm32l5/src/bin/rng.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; +use embassy_stm32::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.mux = ClockSrc::PLL( PLLSource::HSI16, - PLLClkDiv::Div2, - PLLSrcDiv::Div1, - PLLMul::Mul8, - Some(PLLClkDiv::Div2), + PllRDiv::DIV2, + PllPreDiv::DIV1, + PllMul::MUL8, + Some(PllQDiv::DIV2), ); let p = embassy_stm32::init(config); diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 15b84761..498147f9 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -45,7 +45,7 @@ async fn net_task(stack: &'static Stack>) -> ! { #[embassy_executor::main] async fn main(spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PLLClkDiv::Div2, PLLSrcDiv::Div1, PLLMul::Mul10, None); + config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); config.rcc.hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index 7e894e40..db6a9c76 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -22,7 +22,7 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PLLClkDiv::Div2, PLLSrcDiv::Div1, PLLMul::Mul10, None); + config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); config.rcc.hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 0c719560..e19ecbf0 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -20,7 +20,7 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PLLClkDiv::Div2, PLLSrcDiv::Div1, PLLMul::Mul10, None); + config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); config.rcc.hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index 278bd30f..9b2adb0a 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -25,9 +25,9 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.mux = ClockSrc::PLL1R(PllConfig { source: PllSrc::HSI16, - m: PllM::Div2, - n: PllN::Mul10, - r: PllClkDiv::NotDivided, + m: Pllm::DIV2, + n: Plln::MUL10, + r: Plldiv::DIV1, }); //config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz); config.rcc.hsi48 = true; diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 32ba03e4..79a9b5e8 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -202,9 +202,9 @@ pub fn config() -> Config { // 1 MHz PLL input * 240 = 240 MHz PLL VCO mul: unwrap!(PLLMul::try_from(240)), // 240 MHz PLL VCO / 2 = 120 MHz main PLL output - main_div: PLLMainDiv::Div2, + p_div: PLLPDiv::DIV2, // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - pll48_div: unwrap!(PLL48Div::try_from(5)), + q_div: PLLQDiv::DIV5, }; // System clock comes from PLL (= the 120 MHz main PLL output) config.rcc.mux = ClockSrc::PLL; @@ -239,10 +239,10 @@ pub fn config() -> Config { }); config.rcc.pll1 = Some(Pll { source: PllSource::Hse, - prediv: 2, - mul: 125, - divp: Some(2), - divq: Some(2), + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL125, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV2), divr: None, }); config.rcc.ahb_pre = AHBPrescaler::DIV1; @@ -261,16 +261,16 @@ pub fn config() -> Config { config.rcc.hsi48 = true; // needed for RNG config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(2), - divq: Some(8), // SPI1 cksel defaults to pll1_q + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: Some(PllDiv::DIV8), // SPI1 cksel defaults to pll1_q divr: None, }); config.rcc.pll2 = Some(Pll { - prediv: 4, - mul: 50, - divp: Some(8), // 100mhz + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); @@ -290,10 +290,10 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL( // 72Mhz clock (16 / 1 * 18 / 4) PLLSource::HSI16, - PLLClkDiv::Div4, - PLLSrcDiv::Div1, - PLLMul::Mul18, - Some(PLLClkDiv::Div6), // 48Mhz (16 / 1 * 18 / 6) + PllRDiv::DIV4, + PllPreDiv::DIV1, + PllMul::MUL18, + Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) ); } @@ -303,9 +303,9 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL( // 110Mhz clock (16 / 4 * 55 / 2) PLLSource::HSI16, - PLLClkDiv::Div2, - PLLSrcDiv::Div4, - PLLMul::Mul55, + PllRDiv::DIV2, + PllPreDiv::DIV4, + PllMul::MUL55, None, ); } @@ -313,7 +313,7 @@ pub fn config() -> Config { #[cfg(feature = "stm32u585ai")] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz); + config.rcc.mux = ClockSrc::MSI(Msirange::RANGE_48MHZ); } #[cfg(feature = "stm32l073rz")] From 7526b8edba9bbfec7831959afef7736f2d1a39b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20G=C3=B3rski?= Date: Fri, 6 Oct 2023 17:45:04 +0200 Subject: [PATCH 52/95] stm32/eth: Move `phy_addr` from `Ethernet` to `PHY` Previously, PHY addressing was a concern of the `Ethernet` struct which limited the `PHY` implementations which very often have to manage multiple PHYs internally and thus possibly need to address many of them. This change extends `StationManagement` to allow addressing different PHY addresses via SMI. --- embassy-stm32/src/eth/generic_smi.rs | 33 ++++++++++++++-------------- embassy-stm32/src/eth/mod.rs | 4 ++-- embassy-stm32/src/eth/v1/mod.rs | 11 ++++------ embassy-stm32/src/eth/v2/mod.rs | 11 ++++------ 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index 2ed46ca2..1e1094a1 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs @@ -41,39 +41,40 @@ mod phy_consts { } use self::phy_consts::*; -/// Generic SMI Ethernet PHY +/// Generic SMI Ethernet PHY implementation pub struct GenericSMI { + phy_addr: u8, #[cfg(feature = "time")] poll_interval: Duration, - #[cfg(not(feature = "time"))] - _private: (), } impl GenericSMI { - pub fn new() -> Self { + /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication + pub fn new(phy_addr: u8) -> Self { Self { + phy_addr, #[cfg(feature = "time")] poll_interval: Duration::from_millis(500), - #[cfg(not(feature = "time"))] - _private: (), } } } unsafe impl PHY for GenericSMI { - /// Reset PHY and wait for it to come out of reset. fn phy_reset(&mut self, sm: &mut S) { - sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET); - while sm.smi_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} + sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); + while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} } - /// PHY initialisation. fn phy_init(&mut self, sm: &mut S) { // Clear WU CSR self.smi_write_ext(sm, PHY_REG_WUCSR, 0); // Enable auto-negotiation - sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M); + sm.smi_write( + self.phy_addr, + PHY_REG_BCR, + PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M, + ); } fn poll_link(&mut self, sm: &mut S, cx: &mut Context) -> bool { @@ -83,7 +84,7 @@ unsafe impl PHY for GenericSMI { #[cfg(feature = "time")] let _ = Timer::after(self.poll_interval).poll_unpin(cx); - let bsr = sm.smi_read(PHY_REG_BSR); + let bsr = sm.smi_read(self.phy_addr, PHY_REG_BSR); // No link without autonegotiate if bsr & PHY_REG_BSR_ANDONE == 0 { @@ -108,9 +109,9 @@ impl GenericSMI { // Writes a value to an extended PHY register in MMD address space fn smi_write_ext(&mut self, sm: &mut S, reg_addr: u16, reg_data: u16) { - sm.smi_write(PHY_REG_CTL, 0x0003); // set address - sm.smi_write(PHY_REG_ADDAR, reg_addr); - sm.smi_write(PHY_REG_CTL, 0x4003); // set data - sm.smi_write(PHY_REG_ADDAR, reg_data); + sm.smi_write(self.phy_addr, PHY_REG_CTL, 0x0003); // set address + sm.smi_write(self.phy_addr, PHY_REG_ADDAR, reg_addr); + sm.smi_write(self.phy_addr, PHY_REG_CTL, 0x4003); // set data + sm.smi_write(self.phy_addr, PHY_REG_ADDAR, reg_data); } } diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs index 1e057235..556aadd7 100644 --- a/embassy-stm32/src/eth/mod.rs +++ b/embassy-stm32/src/eth/mod.rs @@ -134,9 +134,9 @@ impl<'a, 'd> embassy_net_driver::TxToken for TxToken<'a, 'd> { /// The methods cannot move out of self pub unsafe trait StationManagement { /// Read a register over SMI. - fn smi_read(&mut self, reg: u8) -> u16; + fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16; /// Write a register over SMI. - fn smi_write(&mut self, reg: u8, val: u16); + fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16); } /// Traits for an Ethernet PHY diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index 4d19103d..631a9377 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs @@ -107,7 +107,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { tx_en: impl Peripheral

> + 'd, phy: P, mac_addr: [u8; 6], - phy_addr: u8, ) -> Self { into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); @@ -227,7 +226,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { station_management: EthernetStationManagement { peri: PhantomData, clock_range: clock_range, - phy_addr: phy_addr, }, mac_addr, tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), @@ -271,15 +269,14 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { pub struct EthernetStationManagement { peri: PhantomData, clock_range: Cr, - phy_addr: u8, } unsafe impl StationManagement for EthernetStationManagement { - fn smi_read(&mut self, reg: u8) -> u16 { + fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { let mac = ETH.ethernet_mac(); mac.macmiiar().modify(|w| { - w.set_pa(self.phy_addr); + w.set_pa(phy_addr); w.set_mr(reg); w.set_mw(Mw::READ); // read operation w.set_cr(self.clock_range); @@ -289,12 +286,12 @@ unsafe impl StationManagement for EthernetStationManagement { mac.macmiidr().read().md() } - fn smi_write(&mut self, reg: u8, val: u16) { + fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { let mac = ETH.ethernet_mac(); mac.macmiidr().write(|w| w.set_md(val)); mac.macmiiar().modify(|w| { - w.set_pa(self.phy_addr); + w.set_pa(phy_addr); w.set_mr(reg); w.set_mw(Mw::WRITE); // write w.set_cr(self.clock_range); diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 6efd40e3..12cf618a 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -71,7 +71,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { tx_en: impl Peripheral

> + 'd, phy: P, mac_addr: [u8; 6], - phy_addr: u8, ) -> Self { into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); @@ -202,7 +201,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { station_management: EthernetStationManagement { peri: PhantomData, clock_range: clock_range, - phy_addr: phy_addr, }, mac_addr, }; @@ -242,15 +240,14 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { pub struct EthernetStationManagement { peri: PhantomData, clock_range: u8, - phy_addr: u8, } unsafe impl StationManagement for EthernetStationManagement { - fn smi_read(&mut self, reg: u8) -> u16 { + fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { let mac = ETH.ethernet_mac(); mac.macmdioar().modify(|w| { - w.set_pa(self.phy_addr); + w.set_pa(phy_addr); w.set_rda(reg); w.set_goc(0b11); // read w.set_cr(self.clock_range); @@ -260,12 +257,12 @@ unsafe impl StationManagement for EthernetStationManagement { mac.macmdiodr().read().md() } - fn smi_write(&mut self, reg: u8, val: u16) { + fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { let mac = ETH.ethernet_mac(); mac.macmdiodr().write(|w| w.set_md(val)); mac.macmdioar().modify(|w| { - w.set_pa(self.phy_addr); + w.set_pa(phy_addr); w.set_rda(reg); w.set_goc(0b01); // write w.set_cr(self.clock_range); From e62bf6a9fd97979d74ed8ba8022d867d4a8a0d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20G=C3=B3rski?= Date: Mon, 9 Oct 2023 12:00:23 +0200 Subject: [PATCH 53/95] Patch tests & examples --- examples/stm32f4/src/bin/eth.rs | 3 +-- examples/stm32f7/src/bin/eth.rs | 3 +-- examples/stm32h5/src/bin/eth.rs | 3 +-- examples/stm32h7/src/bin/eth.rs | 3 +-- examples/stm32h7/src/bin/eth_client.rs | 3 +-- tests/stm32/src/bin/eth.rs | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 16bf5d94..6a1d4b08 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -58,9 +58,8 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB13, p.PG11, - GenericSMI::new(), + GenericSMI::new(0), mac_addr, - 0, ); let config = embassy_net::Config::dhcpv4(Default::default()); diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 93c97c8e..7c9ee159 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -59,9 +59,8 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB13, p.PG11, - GenericSMI::new(), + GenericSMI::new(0), mac_addr, - 0, ); let config = embassy_net::Config::dhcpv4(Default::default()); diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 2f445476..2535c6a6 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -80,9 +80,8 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB15, p.PG11, - GenericSMI::new(), + GenericSMI::new(0), mac_addr, - 0, ); let config = embassy_net::Config::dhcpv4(Default::default()); diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index a6603d50..6fbf4344 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -77,9 +77,8 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB13, p.PG11, - GenericSMI::new(), + GenericSMI::new(0), mac_addr, - 0, ); let config = embassy_net::Config::dhcpv4(Default::default()); diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 596de2f4..4db7aa25 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -78,9 +78,8 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB13, p.PG11, - GenericSMI::new(), + GenericSMI::new(0), mac_addr, - 0, ); let config = embassy_net::Config::dhcpv4(Default::default()); diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index 13919238..6d5e05cd 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs @@ -85,9 +85,8 @@ async fn main(spawner: Spawner) { #[cfg(feature = "stm32h563zi")] p.PB15, p.PG11, - GenericSMI::new(), + GenericSMI::new(0), mac_addr, - 0, ); let config = embassy_net::Config::dhcpv4(Default::default()); From 3616d68aaa0d41bd489295942c57e29a43338dac Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Tue, 10 Oct 2023 12:48:21 +0300 Subject: [PATCH 54/95] stm32 flash: check lock bit before unlocking It hardfaults if already unlocked flash is unlocked again. --- embassy-stm32/src/flash/f0.rs | 6 ++++-- embassy-stm32/src/flash/f3.rs | 6 ++++-- embassy-stm32/src/flash/f4.rs | 6 ++++-- embassy-stm32/src/flash/f7.rs | 6 ++++-- embassy-stm32/src/flash/g0.rs | 6 ++++-- embassy-stm32/src/flash/h7.rs | 12 ++++++++---- embassy-stm32/src/flash/l.rs | 18 ++++++++++++------ 7 files changed, 40 insertions(+), 20 deletions(-) diff --git a/embassy-stm32/src/flash/f0.rs b/embassy-stm32/src/flash/f0.rs index d011522b..1ab8435a 100644 --- a/embassy-stm32/src/flash/f0.rs +++ b/embassy-stm32/src/flash/f0.rs @@ -19,8 +19,10 @@ pub(crate) unsafe fn lock() { } pub(crate) unsafe fn unlock() { - pac::FLASH.keyr().write(|w| w.set_fkeyr(0x4567_0123)); - pac::FLASH.keyr().write(|w| w.set_fkeyr(0xCDEF_89AB)); + if pac::FLASH.cr().read().lock() { + pac::FLASH.keyr().write(|w| w.set_fkeyr(0x4567_0123)); + pac::FLASH.keyr().write(|w| w.set_fkeyr(0xCDEF_89AB)); + } } pub(crate) unsafe fn enable_blocking_write() { diff --git a/embassy-stm32/src/flash/f3.rs b/embassy-stm32/src/flash/f3.rs index 065369f6..7e6d7ca2 100644 --- a/embassy-stm32/src/flash/f3.rs +++ b/embassy-stm32/src/flash/f3.rs @@ -19,8 +19,10 @@ pub(crate) unsafe fn lock() { } pub(crate) unsafe fn unlock() { - pac::FLASH.keyr().write(|w| w.set_fkeyr(0x4567_0123)); - pac::FLASH.keyr().write(|w| w.set_fkeyr(0xCDEF_89AB)); + if pac::FLASH.cr().read().lock() { + pac::FLASH.keyr().write(|w| w.set_fkeyr(0x4567_0123)); + pac::FLASH.keyr().write(|w| w.set_fkeyr(0xCDEF_89AB)); + } } pub(crate) unsafe fn enable_blocking_write() { diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 913950fe..81deaa17 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -228,8 +228,10 @@ pub(crate) unsafe fn lock() { } pub(crate) unsafe fn unlock() { - pac::FLASH.keyr().write(|w| w.set_key(0x45670123)); - pac::FLASH.keyr().write(|w| w.set_key(0xCDEF89AB)); + if pac::FLASH.cr().read().lock() { + pac::FLASH.keyr().write(|w| w.set_key(0x45670123)); + pac::FLASH.keyr().write(|w| w.set_key(0xCDEF89AB)); + } } pub(crate) unsafe fn enable_write() { diff --git a/embassy-stm32/src/flash/f7.rs b/embassy-stm32/src/flash/f7.rs index 3a5bdf9c..b52231ca 100644 --- a/embassy-stm32/src/flash/f7.rs +++ b/embassy-stm32/src/flash/f7.rs @@ -19,8 +19,10 @@ pub(crate) unsafe fn lock() { } pub(crate) unsafe fn unlock() { - pac::FLASH.keyr().write(|w| w.set_key(0x4567_0123)); - pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB)); + if pac::FLASH.cr().read().lock() { + pac::FLASH.keyr().write(|w| w.set_key(0x4567_0123)); + pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB)); + } } pub(crate) unsafe fn enable_blocking_write() { diff --git a/embassy-stm32/src/flash/g0.rs b/embassy-stm32/src/flash/g0.rs index 3a457601..19a38897 100644 --- a/embassy-stm32/src/flash/g0.rs +++ b/embassy-stm32/src/flash/g0.rs @@ -24,8 +24,10 @@ pub(crate) unsafe fn unlock() { while pac::FLASH.sr().read().bsy() {} // Unlock flash - pac::FLASH.keyr().write(|w| w.set_keyr(0x4567_0123)); - pac::FLASH.keyr().write(|w| w.set_keyr(0xCDEF_89AB)); + if pac::FLASH.cr().read().lock() { + pac::FLASH.keyr().write(|w| w.set_keyr(0x4567_0123)); + pac::FLASH.keyr().write(|w| w.set_keyr(0xCDEF_89AB)); + } } pub(crate) unsafe fn enable_blocking_write() { diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs index 625bf13f..b064fd6e 100644 --- a/embassy-stm32/src/flash/h7.rs +++ b/embassy-stm32/src/flash/h7.rs @@ -26,11 +26,15 @@ pub(crate) unsafe fn lock() { } pub(crate) unsafe fn unlock() { - pac::FLASH.bank(0).keyr().write(|w| w.set_keyr(0x4567_0123)); - pac::FLASH.bank(0).keyr().write(|w| w.set_keyr(0xCDEF_89AB)); + if pac::FLASH.bank(0).cr().read().lock() { + pac::FLASH.bank(0).keyr().write(|w| w.set_keyr(0x4567_0123)); + pac::FLASH.bank(0).keyr().write(|w| w.set_keyr(0xCDEF_89AB)); + } if is_dual_bank() { - pac::FLASH.bank(1).keyr().write(|w| w.set_keyr(0x4567_0123)); - pac::FLASH.bank(1).keyr().write(|w| w.set_keyr(0xCDEF_89AB)); + if pac::FLASH.bank(1).cr().read().lock() { + pac::FLASH.bank(1).keyr().write(|w| w.set_keyr(0x4567_0123)); + pac::FLASH.bank(1).keyr().write(|w| w.set_keyr(0xCDEF_89AB)); + } } } diff --git a/embassy-stm32/src/flash/l.rs b/embassy-stm32/src/flash/l.rs index 24dcf99b..1db0da92 100644 --- a/embassy-stm32/src/flash/l.rs +++ b/embassy-stm32/src/flash/l.rs @@ -28,17 +28,23 @@ pub(crate) unsafe fn lock() { pub(crate) unsafe fn unlock() { #[cfg(any(flash_wl, flash_wb, flash_l4))] { - pac::FLASH.keyr().write(|w| w.set_keyr(0x4567_0123)); - pac::FLASH.keyr().write(|w| w.set_keyr(0xCDEF_89AB)); + if pac::FLASH.cr().read().lock() { + pac::FLASH.keyr().write(|w| w.set_keyr(0x4567_0123)); + pac::FLASH.keyr().write(|w| w.set_keyr(0xCDEF_89AB)); + } } #[cfg(any(flash_l0, flash_l1))] { - pac::FLASH.pekeyr().write(|w| w.set_pekeyr(0x89ABCDEF)); - pac::FLASH.pekeyr().write(|w| w.set_pekeyr(0x02030405)); + if pac::FLASH.pecr().read().pelock() { + pac::FLASH.pekeyr().write(|w| w.set_pekeyr(0x89ABCDEF)); + pac::FLASH.pekeyr().write(|w| w.set_pekeyr(0x02030405)); + } - pac::FLASH.prgkeyr().write(|w| w.set_prgkeyr(0x8C9DAEBF)); - pac::FLASH.prgkeyr().write(|w| w.set_prgkeyr(0x13141516)); + if pac::FLASH.pecr().read().prglock() { + pac::FLASH.prgkeyr().write(|w| w.set_prgkeyr(0x8C9DAEBF)); + pac::FLASH.prgkeyr().write(|w| w.set_prgkeyr(0x13141516)); + } } } From cd12c9cbceb0ba90a493194d8200b1d8e98bba1b Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Tue, 10 Oct 2023 18:10:53 +0200 Subject: [PATCH 55/95] stm32: add timeout to I2C driver --- embassy-stm32/Cargo.toml | 8 +- embassy-stm32/src/i2c/mod.rs | 5 - embassy-stm32/src/i2c/timeout.rs | 209 ------------------------------- embassy-stm32/src/i2c/v2.rs | 129 +++++++++++-------- examples/stm32f4/src/bin/i2c.rs | 8 +- examples/stm32h5/src/bin/i2c.rs | 8 +- examples/stm32h7/src/bin/i2c.rs | 8 +- 7 files changed, 85 insertions(+), 290 deletions(-) delete mode 100644 embassy-stm32/src/i2c/timeout.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 70e8f2e2..a4e4e51d 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" src_base = "https://github.com/embassy-rs/embassy/blob/embassy-stm32-v$VERSION/embassy-stm32/src/" src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-stm32/src/" -features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any", "time"] +features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any"] flavors = [ { regex_feature = "stm32f0.*", target = "thumbv6m-none-eabi" }, { regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" }, @@ -33,7 +33,7 @@ flavors = [ [dependencies] embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.3", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } @@ -87,7 +87,7 @@ default = ["rt"] rt = ["stm32-metapac/rt"] ## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging -defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"] +defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"] exti = [] low-power = [ "dep:embassy-executor", "embassy-executor/arch-cortex-m" ] @@ -112,7 +112,7 @@ unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"] #! ## Time ## Enables additional driver features that depend on embassy-time -time = ["dep:embassy-time"] +time = [] # Features starting with `_` are for internal use only. They're not intended # to be enabled by other crates, and are not covered by semver guarantees. diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 62d13e90..dde1a504 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -7,11 +7,6 @@ use crate::interrupt; mod _version; pub use _version::*; -#[cfg(feature = "time")] -mod timeout; -#[cfg(feature = "time")] -pub use timeout::*; - use crate::peripherals; #[derive(Debug, PartialEq, Eq)] diff --git a/embassy-stm32/src/i2c/timeout.rs b/embassy-stm32/src/i2c/timeout.rs deleted file mode 100644 index 103017cd..00000000 --- a/embassy-stm32/src/i2c/timeout.rs +++ /dev/null @@ -1,209 +0,0 @@ -use embassy_time::{Duration, Instant}; - -use super::{Error, I2c, Instance}; - -/// An I2C wrapper, which provides `embassy-time` based timeouts for all `embedded-hal` trait methods. -/// -/// This is useful for recovering from a shorted bus or a device stuck in a clock stretching state. -/// A regular [I2c] would freeze until condition is removed. -pub struct TimeoutI2c<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> { - i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, - timeout: Duration, -} - -fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> { - let deadline = Instant::now() + timeout; - move || { - if Instant::now() > deadline { - Err(Error::Timeout) - } else { - Ok(()) - } - } -} - -impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { - pub fn new(i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self { - Self { i2c, timeout } - } - - // ========================= - // Async public API - - #[cfg(i2c_v2)] - pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma, - { - self.write_timeout(address, write, self.timeout).await - } - - #[cfg(i2c_v2)] - pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma, - { - self.i2c.write_timeout(address, write, timeout_fn(timeout)).await - } - - #[cfg(i2c_v2)] - pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma, - { - self.write_vectored_timeout(address, write, self.timeout).await - } - - #[cfg(i2c_v2)] - pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma, - { - self.i2c - .write_vectored_timeout(address, write, timeout_fn(timeout)) - .await - } - - #[cfg(i2c_v2)] - pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma, - { - self.read_timeout(address, buffer, self.timeout).await - } - - #[cfg(i2c_v2)] - pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma, - { - self.i2c.read_timeout(address, buffer, timeout_fn(timeout)).await - } - - #[cfg(i2c_v2)] - pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> - where - TXDMA: super::TxDma, - RXDMA: super::RxDma, - { - self.write_read_timeout(address, write, read, self.timeout).await - } - - #[cfg(i2c_v2)] - pub async fn write_read_timeout( - &mut self, - address: u8, - write: &[u8], - read: &mut [u8], - timeout: Duration, - ) -> Result<(), Error> - where - TXDMA: super::TxDma, - RXDMA: super::RxDma, - { - self.i2c - .write_read_timeout(address, write, read, timeout_fn(timeout)) - .await - } - - // ========================= - // Blocking public API - - /// Blocking read with a custom timeout - pub fn blocking_read_timeout(&mut self, addr: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> { - self.i2c.blocking_read_timeout(addr, read, timeout_fn(timeout)) - } - - /// Blocking read with default timeout, provided in [`TimeoutI2c::new()`] - pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> { - self.blocking_read_timeout(addr, read, self.timeout) - } - - /// Blocking write with a custom timeout - pub fn blocking_write_timeout(&mut self, addr: u8, write: &[u8], timeout: Duration) -> Result<(), Error> { - self.i2c.blocking_write_timeout(addr, write, timeout_fn(timeout)) - } - - /// Blocking write with default timeout, provided in [`TimeoutI2c::new()`] - pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> { - self.blocking_write_timeout(addr, write, self.timeout) - } - - /// Blocking write-read with a custom timeout - pub fn blocking_write_read_timeout( - &mut self, - addr: u8, - write: &[u8], - read: &mut [u8], - timeout: Duration, - ) -> Result<(), Error> { - self.i2c - .blocking_write_read_timeout(addr, write, read, timeout_fn(timeout)) - } - - /// Blocking write-read with default timeout, provided in [`TimeoutI2c::new()`] - pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { - self.blocking_write_read_timeout(addr, write, read, self.timeout) - } -} - -impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read - for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> -{ - type Error = Error; - - fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> { - self.blocking_read(addr, read) - } -} - -impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write - for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> -{ - type Error = Error; - - fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> { - self.blocking_write(addr, write) - } -} - -impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead - for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> -{ - type Error = Error; - - fn write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { - self.blocking_write_read(addr, write, read) - } -} - -#[cfg(feature = "unstable-traits")] -mod eh1 { - use super::*; - - impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { - type Error = Error; - } - - impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { - fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { - self.blocking_read(address, read) - } - - fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { - self.blocking_write(address, write) - } - - fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { - self.blocking_write_read(address, write, read) - } - - fn transaction( - &mut self, - _address: u8, - _operations: &mut [embedded_hal_1::i2c::Operation<'_>], - ) -> Result<(), Self::Error> { - todo!(); - } - } -} diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 543d8f1b..256b3963 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -7,6 +7,7 @@ use embassy_embedded_hal::SetConfig; use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; +use embassy_time::{Duration, Instant}; use crate::dma::{NoDma, Transfer}; use crate::gpio::sealed::AFType; @@ -43,6 +44,7 @@ impl interrupt::typelevel::Handler for InterruptHandl pub struct Config { pub sda_pullup: bool, pub scl_pullup: bool, + pub transaction_timeout: Duration, } impl Default for Config { @@ -50,6 +52,7 @@ impl Default for Config { Self { sda_pullup: false, scl_pullup: false, + transaction_timeout: Duration::from_millis(100), } } } @@ -71,6 +74,7 @@ pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { tx_dma: PeripheralRef<'d, TXDMA>, #[allow(dead_code)] rx_dma: PeripheralRef<'d, RXDMA>, + timeout: Duration, } impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { @@ -132,6 +136,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { _peri: peri, tx_dma, rx_dma, + timeout: config.transaction_timeout, } } @@ -598,22 +603,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { where TXDMA: crate::i2c::TxDma, { - self.write_timeout(address, write, || Ok(())).await + self.write_timeout(address, write, self.timeout).await } - pub async fn write_timeout( - &mut self, - address: u8, - write: &[u8], - check_timeout: impl Fn() -> Result<(), Error>, - ) -> Result<(), Error> + pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, { if write.is_empty() { - self.write_internal(address, write, true, check_timeout) + self.write_internal(address, write, true, timeout_fn(timeout)) } else { - self.write_dma_internal(address, write, true, true, check_timeout).await + embassy_time::with_timeout( + timeout, + self.write_dma_internal(address, write, true, true, timeout_fn(timeout)), + ) + .await + .unwrap_or(Err(Error::Timeout)) } } @@ -621,15 +626,10 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { where TXDMA: crate::i2c::TxDma, { - self.write_vectored_timeout(address, write, || Ok(())).await + self.write_vectored_timeout(address, write, self.timeout).await } - pub async fn write_vectored_timeout( - &mut self, - address: u8, - write: &[&[u8]], - check_timeout: impl Fn() -> Result<(), Error>, - ) -> Result<(), Error> + pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, { @@ -644,8 +644,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { let next = iter.next(); let is_last = next.is_none(); - self.write_dma_internal(address, c, first, is_last, || check_timeout()) - .await?; + embassy_time::with_timeout( + timeout, + self.write_dma_internal(address, c, first, is_last, timeout_fn(timeout)), + ) + .await + .unwrap_or(Err(Error::Timeout))?; first = false; current = next; } @@ -656,22 +660,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { where RXDMA: crate::i2c::RxDma, { - self.read_timeout(address, buffer, || Ok(())).await + self.read_timeout(address, buffer, self.timeout).await } - pub async fn read_timeout( - &mut self, - address: u8, - buffer: &mut [u8], - check_timeout: impl Fn() -> Result<(), Error>, - ) -> Result<(), Error> + pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> where RXDMA: crate::i2c::RxDma, { if buffer.is_empty() { - self.read_internal(address, buffer, false, check_timeout) + self.read_internal(address, buffer, false, timeout_fn(timeout)) } else { - self.read_dma_internal(address, buffer, false, check_timeout).await + embassy_time::with_timeout( + timeout, + self.read_dma_internal(address, buffer, false, timeout_fn(timeout)), + ) + .await + .unwrap_or(Err(Error::Timeout)) } } @@ -680,7 +684,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { TXDMA: super::TxDma, RXDMA: super::RxDma, { - self.write_read_timeout(address, write, read, || Ok(())).await + self.write_read_timeout(address, write, read, self.timeout).await } pub async fn write_read_timeout( @@ -688,23 +692,36 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { address: u8, write: &[u8], read: &mut [u8], - check_timeout: impl Fn() -> Result<(), Error>, + timeout: Duration, ) -> Result<(), Error> where TXDMA: super::TxDma, RXDMA: super::RxDma, { + let start_instant = Instant::now(); + let check_timeout = timeout_fn(timeout); if write.is_empty() { - self.write_internal(address, write, false, || check_timeout())?; + self.write_internal(address, write, false, &check_timeout)?; } else { - self.write_dma_internal(address, write, true, true, || check_timeout()) - .await?; + embassy_time::with_timeout( + timeout, + self.write_dma_internal(address, write, true, true, &check_timeout), + ) + .await + .unwrap_or(Err(Error::Timeout))?; } + let time_left_until_timeout = timeout - Instant::now().duration_since(start_instant); + if read.is_empty() { - self.read_internal(address, read, true, check_timeout)?; + self.read_internal(address, read, true, &check_timeout)?; } else { - self.read_dma_internal(address, read, true, check_timeout).await?; + embassy_time::with_timeout( + time_left_until_timeout, + self.read_dma_internal(address, read, true, &check_timeout), + ) + .await + .unwrap_or(Err(Error::Timeout))?; } Ok(()) @@ -713,31 +730,21 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // ========================= // Blocking public API - pub fn blocking_read_timeout( - &mut self, - address: u8, - read: &mut [u8], - check_timeout: impl Fn() -> Result<(), Error>, - ) -> Result<(), Error> { - self.read_internal(address, read, false, &check_timeout) + pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> { + self.read_internal(address, read, false, timeout_fn(timeout)) // Automatic Stop } pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { - self.blocking_read_timeout(address, read, || Ok(())) + self.blocking_read_timeout(address, read, self.timeout) } - pub fn blocking_write_timeout( - &mut self, - address: u8, - write: &[u8], - check_timeout: impl Fn() -> Result<(), Error>, - ) -> Result<(), Error> { - self.write_internal(address, write, true, &check_timeout) + pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> { + self.write_internal(address, write, true, timeout_fn(timeout)) } pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { - self.blocking_write_timeout(address, write, || Ok(())) + self.blocking_write_timeout(address, write, self.timeout) } pub fn blocking_write_read_timeout( @@ -745,26 +752,29 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { address: u8, write: &[u8], read: &mut [u8], - check_timeout: impl Fn() -> Result<(), Error>, + timeout: Duration, ) -> Result<(), Error> { + let check_timeout = timeout_fn(timeout); self.write_internal(address, write, false, &check_timeout)?; self.read_internal(address, read, true, &check_timeout) // Automatic Stop } pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { - self.blocking_write_read_timeout(address, write, read, || Ok(())) + self.blocking_write_read_timeout(address, write, read, self.timeout) } pub fn blocking_write_vectored_timeout( &mut self, address: u8, write: &[&[u8]], - check_timeout: impl Fn() -> Result<(), Error>, + timeout: Duration, ) -> Result<(), Error> { if write.is_empty() { return Err(Error::ZeroLengthTransfer); } + + let check_timeout = timeout_fn(timeout); let first_length = write[0].len(); let last_slice_index = write.len() - 1; @@ -834,7 +844,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { - self.blocking_write_vectored_timeout(address, write, || Ok(())) + self.blocking_write_vectored_timeout(address, write, self.timeout) } } @@ -1089,3 +1099,14 @@ impl<'d, T: Instance> SetConfig for I2c<'d, T> { Ok(()) } } + +fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> { + let deadline = Instant::now() + timeout; + move || { + if Instant::now() > deadline { + Err(Error::Timeout) + } else { + Ok(()) + } + } +} diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs index a9295732..10ca2bdc 100644 --- a/examples/stm32f4/src/bin/i2c.rs +++ b/examples/stm32f4/src/bin/i2c.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::dma::NoDma; -use embassy_stm32::i2c::{Error, I2c, TimeoutI2c}; +use embassy_stm32::i2c::{Error, I2c}; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, i2c, peripherals}; use embassy_time::Duration; @@ -34,13 +34,9 @@ async fn main(_spawner: Spawner) { Default::default(), ); - // I2C bus can freeze if SCL line is shorted or due to a broken device that clock stretches for too long. - // TimeoutI2c allows recovering from such errors by throwing `Error::Timeout` after a given delay. - let mut timeout_i2c = TimeoutI2c::new(&mut i2c, Duration::from_millis(1000)); - let mut data = [0u8; 1]; - match timeout_i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { + match i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { Ok(()) => info!("Whoami: {}", data[0]), Err(Error::Timeout) => error!("Operation timed out"), Err(e) => error!("I2c Error: {:?}", e), diff --git a/examples/stm32h5/src/bin/i2c.rs b/examples/stm32h5/src/bin/i2c.rs index 8b6fe71a..4ce378e9 100644 --- a/examples/stm32h5/src/bin/i2c.rs +++ b/examples/stm32h5/src/bin/i2c.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::i2c::{Error, I2c, TimeoutI2c}; +use embassy_stm32::i2c::{Error, I2c}; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, i2c, peripherals}; use embassy_time::Duration; @@ -33,13 +33,9 @@ async fn main(_spawner: Spawner) { Default::default(), ); - // I2C bus can freeze if SCL line is shorted or due to a broken device that clock stretches for too long. - // TimeoutI2c allows recovering from such errors by throwing `Error::Timeout` after a given delay. - let mut timeout_i2c = TimeoutI2c::new(&mut i2c, Duration::from_millis(1000)); - let mut data = [0u8; 1]; - match timeout_i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { + match i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { Ok(()) => info!("Whoami: {}", data[0]), Err(Error::Timeout) => error!("Operation timed out"), Err(e) => error!("I2c Error: {:?}", e), diff --git a/examples/stm32h7/src/bin/i2c.rs b/examples/stm32h7/src/bin/i2c.rs index c2979c59..7cd12e5e 100644 --- a/examples/stm32h7/src/bin/i2c.rs +++ b/examples/stm32h7/src/bin/i2c.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::i2c::{Error, I2c, TimeoutI2c}; +use embassy_stm32::i2c::{Error, I2c}; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, i2c, peripherals}; use embassy_time::Duration; @@ -33,13 +33,9 @@ async fn main(_spawner: Spawner) { Default::default(), ); - // I2C bus can freeze if SCL line is shorted or due to a broken device that clock stretches for too long. - // TimeoutI2c allows recovering from such errors by throwing `Error::Timeout` after a given delay. - let mut timeout_i2c = TimeoutI2c::new(&mut i2c, Duration::from_millis(1000)); - let mut data = [0u8; 1]; - match timeout_i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { + match i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { Ok(()) => info!("Whoami: {}", data[0]), Err(Error::Timeout) => error!("Operation timed out"), Err(e) => error!("I2c Error: {:?}", e), From 0cfa8d1bb5807b25612ab21b9894fd59002e6dab Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 11 Oct 2023 00:12:33 +0200 Subject: [PATCH 56/95] stm32/rcc: use more PLL etc enums from PAC. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/build.rs | 2 +- embassy-stm32/src/rcc/c0.rs | 72 ++------- embassy-stm32/src/rcc/f2.rs | 6 +- embassy-stm32/src/rcc/f3.rs | 191 ++++++++++------------- embassy-stm32/src/rcc/g0.rs | 38 +---- embassy-stm32/src/rcc/g4.rs | 127 +++++----------- embassy-stm32/src/rcc/h.rs | 12 +- embassy-stm32/src/rcc/l0.rs | 176 ++++----------------- embassy-stm32/src/rcc/l1.rs | 207 ++++++++----------------- embassy-stm32/src/rcc/l4.rs | 12 +- embassy-stm32/src/rcc/l5.rs | 12 +- embassy-stm32/src/rcc/wb.rs | 180 +++++----------------- embassy-stm32/src/rcc/wba.rs | 8 +- embassy-stm32/src/rcc/wl.rs | 228 +++++++--------------------- embassy-stm32/src/time.rs | 7 + examples/stm32f334/src/bin/adc.rs | 4 +- examples/stm32f334/src/bin/opamp.rs | 4 +- examples/stm32g4/src/bin/adc.rs | 2 +- tests/stm32/src/common.rs | 8 +- 20 files changed, 368 insertions(+), 932 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 70e8f2e2..b6641d71 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e89b8cfc30e480036aaf502f34c874ee42d68026" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ff45aa382efb704dd2275dd69e71af73343f149d" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e89b8cfc30e480036aaf502f34c874ee42d68026", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ff45aa382efb704dd2275dd69e71af73343f149d", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 643f1b6e..810da37e 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -908,7 +908,7 @@ fn main() { match e { "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true, "Timpre" | "Pllrclkpre" => false, - e if e.ends_with("pre") || e.ends_with("div") || e.ends_with("mul") => true, + 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/c0.rs b/embassy-stm32/src/rcc/c0.rs index efa56de7..34d339a7 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -1,6 +1,6 @@ use crate::pac::flash::vals::Latency; -pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; -use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; +use crate::pac::rcc::vals::Sw; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Ppre as APBPrescaler}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -19,33 +19,6 @@ pub enum ClockSrc { LSI, } -#[derive(Clone, Copy)] -pub enum HSIPrescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div32, - Div64, - Div128, -} - -impl Into for HSIPrescaler { - fn into(self) -> Hsidiv { - match self { - HSIPrescaler::NotDivided => Hsidiv::DIV1, - HSIPrescaler::Div2 => Hsidiv::DIV2, - HSIPrescaler::Div4 => Hsidiv::DIV4, - HSIPrescaler::Div8 => Hsidiv::DIV8, - HSIPrescaler::Div16 => Hsidiv::DIV16, - HSIPrescaler::Div32 => Hsidiv::DIV32, - HSIPrescaler::Div64 => Hsidiv::DIV64, - HSIPrescaler::Div128 => Hsidiv::DIV128, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -57,7 +30,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::HSI(HSIPrescaler::NotDivided), + mux: ClockSrc::HSI(HSIPrescaler::DIV1), ahb_pre: AHBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1, } @@ -68,33 +41,32 @@ pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw) = match config.mux { ClockSrc::HSI(div) => { // Enable HSI - let div: Hsidiv = div.into(); RCC.cr().write(|w| { w.set_hsidiv(div); w.set_hsion(true) }); while !RCC.cr().read().hsirdy() {} - (HSI_FREQ.0 >> div.to_bits(), Sw::HSI) + (HSI_FREQ / div, Sw::HSI) } ClockSrc::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - (freq.0, Sw::HSE) + (freq, Sw::HSE) } ClockSrc::LSI => { // Enable LSI RCC.csr2().write(|w| w.set_lsion(true)); while !RCC.csr2().read().lsirdy() {} - (LSI_FREQ.0, Sw::LSI) + (LSI_FREQ, Sw::LSI) } }; // Determine the flash latency implied by the target clock speed // RM0454 § 3.3.4: - let target_flash_latency = if sys_clk <= 24_000_000 { + let target_flash_latency = if sys_clk <= Hertz(24_000_000) { Latency::WS0 } else { Latency::WS1 @@ -129,7 +101,7 @@ pub(crate) unsafe fn init(config: Config) { } // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once - let (sw, hpre, ppre) = (sw.into(), config.ahb_pre.into(), config.apb_pre.into()); + let (sw, hpre, ppre) = (sw.into(), config.ahb_pre, config.apb_pre); RCC.cfgr().modify(|w| { w.set_sw(sw); w.set_hpre(hpre); @@ -150,34 +122,20 @@ pub(crate) unsafe fn init(config: Config) { FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); } - let ahb_div = match config.ahb_pre { - AHBPrescaler::DIV1 => 1, - AHBPrescaler::DIV2 => 2, - AHBPrescaler::DIV4 => 4, - AHBPrescaler::DIV8 => 8, - AHBPrescaler::DIV16 => 16, - AHBPrescaler::DIV64 => 64, - AHBPrescaler::DIV128 => 128, - AHBPrescaler::DIV256 => 256, - AHBPrescaler::DIV512 => 512, - _ => unreachable!(), - }; - let ahb_freq = sys_clk / ahb_div; + let ahb_freq = sys_clk / config.ahb_pre; let (apb_freq, apb_tim_freq) = match config.apb_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - apb1: Hertz(apb_freq), - apb1_tim: Hertz(apb_tim_freq), + sys: sys_clk, + ahb1: ahb_freq, + apb1: apb_freq, + apb1_tim: apb_tim_freq, }); } diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 07b816bf..478d8894 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -301,9 +301,9 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_sw(sw.into()); - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); while RCC.cfgr().read().sws().to_bits() != sw.to_bits() {} diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 630dbd4f..a11eeee5 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -1,7 +1,8 @@ #[cfg(rcc_f3)] use crate::pac::adccommon::vals::Ckmode; use crate::pac::flash::vals::Latency; -use crate::pac::rcc::vals::{Adcpres, Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre}; +pub use crate::pac::rcc::vals::Adcpres; +use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -12,25 +13,6 @@ pub const HSI_FREQ: Hertz = Hertz(8_000_000); /// LSI speed pub const LSI_FREQ: Hertz = Hertz(40_000); -impl From for Adcpres { - fn from(value: AdcClockSource) -> Self { - match value { - AdcClockSource::PllDiv1 => Adcpres::DIV1, - AdcClockSource::PllDiv2 => Adcpres::DIV2, - AdcClockSource::PllDiv4 => Adcpres::DIV4, - AdcClockSource::PllDiv6 => Adcpres::DIV6, - AdcClockSource::PllDiv8 => Adcpres::DIV8, - AdcClockSource::PllDiv12 => Adcpres::DIV12, - AdcClockSource::PllDiv16 => Adcpres::DIV16, - AdcClockSource::PllDiv32 => Adcpres::DIV32, - AdcClockSource::PllDiv64 => Adcpres::DIV64, - AdcClockSource::PllDiv128 => Adcpres::DIV128, - AdcClockSource::PllDiv256 => Adcpres::DIV256, - _ => unreachable!(), - } - } -} - #[cfg(rcc_f3)] impl From for Ckmode { fn from(value: AdcClockSource) -> Self { @@ -45,32 +27,13 @@ impl From for Ckmode { #[derive(Clone, Copy)] pub enum AdcClockSource { - PllDiv1 = 1, - PllDiv2 = 2, - PllDiv4 = 4, - PllDiv6 = 6, - PllDiv8 = 8, - PllDiv12 = 12, - PllDiv16 = 16, - PllDiv32 = 32, - PllDiv64 = 64, - PllDiv128 = 128, - PllDiv256 = 256, + Pll(Adcpres), BusDiv1, BusDiv2, BusDiv4, } impl AdcClockSource { - pub fn is_bus(&self) -> bool { - match self { - Self::BusDiv1 => true, - Self::BusDiv2 => true, - Self::BusDiv4 => true, - _ => false, - } - } - pub fn bus_div(&self) -> u32 { match self { Self::BusDiv1 => 1, @@ -137,67 +100,67 @@ struct PllConfig { /// Initialize and Set the clock frequencies pub(crate) unsafe fn init(config: Config) { // Calculate the real System clock, and PLL configuration if applicable - let (Hertz(sysclk), pll_config) = get_sysclk(&config); - assert!(sysclk <= 72_000_000); + let (sysclk, pll_config) = get_sysclk(&config); + assert!(sysclk.0 <= 72_000_000); // Calculate real AHB clock - let hclk = config.hclk.map(|h| h.0).unwrap_or(sysclk); - let (hpre_bits, hpre_div) = match sysclk / hclk { + let hclk = config.hclk.map(|h| h).unwrap_or(sysclk); + let hpre = match sysclk.0 / hclk.0 { 0 => unreachable!(), - 1 => (Hpre::DIV1, 1), - 2 => (Hpre::DIV2, 2), - 3..=5 => (Hpre::DIV4, 4), - 6..=11 => (Hpre::DIV8, 8), - 12..=39 => (Hpre::DIV16, 16), - 40..=95 => (Hpre::DIV64, 64), - 96..=191 => (Hpre::DIV128, 128), - 192..=383 => (Hpre::DIV256, 256), - _ => (Hpre::DIV512, 512), + 1 => Hpre::DIV1, + 2 => Hpre::DIV2, + 3..=5 => Hpre::DIV4, + 6..=11 => Hpre::DIV8, + 12..=39 => Hpre::DIV16, + 40..=95 => Hpre::DIV64, + 96..=191 => Hpre::DIV128, + 192..=383 => Hpre::DIV256, + _ => Hpre::DIV512, }; - let hclk = sysclk / hpre_div; - assert!(hclk <= 72_000_000); + let hclk = sysclk / hpre; + assert!(hclk <= Hertz(72_000_000)); // Calculate real APB1 clock - let pclk1 = config.pclk1.map(|p| p.0).unwrap_or(hclk); - let (ppre1_bits, ppre1) = match hclk / pclk1 { + let pclk1 = config.pclk1.unwrap_or(hclk); + let ppre1 = match hclk / pclk1 { 0 => unreachable!(), - 1 => (Ppre::DIV1, 1), - 2 => (Ppre::DIV2, 2), - 3..=5 => (Ppre::DIV4, 4), - 6..=11 => (Ppre::DIV8, 8), - _ => (Ppre::DIV16, 16), + 1 => Ppre::DIV1, + 2 => Ppre::DIV2, + 3..=5 => Ppre::DIV4, + 6..=11 => Ppre::DIV8, + _ => Ppre::DIV16, }; - let timer_mul1 = if ppre1 == 1 { 1 } else { 2 }; + let timer_mul1 = if ppre1 == Ppre::DIV1 { 1u32 } else { 2 }; let pclk1 = hclk / ppre1; - assert!(pclk1 <= 36_000_000); + assert!(pclk1 <= Hertz(36_000_000)); // Calculate real APB2 clock - let pclk2 = config.pclk2.map(|p| p.0).unwrap_or(hclk); - let (ppre2_bits, ppre2) = match hclk / pclk2 { + let pclk2 = config.pclk2.unwrap_or(hclk); + let ppre2 = match hclk / pclk2 { 0 => unreachable!(), - 1 => (Ppre::DIV1, 1), - 2 => (Ppre::DIV2, 2), - 3..=5 => (Ppre::DIV4, 4), - 6..=11 => (Ppre::DIV8, 8), - _ => (Ppre::DIV16, 16), + 1 => Ppre::DIV1, + 2 => Ppre::DIV2, + 3..=5 => Ppre::DIV4, + 6..=11 => Ppre::DIV8, + _ => Ppre::DIV16, }; - let timer_mul2 = if ppre2 == 1 { 1 } else { 2 }; + let timer_mul2 = if ppre2 == Ppre::DIV1 { 1u32 } else { 2 }; let pclk2 = hclk / ppre2; - assert!(pclk2 <= 72_000_000); + assert!(pclk2 <= Hertz(72_000_000)); // Set latency based on HCLK frquency // RM0316: "The prefetch buffer must be kept on when using a prescaler // different from 1 on the AHB clock.", "Half-cycle access cannot be // used when there is a prescaler different from 1 on the AHB clock" FLASH.acr().modify(|w| { - w.set_latency(if hclk <= 24_000_000 { + w.set_latency(if hclk <= Hertz(24_000_000) { Latency::WS0 - } else if hclk <= 48_000_000 { + } else if hclk <= Hertz(48_000_000) { Latency::WS1 } else { Latency::WS2 }); - if hpre_div != 1 { + if hpre != Hpre::DIV1 { w.set_hlfcya(false); w.set_prftbe(true); } @@ -240,9 +203,9 @@ pub(crate) unsafe fn init(config: Config) { // Set prescalers // CFGR has been written before (PLL, PLL48) don't overwrite these settings RCC.cfgr().modify(|w| { - w.set_ppre2(ppre2_bits); - w.set_ppre1(ppre1_bits); - w.set_hpre(hpre_bits); + w.set_ppre2(ppre2); + w.set_ppre1(ppre1); + w.set_hpre(hpre); }); // Wait for the new prescalers to kick in @@ -260,45 +223,43 @@ pub(crate) unsafe fn init(config: Config) { }); #[cfg(rcc_f3)] - let adc = config.adc.map(|adc| { - if !adc.is_bus() { + let adc = config.adc.map(|adc| match adc { + AdcClockSource::Pll(adcpres) => { RCC.cfgr2().modify(|w| { // Make sure that we're using the PLL pll_config.unwrap(); - w.set_adc12pres(adc.into()); + w.set_adc12pres(adcpres); - Hertz(sysclk / adc as u32) - }) - } else { - crate::pac::ADC_COMMON.ccr().modify(|w| { - assert!(!(adc.bus_div() == 1 && hpre_bits != Hpre::DIV1)); - - w.set_ckmode(adc.into()); - - Hertz(sysclk / adc.bus_div() as u32) + sysclk / adcpres }) } + _ => crate::pac::ADC_COMMON.ccr().modify(|w| { + assert!(!(adc.bus_div() == 1 && hpre != Hpre::DIV1)); + + w.set_ckmode(adc.into()); + + sysclk / adc.bus_div() + }), }); #[cfg(all(rcc_f3, adc3_common))] - let adc34 = config.adc.map(|adc| { - if !adc.is_bus() { + let adc34 = config.adc34.map(|adc| match adc { + AdcClockSource::Pll(adcpres) => { RCC.cfgr2().modify(|w| { // Make sure that we're using the PLL pll_config.unwrap(); - w.set_adc12pres(adc.into()); + w.set_adc34pres(adcpres); - Hertz(sysclk / adc as u32) - }) - } else { - crate::pac::ADC3_COMMON.ccr().modify(|w| { - assert!(!(adc.bus_div() == 1 && hpre_bits != Hpre::DIV1)); - - w.set_ckmode(adc.into()); - - Hertz(sysclk / adc.bus_div() as u32) + sysclk / adcpres }) } + _ => crate::pac::ADC_COMMON.ccr().modify(|w| { + assert!(!(adc.bus_div() == 1 && hpre != Hpre::DIV1)); + + w.set_ckmode(adc.into()); + + sysclk / adc.bus_div() + }), }); #[cfg(stm32f334)] @@ -310,21 +271,21 @@ pub(crate) unsafe fn init(config: Config) { // Make sure that we're using the PLL pll_config.unwrap(); - assert!((pclk2 == sysclk) || (pclk2 * 2 == sysclk)); + assert!((pclk2 == sysclk) || (pclk2 * 2u32 == sysclk)); RCC.cfgr3().modify(|w| w.set_hrtim1sw(Timsw::PLL)); - Some(Hertz(sysclk * 2)) + Some(sysclk * 2u32) } }; set_freqs(Clocks { - sys: Hertz(sysclk), - apb1: Hertz(pclk1), - apb2: Hertz(pclk2), - apb1_tim: Hertz(pclk1 * timer_mul1), - apb2_tim: Hertz(pclk2 * timer_mul2), - ahb1: Hertz(hclk), + sys: sysclk, + apb1: pclk1, + apb2: pclk2, + apb1_tim: pclk1 * timer_mul1, + apb2_tim: pclk2 * timer_mul2, + ahb1: hclk, #[cfg(rcc_f3)] adc: adc, #[cfg(all(rcc_f3, adc3_common))] @@ -421,16 +382,16 @@ fn calc_pll(config: &Config, Hertz(sysclk): Hertz) -> (Hertz, PllConfig) { #[inline] #[allow(unused_variables)] -fn get_usb_pre(config: &Config, sysclk: u32, pclk1: u32, pll_config: &Option) -> Usbpre { +fn get_usb_pre(config: &Config, sysclk: Hertz, pclk1: Hertz, pll_config: &Option) -> Usbpre { cfg_if::cfg_if! { // Some chips do not have USB if #[cfg(any(stm32f301, stm32f318, stm32f334))] { panic!("USB clock not supported by the chip"); } else { - let usb_ok = config.hse.is_some() && pll_config.is_some() && (pclk1 >= 10_000_000); + let usb_ok = config.hse.is_some() && pll_config.is_some() && (pclk1 >= Hertz(10_000_000)); match (usb_ok, sysclk) { - (true, 72_000_000) => Usbpre::DIV1_5, - (true, 48_000_000) => Usbpre::DIV1, + (true, Hertz(72_000_000)) => Usbpre::DIV1_5, + (true, Hertz(48_000_000)) => Usbpre::DIV1, _ => panic!( "USB clock is only valid if the PLL output frequency is either 48MHz or 72MHz" ), diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 5ac40911..823836af 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -1,6 +1,8 @@ use crate::pac::flash::vals::Latency; -use crate::pac::rcc::vals::{self, Hsidiv, Sw}; -pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler}; +use crate::pac::rcc::vals::{self, Sw}; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Hsidiv as HSI16Prescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler, +}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -20,33 +22,6 @@ pub enum ClockSrc { LSI, } -#[derive(Clone, Copy)] -pub enum HSI16Prescaler { - NotDivided, - Div2, - Div4, - Div8, - Div16, - Div32, - Div64, - Div128, -} - -impl Into for HSI16Prescaler { - fn into(self) -> Hsidiv { - match self { - HSI16Prescaler::NotDivided => Hsidiv::DIV1, - HSI16Prescaler::Div2 => Hsidiv::DIV2, - HSI16Prescaler::Div4 => Hsidiv::DIV4, - HSI16Prescaler::Div8 => Hsidiv::DIV8, - HSI16Prescaler::Div16 => Hsidiv::DIV16, - HSI16Prescaler::Div32 => Hsidiv::DIV32, - HSI16Prescaler::Div64 => Hsidiv::DIV64, - HSI16Prescaler::Div128 => Hsidiv::DIV128, - } - } -} - /// The PLL configuration. /// /// * `VCOCLK = source / m * n` @@ -104,7 +79,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::HSI16(HSI16Prescaler::NotDivided), + mux: ClockSrc::HSI16(HSI16Prescaler::DIV1), ahb_pre: AHBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1, low_power_run: false, @@ -195,7 +170,6 @@ pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw) = match config.mux { ClockSrc::HSI16(div) => { // Enable HSI16 - let div: Hsidiv = div.into(); RCC.cr().write(|w| { w.set_hsidiv(div); w.set_hsion(true) @@ -262,7 +236,7 @@ pub(crate) unsafe fn init(config: Config) { } // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once - let (sw, hpre, ppre) = (sw.into(), config.ahb_pre.into(), config.apb_pre.into()); + let (sw, hpre, ppre) = (sw.into(), config.ahb_pre, config.apb_pre); RCC.cfgr().modify(|w| { w.set_sw(sw); w.set_hpre(hpre); diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 08ccc5fe..43256524 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -3,7 +3,8 @@ use stm32_metapac::rcc::vals::{Adcsel, Pllsrc, Sw}; use stm32_metapac::FLASH; pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Pllm as PllM, Plln as PllN, Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler, + Adcsel as AdcClockSource, Hpre as AHBPrescaler, Pllm as PllM, Plln as PllN, Pllp as PllP, Pllq as PllQ, + Pllr as PllR, Ppre as APBPrescaler, }; use crate::pac::{PWR, RCC}; use crate::rcc::sealed::RccPeripheral; @@ -16,29 +17,6 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); /// LSI speed pub const LSI_FREQ: Hertz = Hertz(32_000); -#[derive(Clone, Copy)] -pub enum AdcClockSource { - NoClk, - SysClk, - PllP, -} - -impl AdcClockSource { - pub fn adcsel(&self) -> Adcsel { - match self { - AdcClockSource::NoClk => Adcsel::NOCLK, - AdcClockSource::SysClk => Adcsel::SYSCLK, - AdcClockSource::PllP => Adcsel::PLLP, - } - } -} - -impl Default for AdcClockSource { - fn default() -> Self { - Self::NoClk - } -} - /// System clock mux source #[derive(Clone, Copy)] pub enum ClockSrc { @@ -88,32 +66,6 @@ pub struct Pll { pub div_r: Option, } -fn ahb_div(ahb: AHBPrescaler) -> u32 { - match ahb { - AHBPrescaler::DIV1 => 1, - AHBPrescaler::DIV2 => 2, - AHBPrescaler::DIV4 => 4, - AHBPrescaler::DIV8 => 8, - AHBPrescaler::DIV16 => 16, - AHBPrescaler::DIV64 => 64, - AHBPrescaler::DIV128 => 128, - AHBPrescaler::DIV256 => 256, - AHBPrescaler::DIV512 => 512, - _ => unreachable!(), - } -} - -fn apb_div(apb: APBPrescaler) -> u32 { - match apb { - APBPrescaler::DIV1 => 1, - APBPrescaler::DIV2 => 2, - APBPrescaler::DIV4 => 4, - APBPrescaler::DIV8 => 8, - APBPrescaler::DIV16 => 16, - _ => unreachable!(), - } -} - /// Sets the source for the 48MHz clock to the USB and RNG peripherals. pub enum Clock48MhzSrc { /// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the @@ -168,8 +120,8 @@ impl Default for Config { low_power_run: false, pll: None, clock_48mhz_src: None, - adc12_clock_source: Default::default(), - adc345_clock_source: Default::default(), + adc12_clock_source: Adcsel::NOCLK, + adc345_clock_source: Adcsel::NOCLK, } } } @@ -203,8 +155,8 @@ pub(crate) unsafe fn init(config: Config) { let internal_freq = src_freq / pll_config.prediv_m * pll_config.mul_n; RCC.pllcfgr().write(|w| { - w.set_plln(pll_config.mul_n.into()); - w.set_pllm(pll_config.prediv_m.into()); + w.set_plln(pll_config.mul_n); + w.set_pllm(pll_config.prediv_m); w.set_pllsrc(pll_config.source.into()); }); @@ -249,14 +201,14 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - (HSI_FREQ.0, Sw::HSI16) + (HSI_FREQ, Sw::HSI16) } ClockSrc::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - (freq.0, Sw::HSE) + (freq, Sw::HSE) } ClockSrc::PLL => { assert!(pll_freq.is_some()); @@ -297,35 +249,32 @@ pub(crate) unsafe fn init(config: Config) { } } - (freq, Sw::PLLRCLK) + (Hertz(freq), Sw::PLLRCLK) } }; RCC.cfgr().modify(|w| { w.set_sw(sw); - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); - let ahb_freq: u32 = match config.ahb_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => sys_clk / ahb_div(pre), - }; + let ahb_freq = sys_clk / config.ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let freq = ahb_freq / apb_div(pre); - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let freq = ahb_freq / apb_div(pre); - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; @@ -373,42 +322,36 @@ pub(crate) unsafe fn init(config: Config) { RCC.ccipr().modify(|w| w.set_clk48sel(source)); } - RCC.ccipr() - .modify(|w| w.set_adc12sel(config.adc12_clock_source.adcsel())); - RCC.ccipr() - .modify(|w| w.set_adc345sel(config.adc345_clock_source.adcsel())); + RCC.ccipr().modify(|w| w.set_adc12sel(config.adc12_clock_source)); + RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source)); let adc12_ck = match config.adc12_clock_source { - AdcClockSource::NoClk => None, - AdcClockSource::PllP => match &pll_freq { - Some(pll) => pll.pll_p, - None => None, - }, - AdcClockSource::SysClk => Some(Hertz(sys_clk)), + AdcClockSource::NOCLK => None, + AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p, + AdcClockSource::SYSCLK => Some(sys_clk), + _ => unreachable!(), }; let adc345_ck = match config.adc345_clock_source { - AdcClockSource::NoClk => None, - AdcClockSource::PllP => match &pll_freq { - Some(pll) => pll.pll_p, - None => None, - }, - AdcClockSource::SysClk => Some(Hertz(sys_clk)), + AdcClockSource::NOCLK => None, + AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p, + AdcClockSource::SYSCLK => Some(sys_clk), + _ => unreachable!(), }; if config.low_power_run { - assert!(sys_clk <= 2_000_000); + assert!(sys_clk <= Hertz(2_000_000)); PWR.cr1().modify(|w| w.set_lpr(true)); } set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - ahb2: Hertz(ahb_freq), - apb1: Hertz(apb1_freq), - apb1_tim: Hertz(apb1_tim_freq), - apb2: Hertz(apb2_freq), - apb2_tim: Hertz(apb2_tim_freq), + sys: sys_clk, + ahb1: ahb_freq, + ahb2: ahb_freq, + apb1: apb1_freq, + apb1_tim: apb1_tim_freq, + apb2: apb2_freq, + apb2_tim: apb2_tim_freq, adc: adc12_ck, adc34: adc345_ck, }); diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index a11fd473..d2906499 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -26,13 +26,13 @@ pub const HSI48_FREQ: Hertz = Hertz(48_000_000); /// LSI speed pub const LSI_FREQ: Hertz = Hertz(32_000); -const VCO_RANGE: RangeInclusive = 150_000_000..=420_000_000; +const VCO_RANGE: RangeInclusive = Hertz(150_000_000)..=Hertz(420_000_000); #[cfg(any(stm32h5, pwr_h7rm0455))] -const VCO_WIDE_RANGE: RangeInclusive = 128_000_000..=560_000_000; +const VCO_WIDE_RANGE: RangeInclusive = Hertz(128_000_000)..=Hertz(560_000_000); #[cfg(pwr_h7rm0468)] -const VCO_WIDE_RANGE: RangeInclusive = 192_000_000..=836_000_000; +const VCO_WIDE_RANGE: RangeInclusive = Hertz(192_000_000)..=Hertz(836_000_000); #[cfg(any(pwr_h7rm0399, pwr_h7rm0433))] -const VCO_WIDE_RANGE: RangeInclusive = 192_000_000..=960_000_000; +const VCO_WIDE_RANGE: RangeInclusive = Hertz(192_000_000)..=Hertz(960_000_000); pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; @@ -641,9 +641,9 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { let wide_allowed = ref_range != Pllrge::RANGE1; let vco_clk = ref_clk * config.mul; - let vco_range = if VCO_RANGE.contains(&vco_clk.0) { + let vco_range = if VCO_RANGE.contains(&vco_clk) { Pllvcosel::MEDIUMVCO - } else if wide_allowed && VCO_WIDE_RANGE.contains(&vco_clk.0) { + } else if wide_allowed && VCO_WIDE_RANGE.contains(&vco_clk) { Pllvcosel::WIDEVCO } else { panic!("pll vco_clk out of range: {} mhz", vco_clk.0) diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index b4236126..3fd8074d 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs @@ -1,8 +1,10 @@ use super::bd::BackupDomain; use super::RtcClockSource; pub use crate::pac::pwr::vals::Vos as VoltageScale; -use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; -pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler, +}; +use crate::pac::rcc::vals::{Pllsrc, Sw}; #[cfg(crs)] use crate::pac::{crs, CRS, SYSCFG}; use crate::pac::{FLASH, PWR, RCC}; @@ -24,56 +26,6 @@ pub enum ClockSrc { HSI16, } -/// MSI Clock Range -/// -/// These ranges control the frequency of the MSI. Internally, these ranges map -/// to the `MSIRANGE` bits in the `RCC_ICSCR` register. -#[derive(Clone, Copy)] -pub enum MSIRange { - /// Around 65.536 kHz - Range0, - /// Around 131.072 kHz - Range1, - /// Around 262.144 kHz - Range2, - /// Around 524.288 kHz - Range3, - /// Around 1.048 MHz - Range4, - /// Around 2.097 MHz (reset value) - Range5, - /// Around 4.194 MHz - Range6, -} - -impl Default for MSIRange { - fn default() -> MSIRange { - MSIRange::Range5 - } -} - -/// PLL divider -#[derive(Clone, Copy)] -pub enum PLLDiv { - Div2, - Div3, - Div4, -} - -/// PLL multiplier -#[derive(Clone, Copy)] -pub enum PLLMul { - Mul3, - Mul4, - Mul6, - Mul8, - Mul12, - Mul16, - Mul24, - Mul32, - Mul48, -} - /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { @@ -81,32 +33,6 @@ pub enum PLLSource { HSE(Hertz), } -impl From for Pllmul { - fn from(val: PLLMul) -> Pllmul { - match val { - PLLMul::Mul3 => Pllmul::MUL3, - PLLMul::Mul4 => Pllmul::MUL4, - PLLMul::Mul6 => Pllmul::MUL6, - PLLMul::Mul8 => Pllmul::MUL8, - PLLMul::Mul12 => Pllmul::MUL12, - PLLMul::Mul16 => Pllmul::MUL16, - PLLMul::Mul24 => Pllmul::MUL24, - PLLMul::Mul32 => Pllmul::MUL32, - PLLMul::Mul48 => Pllmul::MUL48, - } - } -} - -impl From for Plldiv { - fn from(val: PLLDiv) -> Plldiv { - match val { - PLLDiv::Div2 => Plldiv::DIV2, - PLLDiv::Div3 => Plldiv::DIV3, - PLLDiv::Div4 => Plldiv::DIV4, - } - } -} - impl From for Pllsrc { fn from(val: PLLSource) -> Pllsrc { match val { @@ -116,20 +42,6 @@ impl From for Pllsrc { } } -impl From for Msirange { - fn from(val: MSIRange) -> Msirange { - match val { - MSIRange::Range0 => Msirange::RANGE0, - MSIRange::Range1 => Msirange::RANGE1, - MSIRange::Range2 => Msirange::RANGE2, - MSIRange::Range3 => Msirange::RANGE3, - MSIRange::Range4 => Msirange::RANGE4, - MSIRange::Range5 => Msirange::RANGE5, - MSIRange::Range6 => Msirange::RANGE6, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -148,7 +60,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::MSI(MSIRange::default()), + mux: ClockSrc::MSI(MSIRange::RANGE5), ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, @@ -171,28 +83,28 @@ pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw) = match config.mux { ClockSrc::MSI(range) => { // Set MSI range - RCC.icscr().write(|w| w.set_msirange(range.into())); + RCC.icscr().write(|w| w.set_msirange(range)); // Enable MSI RCC.cr().write(|w| w.set_msion(true)); while !RCC.cr().read().msirdy() {} let freq = 32_768 * (1 << (range as u8 + 1)); - (freq, Sw::MSI) + (Hertz(freq), Sw::MSI) } ClockSrc::HSI16 => { // Enable HSI16 RCC.cr().write(|w| w.set_hsi16on(true)); while !RCC.cr().read().hsi16rdyf() {} - (HSI_FREQ.0, Sw::HSI16) + (HSI_FREQ, Sw::HSI16) } ClockSrc::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - (freq.0, Sw::HSE) + (freq, Sw::HSE) } ClockSrc::PLL(src, mul, div) => { let freq = match src { @@ -200,13 +112,13 @@ pub(crate) unsafe fn init(config: Config) { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - freq.0 + freq } PLLSource::HSI16 => { // Enable HSI RCC.cr().write(|w| w.set_hsi16on(true)); while !RCC.cr().read().hsi16rdyf() {} - HSI_FREQ.0 + HSI_FREQ } }; @@ -214,28 +126,13 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_pllon(false)); while RCC.cr().read().pllrdy() {} - let freq = match mul { - PLLMul::Mul3 => freq * 3, - PLLMul::Mul4 => freq * 4, - PLLMul::Mul6 => freq * 6, - PLLMul::Mul8 => freq * 8, - PLLMul::Mul12 => freq * 12, - PLLMul::Mul16 => freq * 16, - PLLMul::Mul24 => freq * 24, - PLLMul::Mul32 => freq * 32, - PLLMul::Mul48 => freq * 48, - }; + let freq = freq * mul / div; - let freq = match div { - PLLDiv::Div2 => freq / 2, - PLLDiv::Div3 => freq / 3, - PLLDiv::Div4 => freq / 4, - }; - assert!(freq <= 32_000_000); + assert!(freq <= Hertz(32_000_000)); RCC.cfgr().write(move |w| { - w.set_pllmul(mul.into()); - w.set_plldiv(div.into()); + w.set_pllmul(mul); + w.set_plldiv(div); w.set_pllsrc(src.into()); }); @@ -254,11 +151,11 @@ pub(crate) unsafe fn init(config: Config) { ); let wait_states = match config.voltage_scale { - VoltageScale::RANGE1 => match sys_clk { + VoltageScale::RANGE1 => match sys_clk.0 { ..=16_000_000 => 0, _ => 1, }, - VoltageScale::RANGE2 => match sys_clk { + VoltageScale::RANGE2 => match sys_clk.0 { ..=8_000_000 => 0, _ => 1, }, @@ -271,37 +168,26 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_sw(sw); - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); - let ahb_freq: u32 = match config.ahb_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: Hpre = pre.into(); - let pre = 1 << (pre.to_bits() as u32 - 7); - sys_clk / pre - } - }; + let ahb_freq = sys_clk / config.ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; @@ -339,11 +225,11 @@ pub(crate) unsafe fn init(config: Config) { } set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - apb1: Hertz(apb1_freq), - apb2: Hertz(apb2_freq), - apb1_tim: Hertz(apb1_tim_freq), - apb2_tim: Hertz(apb2_tim_freq), + sys: sys_clk, + ahb1: ahb_freq, + apb1: apb1_freq, + apb2: apb2_freq, + apb1_tim: apb1_tim_freq, + apb2_tim: apb2_tim_freq, }); } diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs index e445a716..7c75b888 100644 --- a/embassy-stm32/src/rcc/l1.rs +++ b/embassy-stm32/src/rcc/l1.rs @@ -1,5 +1,7 @@ -use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; -pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler, +}; +use crate::pac::rcc::vals::{Pllsrc, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -19,56 +21,6 @@ pub enum ClockSrc { HSI, } -/// MSI Clock Range -/// -/// These ranges control the frequency of the MSI. Internally, these ranges map -/// to the `MSIRANGE` bits in the `RCC_ICSCR` register. -#[derive(Clone, Copy)] -pub enum MSIRange { - /// Around 65.536 kHz - Range0, - /// Around 131.072 kHz - Range1, - /// Around 262.144 kHz - Range2, - /// Around 524.288 kHz - Range3, - /// Around 1.048 MHz - Range4, - /// Around 2.097 MHz (reset value) - Range5, - /// Around 4.194 MHz - Range6, -} - -impl Default for MSIRange { - fn default() -> MSIRange { - MSIRange::Range5 - } -} - -/// PLL divider -#[derive(Clone, Copy)] -pub enum PLLDiv { - Div2, - Div3, - Div4, -} - -/// PLL multiplier -#[derive(Clone, Copy)] -pub enum PLLMul { - Mul3, - Mul4, - Mul6, - Mul8, - Mul12, - Mul16, - Mul24, - Mul32, - Mul48, -} - /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { @@ -76,32 +28,6 @@ pub enum PLLSource { HSE(Hertz), } -impl From for Pllmul { - fn from(val: PLLMul) -> Pllmul { - match val { - PLLMul::Mul3 => Pllmul::MUL3, - PLLMul::Mul4 => Pllmul::MUL4, - PLLMul::Mul6 => Pllmul::MUL6, - PLLMul::Mul8 => Pllmul::MUL8, - PLLMul::Mul12 => Pllmul::MUL12, - PLLMul::Mul16 => Pllmul::MUL16, - PLLMul::Mul24 => Pllmul::MUL24, - PLLMul::Mul32 => Pllmul::MUL32, - PLLMul::Mul48 => Pllmul::MUL48, - } - } -} - -impl From for Plldiv { - fn from(val: PLLDiv) -> Plldiv { - match val { - PLLDiv::Div2 => Plldiv::DIV2, - PLLDiv::Div3 => Plldiv::DIV3, - PLLDiv::Div4 => Plldiv::DIV4, - } - } -} - impl From for Pllsrc { fn from(val: PLLSource) -> Pllsrc { match val { @@ -111,20 +37,6 @@ impl From for Pllsrc { } } -impl From for Msirange { - fn from(val: MSIRange) -> Msirange { - match val { - MSIRange::Range0 => Msirange::RANGE0, - MSIRange::Range1 => Msirange::RANGE1, - MSIRange::Range2 => Msirange::RANGE2, - MSIRange::Range3 => Msirange::RANGE3, - MSIRange::Range4 => Msirange::RANGE4, - MSIRange::Range5 => Msirange::RANGE5, - MSIRange::Range6 => Msirange::RANGE6, - } - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -137,7 +49,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::MSI(MSIRange::default()), + mux: ClockSrc::MSI(MSIRange::RANGE5), ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, @@ -149,28 +61,28 @@ pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw) = match config.mux { ClockSrc::MSI(range) => { // Set MSI range - RCC.icscr().write(|w| w.set_msirange(range.into())); + RCC.icscr().write(|w| w.set_msirange(range)); // Enable MSI RCC.cr().write(|w| w.set_msion(true)); while !RCC.cr().read().msirdy() {} let freq = 32_768 * (1 << (range as u8 + 1)); - (freq, Sw::MSI) + (Hertz(freq), Sw::MSI) } ClockSrc::HSI => { // Enable HSI RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - (HSI_FREQ.0, Sw::HSI) + (HSI_FREQ, Sw::HSI) } ClockSrc::HSE(freq) => { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - (freq.0, Sw::HSE) + (freq, Sw::HSE) } ClockSrc::PLL(src, mul, div) => { let freq = match src { @@ -178,13 +90,13 @@ pub(crate) unsafe fn init(config: Config) { // Enable HSE RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} - freq.0 + freq } PLLSource::HSI => { // Enable HSI RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - HSI_FREQ.0 + HSI_FREQ } }; @@ -192,28 +104,13 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_pllon(false)); while RCC.cr().read().pllrdy() {} - let freq = match mul { - PLLMul::Mul3 => freq * 3, - PLLMul::Mul4 => freq * 4, - PLLMul::Mul6 => freq * 6, - PLLMul::Mul8 => freq * 8, - PLLMul::Mul12 => freq * 12, - PLLMul::Mul16 => freq * 16, - PLLMul::Mul24 => freq * 24, - PLLMul::Mul32 => freq * 32, - PLLMul::Mul48 => freq * 48, - }; + let freq = freq * mul / div; - let freq = match div { - PLLDiv::Div2 => freq / 2, - PLLDiv::Div3 => freq / 3, - PLLDiv::Div4 => freq / 4, - }; - assert!(freq <= 32_000_000); + assert!(freq <= Hertz(32_000_000)); RCC.cfgr().write(move |w| { - w.set_pllmul(mul.into()); - w.set_plldiv(div.into()); + w.set_pllmul(mul); + w.set_plldiv(div); w.set_pllsrc(src.into()); }); @@ -226,7 +123,7 @@ pub(crate) unsafe fn init(config: Config) { }; // Set flash 64-bit access, prefetch and wait states - if sys_clk >= 16_000_000 { + if sys_clk >= Hertz(16_000_000) { FLASH.acr().write(|w| w.set_acc64(true)); FLASH.acr().modify(|w| w.set_prften(true)); FLASH.acr().modify(|w| w.set_latency(true)); @@ -234,46 +131,68 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_sw(sw); - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); - let ahb_freq: u32 = match config.ahb_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: Hpre = pre.into(); - let pre = 1 << (pre.to_bits() as u32 - 7); - sys_clk / pre - } - }; + let ahb_freq = sys_clk / config.ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: Ppre = pre.into(); - let pre: u8 = 1 << (pre.to_bits() - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; + #[cfg(crs)] + if config.enable_hsi48 { + // Reset CRS peripheral + RCC.apb1rstr().modify(|w| w.set_crsrst(true)); + RCC.apb1rstr().modify(|w| w.set_crsrst(false)); + + // Enable CRS peripheral + RCC.apb1enr().modify(|w| w.set_crsen(true)); + + // Initialize CRS + CRS.cfgr().write(|w| + + // Select LSE as synchronization source + w.set_syncsrc(crs::vals::Syncsrc::LSE)); + CRS.cr().modify(|w| { + w.set_autotrimen(true); + w.set_cen(true); + }); + + // Enable VREFINT reference for HSI48 oscillator + SYSCFG.cfgr3().modify(|w| { + w.set_enref_hsi48(true); + w.set_en_vrefint(true); + }); + + // Select HSI48 as USB clock + RCC.ccipr().modify(|w| w.set_hsi48msel(true)); + + // Enable dedicated USB clock + RCC.crrcr().modify(|w| w.set_hsi48on(true)); + while !RCC.crrcr().read().hsi48rdy() {} + } + set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - apb1: Hertz(apb1_freq), - apb2: Hertz(apb2_freq), - apb1_tim: Hertz(apb1_tim_freq), - apb2_tim: Hertz(apb2_tim_freq), + sys: sys_clk, + ahb1: ahb_freq, + apb1: apb1_freq, + apb2: apb2_freq, + apb1_tim: apb1_tim_freq, + apb2_tim: apb2_tim_freq, }); } diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 0e35b42e..686bbd4e 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -101,8 +101,7 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::MSI(range) => { // Enable MSI RCC.cr().write(|w| { - let bits: Msirange = range.into(); - w.set_msirange(bits); + w.set_msirange(range); w.set_msirgsel(true); w.set_msion(true); @@ -154,8 +153,7 @@ pub(crate) unsafe fn init(config: Config) { PLLSource::MSI(range) => { // Enable MSI RCC.cr().write(|w| { - let bits: Msirange = range.into(); - w.set_msirange(bits); + w.set_msirange(range); w.set_msipllen(false); // should be turned on if LSE is started w.set_msirgsel(true); w.set_msion(true); @@ -255,9 +253,9 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_sw(sw); - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); let ahb_freq = sys_clk / config.ahb_pre; diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index d9b3ee28..ac4804d4 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs @@ -100,8 +100,7 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::MSI(range) => { // Enable MSI RCC.cr().write(|w| { - let bits: Msirange = range.into(); - w.set_msirange(bits); + w.set_msirange(range); w.set_msirgsel(true); w.set_msion(true); @@ -153,8 +152,7 @@ pub(crate) unsafe fn init(config: Config) { PLLSource::MSI(range) => { // Enable MSI RCC.cr().write(|w| { - let bits: Msirange = range.into(); - w.set_msirange(bits); + w.set_msirange(range); w.set_msipllen(false); // should be turned on if LSE is started w.set_msirgsel(true); w.set_msion(true); @@ -250,9 +248,9 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_sw(sw); - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); let ahb_freq = sys_clk / config.ahb_pre; diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index ee2a8ae1..f8eeaa95 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -1,107 +1,42 @@ -pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource, + Ppre as APBPrescaler, Sw as Sysclk, +}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::Clocks; use crate::time::{khz, mhz, Hertz}; -/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, -/// and with the addition of the init function to configure a system clock. - -/// Only the basic setup using the HSE and HSI clocks are supported as of now. - /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); /// LSI speed pub const LSI_FREQ: Hertz = Hertz(32_000); -#[derive(Clone, Copy)] -pub enum HsePrescaler { - NotDivided, - Div2, -} - -impl From for bool { - fn from(value: HsePrescaler) -> Self { - match value { - HsePrescaler::NotDivided => false, - HsePrescaler::Div2 => true, - } - } -} - pub struct Hse { pub prediv: HsePrescaler, pub frequency: Hertz, } -/// System clock mux source -#[derive(Clone, Copy, PartialEq)] -pub enum Sysclk { - /// MSI selected as sysclk - MSI, - /// HSI selected as sysclk - HSI, - /// HSE selected as sysclk - HSE, - /// PLL selected as sysclk - Pll, -} - -impl From for u8 { - fn from(value: Sysclk) -> Self { - match value { - Sysclk::MSI => 0b00, - Sysclk::HSI => 0b01, - Sysclk::HSE => 0b10, - Sysclk::Pll => 0b11, - } - } -} - -#[derive(Clone, Copy, PartialEq)] -pub enum PllSource { - Hsi, - Msi, - Hse, -} - -impl From for u8 { - fn from(value: PllSource) -> Self { - match value { - PllSource::Msi => 0b01, - PllSource::Hsi => 0b10, - PllSource::Hse => 0b11, - } - } -} - -pub enum Pll48Source { - PllSai, - Pll, - Msi, - Hsi48, -} - pub struct PllMux { /// Source clock selection. pub source: PllSource, /// PLL pre-divider (DIVM). Must be between 1 and 63. - pub prediv: u8, + pub prediv: Pllm, } pub struct Pll { /// PLL multiplication factor. Must be between 4 and 512. - pub mul: u16, + pub mul: Plln, /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128. /// On PLL1, it must be even (in particular, it cannot be 1.) - pub divp: Option, + pub divp: Option, /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128. - pub divq: Option, + pub divq: Option, /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128. - pub divr: Option, + pub divr: Option, } /// Clocks configutation @@ -111,7 +46,6 @@ pub struct Config { pub lsi: bool, pub sys: Sysclk, pub mux: Option, - pub pll48: Option, pub rtc: Option, pub pll: Option, @@ -127,23 +61,22 @@ pub struct Config { pub const WPAN_DEFAULT: Config = Config { hse: Some(Hse { frequency: mhz(32), - prediv: HsePrescaler::NotDivided, + prediv: HsePrescaler::DIV1, }), lse: Some(khz(32)), - sys: Sysclk::Pll, + sys: Sysclk::PLL, mux: Some(PllMux { - source: PllSource::Hse, - prediv: 2, + source: PllSource::HSE, + prediv: Pllm::DIV2, }), - pll48: None, rtc: Some(RtcClockSource::LSE), lsi: false, pll: Some(Pll { - mul: 12, - divp: Some(3), - divq: Some(4), - divr: Some(3), + mul: Plln::MUL12, + divp: Some(Pllp::DIV3), + divq: Some(Pllq::DIV4), + divr: Some(Pllr::DIV3), }), pllsai: None, @@ -160,9 +93,8 @@ impl Default for Config { Config { hse: None, lse: None, - sys: Sysclk::HSI, + sys: Sysclk::HSI16, mux: None, - pll48: None, pll: None, pllsai: None, rtc: None, @@ -178,15 +110,12 @@ impl Default for Config { } pub(crate) fn compute_clocks(config: &Config) -> Clocks { - let hse_clk = config.hse.as_ref().map(|hse| match hse.prediv { - HsePrescaler::NotDivided => hse.frequency, - HsePrescaler::Div2 => hse.frequency / 2u32, - }); + let hse_clk = config.hse.as_ref().map(|hse| hse.frequency / hse.prediv); let mux_clk = config.mux.as_ref().map(|pll_mux| { (match pll_mux.source { - PllSource::Hse => hse_clk.unwrap(), - PllSource::Hsi => HSI_FREQ, + PllSource::HSE => hse_clk.unwrap(), + PllSource::HSI16 => HSI_FREQ, _ => unreachable!(), } / pll_mux.prediv) }); @@ -206,44 +135,19 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks { let sys_clk = match config.sys { Sysclk::HSE => hse_clk.unwrap(), - Sysclk::HSI => HSI_FREQ, - Sysclk::Pll => pll_r.unwrap(), + Sysclk::HSI16 => HSI_FREQ, + Sysclk::PLL => pll_r.unwrap(), _ => unreachable!(), }; - let ahb1_clk = match config.ahb1_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: u8 = pre.into(); - let pre = 1u32 << (pre as u32 - 7); - sys_clk / pre - } - }; - - let ahb2_clk = match config.ahb2_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: u8 = pre.into(); - let pre = 1u32 << (pre as u32 - 7); - sys_clk / pre - } - }; - - let ahb3_clk = match config.ahb3_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: u8 = pre.into(); - let pre = 1u32 << (pre as u32 - 7); - sys_clk / pre - } - }; + let ahb1_clk = sys_clk / config.ahb1_pre; + let ahb2_clk = sys_clk / config.ahb2_pre; + let ahb3_clk = sys_clk / config.ahb3_pre; let (apb1_clk, apb1_tim_clk) = match config.apb1_pre { APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), pre => { - let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb1_clk / pre as u32; + let freq = ahb1_clk / pre; (freq, freq * 2u32) } }; @@ -251,9 +155,7 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks { let (apb2_clk, apb2_tim_clk) = match config.apb2_pre { APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), pre => { - let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb1_clk / pre as u32; + let freq = ahb1_clk / pre; (freq, freq * 2u32) } }; @@ -282,12 +184,12 @@ pub(crate) fn configure_clocks(config: &Config) { let rcc = crate::pac::RCC; let needs_hsi = if let Some(pll_mux) = &config.mux { - pll_mux.source == PllSource::Hsi + pll_mux.source == PllSource::HSI16 } else { false }; - if needs_hsi || config.sys == Sysclk::HSI { + if needs_hsi || config.sys == Sysclk::HSI16 { rcc.cr().modify(|w| { w.set_hsion(true); }); @@ -306,7 +208,7 @@ pub(crate) fn configure_clocks(config: &Config) { match &config.hse { Some(hse) => { rcc.cr().modify(|w| { - w.set_hsepre(hse.prediv.into()); + w.set_hsepre(hse.prediv); w.set_hseon(true); }); @@ -328,18 +230,18 @@ pub(crate) fn configure_clocks(config: &Config) { match &config.pll { Some(pll) => { rcc.pllcfgr().modify(|w| { - w.set_plln(pll.mul as u8); + w.set_plln(pll.mul); pll.divp.map(|divp| { w.set_pllpen(true); - w.set_pllp((divp - 1) as u8) + w.set_pllp(divp) }); pll.divq.map(|divq| { w.set_pllqen(true); - w.set_pllq((divq - 1) as u8) + w.set_pllq(divq) }); pll.divr.map(|divr| { - // w.set_pllren(true); - w.set_pllr((divr - 1) as u8); + w.set_pllren(true); + w.set_pllr(divr); }); }); @@ -352,13 +254,13 @@ pub(crate) fn configure_clocks(config: &Config) { rcc.cfgr().modify(|w| { w.set_sw(config.sys.into()); - w.set_hpre(config.ahb1_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb1_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); rcc.extcfgr().modify(|w| { - w.set_c2hpre(config.ahb2_pre.into()); - w.set_shdhpre(config.ahb3_pre.into()); + w.set_c2hpre(config.ahb2_pre); + w.set_shdhpre(config.ahb3_pre); }); } diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index c5d7ab62..9ade369f 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -108,13 +108,13 @@ pub(crate) unsafe fn init(config: Config) { }); RCC.cfgr2().modify(|w| { - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); RCC.cfgr3().modify(|w| { - w.set_ppre7(config.apb7_pre.into()); + w.set_ppre7(config.apb7_pre); }); let ahb_freq = sys_clk / config.ahb_pre; diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 7baedfcd..f12588a5 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -1,16 +1,14 @@ pub use crate::pac::pwr::vals::Vos as VoltageScale; -use crate::pac::rcc::vals::Adcsel; -pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; +use crate::pac::rcc::vals::Sw; +pub use crate::pac::rcc::vals::{ + Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm, Plln, Pllp, Pllq, Pllr, + Pllsrc as PllSource, Ppre as APBPrescaler, +}; use crate::pac::{FLASH, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; -/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, -/// and with the addition of the init function to configure a system clock. - -/// Only the basic setup using the HSE and HSI clocks are supported as of now. - /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); @@ -28,109 +26,6 @@ pub enum ClockSrc { HSI16, } -#[derive(Clone, Copy, PartialOrd, PartialEq)] -pub enum MSIRange { - /// Around 100 kHz - Range0, - /// Around 200 kHz - Range1, - /// Around 400 kHz - Range2, - /// Around 800 kHz - Range3, - /// Around 1 MHz - Range4, - /// Around 2 MHz - Range5, - /// Around 4 MHz (reset value) - Range6, - /// Around 8 MHz - Range7, - /// Around 16 MHz - Range8, - /// Around 24 MHz - Range9, - /// Around 32 MHz - Range10, - /// Around 48 MHz - Range11, -} - -impl MSIRange { - fn freq(&self) -> u32 { - match self { - MSIRange::Range0 => 100_000, - MSIRange::Range1 => 200_000, - MSIRange::Range2 => 400_000, - MSIRange::Range3 => 800_000, - MSIRange::Range4 => 1_000_000, - MSIRange::Range5 => 2_000_000, - MSIRange::Range6 => 4_000_000, - MSIRange::Range7 => 8_000_000, - MSIRange::Range8 => 16_000_000, - MSIRange::Range9 => 24_000_000, - MSIRange::Range10 => 32_000_000, - MSIRange::Range11 => 48_000_000, - } - } - - fn vos(&self) -> VoltageScale { - if self > &MSIRange::Range8 { - VoltageScale::RANGE1 - } else { - VoltageScale::RANGE2 - } - } -} - -impl Default for MSIRange { - fn default() -> MSIRange { - MSIRange::Range6 - } -} - -impl Into for MSIRange { - fn into(self) -> u8 { - match self { - MSIRange::Range0 => 0b0000, - MSIRange::Range1 => 0b0001, - MSIRange::Range2 => 0b0010, - MSIRange::Range3 => 0b0011, - MSIRange::Range4 => 0b0100, - MSIRange::Range5 => 0b0101, - MSIRange::Range6 => 0b0110, - MSIRange::Range7 => 0b0111, - MSIRange::Range8 => 0b1000, - MSIRange::Range9 => 0b1001, - MSIRange::Range10 => 0b1010, - MSIRange::Range11 => 0b1011, - } - } -} - -#[derive(Clone, Copy)] -pub enum AdcClockSource { - HSI16, - PLLPCLK, - SYSCLK, -} - -impl AdcClockSource { - pub fn adcsel(&self) -> Adcsel { - match self { - AdcClockSource::HSI16 => Adcsel::HSI16, - AdcClockSource::PLLPCLK => Adcsel::PLLPCLK, - AdcClockSource::SYSCLK => Adcsel::SYSCLK, - } - } -} - -impl Default for AdcClockSource { - fn default() -> Self { - Self::HSI16 - } -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -148,7 +43,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::MSI(MSIRange::default()), + mux: ClockSrc::MSI(MSIRange::RANGE4M), ahb_pre: AHBPrescaler::DIV1, shd_ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, @@ -156,73 +51,46 @@ impl Default for Config { rtc_mux: RtcClockSource::LSI, lsi: true, lse: None, - adc_clock_source: AdcClockSource::default(), + adc_clock_source: AdcClockSource::HSI16, } } } -#[repr(u8)] -pub enum Lsedrv { - Low = 0, - MediumLow = 1, - MediumHigh = 2, - High = 3, -} - pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw, vos) = match config.mux { - ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::RANGE2), - ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::RANGE1), - ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), + ClockSrc::HSI16 => (HSI_FREQ, Sw::HSI16, VoltageScale::RANGE2), + ClockSrc::HSE32 => (HSE32_FREQ, Sw::HSE32, VoltageScale::RANGE1), + ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), }; - let ahb_freq: u32 = match config.ahb_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: u8 = pre.into(); - let pre = 1 << (pre as u32 - 7); - sys_clk / pre - } - }; - - let shd_ahb_freq: u32 = match config.shd_ahb_pre { - AHBPrescaler::DIV1 => sys_clk, - pre => { - let pre: u8 = pre.into(); - let pre = 1 << (pre as u32 - 7); - sys_clk / pre - } - }; + let ahb_freq = sys_clk / config.ahb_pre; + let shd_ahb_freq = sys_clk / config.shd_ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { APBPrescaler::DIV1 => (ahb_freq, ahb_freq), pre => { - let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let freq = ahb_freq / pre; + (freq, freq * 2u32) } }; // Adjust flash latency - let flash_clk_src_freq: u32 = shd_ahb_freq; + let flash_clk_src_freq = shd_ahb_freq; let ws = match vos { - VoltageScale::RANGE1 => match flash_clk_src_freq { + VoltageScale::RANGE1 => match flash_clk_src_freq.0 { 0..=18_000_000 => 0b000, 18_000_001..=36_000_000 => 0b001, _ => 0b010, }, - VoltageScale::RANGE2 => match flash_clk_src_freq { + VoltageScale::RANGE2 => match flash_clk_src_freq.0 { 0..=6_000_000 => 0b000, 6_000_001..=12_000_000 => 0b001, _ => 0b010, @@ -258,7 +126,7 @@ pub(crate) unsafe fn init(config: Config) { assert!(!cr.msion() || cr.msirdy()); RCC.cr().write(|w| { w.set_msirgsel(true); - w.set_msirange(range.into()); + w.set_msirange(range); w.set_msion(true); if config.rtc_mux == RtcClockSource::LSE { @@ -273,34 +141,56 @@ pub(crate) unsafe fn init(config: Config) { } RCC.extcfgr().modify(|w| { - if config.shd_ahb_pre == AHBPrescaler::DIV1 { - w.set_shdhpre(0); - } else { - w.set_shdhpre(config.shd_ahb_pre.into()); - } + w.set_shdhpre(config.shd_ahb_pre); }); RCC.cfgr().modify(|w| { w.set_sw(sw.into()); w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); }); // ADC clock MUX - RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source.adcsel())); + RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); // TODO: switch voltage range set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - ahb2: Hertz(ahb_freq), - ahb3: Hertz(shd_ahb_freq), - apb1: Hertz(apb1_freq), - apb2: Hertz(apb2_freq), - apb3: Hertz(shd_ahb_freq), - apb1_tim: Hertz(apb1_tim_freq), - apb2_tim: Hertz(apb2_tim_freq), + sys: sys_clk, + ahb1: ahb_freq, + ahb2: ahb_freq, + ahb3: shd_ahb_freq, + apb1: apb1_freq, + apb2: apb2_freq, + apb3: shd_ahb_freq, + apb1_tim: apb1_tim_freq, + apb2_tim: apb2_tim_freq, }); } + +fn msirange_to_hertz(range: MSIRange) -> Hertz { + match range { + MSIRange::RANGE100K => Hertz(100_000), + MSIRange::RANGE200K => Hertz(200_000), + MSIRange::RANGE400K => Hertz(400_000), + MSIRange::RANGE800K => Hertz(800_000), + MSIRange::RANGE1M => Hertz(1_000_000), + MSIRange::RANGE2M => Hertz(2_000_000), + MSIRange::RANGE4M => Hertz(4_000_000), + MSIRange::RANGE8M => Hertz(8_000_000), + MSIRange::RANGE16M => Hertz(16_000_000), + MSIRange::RANGE24M => Hertz(24_000_000), + MSIRange::RANGE32M => Hertz(32_000_000), + MSIRange::RANGE48M => Hertz(48_000_000), + _ => unreachable!(), + } +} + +fn msirange_to_vos(range: MSIRange) -> VoltageScale { + if range.to_bits() > MSIRange::RANGE16M.to_bits() { + VoltageScale::RANGE1 + } else { + VoltageScale::RANGE2 + } +} diff --git a/embassy-stm32/src/time.rs b/embassy-stm32/src/time.rs index 604503e6..a0bc3394 100644 --- a/embassy-stm32/src/time.rs +++ b/embassy-stm32/src/time.rs @@ -77,3 +77,10 @@ impl Div for Hertz { self / (rhs as u32) } } + +impl Div for Hertz { + type Output = u32; + fn div(self, rhs: Hertz) -> Self::Output { + self.0 / rhs.0 + } +} diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs index ed246a7d..a9286c44 100644 --- a/examples/stm32f334/src/bin/adc.rs +++ b/examples/stm32f334/src/bin/adc.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::peripherals::ADC1; -use embassy_stm32::rcc::AdcClockSource; +use embassy_stm32::rcc::{AdcClockSource, Adcpres}; use embassy_stm32::time::mhz; use embassy_stm32::{adc, bind_interrupts, Config}; use embassy_time::{Delay, Duration, Timer}; @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) -> ! { config.rcc.hclk = Some(mhz(64)); config.rcc.pclk1 = Some(mhz(32)); config.rcc.pclk2 = Some(mhz(64)); - config.rcc.adc = Some(AdcClockSource::PllDiv1); + config.rcc.adc = Some(AdcClockSource::Pll(Adcpres::DIV1)); let mut p = embassy_stm32::init(config); diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index 3fffcfb1..fb5a85bc 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::opamp::{OpAmp, OpAmpGain}; use embassy_stm32::peripherals::ADC2; -use embassy_stm32::rcc::AdcClockSource; +use embassy_stm32::rcc::{AdcClockSource, Adcpres}; use embassy_stm32::time::mhz; use embassy_stm32::{adc, bind_interrupts, Config}; use embassy_time::{Delay, Duration, Timer}; @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) -> ! { config.rcc.hclk = Some(mhz(64)); config.rcc.pclk1 = Some(mhz(32)); config.rcc.pclk2 = Some(mhz(64)); - config.rcc.adc = Some(AdcClockSource::PllDiv1); + config.rcc.adc = Some(AdcClockSource::Pll(Adcpres::DIV1)); let mut p = embassy_stm32::init(config); diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index da9b18a0..30a112b7 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { div_r: Some(PllR::DIV2), }); - config.rcc.adc12_clock_source = AdcClockSource::SysClk; + config.rcc.adc12_clock_source = AdcClockSource::SYSCLK; config.rcc.mux = ClockSrc::PLL; let mut p = embassy_stm32::init(config); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 79a9b5e8..f2ba5f7f 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -322,8 +322,8 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL( // 32Mhz clock (16 * 4 / 2) PLLSource::HSI16, - PLLMul::Mul4, - PLLDiv::Div2, + PLLMul::MUL4, + PLLDiv::DIV2, ); } @@ -333,8 +333,8 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL( // 32Mhz clock (16 * 4 / 2) PLLSource::HSI, - PLLMul::Mul4, - PLLDiv::Div2, + PLLMul::MUL4, + PLLDiv::DIV2, ); } From d0d0ceec6acc0bae8a16f0ebdffaf24b40a018cd Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 11 Oct 2023 01:01:27 +0200 Subject: [PATCH 57/95] stm32/rcc: rename HSE32 to HSE --- embassy-stm32/src/rcc/wba.rs | 4 ++-- embassy-stm32/src/rcc/wl.rs | 12 ++++++------ examples/stm32wl/src/bin/lora_lorawan.rs | 2 +- examples/stm32wl/src/bin/lora_p2p_receive.rs | 2 +- examples/stm32wl/src/bin/lora_p2p_send.rs | 2 +- examples/stm32wl/src/bin/random.rs | 2 +- examples/stm32wl/src/bin/rtc.rs | 2 +- examples/stm32wl/src/bin/uart_async.rs | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index 9ade369f..d79b3063 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -28,7 +28,7 @@ pub enum PllSrc { impl Into for PllSrc { fn into(self) -> Pllsrc { match self { - PllSrc::HSE(..) => Pllsrc::HSE32, + PllSrc::HSE(..) => Pllsrc::HSE, PllSrc::HSI16 => Pllsrc::HSI16, } } @@ -37,7 +37,7 @@ impl Into for PllSrc { impl Into for ClockSrc { fn into(self) -> Sw { match self { - ClockSrc::HSE(..) => Sw::HSE32, + ClockSrc::HSE(..) => Sw::HSE, ClockSrc::HSI16 => Sw::HSI16, } } diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index f12588a5..4c3fe505 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -15,14 +15,14 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); /// LSI speed pub const LSI_FREQ: Hertz = Hertz(32_000); -/// HSE32 speed -pub const HSE32_FREQ: Hertz = Hertz(32_000_000); +/// HSE speed +pub const HSE_FREQ: Hertz = Hertz(32_000_000); /// System clock mux source #[derive(Clone, Copy)] pub enum ClockSrc { MSI(MSIRange), - HSE32, + HSE, HSI16, } @@ -59,7 +59,7 @@ impl Default for Config { pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw, vos) = match config.mux { ClockSrc::HSI16 => (HSI_FREQ, Sw::HSI16, VoltageScale::RANGE2), - ClockSrc::HSE32 => (HSE32_FREQ, Sw::HSE32, VoltageScale::RANGE1), + ClockSrc::HSE => (HSE_FREQ, Sw::HSE, VoltageScale::RANGE1), ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), }; @@ -113,8 +113,8 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} } - ClockSrc::HSE32 => { - // Enable HSE32 + ClockSrc::HSE => { + // Enable HSE RCC.cr().write(|w| { w.set_hsebyppwr(true); w.set_hseon(true); diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index fb249532..6546a4bf 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -33,7 +33,7 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI; let p = embassy_stm32::init(config); diff --git a/examples/stm32wl/src/bin/lora_p2p_receive.rs b/examples/stm32wl/src/bin/lora_p2p_receive.rs index 3d8c31ff..19b0d853 100644 --- a/examples/stm32wl/src/bin/lora_p2p_receive.rs +++ b/examples/stm32wl/src/bin/lora_p2p_receive.rs @@ -26,7 +26,7 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; let p = embassy_stm32::init(config); let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); diff --git a/examples/stm32wl/src/bin/lora_p2p_send.rs b/examples/stm32wl/src/bin/lora_p2p_send.rs index fbd0b032..85f6a84b 100644 --- a/examples/stm32wl/src/bin/lora_p2p_send.rs +++ b/examples/stm32wl/src/bin/lora_p2p_send.rs @@ -26,7 +26,7 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; let p = embassy_stm32::init(config); let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 18eeac4f..d5b81970 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -15,7 +15,7 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI; let p = embassy_stm32::init(config); diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index 11734e4b..b26ddc2f 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs @@ -16,7 +16,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn main(_spawner: Spawner) { let p = { let mut config = Config::default(); - config.rcc.mux = ClockSrc::HSE32; + config.rcc.mux = ClockSrc::HSE; config.rcc.lse = Some(Hertz(32_768)); config.rcc.rtc_mux = RtcClockSource::LSE; embassy_stm32::init(config) diff --git a/examples/stm32wl/src/bin/uart_async.rs b/examples/stm32wl/src/bin/uart_async.rs index 2c9b7c69..44e8f83a 100644 --- a/examples/stm32wl/src/bin/uart_async.rs +++ b/examples/stm32wl/src/bin/uart_async.rs @@ -21,7 +21,7 @@ but can be surely changed for your needs. #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; let p = embassy_stm32::init(config); defmt::info!("Starting system"); From 21915a9a3fed5390c9f505fff29f49ee32d55e78 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 11 Oct 2023 01:08:01 +0200 Subject: [PATCH 58/95] stm32/rcc: unify L0 and L1. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/bd.rs | 2 +- embassy-stm32/src/rcc/{l0.rs => l0l1.rs} | 28 ++-- embassy-stm32/src/rcc/l1.rs | 198 ----------------------- embassy-stm32/src/rcc/mod.rs | 3 +- tests/stm32/src/common.rs | 2 +- 6 files changed, 17 insertions(+), 220 deletions(-) rename embassy-stm32/src/rcc/{l0.rs => l0l1.rs} (91%) delete mode 100644 embassy-stm32/src/rcc/l1.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index b6641d71..6137e3c0 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ff45aa382efb704dd2275dd69e71af73343f149d" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ff45aa382efb704dd2275dd69e71af73343f149d", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index 9c784c3a..c18e92bc 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -163,7 +163,7 @@ impl BackupDomain { } // If not OK, reset backup domain and configure it. - #[cfg(not(any(rcc_l0, rcc_l1)))] + #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1)))] { Self::modify(|w| w.set_bdrst(true)); Self::modify(|w| w.set_bdrst(false)); diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0l1.rs similarity index 91% rename from embassy-stm32/src/rcc/l0.rs rename to embassy-stm32/src/rcc/l0l1.rs index 3fd8074d..4b1acae5 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -95,7 +95,7 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::HSI16 => { // Enable HSI16 RCC.cr().write(|w| w.set_hsi16on(true)); - while !RCC.cr().read().hsi16rdyf() {} + while !RCC.cr().read().hsi16rdy() {} (HSI_FREQ, Sw::HSI16) } @@ -117,7 +117,7 @@ pub(crate) unsafe fn init(config: Config) { PLLSource::HSI16 => { // Enable HSI RCC.cr().write(|w| w.set_hsi16on(true)); - while !RCC.cr().read().hsi16rdyf() {} + while !RCC.cr().read().hsi16rdy() {} HSI_FREQ } }; @@ -150,21 +150,17 @@ pub(crate) unsafe fn init(config: Config) { config.lse.map(|_| Default::default()), ); - let wait_states = match config.voltage_scale { - VoltageScale::RANGE1 => match sys_clk.0 { - ..=16_000_000 => 0, - _ => 1, - }, - VoltageScale::RANGE2 => match sys_clk.0 { - ..=8_000_000 => 0, - _ => 1, - }, - VoltageScale::RANGE3 => 0, - _ => unreachable!(), + let wait_states = match (config.voltage_scale, sys_clk.0) { + (VoltageScale::RANGE1, ..=16_000_000) => 0, + (VoltageScale::RANGE2, ..=8_000_000) => 0, + (VoltageScale::RANGE3, ..=4_200_000) => 0, + _ => 1, }; - FLASH.acr().modify(|w| { - w.set_latency(wait_states != 0); - }); + + #[cfg(stm32l1)] + FLASH.acr().write(|w| w.set_acc64(true)); + FLASH.acr().modify(|w| w.set_prften(true)); + FLASH.acr().modify(|w| w.set_latency(wait_states != 0)); RCC.cfgr().modify(|w| { w.set_sw(sw); diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs deleted file mode 100644 index 7c75b888..00000000 --- a/embassy-stm32/src/rcc/l1.rs +++ /dev/null @@ -1,198 +0,0 @@ -pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler, -}; -use crate::pac::rcc::vals::{Pllsrc, Sw}; -use crate::pac::{FLASH, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - MSI(MSIRange), - PLL(PLLSource, PLLMul, PLLDiv), - HSE(Hertz), - HSI, -} - -/// PLL clock input source -#[derive(Clone, Copy)] -pub enum PLLSource { - HSI, - HSE(Hertz), -} - -impl From for Pllsrc { - fn from(val: PLLSource) -> Pllsrc { - match val { - PLLSource::HSI => Pllsrc::HSI, - PLLSource::HSE(_) => Pllsrc::HSE, - } - } -} - -/// Clocks configutation -pub struct Config { - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - mux: ClockSrc::MSI(MSIRange::RANGE5), - ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - } - } -} - -pub(crate) unsafe fn init(config: Config) { - let (sys_clk, sw) = match config.mux { - ClockSrc::MSI(range) => { - // Set MSI range - RCC.icscr().write(|w| w.set_msirange(range)); - - // Enable MSI - RCC.cr().write(|w| w.set_msion(true)); - while !RCC.cr().read().msirdy() {} - - let freq = 32_768 * (1 << (range as u8 + 1)); - (Hertz(freq), Sw::MSI) - } - ClockSrc::HSI => { - // Enable HSI - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - (HSI_FREQ, Sw::HSI) - } - ClockSrc::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - - (freq, Sw::HSE) - } - ClockSrc::PLL(src, mul, div) => { - let freq = match src { - PLLSource::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - freq - } - PLLSource::HSI => { - // Enable HSI - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - HSI_FREQ - } - }; - - // Disable PLL - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} - - let freq = freq * mul / div; - - assert!(freq <= Hertz(32_000_000)); - - RCC.cfgr().write(move |w| { - w.set_pllmul(mul); - w.set_plldiv(div); - w.set_pllsrc(src.into()); - }); - - // Enable PLL - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - - (freq, Sw::PLL) - } - }; - - // Set flash 64-bit access, prefetch and wait states - if sys_clk >= Hertz(16_000_000) { - FLASH.acr().write(|w| w.set_acc64(true)); - FLASH.acr().modify(|w| w.set_prften(true)); - FLASH.acr().modify(|w| w.set_latency(true)); - } - - RCC.cfgr().modify(|w| { - w.set_sw(sw); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - - let ahb_freq = sys_clk / config.ahb_pre; - - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - #[cfg(crs)] - if config.enable_hsi48 { - // Reset CRS peripheral - RCC.apb1rstr().modify(|w| w.set_crsrst(true)); - RCC.apb1rstr().modify(|w| w.set_crsrst(false)); - - // Enable CRS peripheral - RCC.apb1enr().modify(|w| w.set_crsen(true)); - - // Initialize CRS - CRS.cfgr().write(|w| - - // Select LSE as synchronization source - w.set_syncsrc(crs::vals::Syncsrc::LSE)); - CRS.cr().modify(|w| { - w.set_autotrimen(true); - w.set_cen(true); - }); - - // Enable VREFINT reference for HSI48 oscillator - SYSCFG.cfgr3().modify(|w| { - w.set_enref_hsi48(true); - w.set_en_vrefint(true); - }); - - // Select HSI48 as USB clock - RCC.ccipr().modify(|w| w.set_hsi48msel(true)); - - // Enable dedicated USB clock - RCC.crrcr().modify(|w| w.set_hsi48on(true)); - while !RCC.crrcr().read().hsi48rdy() {} - } - - set_freqs(Clocks { - sys: sys_clk, - ahb1: ahb_freq, - apb1: apb1_freq, - apb2: apb2_freq, - apb1_tim: apb1_tim_freq, - apb2_tim: apb2_tim_freq, - }); -} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 52dc386b..3d4de0e6 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -19,8 +19,7 @@ pub use mco::*; #[cfg_attr(rcc_g0, path = "g0.rs")] #[cfg_attr(rcc_g4, path = "g4.rs")] #[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] -#[cfg_attr(rcc_l0, path = "l0.rs")] -#[cfg_attr(rcc_l1, path = "l1.rs")] +#[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] #[cfg_attr(rcc_l4, path = "l4.rs")] #[cfg_attr(rcc_l5, path = "l5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index f2ba5f7f..2bf50079 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -332,7 +332,7 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::PLL( // 32Mhz clock (16 * 4 / 2) - PLLSource::HSI, + PLLSource::HSI16, PLLMul::MUL4, PLLDiv::DIV2, ); From 3ec4e6320a3e9f7723a91e727004a35c3c903765 Mon Sep 17 00:00:00 2001 From: Jonathan Dickinson Date: Tue, 10 Oct 2023 20:14:09 -0400 Subject: [PATCH 59/95] fix (rp i2c): set i2c slew rate to spec value The RP2040 datasheet indicates that I2C pins should have a limited slew rate (Page 440 - 4.3.1.3.). This configures that for both `I2c` and `I2cSlave`. In addition, the pin configuration has been centralized to a single fn. --- embassy-rp/src/i2c.rs | 36 ++++++++++++++++++------------------ embassy-rp/src/i2c_slave.rs | 23 +++++------------------ 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 77777ad3..b4036f20 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs @@ -6,7 +6,6 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use pac::i2c; -use crate::gpio::sealed::Pin; use crate::gpio::AnyPin; use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::{interrupt, pac, peripherals, Peripheral}; @@ -318,6 +317,22 @@ impl interrupt::typelevel::Handler for InterruptHandl } } +pub(crate) fn set_up_i2c_pin<'d, P, T>(pin: &P) +where + P: core::ops::Deref, + T: crate::gpio::Pin, +{ + pin.gpio().ctrl().write(|w| w.set_funcsel(3)); + pin.pad_ctrl().write(|w| { + w.set_schmitt(true); + w.set_slewfast(false); + w.set_ie(true); + w.set_od(false); + w.set_pue(true); + w.set_pde(false); + }); +} + impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { fn new_inner( _peri: impl Peripheral

+ 'd, @@ -355,23 +370,8 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { p.ic_rx_tl().write(|w| w.set_rx_tl(0)); // Configure SCL & SDA pins - scl.gpio().ctrl().write(|w| w.set_funcsel(3)); - sda.gpio().ctrl().write(|w| w.set_funcsel(3)); - - scl.pad_ctrl().write(|w| { - w.set_schmitt(true); - w.set_ie(true); - w.set_od(false); - w.set_pue(true); - w.set_pde(false); - }); - sda.pad_ctrl().write(|w| { - w.set_schmitt(true); - w.set_ie(true); - w.set_od(false); - w.set_pue(true); - w.set_pde(false); - }); + set_up_i2c_pin(&scl); + set_up_i2c_pin(&sda); // Configure baudrate diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs index 30e78925..9271ede3 100644 --- a/embassy-rp/src/i2c_slave.rs +++ b/embassy-rp/src/i2c_slave.rs @@ -5,7 +5,9 @@ use core::task::Poll; use embassy_hal_internal::into_ref; use pac::i2c; -use crate::i2c::{i2c_reserved_addr, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE}; +use crate::i2c::{ + i2c_reserved_addr, set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE, +}; use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::{pac, Peripheral}; @@ -100,23 +102,8 @@ impl<'d, T: Instance> I2cSlave<'d, T> { p.ic_rx_tl().write(|w| w.set_rx_tl(0)); // Configure SCL & SDA pins - scl.gpio().ctrl().write(|w| w.set_funcsel(3)); - sda.gpio().ctrl().write(|w| w.set_funcsel(3)); - - scl.pad_ctrl().write(|w| { - w.set_schmitt(true); - w.set_ie(true); - w.set_od(false); - w.set_pue(true); - w.set_pde(false); - }); - sda.pad_ctrl().write(|w| { - w.set_schmitt(true); - w.set_ie(true); - w.set_od(false); - w.set_pue(true); - w.set_pde(false); - }); + set_up_i2c_pin(&scl); + set_up_i2c_pin(&sda); // Clear interrupts p.ic_clr_intr().read(); From 322f9cb1535750bd90745e445c5f68915aab0eb1 Mon Sep 17 00:00:00 2001 From: Jonathan Dickinson Date: Tue, 10 Oct 2023 20:24:38 -0400 Subject: [PATCH 60/95] fix (rp i2c): fix restart/stop flags for i2c master methods Update the start and stop flags for all read/write/read_write methods to match those in the default blocking implementation of these methods (as well as other RP2040 I2C implementations, and expected I2C behavior). Also adds a write_read_async method that doesnt require using embedded-hal, as this is required to use I2C in an idiomatic fashion (see TI Application Report SLVA704). --- embassy-rp/src/i2c.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 77777ad3..0b34cd30 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs @@ -295,13 +295,24 @@ impl<'d, T: Instance> I2c<'d, T, Async> { pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> { Self::setup(addr)?; - self.read_async_internal(buffer, false, true).await + self.read_async_internal(buffer, true, true).await } pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator) -> Result<(), Error> { Self::setup(addr)?; self.write_async_internal(bytes, true).await } + + pub async fn write_read_async( + &mut self, + addr: u16, + bytes: impl IntoIterator, + buffer: &mut [u8], + ) -> Result<(), Error> { + Self::setup(addr)?; + self.write_async_internal(bytes, false).await?; + self.read_async_internal(buffer, true, true).await + } } pub struct InterruptHandler { @@ -713,7 +724,7 @@ mod nightly { Self::setup(addr)?; self.write_async_internal(write.iter().cloned(), false).await?; - self.read_async_internal(read, false, true).await + self.read_async_internal(read, true, true).await } async fn transaction(&mut self, address: A, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { From b91d1eaca07a65e8d4b688a3f9059c5578e92836 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 11 Oct 2023 03:53:27 +0200 Subject: [PATCH 61/95] stm32/rcc: add LSE/LSI to all chips, add RTC to more chips. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/bd.rs | 219 +++++++++++------- embassy-stm32/src/rcc/c0.rs | 10 +- embassy-stm32/src/rcc/f0.rs | 8 +- embassy-stm32/src/rcc/f1.rs | 8 +- embassy-stm32/src/rcc/f2.rs | 20 +- embassy-stm32/src/rcc/f3.rs | 7 +- embassy-stm32/src/rcc/f4.rs | 25 +- embassy-stm32/src/rcc/f7.rs | 20 +- embassy-stm32/src/rcc/g0.rs | 10 +- embassy-stm32/src/rcc/g4.rs | 9 +- embassy-stm32/src/rcc/h.rs | 40 +--- embassy-stm32/src/rcc/l0l1.rs | 20 +- embassy-stm32/src/rcc/l4.rs | 23 +- embassy-stm32/src/rcc/l5.rs | 23 +- embassy-stm32/src/rcc/mod.rs | 18 +- embassy-stm32/src/rcc/u5.rs | 9 +- embassy-stm32/src/rcc/wb.rs | 66 ++---- embassy-stm32/src/rcc/wba.rs | 9 +- embassy-stm32/src/rcc/wl.rs | 26 +-- embassy-stm32/src/rtc/mod.rs | 16 +- examples/stm32f4/src/bin/rtc.rs | 6 +- examples/stm32h7/src/bin/rtc.rs | 14 +- examples/stm32l4/src/bin/rtc.rs | 5 +- .../src/bin/spe_adin1110_http_server.rs | 2 - examples/stm32wl/src/bin/lora_lorawan.rs | 1 - examples/stm32wl/src/bin/random.rs | 1 - examples/stm32wl/src/bin/rtc.rs | 8 +- tests/stm32/Cargo.toml | 20 +- tests/stm32/src/bin/rtc.rs | 16 +- tests/stm32/src/bin/stop.rs | 7 +- 31 files changed, 267 insertions(+), 403 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 6137e3c0..33583d22 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index c18e92bc..66ca65f8 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -1,14 +1,24 @@ +use core::sync::atomic::{compiler_fence, Ordering}; + +use crate::pac::common::{Reg, RW}; +pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource; +use crate::time::Hertz; + +#[cfg(any(stm32f0, stm32f1, stm32f3))] +pub const LSI_FREQ: Hertz = Hertz(40_000); +#[cfg(not(any(stm32f0, stm32f1, stm32f3)))] +pub const LSI_FREQ: Hertz = Hertz(32_000); + #[allow(dead_code)] #[derive(Clone, Copy)] -pub enum LseCfg { +pub enum LseMode { Oscillator(LseDrive), Bypass, } -impl Default for LseCfg { - fn default() -> Self { - Self::Oscillator(Default::default()) - } +pub struct LseConfig { + pub frequency: Hertz, + pub mode: LseMode, } #[allow(dead_code)] @@ -36,90 +46,116 @@ impl From for crate::pac::rcc::vals::Lsedrv { } } -pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource; - #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] -#[allow(dead_code)] type Bdcr = crate::pac::rcc::regs::Bdcr; - #[cfg(any(rtc_v2l0, rtc_v2l1))] -#[allow(dead_code)] type Bdcr = crate::pac::rcc::regs::Csr; +#[cfg(any(stm32c0))] +type Bdcr = crate::pac::rcc::regs::Csr1; -#[allow(dead_code)] -pub struct BackupDomain {} +#[cfg(any(stm32c0))] +fn unlock() {} -impl BackupDomain { - #[cfg(any( - rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, - rtc_v3u5 - ))] - #[allow(dead_code, unused_variables)] - fn modify(f: impl FnOnce(&mut Bdcr) -> R) -> R { - #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1, rtc_v2l0))] - let cr = crate::pac::PWR.cr(); - #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] - let cr = crate::pac::PWR.cr1(); +#[cfg(not(any(stm32c0)))] +fn unlock() { + #[cfg(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1))] + let cr = crate::pac::PWR.cr(); + #[cfg(not(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1, stm32u5, stm32h5, stm32wba)))] + let cr = crate::pac::PWR.cr1(); + #[cfg(any(stm32u5, stm32h5, stm32wba))] + let cr = crate::pac::PWR.dbpcr(); - // TODO: Missing from PAC for l0 and f0? - #[cfg(not(any(rtc_v2f0, rtc_v3u5)))] - { - cr.modify(|w| w.set_dbp(true)); - while !cr.read().dbp() {} + cr.modify(|w| w.set_dbp(true)); + while !cr.read().dbp() {} +} + +fn bdcr() -> Reg { + #[cfg(any(rtc_v2l0, rtc_v2l1))] + return crate::pac::RCC.csr(); + #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] + return crate::pac::RCC.bdcr(); + #[cfg(any(stm32c0))] + return crate::pac::RCC.csr1(); +} + +pub struct LsConfig { + pub rtc: RtcClockSource, + pub lsi: bool, + pub lse: Option, +} + +impl LsConfig { + pub const fn default_lse() -> Self { + Self { + rtc: RtcClockSource::LSE, + lse: Some(LseConfig { + frequency: Hertz(32_000), + mode: LseMode::Oscillator(LseDrive::MediumHigh), + }), + lsi: false, } - - #[cfg(any(rtc_v2l0, rtc_v2l1))] - let cr = crate::pac::RCC.csr(); - - #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] - let cr = crate::pac::RCC.bdcr(); - - cr.modify(|w| f(w)) } - #[cfg(any( - rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, - rtc_v3u5 - ))] - #[allow(dead_code)] - fn read() -> Bdcr { - #[cfg(any(rtc_v2l0, rtc_v2l1))] - let r = crate::pac::RCC.csr().read(); - - #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] - let r = crate::pac::RCC.bdcr().read(); - - r + pub const fn default_lsi() -> Self { + Self { + rtc: RtcClockSource::LSI, + lsi: true, + lse: None, + } } - #[cfg(any( - rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, - rtc_v3u5 - ))] - #[allow(dead_code, unused_variables)] - pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option) { - use atomic_polyfill::{compiler_fence, Ordering}; + pub const fn off() -> Self { + Self { + rtc: RtcClockSource::NOCLOCK, + lsi: false, + lse: None, + } + } +} - match clock_source { - RtcClockSource::LSI => assert!(lsi), - RtcClockSource::LSE => assert!(lse.is_some()), - _ => {} +impl Default for LsConfig { + fn default() -> Self { + // on L5, just the fact that LSI is enabled makes things crash. + // TODO: investigate. + + #[cfg(not(stm32l5))] + return Self::default_lsi(); + #[cfg(stm32l5)] + return Self::off(); + } +} + +impl LsConfig { + pub(crate) fn init(&self) -> Option { + let rtc_clk = match self.rtc { + RtcClockSource::LSI => { + assert!(self.lsi); + Some(LSI_FREQ) + } + RtcClockSource::LSE => Some(self.lse.as_ref().unwrap().frequency), + RtcClockSource::NOCLOCK => None, + _ => todo!(), }; - let (lse_en, lse_byp, lse_drv) = match lse { - Some(LseCfg::Oscillator(lse_drv)) => (true, false, Some(lse_drv)), - Some(LseCfg::Bypass) => (true, true, None), + + let (lse_en, lse_byp, lse_drv) = match &self.lse { + Some(c) => match c.mode { + LseMode::Oscillator(lse_drv) => (true, false, Some(lse_drv)), + LseMode::Bypass => (true, true, None), + }, None => (false, false, None), }; + _ = lse_drv; // not all chips have it. - if lsi { - #[cfg(rtc_v3u5)] + // Disable backup domain write protection + unlock(); + + if self.lsi { + #[cfg(any(stm32u5, stm32h5, stm32wba))] let csr = crate::pac::RCC.bdcr(); - - #[cfg(not(rtc_v3u5))] + #[cfg(not(any(stm32u5, stm32h5, stm32wba, stm32c0)))] let csr = crate::pac::RCC.csr(); - - // Disable backup domain write protection - Self::modify(|_| {}); + #[cfg(any(stm32c0))] + let csr = crate::pac::RCC.csr2(); #[cfg(not(any(rcc_wb, rcc_wba)))] csr.modify(|w| w.set_lsion(true)); @@ -139,12 +175,12 @@ impl BackupDomain { // first check if the configuration matches what we want. // check if it's already enabled and in the source we want. - let reg = Self::read(); + let reg = bdcr().read(); let mut ok = true; - ok &= reg.rtcsel() == clock_source; + ok &= reg.rtcsel() == self.rtc; #[cfg(not(rcc_wba))] { - ok &= reg.rtcen() == (clock_source != RtcClockSource::NOCLOCK); + ok &= reg.rtcen() == (self.rtc != RtcClockSource::NOCLOCK); } ok &= reg.lseon() == lse_en; ok &= reg.lsebyp() == lse_byp; @@ -155,22 +191,29 @@ impl BackupDomain { // if configuration is OK, we're done. if ok { - // RTC code assumes backup domain is unlocked - Self::modify(|w| {}); - - trace!("BDCR ok: {:08x}", Self::read().0); - return; + trace!("BDCR ok: {:08x}", bdcr().read().0); + return rtc_clk; } // If not OK, reset backup domain and configure it. - #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1)))] + #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1, stm32h5, stm32c0)))] { - Self::modify(|w| w.set_bdrst(true)); - Self::modify(|w| w.set_bdrst(false)); + bdcr().modify(|w| w.set_bdrst(true)); + bdcr().modify(|w| w.set_bdrst(false)); + } + #[cfg(any(stm32h5))] + { + bdcr().modify(|w| w.set_vswrst(true)); + bdcr().modify(|w| w.set_vswrst(false)); + } + #[cfg(any(stm32c0))] + { + bdcr().modify(|w| w.set_rtcrst(true)); + bdcr().modify(|w| w.set_rtcrst(false)); } if lse_en { - Self::modify(|w| { + bdcr().modify(|w| { #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] if let Some(lse_drv) = lse_drv { w.set_lsedrv(lse_drv.into()); @@ -179,22 +222,24 @@ impl BackupDomain { w.set_lseon(true); }); - while !Self::read().lserdy() {} + while !bdcr().read().lserdy() {} } - if clock_source != RtcClockSource::NOCLOCK { - Self::modify(|w| { + if self.rtc != RtcClockSource::NOCLOCK { + bdcr().modify(|w| { #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet."); #[cfg(not(rcc_wba))] w.set_rtcen(true); - w.set_rtcsel(clock_source); + w.set_rtcsel(self.rtc); }); } - trace!("BDCR configured: {:08x}", Self::read().0); + trace!("BDCR configured: {:08x}", bdcr().read().0); compiler_fence(Ordering::SeqCst); + + rtc_clk } } diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index 34d339a7..eeb6418a 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -8,9 +8,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(48_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// System clock mux source #[derive(Clone, Copy)] pub enum ClockSrc { @@ -24,6 +21,7 @@ pub struct Config { pub mux: ClockSrc, pub ahb_pre: AHBPrescaler, pub apb_pre: APBPrescaler, + pub ls: super::LsConfig, } impl Default for Config { @@ -33,6 +31,7 @@ impl Default for Config { mux: ClockSrc::HSI(HSIPrescaler::DIV1), ahb_pre: AHBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1, + ls: Default::default(), } } } @@ -60,10 +59,12 @@ pub(crate) unsafe fn init(config: Config) { // Enable LSI RCC.csr2().write(|w| w.set_lsion(true)); while !RCC.csr2().read().lsirdy() {} - (LSI_FREQ, Sw::LSI) + (super::LSI_FREQ, Sw::LSI) } }; + let rtc = config.ls.init(); + // Determine the flash latency implied by the target clock speed // RM0454 § 3.3.4: let target_flash_latency = if sys_clk <= Hertz(24_000_000) { @@ -137,5 +138,6 @@ pub(crate) unsafe fn init(config: Config) { ahb1: ahb_freq, apb1: apb_freq, apb1_tim: apb_tim_freq, + rtc, }); } diff --git a/embassy-stm32/src/rcc/f0.rs b/embassy-stm32/src/rcc/f0.rs index ca6eed28..cc712e87 100644 --- a/embassy-stm32/src/rcc/f0.rs +++ b/embassy-stm32/src/rcc/f0.rs @@ -8,9 +8,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(8_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(40_000); - /// Configuration of the clocks /// /// hse takes precedence over hsi48 if both are enabled @@ -27,6 +24,8 @@ pub struct Config { pub sys_ck: Option, pub hclk: Option, pub pclk: Option, + + pub ls: super::LsConfig, } pub(crate) unsafe fn init(config: Config) { @@ -159,6 +158,8 @@ pub(crate) unsafe fn init(config: Config) { }) } + let rtc = config.ls.init(); + set_freqs(Clocks { sys: Hertz(real_sysclk), apb1: Hertz(pclk), @@ -166,5 +167,6 @@ pub(crate) unsafe fn init(config: Config) { apb1_tim: Hertz(pclk * timer_mul), apb2_tim: Hertz(pclk * timer_mul), ahb1: Hertz(hclk), + rtc, }); } diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs index 081c0c76..56c49cd8 100644 --- a/embassy-stm32/src/rcc/f1.rs +++ b/embassy-stm32/src/rcc/f1.rs @@ -9,9 +9,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(8_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(40_000); - /// Configuration of the clocks /// #[non_exhaustive] @@ -25,6 +22,8 @@ pub struct Config { pub pclk2: Option, pub adcclk: Option, pub pllxtpre: bool, + + pub ls: super::LsConfig, } pub(crate) unsafe fn init(config: Config) { @@ -177,6 +176,8 @@ pub(crate) unsafe fn init(config: Config) { }); }); + let rtc = config.ls.init(); + set_freqs(Clocks { sys: Hertz(real_sysclk), apb1: Hertz(pclk1), @@ -185,5 +186,6 @@ pub(crate) unsafe fn init(config: Config) { apb2_tim: Hertz(pclk2 * timer_mul2), ahb1: Hertz(hclk), adc: Some(Hertz(adcclk)), + rtc, }); } diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 478d8894..ab588233 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -5,17 +5,12 @@ pub use crate::pac::rcc::vals::{ Ppre as APBPrescaler, }; use crate::pac::{FLASH, RCC}; -use crate::rcc::bd::BackupDomain; use crate::rcc::{set_freqs, Clocks}; -use crate::rtc::RtcClockSource; use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - #[derive(Clone, Copy)] pub struct HSEConfig { pub frequency: Hertz, @@ -180,13 +175,11 @@ pub struct Config { pub pll_mux: PLLSrc, pub pll: PLLConfig, pub mux: ClockSrc, - pub rtc: Option, - pub lsi: bool, - pub lse: Option, pub voltage: VoltageScale, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, + pub ls: super::LsConfig, } impl Default for Config { @@ -199,12 +192,10 @@ impl Default for Config { pll: PLLConfig::default(), voltage: VoltageScale::Range3, mux: ClockSrc::HSI, - rtc: None, - lsi: false, - lse: None, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, + ls: Default::default(), } } } @@ -312,11 +303,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_hsion(false)); } - BackupDomain::configure_ls( - config.rtc.unwrap_or(RtcClockSource::NOCLOCK), - config.lsi, - config.lse.map(|_| Default::default()), - ); + let rtc = config.ls.init(); set_freqs(Clocks { sys: sys_clk, @@ -328,5 +315,6 @@ pub(crate) unsafe fn init(config: Config) { apb2: apb2_freq, apb2_tim: apb2_tim_freq, pll48: Some(pll_clocks.pll48_freq), + rtc, }); } diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index a11eeee5..2aa79cec 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -10,9 +10,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(8_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(40_000); - #[cfg(rcc_f3)] impl From for Ckmode { fn from(value: AdcClockSource) -> Self { @@ -87,6 +84,7 @@ pub struct Config { pub adc34: Option, #[cfg(stm32f334)] pub hrtim: HrtimClockSource, + pub ls: super::LsConfig, } // Information required to setup the PLL clock @@ -279,6 +277,8 @@ pub(crate) unsafe fn init(config: Config) { } }; + let rtc = config.ls.init(); + set_freqs(Clocks { sys: sysclk, apb1: pclk1, @@ -294,6 +294,7 @@ pub(crate) unsafe fn init(config: Config) { adc34: None, #[cfg(stm32f334)] hrtim: hrtim, + rtc, }); } diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index 754a0d57..79c2d2f6 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -1,17 +1,11 @@ -use stm32_metapac::rcc::vals::{Pllm, Plln, Pllq, Pllr}; - -use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; +use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllq, Pllr, Ppre, Sw}; use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// Clocks configuration #[non_exhaustive] #[derive(Default)] @@ -30,9 +24,7 @@ pub struct Config { pub pllsai: Option, pub pll48: bool, - pub rtc: Option, - pub lsi: bool, - pub lse: Option, + pub ls: super::LsConfig, } #[cfg(stm32f410)] @@ -344,17 +336,7 @@ pub(crate) unsafe fn init(config: Config) { }) }); - BackupDomain::configure_ls( - config.rtc.unwrap_or(RtcClockSource::NOCLOCK), - config.lsi, - config.lse.map(|_| Default::default()), - ); - - let rtc = match config.rtc { - Some(RtcClockSource::LSI) => Some(LSI_FREQ), - Some(RtcClockSource::LSE) => Some(config.lse.unwrap()), - _ => None, - }; + let rtc = config.ls.init(); set_freqs(Clocks { sys: Hertz(sysclk), @@ -377,7 +359,6 @@ pub(crate) unsafe fn init(config: Config) { pllsai: plls.pllsaiclk.map(Hertz), rtc, - rtc_hse: None, }); } diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs index 565f6aa9..0a0a1cf2 100644 --- a/embassy-stm32/src/rcc/f7.rs +++ b/embassy-stm32/src/rcc/f7.rs @@ -1,16 +1,12 @@ use crate::pac::pwr::vals::Vos; use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw}; use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// Clocks configuration #[non_exhaustive] #[derive(Default)] @@ -23,9 +19,7 @@ pub struct Config { pub pclk2: Option, pub pll48: bool, - pub rtc: Option, - pub lsi: bool, - pub lse: Option, + pub ls: super::LsConfig, } fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option, pll48clk: bool) -> PllResults { @@ -261,17 +255,7 @@ pub(crate) unsafe fn init(config: Config) { }) }); - BackupDomain::configure_ls( - config.rtc.unwrap_or(RtcClockSource::NOCLOCK), - config.lsi, - config.lse.map(|_| Default::default()), - ); - - let rtc = match config.rtc { - Some(RtcClockSource::LSI) => Some(LSI_FREQ), - Some(RtcClockSource::LSE) => Some(config.lse.unwrap()), - _ => None, - }; + let rtc = config.ls.init(); set_freqs(Clocks { sys: Hertz(sysclk), diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 823836af..962b1dc0 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -10,9 +10,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// System clock mux source #[derive(Clone, Copy)] pub enum ClockSrc { @@ -73,6 +70,7 @@ pub struct Config { pub ahb_pre: AHBPrescaler, pub apb_pre: APBPrescaler, pub low_power_run: bool, + pub ls: super::LsConfig, } impl Default for Config { @@ -83,6 +81,7 @@ impl Default for Config { ahb_pre: AHBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1, low_power_run: false, + ls: Default::default(), } } } @@ -193,7 +192,7 @@ pub(crate) unsafe fn init(config: Config) { // Enable LSI RCC.csr().write(|w| w.set_lsion(true)); while !RCC.csr().read().lsirdy() {} - (LSI_FREQ, Sw::LSI) + (super::LSI_FREQ, Sw::LSI) } }; @@ -272,10 +271,13 @@ pub(crate) unsafe fn init(config: Config) { PWR.cr1().modify(|w| w.set_lpr(true)); } + let rtc = config.ls.init(); + set_freqs(Clocks { sys: sys_clk, ahb1: ahb_freq, apb1: apb_freq, apb1_tim: apb_tim_freq, + rtc, }); } diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 43256524..a4078e38 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -14,9 +14,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// System clock mux source #[derive(Clone, Copy)] pub enum ClockSrc { @@ -101,6 +98,8 @@ pub struct Config { pub clock_48mhz_src: Option, pub adc12_clock_source: AdcClockSource, pub adc345_clock_source: AdcClockSource, + + pub ls: super::LsConfig, } /// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator. @@ -122,6 +121,7 @@ impl Default for Config { clock_48mhz_src: None, adc12_clock_source: Adcsel::NOCLK, adc345_clock_source: Adcsel::NOCLK, + ls: Default::default(), } } } @@ -344,6 +344,8 @@ pub(crate) unsafe fn init(config: Config) { PWR.cr1().modify(|w| w.set_lpr(true)); } + let rtc = config.ls.init(); + set_freqs(Clocks { sys: sys_clk, ahb1: ahb_freq, @@ -354,5 +356,6 @@ pub(crate) unsafe fn init(config: Config) { apb2_tim: apb2_tim_freq, adc: adc12_ck, adc34: adc345_ck, + rtc, }); } diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index d2906499..7236d82f 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -9,8 +9,6 @@ pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre}; pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul}; use crate::pac::{FLASH, PWR, RCC}; -#[cfg(stm32h7)] -use crate::rcc::bd::{BackupDomain, LseCfg, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -23,9 +21,6 @@ pub const CSI_FREQ: Hertz = Hertz(4_000_000); /// HSI48 speed pub const HSI48_FREQ: Hertz = Hertz(48_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - const VCO_RANGE: RangeInclusive = Hertz(150_000_000)..=Hertz(420_000_000); #[cfg(any(stm32h5, pwr_h7rm0455))] const VCO_WIDE_RANGE: RangeInclusive = Hertz(128_000_000)..=Hertz(560_000_000); @@ -196,8 +191,7 @@ pub struct Config { pub adc_clock_source: AdcClockSource, pub timer_prescaler: TimerPrescaler, pub voltage_scale: VoltageScale, - #[cfg(stm32h7)] - pub rtc_mux: Option, + pub ls: super::LsConfig, } impl Default for Config { @@ -231,8 +225,7 @@ impl Default for Config { adc_clock_source: AdcClockSource::from_bits(0), // PLL2_P on H7, HCLK on H5 timer_prescaler: TimerPrescaler::DefaultX2, voltage_scale: VoltageScale::Scale0, - #[cfg(stm32h7)] - rtc_mux: None, + ls: Default::default(), } } } @@ -471,18 +464,7 @@ pub(crate) unsafe fn init(config: Config) { flash_setup(hclk, config.voltage_scale); - #[cfg(stm32h7)] - { - let lsecfg = config.lse.map(|lse| match lse { - Lse::Bypass(freq) => { - assert!(freq <= Hertz(1_000_000)); - LseCfg::Bypass - } - Lse::Oscillator => LseCfg::Oscillator(Default::default()), - }); - - BackupDomain::configure_ls(config.rtc_mux.unwrap_or(RtcClockSource::NOCLOCK), config.lsi, lsecfg); - } + let rtc = config.ls.init(); #[cfg(stm32h7)] { @@ -548,17 +530,6 @@ pub(crate) unsafe fn init(config: Config) { while !pac::SYSCFG.cccsr().read().ready() {} } - #[cfg(stm32h7)] - let rtc_clk = match config.rtc_mux { - Some(RtcClockSource::LSI) => Some(LSI_FREQ), - Some(RtcClockSource::LSE) => Some(match config.lse { - Some(Lse::Oscillator) => Hertz(32768), - Some(Lse::Bypass(freq)) => freq, - None => panic!("LSE not configured"), - }), - _ => None, - }; - set_freqs(Clocks { sys, ahb1: hclk, @@ -573,10 +544,7 @@ pub(crate) unsafe fn init(config: Config) { apb1_tim, apb2_tim, adc, - #[cfg(stm32h7)] - rtc: rtc_clk, - #[cfg(stm32h7)] - rtc_hse: None, + rtc, }); } diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index 4b1acae5..d8a1fc10 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -1,5 +1,3 @@ -use super::bd::BackupDomain; -use super::RtcClockSource; pub use crate::pac::pwr::vals::Vos as VoltageScale; pub use crate::pac::rcc::vals::{ Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler, @@ -14,9 +12,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// System clock mux source #[derive(Clone, Copy)] pub enum ClockSrc { @@ -50,9 +45,7 @@ pub struct Config { pub apb2_pre: APBPrescaler, #[cfg(crs)] pub enable_hsi48: bool, - pub rtc: Option, - pub lse: Option, - pub lsi: bool, + pub ls: super::LsConfig, pub voltage_scale: VoltageScale, } @@ -66,10 +59,8 @@ impl Default for Config { apb2_pre: APBPrescaler::DIV1, #[cfg(crs)] enable_hsi48: false, - rtc: None, - lse: None, - lsi: false, voltage_scale: VoltageScale::RANGE1, + ls: Default::default(), } } } @@ -144,11 +135,7 @@ pub(crate) unsafe fn init(config: Config) { } }; - BackupDomain::configure_ls( - config.rtc.unwrap_or(RtcClockSource::NOCLOCK), - config.lsi, - config.lse.map(|_| Default::default()), - ); + let rtc = config.ls.init(); let wait_states = match (config.voltage_scale, sys_clk.0) { (VoltageScale::RANGE1, ..=16_000_000) => 0, @@ -227,5 +214,6 @@ pub(crate) unsafe fn init(config: Config) { apb2: apb2_freq, apb1_tim: apb1_tim_freq, apb2_tim: apb2_tim_freq, + rtc, }); } diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 686bbd4e..1e5733d3 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{ }; use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; use crate::pac::{FLASH, RCC}; -use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// System clock mux source #[derive(Clone, Copy)] pub enum ClockSrc { @@ -51,9 +47,7 @@ pub struct Config { pub pllsai1: Option<(PllMul, PllPreDiv, Option, Option, Option)>, #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] pub hsi48: bool, - pub rtc_mux: RtcClockSource, - pub lse: Option, - pub lsi: bool, + pub ls: super::LsConfig, } impl Default for Config { @@ -67,9 +61,7 @@ impl Default for Config { pllsai1: None, #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] hsi48: false, - rtc_mux: RtcClockSource::LSI, - lsi: true, - lse: None, + ls: Default::default(), } } } @@ -95,7 +87,7 @@ pub(crate) unsafe fn init(config: Config) { while RCC.cfgr().read().sws() != Sw::MSI {} } - BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); + let rtc = config.ls.init(); let (sys_clk, sw) = match config.mux { ClockSrc::MSI(range) => { @@ -105,12 +97,8 @@ pub(crate) unsafe fn init(config: Config) { w.set_msirgsel(true); w.set_msion(true); - if config.rtc_mux == RtcClockSource::LSE { - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(true); - } else { - w.set_msipllen(false); - } + // If LSE is enabled, enable calibration of MSI + w.set_msipllen(config.ls.lse.is_some()); }); while !RCC.cr().read().msirdy() {} @@ -285,6 +273,7 @@ pub(crate) unsafe fn init(config: Config) { apb2: apb2_freq, apb1_tim: apb1_tim_freq, apb2_tim: apb2_tim_freq, + rtc, }); } diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index ac4804d4..1f4e0034 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs @@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{ }; use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::bd::RtcClockSource; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// System clock mux source #[derive(Clone, Copy)] pub enum ClockSrc { @@ -50,9 +46,7 @@ pub struct Config { pub apb2_pre: APBPrescaler, pub pllsai1: Option<(PllMul, PllPreDiv, Option, Option, Option)>, pub hsi48: bool, - pub rtc_mux: RtcClockSource, - pub lse: Option, - pub lsi: bool, + pub ls: super::LsConfig, } impl Default for Config { @@ -65,9 +59,7 @@ impl Default for Config { apb2_pre: APBPrescaler::DIV1, pllsai1: None, hsi48: false, - rtc_mux: RtcClockSource::LSI, - lsi: true, - lse: None, + ls: Default::default(), } } } @@ -93,7 +85,7 @@ pub(crate) unsafe fn init(config: Config) { while RCC.cfgr().read().sws() != Sw::MSI {} } - //BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); + let rtc = config.ls.init(); PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0)); let (sys_clk, sw) = match config.mux { @@ -104,12 +96,8 @@ pub(crate) unsafe fn init(config: Config) { w.set_msirgsel(true); w.set_msion(true); - if config.rtc_mux == RtcClockSource::LSE { - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(true); - } else { - w.set_msipllen(false); - } + // If LSE is enabled, enable calibration of MSI + w.set_msipllen(config.ls.lse.is_some()); }); while !RCC.cr().read().msirdy() {} @@ -280,6 +268,7 @@ pub(crate) unsafe fn init(config: Config) { apb2: apb2_freq, apb1_tim: apb1_tim_freq, apb2_tim: apb2_tim_freq, + rtc, }); } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 3d4de0e6..a9e53d42 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -2,11 +2,11 @@ use core::mem::MaybeUninit; -pub use crate::rcc::bd::RtcClockSource; use crate::time::Hertz; -pub(crate) mod bd; +mod bd; mod mco; +pub use bd::*; pub use mco::*; #[cfg_attr(rcc_f0, path = "f0.rs")] @@ -132,13 +132,7 @@ pub struct Clocks { #[cfg(stm32f334)] pub hrtim: Option, - #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_f7, rcc_h7, rcc_h7rm0433, rcc_h7ab))] - /// Set only if the lsi or lse is configured, indicates stop is supported pub rtc: Option, - - #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h7, rcc_h7rm0433, rcc_h7ab))] - /// Set if the hse is configured, indicates stop is not supported - pub rtc_hse: Option, } #[cfg(feature = "low-power")] @@ -166,14 +160,6 @@ pub(crate) fn clock_refcount_sub() { /// The existence of this value indicates that the clock configuration can no longer be changed static mut CLOCK_FREQS: MaybeUninit = MaybeUninit::uninit(); -#[cfg(stm32wb)] -/// RCC initialization function -pub(crate) unsafe fn init(config: Config) { - set_freqs(compute_clocks(&config)); - - configure_clocks(&config); -} - /// Sets the clock frequencies /// /// Safety: Sets a mutable global. diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index d8fb1730..68a8d3a3 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -7,9 +7,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - pub use crate::pac::pwr::vals::Vos as VoltageScale; #[derive(Copy, Clone)] @@ -111,7 +108,6 @@ impl Into for ClockSrc { } } -#[derive(Copy, Clone)] pub struct Config { pub mux: ClockSrc, pub ahb_pre: AHBPrescaler, @@ -125,6 +121,7 @@ pub struct Config { /// /// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits. pub voltage_range: VoltageScale, + pub ls: super::LsConfig, } impl Config { @@ -193,6 +190,7 @@ impl Default for Config { apb3_pre: APBPrescaler::DIV1, hsi48: false, voltage_range: VoltageScale::RANGE3, + ls: Default::default(), } } } @@ -434,6 +432,8 @@ pub(crate) unsafe fn init(config: Config) { } }; + let rtc = config.ls.init(); + set_freqs(Clocks { sys: sys_clk, ahb1: ahb_freq, @@ -444,6 +444,7 @@ pub(crate) unsafe fn init(config: Config) { apb3: apb3_freq, apb1_tim: apb1_tim_freq, apb2_tim: apb2_tim_freq, + rtc, }); } diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index f8eeaa95..181e6bb5 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -2,16 +2,12 @@ pub use crate::pac::rcc::vals::{ Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, }; -use crate::rcc::bd::{BackupDomain, RtcClockSource}; -use crate::rcc::Clocks; -use crate::time::{khz, mhz, Hertz}; +use crate::rcc::{set_freqs, Clocks}; +use crate::time::{mhz, Hertz}; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - pub struct Hse { pub prediv: HsePrescaler, @@ -42,11 +38,8 @@ pub struct Pll { /// Clocks configutation pub struct Config { pub hse: Option, - pub lse: Option, - pub lsi: bool, pub sys: Sysclk, pub mux: Option, - pub rtc: Option, pub pll: Option, pub pllsai: Option, @@ -56,6 +49,8 @@ pub struct Config { pub ahb3_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, + + pub ls: super::LsConfig, } pub const WPAN_DEFAULT: Config = Config { @@ -63,14 +58,13 @@ pub const WPAN_DEFAULT: Config = Config { frequency: mhz(32), prediv: HsePrescaler::DIV1, }), - lse: Some(khz(32)), sys: Sysclk::PLL, mux: Some(PllMux { source: PllSource::HSE, prediv: Pllm::DIV2, }), - rtc: Some(RtcClockSource::LSE), - lsi: false, + + ls: super::LsConfig::default_lse(), pll: Some(Pll { mul: Plln::MUL12, @@ -92,13 +86,12 @@ impl Default for Config { fn default() -> Config { Config { hse: None, - lse: None, sys: Sysclk::HSI16, mux: None, pll: None, pllsai: None, - rtc: None, - lsi: false, + + ls: Default::default(), ahb1_pre: AHBPrescaler::DIV1, ahb2_pre: AHBPrescaler::DIV1, @@ -109,7 +102,9 @@ impl Default for Config { } } -pub(crate) fn compute_clocks(config: &Config) -> Clocks { +#[cfg(stm32wb)] +/// RCC initialization function +pub(crate) unsafe fn init(config: Config) { let hse_clk = config.hse.as_ref().map(|hse| hse.frequency / hse.prediv); let mux_clk = config.mux.as_ref().map(|pll_mux| { @@ -160,27 +155,6 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks { } }; - let rtc_clk = match config.rtc { - Some(RtcClockSource::LSI) => Some(LSI_FREQ), - Some(RtcClockSource::LSE) => Some(config.lse.unwrap()), - _ => None, - }; - - Clocks { - sys: sys_clk, - ahb1: ahb1_clk, - ahb2: ahb2_clk, - ahb3: ahb3_clk, - apb1: apb1_clk, - apb2: apb2_clk, - apb1_tim: apb1_tim_clk, - apb2_tim: apb2_tim_clk, - rtc: rtc_clk, - rtc_hse: None, - } -} - -pub(crate) fn configure_clocks(config: &Config) { let rcc = crate::pac::RCC; let needs_hsi = if let Some(pll_mux) = &config.mux { @@ -199,11 +173,7 @@ pub(crate) fn configure_clocks(config: &Config) { rcc.cfgr().modify(|w| w.set_stopwuck(true)); - BackupDomain::configure_ls( - config.rtc.unwrap_or(RtcClockSource::NOCLOCK), - config.lsi, - config.lse.map(|_| Default::default()), - ); + let rtc = config.ls.init(); match &config.hse { Some(hse) => { @@ -263,4 +233,16 @@ pub(crate) fn configure_clocks(config: &Config) { w.set_c2hpre(config.ahb2_pre); w.set_shdhpre(config.ahb3_pre); }); + + set_freqs(Clocks { + sys: sys_clk, + ahb1: ahb1_clk, + ahb2: ahb2_clk, + ahb3: ahb3_clk, + apb1: apb1_clk, + apb2: apb2_clk, + apb1_tim: apb1_tim_clk, + apb2_tim: apb2_tim_clk, + rtc, + }) } diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index d79b3063..ff5669ec 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -7,9 +7,6 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - pub use crate::pac::pwr::vals::Vos as VoltageScale; pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; @@ -43,13 +40,13 @@ impl Into for ClockSrc { } } -#[derive(Copy, Clone)] pub struct Config { pub mux: ClockSrc, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, pub apb7_pre: APBPrescaler, + pub ls: super::LsConfig, } impl Default for Config { @@ -60,6 +57,7 @@ impl Default for Config { apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, apb7_pre: APBPrescaler::DIV1, + ls: Default::default(), } } } @@ -140,6 +138,8 @@ pub(crate) unsafe fn init(config: Config) { } }; + let rtc = config.ls.init(); + set_freqs(Clocks { sys: sys_clk, ahb1: ahb_freq, @@ -150,5 +150,6 @@ pub(crate) unsafe fn init(config: Config) { apb7: apb7_freq, apb1_tim: apb1_tim_freq, apb2_tim: apb2_tim_freq, + rtc, }); } diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 4c3fe505..366ca136 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{ Pllsrc as PllSource, Ppre as APBPrescaler, }; use crate::pac::{FLASH, RCC}; -use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// LSI speed -pub const LSI_FREQ: Hertz = Hertz(32_000); - /// HSE speed pub const HSE_FREQ: Hertz = Hertz(32_000_000); @@ -33,10 +29,8 @@ pub struct Config { pub shd_ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, - pub rtc_mux: RtcClockSource, - pub lse: Option, - pub lsi: bool, pub adc_clock_source: AdcClockSource, + pub ls: super::LsConfig, } impl Default for Config { @@ -48,10 +42,8 @@ impl Default for Config { shd_ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, - rtc_mux: RtcClockSource::LSI, - lsi: true, - lse: None, adc_clock_source: AdcClockSource::HSI16, + ls: Default::default(), } } } @@ -104,9 +96,6 @@ pub(crate) unsafe fn init(config: Config) { while FLASH.acr().read().latency() != ws {} - // Enables the LSI if configured - BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); - match config.mux { ClockSrc::HSI16 => { // Enable HSI16 @@ -129,12 +118,8 @@ pub(crate) unsafe fn init(config: Config) { w.set_msirange(range); w.set_msion(true); - if config.rtc_mux == RtcClockSource::LSE { - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(true); - } else { - w.set_msipllen(false); - } + // If LSE is enabled, enable calibration of MSI + w.set_msipllen(config.ls.lse.is_some()); }); while !RCC.cr().read().msirdy() {} } @@ -156,6 +141,8 @@ pub(crate) unsafe fn init(config: Config) { // TODO: switch voltage range + let rtc = config.ls.init(); + set_freqs(Clocks { sys: sys_clk, ahb1: ahb_freq, @@ -166,6 +153,7 @@ pub(crate) unsafe fn init(config: Config) { apb3: shd_ahb_freq, apb1_tim: apb1_tim_freq, apb2_tim: apb2_tim_freq, + rtc, }); } diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 28dde2eb..cf34d219 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -10,7 +10,6 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::Mutex; pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; -pub use crate::rcc::RtcClockSource; use crate::time::Hertz; /// refer to AN4759 to compare features of RTC2 and RTC3 @@ -184,7 +183,7 @@ impl Default for RtcCalibrationCyclePeriod { impl Rtc { pub fn new(_rtc: impl Peripheral

, rtc_config: RtcConfig) -> Self { - #[cfg(any(rcc_wle, rcc_wl5, rcc_g4, rcc_g0, rtc_v2l4, rtc_v2wb))] + #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] ::enable(); let mut this = Self { @@ -204,19 +203,8 @@ impl Rtc { } fn frequency() -> Hertz { - #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))] let freqs = unsafe { crate::rcc::get_freqs() }; - - // Load the clock frequency from the rcc mod, if supported - #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))] - match freqs.rtc { - Some(hertz) => hertz, - None => freqs.rtc_hse.unwrap(), - } - - // Assume the default value, if not supported - #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab)))] - Hertz(32_768) + freqs.rtc.unwrap() } /// Acquire a [`RtcTimeProvider`] instance. diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs index e3374600..e95ad577 100644 --- a/examples/stm32f4/src/bin/rtc.rs +++ b/examples/stm32f4/src/bin/rtc.rs @@ -5,16 +5,14 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; +use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let mut config = Config::default(); - config.rcc.lsi = true; - config.rcc.rtc = Option::Some(RtcClockSource::LSI); + let config = Config::default(); let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32h7/src/bin/rtc.rs b/examples/stm32h7/src/bin/rtc.rs index eeb94073..f2a19af8 100644 --- a/examples/stm32h7/src/bin/rtc.rs +++ b/examples/stm32h7/src/bin/rtc.rs @@ -5,20 +5,18 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::Lse; -use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; +use embassy_stm32::rcc::LsConfig; +use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let p = { - let mut config = Config::default(); - config.rcc.lse = Some(Lse::Oscillator); - config.rcc.rtc_mux = Some(RtcClockSource::LSE); - embassy_stm32::init(config) - }; + let mut config = Config::default(); + config.rcc.ls = LsConfig::default_lse(); + + let p = embassy_stm32::init(config); info!("Hello World!"); let now = NaiveDate::from_ymd_opt(2020, 5, 15) diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index 7e2b8c78..33efc76b 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -5,7 +5,7 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{self, ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; @@ -23,8 +23,7 @@ async fn main(_spawner: Spawner) { PllMul::MUL20, None, ); - config.rcc.lse = Some(Hertz(32_768)); - config.rcc.rtc_mux = rcc::RtcClockSource::LSE; + config.rcc.ls = LsConfig::default_lse(); embassy_stm32::init(config) }; info!("Hello World!"); diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 8db89be2..7193d1f1 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -32,7 +32,6 @@ use embedded_io::Write as bWrite; use embedded_io_async::Write; use hal::gpio::{Input, Level, Output, Speed}; use hal::i2c::{self, I2c}; -use hal::rcc::{self}; use hal::rng::{self, Rng}; use hal::{bind_interrupts, exti, pac, peripherals}; use heapless::Vec; @@ -86,7 +85,6 @@ async fn main(spawner: Spawner) { None, ); config.rcc.hsi48 = true; // needed for rng - config.rcc.rtc_mux = rcc::RtcClockSource::LSI; let dp = embassy_stm32::init(config); diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 6546a4bf..8c789afb 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -34,7 +34,6 @@ bind_interrupts!(struct Irqs{ async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; - config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI; let p = embassy_stm32::init(config); pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)); diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index d5b81970..7c7e8a4e 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -16,7 +16,6 @@ bind_interrupts!(struct Irqs{ async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; - config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI; let p = embassy_stm32::init(config); pac::RCC.ccipr().modify(|w| { diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index b26ddc2f..a6bb2801 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs @@ -5,9 +5,8 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::ClockSrc; -use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; -use embassy_stm32::time::Hertz; +use embassy_stm32::rcc::{ClockSrc, LsConfig}; +use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -17,8 +16,7 @@ async fn main(_spawner: Spawner) { let p = { let mut config = Config::default(); config.rcc.mux = ClockSrc::HSE; - config.rcc.lse = Some(Hertz(32_768)); - config.rcc.rtc_mux = RtcClockSource::LSE; + config.rcc.ls = LsConfig::default_lse(); embassy_stm32::init(config) }; info!("Hello World!"); diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index ef835eed..a1481c7c 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -10,19 +10,19 @@ stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo -stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo +stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma"] # Nucleo stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo -stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo -stm32h563zi = ["embassy-stm32/stm32h563zi", "eth"] # Nucleo -stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board +stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" ] # Nucleo +stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth"] # Nucleo +stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono"] # IoT board stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo -stm32l152re = ["embassy-stm32/stm32l152re", "not-gpdma"] # Nucleo -stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "not-gpdma"] # Nucleo -stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "not-gpdma"] # Nucleo +stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] # Nucleo +stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma"] # Nucleo +stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma"] # Nucleo stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo -stm32f767zi = ["embassy-stm32/stm32f767zi", "not-gpdma", "eth"] # Nucleo -stm32f207zg = ["embassy-stm32/stm32f207zg", "not-gpdma", "eth"] # Nucleo -stm32f303ze = ["embassy-stm32/stm32f303ze", "not-gpdma"] # Nucleo +stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth"] # Nucleo +stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth"] # Nucleo +stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] # Nucleo stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma"] # Nucleo eth = [] diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs index 1f0d630c..46fdbfae 100644 --- a/tests/stm32/src/bin/rtc.rs +++ b/tests/stm32/src/bin/rtc.rs @@ -10,26 +10,14 @@ use chrono::{NaiveDate, NaiveDateTime}; use common::*; use defmt::assert; use embassy_executor::Spawner; -use embassy_stm32::rcc::RtcClockSource; +use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_time::{Duration, Timer}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = config(); - - #[cfg(feature = "stm32h755zi")] - { - use embassy_stm32::rcc::Lse; - config.rcc.lse = Some(Lse::Oscillator); - config.rcc.rtc_mux = Some(RtcClockSource::LSE); - } - #[cfg(not(feature = "stm32h755zi"))] - { - use embassy_stm32::time::Hertz; - config.rcc.lse = Some(Hertz(32_768)); - config.rcc.rtc = Some(RtcClockSource::LSE); - } + config.rcc.ls = LsConfig::default_lse(); let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 55c4aa90..929869bc 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs @@ -11,9 +11,8 @@ use common::*; use cortex_m_rt::entry; use embassy_executor::Spawner; use embassy_stm32::low_power::{stop_with_rtc, Executor}; -use embassy_stm32::rcc::RtcClockSource; +use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; -use embassy_stm32::time::Hertz; use embassy_stm32::Config; use embassy_time::{Duration, Timer}; use static_cell::make_static; @@ -49,9 +48,7 @@ async fn async_main(spawner: Spawner) { let _ = config(); let mut config = Config::default(); - - config.rcc.lse = Some(Hertz(32_768)); - config.rcc.rtc = Some(RtcClockSource::LSE); + config.rcc.ls = LsConfig::default_lse(); let p = embassy_stm32::init(config); info!("Hello World!"); From 4a43cd398211163b9510798d99fed7f17b02f58f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 11 Oct 2023 13:39:04 +0200 Subject: [PATCH 62/95] stm32/rcc: LSE xtal is 32768hz, not 32000hz. Fixes #2043 --- embassy-stm32/src/rcc/bd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index 66ca65f8..a7c4b4f9 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -89,7 +89,7 @@ impl LsConfig { Self { rtc: RtcClockSource::LSE, lse: Some(LseConfig { - frequency: Hertz(32_000), + frequency: Hertz(32_768), mode: LseMode::Oscillator(LseDrive::MediumHigh), }), lsi: false, From bfcca79c1e51a5cae6c5c40018b4a923e798c5ca Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 22:12:03 +0200 Subject: [PATCH 63/95] Add time feature back and gate i2c on time --- embassy-stm32/Cargo.toml | 8 ++++---- embassy-stm32/src/i2c/mod.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index a4e4e51d..70e8f2e2 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" src_base = "https://github.com/embassy-rs/embassy/blob/embassy-stm32-v$VERSION/embassy-stm32/src/" src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-stm32/src/" -features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any"] +features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any", "time"] flavors = [ { regex_feature = "stm32f0.*", target = "thumbv6m-none-eabi" }, { regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" }, @@ -33,7 +33,7 @@ flavors = [ [dependencies] embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.3", path = "../embassy-time" } +embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } @@ -87,7 +87,7 @@ default = ["rt"] rt = ["stm32-metapac/rt"] ## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging -defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"] +defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"] exti = [] low-power = [ "dep:embassy-executor", "embassy-executor/arch-cortex-m" ] @@ -112,7 +112,7 @@ unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"] #! ## Time ## Enables additional driver features that depend on embassy-time -time = [] +time = ["dep:embassy-time"] # Features starting with `_` are for internal use only. They're not intended # to be enabled by other crates, and are not covered by semver guarantees. diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index dde1a504..c35f5997 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -3,7 +3,7 @@ use crate::interrupt; #[cfg_attr(i2c_v1, path = "v1.rs")] -#[cfg_attr(i2c_v2, path = "v2.rs")] +#[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")] mod _version; pub use _version::*; From 1cd3ae9bd51a34a29b0d34374f8ecc08b9b830f9 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 22:20:17 +0200 Subject: [PATCH 64/95] Add comment about feature gate on I2C mod --- embassy-stm32/src/i2c/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index c35f5997..d5bb2ed2 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -2,6 +2,8 @@ use crate::interrupt; +// I2C V2 is gated on the `time` feature because timing facilities are necessary +// to provide timeout functionality in order to prevent some APIs from stalling indefinitely #[cfg_attr(i2c_v1, path = "v1.rs")] #[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")] mod _version; From 7b1cd4293637a0da1c57a12976349715a27e2d04 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 22:20:27 +0200 Subject: [PATCH 65/95] Add time feature to CI --- ci.sh | 112 +++++++++++++++++++++++++-------------------------- ci_stable.sh | 66 +++++++++++++++--------------- 2 files changed, 89 insertions(+), 89 deletions(-) diff --git a/ci.sh b/ci.sh index 33222298..4098743f 100755 --- a/ci.sh +++ b/ci.sh @@ -69,62 +69,62 @@ cargo batch \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,intrinsics \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,qspi-as-gpio \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f412zg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f415zg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f417zg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f423zh,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f427zi,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f437zi,log,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f439zi,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f446ze,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f469zi,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f479zi,defmt,exti,time-driver-any,unstable-traits,embedded-sdmmc \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l422cb,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l073cz,defmt,exti,time-driver-any,unstable-traits,low-power \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f378cc,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5jb,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32g474pe,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h503rb,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h562ag,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f412zg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f415zg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f417zg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f423zh,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f427zi,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f437zi,log,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f439zi,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f446ze,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f469zi,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f479zi,defmt,exti,time-driver-any,unstable-traits,embedded-sdmmc,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l422cb,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l073cz,defmt,exti,time-driver-any,unstable-traits,low-power,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f378cc,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5jb,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32g474pe,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h503rb,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h562ag,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ diff --git a/ci_stable.sh b/ci_stable.sh index 4ee5f410..61b02175 100755 --- a/ci_stable.sh +++ b/ci_stable.sh @@ -35,38 +35,38 @@ cargo batch \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features unstable-traits,log \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features qspi-as-gpio \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any \ - --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --no-default-features --out-dir out/examples/nrf52840 --bin raw_spawn \ --- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --no-default-features --out-dir out/examples/stm32l0 --bin raw_spawn \ From ee93bbf1d45226ae71234287c382bf1ed530ca97 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 22:45:54 +0200 Subject: [PATCH 66/95] Gate pub use _version::* --- embassy-stm32/src/i2c/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index d5bb2ed2..61989c23 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -7,6 +7,8 @@ use crate::interrupt; #[cfg_attr(i2c_v1, path = "v1.rs")] #[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")] mod _version; + +#[cfg(any(i2c_v1, all(i2c_v2, feature = "time")))] pub use _version::*; use crate::peripherals; From b6c0ddb7df86a8c5531ef6ae4c026b2e7175c96b Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:05:12 +0200 Subject: [PATCH 67/95] Move the feature gates to the i2c module instead of the pub use statement --- embassy-stm32/src/i2c/mod.rs | 2 -- embassy-stm32/src/lib.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 61989c23..d5bb2ed2 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -7,8 +7,6 @@ use crate::interrupt; #[cfg_attr(i2c_v1, path = "v1.rs")] #[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")] mod _version; - -#[cfg(any(i2c_v1, all(i2c_v2, feature = "time")))] pub use _version::*; use crate::peripherals; diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index e883678b..cfb78da3 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -41,7 +41,7 @@ pub mod flash; pub mod fmc; #[cfg(hrtim)] pub mod hrtim; -#[cfg(i2c)] +#[cfg(all(i2c, any(i2c_v1, all(i2c_v2, feature = "time"))))] pub mod i2c; #[cfg(all(spi_v1, rcc_f4))] pub mod i2s; From cd68f85501fabaf22587a900e60c70b6dae43767 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:25:13 +0200 Subject: [PATCH 68/95] Added guards to individual APIs --- embassy-stm32/src/i2c/mod.rs | 2 +- embassy-stm32/src/i2c/v2.rs | 94 ++++++++++++++++++++++++++++++++---- embassy-stm32/src/lib.rs | 2 +- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index d5bb2ed2..204ad679 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -5,7 +5,7 @@ use crate::interrupt; // I2C V2 is gated on the `time` feature because timing facilities are necessary // to provide timeout functionality in order to prevent some APIs from stalling indefinitely #[cfg_attr(i2c_v1, path = "v1.rs")] -#[cfg_attr(all(i2c_v2, feature = "time"), path = "v2.rs")] +#[cfg_attr(i2c_v2, path = "v2.rs")] mod _version; pub use _version::*; diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 256b3963..33c39740 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -44,6 +44,7 @@ impl interrupt::typelevel::Handler for InterruptHandl pub struct Config { pub sda_pullup: bool, pub scl_pullup: bool, + #[cfg(feature = "time")] pub transaction_timeout: Duration, } @@ -52,6 +53,7 @@ impl Default for Config { Self { sda_pullup: false, scl_pullup: false, + #[cfg(feature = "time")] transaction_timeout: Duration::from_millis(100), } } @@ -74,6 +76,7 @@ pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { tx_dma: PeripheralRef<'d, TXDMA>, #[allow(dead_code)] rx_dma: PeripheralRef<'d, RXDMA>, + #[cfg(feature = "time")] timeout: Duration, } @@ -136,6 +139,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { _peri: peri, tx_dma, rx_dma, + #[cfg(feature = "time")] timeout: config.transaction_timeout, } } @@ -599,6 +603,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // ========================= // Async public API + #[cfg(feature = "time")] pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, @@ -606,6 +611,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { self.write_timeout(address, write, self.timeout).await } + #[cfg(feature = "time")] pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, @@ -622,6 +628,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } + #[cfg(feature = "time")] pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, @@ -629,6 +636,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { self.write_vectored_timeout(address, write, self.timeout).await } + #[cfg(feature = "time")] pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, @@ -656,6 +664,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } + #[cfg(feature = "time")] pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> where RXDMA: crate::i2c::RxDma, @@ -663,6 +672,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { self.read_timeout(address, buffer, self.timeout).await } + #[cfg(feature = "time")] pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> where RXDMA: crate::i2c::RxDma, @@ -679,6 +689,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } + #[cfg(feature = "time")] pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> where TXDMA: super::TxDma, @@ -687,6 +698,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { self.write_read_timeout(address, write, read, self.timeout).await } + #[cfg(feature = "time")] pub async fn write_read_timeout( &mut self, address: u8, @@ -730,23 +742,43 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // ========================= // Blocking public API + #[cfg(feature = "time")] pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> { self.read_internal(address, read, false, timeout_fn(timeout)) // Automatic Stop } - pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { - self.blocking_read_timeout(address, read, self.timeout) + #[cfg(not(feature = "time"))] + pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> { + self.read_internal(address, read, false, check_timeout) + // Automatic Stop } + pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { + #[cfg(feature = "time")] + self.blocking_read_timeout(address, read, self.timeout) + #[cfg(not(feature = "time"))] + self.blocking_read_timeout(address, read, || Ok(())) + } + + #[cfg(feature = "time")] pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> { self.write_internal(address, write, true, timeout_fn(timeout)) } - pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { - self.blocking_write_timeout(address, write, self.timeout) + #[cfg(not(feature = "time"))] + pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> { + self.write_internal(address, write, true, check_timeout) } + pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { + #[cfg(feature = "time")] + self.blocking_write_timeout(address, write, self.timeout) + #[cfg(not(feature = "time"))] + self.blocking_write_timeout(address, write, || Ok(())) + } + + #[cfg(feature = "time")] pub fn blocking_write_read_timeout( &mut self, address: u8, @@ -760,21 +792,37 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Automatic Stop } - pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { - self.blocking_write_read_timeout(address, write, read, self.timeout) + #[cfg(not(feature = "time"))] + pub fn blocking_write_read_timeout( + &mut self, + address: u8, + write: &[u8], + read: &mut [u8], + check_timeout: impl Fn() -> Result<(), Error>, + ) -> Result<(), Error> { + let check_timeout = timeout_fn(timeout); + self.write_internal(address, write, false, &check_timeout)?; + self.read_internal(address, read, true, &check_timeout) + // Automatic Stop } - pub fn blocking_write_vectored_timeout( + pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { + #[cfg(feature = "time")] + self.blocking_write_read_timeout(address, write, read, self.timeout) + #[cfg(not(feature = "time"))] + self.blocking_write_read_timeout(address, write, read, || Ok(())) + } + + fn blocking_write_vectored_with_timeout( &mut self, address: u8, write: &[&[u8]], - timeout: Duration, + check_timeout: impl Fn() -> Result<(), Error>, ) -> Result<(), Error> { if write.is_empty() { return Err(Error::ZeroLengthTransfer); } - let check_timeout = timeout_fn(timeout); let first_length = write[0].len(); let last_slice_index = write.len() - 1; @@ -843,8 +891,32 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { result } + #[cfg(feature = "time")] + pub fn blocking_write_vectored_timeout( + &mut self, + address: u8, + write: &[&[u8]], + timeout: Duration, + ) -> Result<(), Error> { + let check_timeout = timeout_fn(timeout); + self.blocking_write_vectored_with_timeout(address, write, check_timeout) + } + + #[cfg(not(feature = "time"))] + pub fn blocking_write_vectored_timeout( + &mut self, + address: u8, + write: &[&[u8]], + check_timeout: impl Fn() -> Result<(), Error>, + ) -> Result<(), Error> { + self.blocking_write_vectored_with_timeout(address, write, check_timeout) + } + pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { + #[cfg(feature = "time")] self.blocking_write_vectored_timeout(address, write, self.timeout) + #[cfg(not(feature = "time"))] + self.blocking_write_vectored_timeout(address, write, || Ok(())) } } @@ -854,6 +926,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { } } +#[cfg(feature = "time")] mod eh02 { use super::*; @@ -1053,7 +1126,7 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] +#[cfg(all(feature = "unstable-traits", feature = "nightly", feature = "time"))] mod eha { use super::super::{RxDma, TxDma}; use super::*; @@ -1100,6 +1173,7 @@ impl<'d, T: Instance> SetConfig for I2c<'d, T> { } } +#[cfg(feature = "time")] fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> { let deadline = Instant::now() + timeout; move || { diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index cfb78da3..e883678b 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -41,7 +41,7 @@ pub mod flash; pub mod fmc; #[cfg(hrtim)] pub mod hrtim; -#[cfg(all(i2c, any(i2c_v1, all(i2c_v2, feature = "time"))))] +#[cfg(i2c)] pub mod i2c; #[cfg(all(spi_v1, rcc_f4))] pub mod i2s; From 251d004708762210a2279bee66c1e5b2dcdf93cb Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:32:40 +0200 Subject: [PATCH 69/95] Try using cfg! macro --- embassy-stm32/src/i2c/v2.rs | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 33c39740..6627d7f6 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -755,10 +755,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { - #[cfg(feature = "time")] - self.blocking_read_timeout(address, read, self.timeout) - #[cfg(not(feature = "time"))] - self.blocking_read_timeout(address, read, || Ok(())) + if cfg!(feature = "time") { + self.blocking_read_timeout(address, read, self.timeout) + } else { + self.blocking_read_timeout(address, read, || Ok(())) + } } #[cfg(feature = "time")] @@ -772,10 +773,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { - #[cfg(feature = "time")] - self.blocking_write_timeout(address, write, self.timeout) - #[cfg(not(feature = "time"))] - self.blocking_write_timeout(address, write, || Ok(())) + if cfg!(feature = "time") { + self.blocking_write_timeout(address, write, self.timeout) + } else { + self.blocking_write_timeout(address, write, || Ok(())) + } } #[cfg(feature = "time")] @@ -807,10 +809,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { - #[cfg(feature = "time")] - self.blocking_write_read_timeout(address, write, read, self.timeout) - #[cfg(not(feature = "time"))] - self.blocking_write_read_timeout(address, write, read, || Ok(())) + if cfg!(feature = "time") { + self.blocking_write_read_timeout(address, write, read, self.timeout) + } else { + self.blocking_write_read_timeout(address, write, read, || Ok(())) + } } fn blocking_write_vectored_with_timeout( @@ -913,10 +916,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { - #[cfg(feature = "time")] - self.blocking_write_vectored_timeout(address, write, self.timeout) - #[cfg(not(feature = "time"))] - self.blocking_write_vectored_timeout(address, write, || Ok(())) + if cfg!(feature = "time") { + self.blocking_write_vectored_timeout(address, write, self.timeout) + } else { + self.blocking_write_vectored_timeout(address, write, || Ok(())) + } } } From ee5ea7aa06491a2bbd523ac054604977cb0c9e33 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:34:02 +0200 Subject: [PATCH 70/95] cargo fmt --- embassy-stm32/src/i2c/v2.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 6627d7f6..093b960d 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -749,7 +749,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } #[cfg(not(feature = "time"))] - pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> { + pub fn blocking_read_timeout( + &mut self, + address: u8, + read: &mut [u8], + check_timeout: impl Fn() -> Result<(), Error>, + ) -> Result<(), Error> { self.read_internal(address, read, false, check_timeout) // Automatic Stop } @@ -768,7 +773,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } #[cfg(not(feature = "time"))] - pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> { + pub fn blocking_write_timeout( + &mut self, + address: u8, + write: &[u8], + check_timeout: impl Fn() -> Result<(), Error>, + ) -> Result<(), Error> { self.write_internal(address, write, true, check_timeout) } From f76d50e837cab098cd255c15ee0655c8d3ffb55b Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:39:24 +0200 Subject: [PATCH 71/95] cfg! macro didn't work, had to duplicate functions with different guards --- embassy-stm32/src/i2c/v2.rs | 50 +++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 093b960d..926a3f7a 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -7,6 +7,7 @@ use embassy_embedded_hal::SetConfig; use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; +#[cfg(feature = "time")] use embassy_time::{Duration, Instant}; use crate::dma::{NoDma, Transfer}; @@ -759,12 +760,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Automatic Stop } + #[cfg(feature = "time")] pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { - if cfg!(feature = "time") { - self.blocking_read_timeout(address, read, self.timeout) - } else { - self.blocking_read_timeout(address, read, || Ok(())) - } + self.blocking_read_timeout(address, read, self.timeout) + } + + #[cfg(not(feature = "time"))] + pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { + self.blocking_read_timeout(address, read, || Ok(())) } #[cfg(feature = "time")] @@ -782,12 +785,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { self.write_internal(address, write, true, check_timeout) } + #[cfg(feature = "time")] pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { - if cfg!(feature = "time") { - self.blocking_write_timeout(address, write, self.timeout) - } else { - self.blocking_write_timeout(address, write, || Ok(())) - } + self.blocking_write_timeout(address, write, self.timeout) + } + + #[cfg(not(feature = "time"))] + pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { + self.blocking_write_timeout(address, write, || Ok(())) } #[cfg(feature = "time")] @@ -812,18 +817,19 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { read: &mut [u8], check_timeout: impl Fn() -> Result<(), Error>, ) -> Result<(), Error> { - let check_timeout = timeout_fn(timeout); self.write_internal(address, write, false, &check_timeout)?; self.read_internal(address, read, true, &check_timeout) // Automatic Stop } + #[cfg(feature = "time")] pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { - if cfg!(feature = "time") { - self.blocking_write_read_timeout(address, write, read, self.timeout) - } else { - self.blocking_write_read_timeout(address, write, read, || Ok(())) - } + self.blocking_write_read_timeout(address, write, read, self.timeout) + } + + #[cfg(not(feature = "time"))] + pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { + self.blocking_write_read_timeout(address, write, read, || Ok(())) } fn blocking_write_vectored_with_timeout( @@ -925,12 +931,14 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { self.blocking_write_vectored_with_timeout(address, write, check_timeout) } + #[cfg(feature = "time")] pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { - if cfg!(feature = "time") { - self.blocking_write_vectored_timeout(address, write, self.timeout) - } else { - self.blocking_write_vectored_timeout(address, write, || Ok(())) - } + self.blocking_write_vectored_timeout(address, write, self.timeout) + } + + #[cfg(not(feature = "time"))] + pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { + self.blocking_write_vectored_timeout(address, write, || Ok(())) } } From 032b1f2d5976422b12e5cb023de939e5a1cd0c37 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:42:40 +0200 Subject: [PATCH 72/95] Fix some issues with unused stuff --- embassy-stm32/src/i2c/v2.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 926a3f7a..8a7fa6a9 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -74,6 +74,7 @@ impl State { pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { _peri: PeripheralRef<'d, T>, + #[allow(dead_code)] tx_dma: PeripheralRef<'d, TXDMA>, #[allow(dead_code)] rx_dma: PeripheralRef<'d, RXDMA>, @@ -432,6 +433,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { result } + #[cfg(feature = "time")] async fn write_dma_internal( &mut self, address: u8, @@ -522,6 +524,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } + #[cfg(feature = "time")] async fn read_dma_internal( &mut self, address: u8, From 2f7c2750d1ec1f741c5c7900a73aca392abecaa3 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:45:47 +0200 Subject: [PATCH 73/95] Feature guarded more unused stuff --- embassy-stm32/src/i2c/v2.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 8a7fa6a9..291ac13f 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -1,16 +1,22 @@ use core::cmp; +#[cfg(feature = "time")] use core::future::poll_fn; use core::marker::PhantomData; +#[cfg(feature = "time")] use core::task::Poll; use embassy_embedded_hal::SetConfig; +#[cfg(feature = "time")] use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; #[cfg(feature = "time")] use embassy_time::{Duration, Instant}; -use crate::dma::{NoDma, Transfer}; +use crate::dma::NoDma; +#[cfg(feature = "time")] +use crate::dma::Transfer; + use crate::gpio::sealed::AFType; use crate::gpio::Pull; use crate::i2c::{Error, Instance, SclPin, SdaPin}; From e6c47c371823b61124276da9677f1aa1d4b2a2f7 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:47:24 +0200 Subject: [PATCH 74/95] cargo fmt --- embassy-stm32/src/i2c/v2.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 291ac13f..41aa0b6d 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -16,7 +16,6 @@ use embassy_time::{Duration, Instant}; use crate::dma::NoDma; #[cfg(feature = "time")] use crate::dma::Transfer; - use crate::gpio::sealed::AFType; use crate::gpio::Pull; use crate::i2c::{Error, Instance, SclPin, SdaPin}; From 4cec4b0548b6782e350bbea0579cdfb6f40d6623 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:52:26 +0200 Subject: [PATCH 75/95] Remove more unused stuff --- examples/stm32f4/src/bin/i2c.rs | 1 - examples/stm32h5/src/bin/i2c.rs | 1 - examples/stm32h7/src/bin/i2c.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs index 10ca2bdc..032bd97e 100644 --- a/examples/stm32f4/src/bin/i2c.rs +++ b/examples/stm32f4/src/bin/i2c.rs @@ -8,7 +8,6 @@ use embassy_stm32::dma::NoDma; use embassy_stm32::i2c::{Error, I2c}; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, i2c, peripherals}; -use embassy_time::Duration; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x5F; diff --git a/examples/stm32h5/src/bin/i2c.rs b/examples/stm32h5/src/bin/i2c.rs index 4ce378e9..8b1662f3 100644 --- a/examples/stm32h5/src/bin/i2c.rs +++ b/examples/stm32h5/src/bin/i2c.rs @@ -7,7 +7,6 @@ use embassy_executor::Spawner; use embassy_stm32::i2c::{Error, I2c}; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, i2c, peripherals}; -use embassy_time::Duration; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x5F; diff --git a/examples/stm32h7/src/bin/i2c.rs b/examples/stm32h7/src/bin/i2c.rs index 7cd12e5e..9aa0ca08 100644 --- a/examples/stm32h7/src/bin/i2c.rs +++ b/examples/stm32h7/src/bin/i2c.rs @@ -7,7 +7,6 @@ use embassy_executor::Spawner; use embassy_stm32::i2c::{Error, I2c}; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, i2c, peripherals}; -use embassy_time::Duration; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x5F; From 063e6f96daecf8f68a538c0f1904619d84333926 Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Wed, 11 Oct 2023 23:56:21 +0200 Subject: [PATCH 76/95] Remove outdated comment --- embassy-stm32/src/i2c/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 204ad679..dde1a504 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -2,8 +2,6 @@ use crate::interrupt; -// I2C V2 is gated on the `time` feature because timing facilities are necessary -// to provide timeout functionality in order to prevent some APIs from stalling indefinitely #[cfg_attr(i2c_v1, path = "v1.rs")] #[cfg_attr(i2c_v2, path = "v2.rs")] mod _version; From 32b89eeba18d2d0a9c3705212768d4ade3f4948d Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 12 Oct 2023 01:35:23 +0200 Subject: [PATCH 77/95] net: remove atomic-polyfill. --- cyw43/Cargo.toml | 1 - embassy-net/Cargo.toml | 1 - embassy-net/src/tcp.rs | 15 +++++++-------- examples/stm32h7/src/bin/eth_client.rs | 4 ++-- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index dae7419c..c201405e 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml @@ -15,7 +15,6 @@ embassy-time = { version = "0.1.3", path = "../embassy-time"} embassy-sync = { version = "0.3.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"} -atomic-polyfill = "0.1.5" defmt = { version = "0.3", optional = true } log = { version = "0.4.17", optional = true } diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index c2fffba8..a3c18046 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -64,4 +64,3 @@ stable_deref_trait = { version = "1.2.0", default-features = false } futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } atomic-pool = "1.0" embedded-nal-async = { version = "0.6.0", optional = true } -atomic-polyfill = { version = "1.0" } diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index a12fd382..b5615cb6 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -579,11 +579,10 @@ mod embedded_io_impls { /// TCP client compatible with `embedded-nal-async` traits. #[cfg(feature = "nightly")] pub mod client { - use core::cell::UnsafeCell; + use core::cell::{Cell, UnsafeCell}; use core::mem::MaybeUninit; use core::ptr::NonNull; - use atomic_polyfill::{AtomicBool, Ordering}; use embedded_nal_async::IpAddr; use super::*; @@ -702,15 +701,13 @@ pub mod client { } } - unsafe impl Sync for TcpClientState {} - struct Pool { - used: [AtomicBool; N], + used: [Cell; N], data: [UnsafeCell>; N], } impl Pool { - const VALUE: AtomicBool = AtomicBool::new(false); + const VALUE: Cell = Cell::new(false); const UNINIT: UnsafeCell> = UnsafeCell::new(MaybeUninit::uninit()); const fn new() -> Self { @@ -724,7 +721,9 @@ pub mod client { impl Pool { fn alloc(&self) -> Option> { for n in 0..N { - if self.used[n].swap(true, Ordering::SeqCst) == false { + // this can't race because Pool is not Sync. + if !self.used[n].get() { + self.used[n].set(true); let p = self.data[n].get() as *mut T; return Some(unsafe { NonNull::new_unchecked(p) }); } @@ -738,7 +737,7 @@ pub mod client { let n = p.as_ptr().offset_from(origin); assert!(n >= 0); assert!((n as usize) < N); - self.used[n as usize].store(false, Ordering::SeqCst); + self.used[n as usize].set(false); } } } diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 4db7aa25..09d27cdb 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -105,8 +105,8 @@ async fn main(spawner: Spawner) -> ! { info!("Network task initialized"); - static STATE: TcpClientState<1, 1024, 1024> = TcpClientState::new(); - let client = TcpClient::new(&stack, &STATE); + let state: TcpClientState<1, 1024, 1024> = TcpClientState::new(); + let client = TcpClient::new(&stack, &state); loop { let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(10, 42, 0, 1), 8000)); From 70a91945fca97229518f4f8f011233650448771d Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 12 Oct 2023 01:16:42 +0200 Subject: [PATCH 78/95] stm32: remove atomic-polyfill. --- embassy-stm32/Cargo.toml | 1 - embassy-stm32/build.rs | 34 ++++++++++++++++++++++++++++---- embassy-stm32/src/dma/bdma.rs | 18 ++++++++++++++--- embassy-stm32/src/lib.rs | 4 +++- embassy-stm32/src/low_power.rs | 2 +- embassy-stm32/src/rcc/mod.rs | 16 +++++++++------ embassy-stm32/src/time_driver.rs | 22 ++++++++++----------- embassy-time/Cargo.toml | 1 - 8 files changed, 69 insertions(+), 29 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 33583d22..a2c5da2b 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -58,7 +58,6 @@ rand_core = "0.6.3" sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" -atomic-polyfill = "1.0.1" stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c" } vcell = "0.1.3" bxcan = "0.7.0" diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 810da37e..fa10b7f7 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -8,6 +8,32 @@ use quote::{format_ident, quote}; use stm32_metapac::metadata::{MemoryRegionKind, METADATA}; fn main() { + let target = env::var("TARGET").unwrap(); + + if target.starts_with("thumbv6m-") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv6m"); + } else if target.starts_with("thumbv7m-") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv7m"); + } else if target.starts_with("thumbv7em-") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv7m"); + println!("cargo:rustc-cfg=armv7em"); // (not currently used) + } else if target.starts_with("thumbv8m.base") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv8m"); + println!("cargo:rustc-cfg=armv8m_base"); + } else if target.starts_with("thumbv8m.main") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv8m"); + println!("cargo:rustc-cfg=armv8m_main"); + } + + if target.ends_with("-eabihf") { + println!("cargo:rustc-cfg=has_fpu"); + } + let chip_name = match env::vars() .map(|(a, _)| a) .filter(|x| x.starts_with("CARGO_FEATURE_STM32")) @@ -434,20 +460,20 @@ fn main() { unsafe { crate::rcc::get_freqs().#clk } } fn enable() { - critical_section::with(|_| { + critical_section::with(|_cs| { #before_enable #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_add(); + crate::rcc::clock_refcount_add(_cs); crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); #after_enable }) } fn disable() { - critical_section::with(|_| { + critical_section::with(|_cs| { #before_disable crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_sub(); + crate::rcc::clock_refcount_sub(_cs); }) } fn reset() { diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 20ff29be..62eb65b1 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -2,10 +2,9 @@ use core::future::Future; use core::pin::Pin; -use core::sync::atomic::{fence, Ordering}; +use core::sync::atomic::{fence, AtomicUsize, Ordering}; use core::task::{Context, Poll, Waker}; -use atomic_polyfill::AtomicUsize; use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; @@ -127,7 +126,13 @@ pub(crate) unsafe fn on_irq_inner(dma: pac::bdma::Dma, channel_num: usize, index } else if isr.tcif(channel_num) && cr.read().tcie() { // Acknowledge transfer complete interrupt dma.ifcr().write(|w| w.set_tcif(channel_num, true)); + #[cfg(not(armv6m))] STATE.complete_count[index].fetch_add(1, Ordering::Release); + #[cfg(armv6m)] + critical_section::with(|_| { + let x = STATE.complete_count[index].load(Ordering::Relaxed); + STATE.complete_count[index].store(x + 1, Ordering::Release); + }) } else { return; } @@ -391,7 +396,14 @@ impl<'a, C: Channel> DmaCtrl for DmaCtrlImpl<'a, C> { } fn reset_complete_count(&mut self) -> usize { - STATE.complete_count[self.0.index()].swap(0, Ordering::AcqRel) + #[cfg(not(armv6m))] + return STATE.complete_count[self.0.index()].swap(0, Ordering::AcqRel); + #[cfg(armv6m)] + return critical_section::with(|_| { + let x = STATE.complete_count[self.0.index()].load(Ordering::Acquire); + STATE.complete_count[self.0.index()].store(0, Ordering::Release); + x + }); } fn set_waker(&mut self, waker: &Waker) { diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index e883678b..37c94f82 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -225,7 +225,9 @@ pub fn init(config: Config) -> Peripherals { #[cfg(feature = "low-power")] while !crate::rcc::low_power_ready() { - crate::rcc::clock_refcount_sub(); + critical_section::with(|cs| { + crate::rcc::clock_refcount_sub(cs); + }); } } diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index bb714b8c..861a59d7 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -1,7 +1,7 @@ use core::arch::asm; use core::marker::PhantomData; +use core::sync::atomic::{compiler_fence, Ordering}; -use atomic_polyfill::{compiler_fence, Ordering}; use cortex_m::peripheral::SCB; use embassy_executor::*; diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index a9e53d42..abb53fd1 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -27,9 +27,10 @@ pub use mco::*; #[cfg_attr(rcc_wba, path = "wba.rs")] #[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] mod _version; -pub use _version::*; #[cfg(feature = "low-power")] -use atomic_polyfill::{AtomicU32, Ordering}; +use core::sync::atomic::{AtomicU32, Ordering}; + +pub use _version::*; // Model Clock Configuration // @@ -145,14 +146,17 @@ pub fn low_power_ready() -> bool { } #[cfg(feature = "low-power")] -pub(crate) fn clock_refcount_add() { +pub(crate) fn clock_refcount_add(_cs: critical_section::CriticalSection) { // We don't check for overflow because constructing more than u32 peripherals is unlikely - CLOCK_REFCOUNT.fetch_add(1, Ordering::Relaxed); + let n = CLOCK_REFCOUNT.load(Ordering::Relaxed); + CLOCK_REFCOUNT.store(n + 1, Ordering::Relaxed); } #[cfg(feature = "low-power")] -pub(crate) fn clock_refcount_sub() { - assert!(CLOCK_REFCOUNT.fetch_sub(1, Ordering::Relaxed) != 0); +pub(crate) fn clock_refcount_sub(_cs: critical_section::CriticalSection) { + let n = CLOCK_REFCOUNT.load(Ordering::Relaxed); + assert!(n != 0); + CLOCK_REFCOUNT.store(n - 1, Ordering::Relaxed); } /// Frozen clock frequencies diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 91750241..e88198e6 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -1,9 +1,8 @@ use core::cell::Cell; use core::convert::TryInto; -use core::sync::atomic::{compiler_fence, Ordering}; +use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; use core::{mem, ptr}; -use atomic_polyfill::{AtomicU32, AtomicU8}; use critical_section::CriticalSection; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::Mutex; @@ -229,7 +228,9 @@ impl RtcDriver { fn next_period(&self) { let r = T::regs_gp16(); - let period = self.period.fetch_add(1, Ordering::Relaxed) + 1; + // We only modify the period from the timer interrupt, so we know this can't race. + let period = self.period.load(Ordering::Relaxed) + 1; + self.period.store(period, Ordering::Relaxed); let t = (period as u64) << 15; critical_section::with(move |cs| { @@ -403,18 +404,15 @@ impl Driver for RtcDriver { } unsafe fn allocate_alarm(&self) -> Option { - let id = self.alarm_count.fetch_update(Ordering::AcqRel, Ordering::Acquire, |x| { - if x < ALARM_COUNT as u8 { - Some(x + 1) + critical_section::with(|_| { + let id = self.alarm_count.load(Ordering::Relaxed); + if id < ALARM_COUNT as u8 { + self.alarm_count.store(id + 1, Ordering::Relaxed); + Some(AlarmHandle::new(id)) } else { None } - }); - - match id { - Ok(id) => Some(AlarmHandle::new(id)), - Err(_) => None, - } + }) } fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) { diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 8f034a9d..e4b88d78 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -218,7 +218,6 @@ embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = embedded-hal-async = { version = "=1.0.0-rc.1", optional = true} futures-util = { version = "0.3.17", default-features = false } -atomic-polyfill = "1.0.1" critical-section = "1.1" cfg-if = "1.0.0" heapless = "0.7" From 57ccc1051a2790073f3963a8ab079bc072d0014f Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 11 Oct 2023 20:59:47 -0500 Subject: [PATCH 79/95] stm32: add initial rcc mux for h5 --- embassy-stm32/build.rs | 115 ++++++++++++++++++++++++++++++++--- embassy-stm32/src/rcc/h.rs | 51 +++++++++++++++- embassy-stm32/src/rcc/mod.rs | 46 ++++++++++++++ 3 files changed, 202 insertions(+), 10 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index fa10b7f7..5b6b22ea 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -5,7 +5,8 @@ use std::{env, fs}; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; -use stm32_metapac::metadata::{MemoryRegionKind, METADATA}; +use stm32_metapac::metadata::ir::{BlockItemInner, Enum}; +use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA}; fn main() { let target = env::var("TARGET").unwrap(); @@ -387,6 +388,51 @@ fn main() { }); } + // ======== + // Generate rcc fieldset and enum maps + let rcc_enum_map: HashMap<&str, HashMap<&str, &Enum>> = { + let rcc_registers = METADATA + .peripherals + .iter() + .filter_map(|p| p.registers.as_ref()) + .find(|r| r.kind == "rcc") + .unwrap() + .ir; + + let rcc_blocks = rcc_registers.blocks.iter().find(|b| b.name == "Rcc").unwrap().items; + + let rcc_block_item_map: HashMap<&str, &str> = rcc_blocks + .iter() + .filter_map(|b| match &b.inner { + BlockItemInner::Register(register) => register.fieldset.map(|f| (f, b.name)), + _ => None, + }) + .collect(); + + let rcc_enum_map: HashMap<&str, &Enum> = rcc_registers.enums.iter().map(|e| (e.name, e)).collect(); + + rcc_registers + .fieldsets + .iter() + .filter_map(|f| { + rcc_block_item_map.get(f.name).map(|b| { + ( + *b, + f.fields + .iter() + .filter_map(|f| { + let enumm = f.enumm?; + let enumm = rcc_enum_map.get(enumm)?; + + Some((f.name, *enumm)) + }) + .collect(), + ) + }) + }) + .collect() + }; + // ======== // Generate RccPeripheral impls @@ -454,10 +500,61 @@ fn main() { (TokenStream::new(), TokenStream::new()) }; + let mux_for = |mux: Option<&'static PeripheralRccRegister>| { + // temporary hack to restrict the scope of the implementation to h5 + if !&chip_name.starts_with("stm32h5") { + return None; + } + + let mux = mux?; + let fieldset = rcc_enum_map.get(mux.register)?; + let enumm = fieldset.get(mux.field)?; + + Some((mux, *enumm)) + }; + + let clock_frequency = match mux_for(rcc.mux.as_ref()) { + Some((mux, rcc_enumm)) => { + let fieldset_name = format_ident!("{}", mux.register); + let field_name = format_ident!("{}", mux.field); + let enum_name = format_ident!("{}", rcc_enumm.name); + + let match_arms: TokenStream = rcc_enumm + .variants + .iter() + .filter(|v| v.name != "DISABLE") + .map(|v| { + let variant_name = format_ident!("{}", v.name); + + // temporary hack to restrict the scope of the implementation until clock names can be stabilized + let clock_name = format_ident!("mux_{}", v.name.to_ascii_lowercase()); + + quote! { + #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() }, + } + }) + .collect(); + + quote! { + use crate::pac::rcc::vals::#enum_name; + + #[allow(unreachable_patterns)] + match crate::pac::RCC.#fieldset_name().read().#field_name() { + #match_arms + + _ => unreachable!(), + } + } + } + None => quote! { + unsafe { crate::rcc::get_freqs().#clk } + }, + }; + g.extend(quote! { impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { fn frequency() -> crate::time::Hertz { - unsafe { crate::rcc::get_freqs().#clk } + #clock_frequency } fn enable() { critical_section::with(|_cs| { @@ -486,12 +583,14 @@ fn main() { } } - let mut refcount_mod = TokenStream::new(); - for refcount_static in refcount_statics { - refcount_mod.extend(quote! { - pub(crate) static mut #refcount_static: u8 = 0; - }); - } + let refcount_mod: TokenStream = refcount_statics + .iter() + .map(|refcount_static| { + quote! { + pub(crate) static mut #refcount_static: u8 = 0; + } + }) + .collect(); g.extend(quote! { mod refcount_statics { diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 7236d82f..d37dd45d 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -388,7 +388,7 @@ pub(crate) unsafe fn init(config: Config) { let pll1 = init_pll(0, config.pll1, &pll_input); let pll2 = init_pll(1, config.pll2, &pll_input); #[cfg(any(rcc_h5, stm32h7))] - let _pll3 = init_pll(2, config.pll3, &pll_input); + let pll3 = init_pll(2, config.pll3, &pll_input); // Configure sysclk let (sys, sw) = match config.sys { @@ -447,7 +447,7 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(stm32h7)] let adc = match config.adc_clock_source { AdcClockSource::PLL2_P => pll2.p, - AdcClockSource::PLL3_R => _pll3.r, + AdcClockSource::PLL3_R => pll3.r, AdcClockSource::PER => _per_ck, _ => unreachable!(), }; @@ -545,6 +545,53 @@ pub(crate) unsafe fn init(config: Config) { apb2_tim, adc, rtc, + + #[cfg(stm32h5)] + mux_rcc_pclk1: Some(apb1), + #[cfg(stm32h5)] + mux_pll2_q: None, + #[cfg(stm32h5)] + mux_pll3_q: None, + #[cfg(stm32h5)] + mux_hsi_ker: None, + #[cfg(stm32h5)] + mux_csi_ker: None, + #[cfg(stm32h5)] + mux_lse: None, + #[cfg(stm32h5)] + mux_pll1_q: pll1.q, + #[cfg(stm32h5)] + mux_pll2_p: pll2.p, + #[cfg(rcc_h5)] + mux_pll3_p: pll3.p, + #[cfg(stm32h5)] + mux_audioclk: None, + #[cfg(stm32h5)] + mux_per: None, + + #[cfg(rcc_h5)] + mux_pll3_r: pll3.r, + #[cfg(all(not(rcc_h5), stm32h5))] + mux_pll3_r: None, + #[cfg(stm32h5)] + mux_rcc_pclk3: Some(apb3), + #[cfg(stm32h5)] + mux_pll3_1: None, + #[cfg(stm32h5)] + mux_hsi48_ker: None, + #[cfg(stm32h5)] + mux_lsi_ker: None, + #[cfg(stm32h5)] + mux_pll2_r: pll2.r, + #[cfg(stm32h5)] + mux_rcc_pclk2: Some(apb2), + #[cfg(stm32h5)] + mux_rcc_pclk4: None, + #[cfg(stm32h5)] + mux_hse: hse, + + #[cfg(stm32h5)] + mux_hsi48: None, }); } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index abb53fd1..695d4158 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -134,6 +134,52 @@ pub struct Clocks { pub hrtim: Option, pub rtc: Option, + + #[cfg(stm32h5)] + pub mux_rcc_pclk1: Option, + #[cfg(stm32h5)] + pub mux_pll2_q: Option, + #[cfg(stm32h5)] + pub mux_pll3_q: Option, + #[cfg(stm32h5)] + pub mux_hsi_ker: Option, + #[cfg(stm32h5)] + pub mux_csi_ker: Option, + #[cfg(stm32h5)] + pub mux_lse: Option, + + #[cfg(stm32h5)] + pub mux_pll1_q: Option, + #[cfg(stm32h5)] + pub mux_pll2_p: Option, + #[cfg(rcc_h5)] + pub mux_pll3_p: Option, + #[cfg(stm32h5)] + pub mux_audioclk: Option, + #[cfg(stm32h5)] + pub mux_per: Option, + + #[cfg(stm32h5)] + pub mux_pll3_r: Option, + #[cfg(stm32h5)] + pub mux_rcc_pclk3: Option, + #[cfg(stm32h5)] + pub mux_pll3_1: Option, + #[cfg(stm32h5)] + pub mux_hsi48_ker: Option, + #[cfg(stm32h5)] + pub mux_lsi_ker: Option, + #[cfg(stm32h5)] + pub mux_pll2_r: Option, + #[cfg(stm32h5)] + pub mux_rcc_pclk2: Option, + #[cfg(stm32h5)] + pub mux_rcc_pclk4: Option, + #[cfg(stm32h5)] + pub mux_hse: Option, + + #[cfg(stm32h5)] + pub mux_hsi48: Option, } #[cfg(feature = "low-power")] From f65a96c54146179f76a7a2a784c5bb89590e5de1 Mon Sep 17 00:00:00 2001 From: pbert Date: Wed, 11 Oct 2023 18:06:43 +0200 Subject: [PATCH 80/95] STM32: combine RccPeripherals reset() and enable() to reset_and_enable() --- embassy-stm32/build.rs | 4 +- embassy-stm32/src/adc/f1.rs | 3 +- embassy-stm32/src/adc/f3.rs | 3 +- embassy-stm32/src/adc/v1.rs | 3 +- embassy-stm32/src/adc/v2.rs | 3 +- embassy-stm32/src/adc/v4.rs | 3 +- embassy-stm32/src/can/bxcan.rs | 3 +- embassy-stm32/src/crc/v1.rs | 4 +- embassy-stm32/src/crc/v2v3.rs | 7 +-- embassy-stm32/src/dac/mod.rs | 56 ++++++++----------- embassy-stm32/src/dcmi.rs | 3 +- embassy-stm32/src/fmc.rs | 3 +- embassy-stm32/src/gpio.rs | 2 +- embassy-stm32/src/hrtim/mod.rs | 3 +- embassy-stm32/src/i2c/v1.rs | 3 +- embassy-stm32/src/i2c/v2.rs | 3 +- embassy-stm32/src/ipcc.rs | 3 +- embassy-stm32/src/lib.rs | 6 +- embassy-stm32/src/qspi/mod.rs | 3 +- embassy-stm32/src/rcc/g4.rs | 2 +- embassy-stm32/src/rcc/mod.rs | 3 +- embassy-stm32/src/rng.rs | 3 +- embassy-stm32/src/rtc/mod.rs | 2 +- embassy-stm32/src/sai/mod.rs | 54 +++++++++--------- embassy-stm32/src/sdmmc/mod.rs | 3 +- embassy-stm32/src/spi/mod.rs | 3 +- embassy-stm32/src/time_driver.rs | 3 +- embassy-stm32/src/timer/complementary_pwm.rs | 3 +- embassy-stm32/src/timer/qei.rs | 3 +- embassy-stm32/src/timer/simple_pwm.rs | 3 +- embassy-stm32/src/usart/buffered.rs | 15 ++--- embassy-stm32/src/usart/mod.rs | 27 ++++----- embassy-stm32/src/usb/usb.rs | 3 +- embassy-stm32/src/usb_otg/usb.rs | 3 +- examples/stm32h7/src/bin/dac_dma.rs | 4 +- .../stm32h7/src/bin/low_level_timer_api.rs | 3 +- examples/stm32l4/src/bin/dac_dma.rs | 4 +- 37 files changed, 105 insertions(+), 154 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 5b6b22ea..719a52d1 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -559,6 +559,7 @@ fn main() { fn enable() { critical_section::with(|_cs| { #before_enable + #rst #[cfg(feature = "low-power")] crate::rcc::clock_refcount_add(_cs); crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); @@ -573,9 +574,6 @@ fn main() { crate::rcc::clock_refcount_sub(_cs); }) } - fn reset() { - #rst - } } impl crate::rcc::RccPeripheral for peripherals::#pname {} diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index c1326481..5f5bf4bf 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs @@ -51,8 +51,7 @@ impl super::sealed::AdcPin for Temperature { impl<'d, T: Instance> Adc<'d, T> { pub fn new(adc: impl Peripheral

+ 'd, delay: &mut impl DelayUs) -> Self { into_ref!(adc); - T::enable(); - T::reset(); + T::reset_and_enable(); T::regs().cr2().modify(|reg| reg.set_adon(true)); // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’) diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs index 7c13f810..e94f6141 100644 --- a/embassy-stm32/src/adc/f3.rs +++ b/embassy-stm32/src/adc/f3.rs @@ -64,8 +64,7 @@ impl<'d, T: Instance> Adc<'d, T> { into_ref!(adc); - T::enable(); - T::reset(); + T::reset_and_enable(); // Enable the adc regulator T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE)); diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index fded26e4..f03acdcf 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs @@ -61,8 +61,7 @@ impl<'d, T: Instance> Adc<'d, T> { delay: &mut impl DelayUs, ) -> Self { into_ref!(adc); - T::enable(); - T::reset(); + T::reset_and_enable(); // Delay 1μs when using HSI14 as the ADC clock. // diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index a669013c..89e7616b 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs @@ -95,8 +95,7 @@ where { pub fn new(adc: impl Peripheral

+ 'd, delay: &mut impl DelayUs) -> Self { into_ref!(adc); - T::enable(); - T::reset(); + T::reset_and_enable(); let presc = Prescaler::from_pclk2(T::frequency()); T::common_regs().ccr().modify(|w| w.set_adcpre(presc.adcpre())); diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index 655c0cb6..6d86e5cd 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs @@ -127,8 +127,7 @@ impl Prescaler { impl<'d, T: Instance> Adc<'d, T> { pub fn new(adc: impl Peripheral

+ 'd, delay: &mut impl DelayUs) -> Self { embassy_hal_internal::into_ref!(adc); - T::enable(); - T::reset(); + T::reset_and_enable(); let prescaler = Prescaler::from_ker_ck(T::frequency()); diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 7ad13cec..903f7e48 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -136,8 +136,7 @@ impl<'d, T: Instance> Can<'d, T> { rx.set_as_af(rx.af_num(), AFType::Input); tx.set_as_af(tx.af_num(), AFType::OutputPushPull); - T::enable(); - T::reset(); + T::reset_and_enable(); { use crate::pac::can::vals::{Errie, Fmpie, Tmeie}; diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs index 154f2eb9..282e1ad8 100644 --- a/embassy-stm32/src/crc/v1.rs +++ b/embassy-stm32/src/crc/v1.rs @@ -16,9 +16,7 @@ impl<'d> Crc<'d> { // Note: enable and reset come from RccPeripheral. // enable CRC clock in RCC. - CRC::enable(); - // Reset CRC to default values. - CRC::reset(); + CRC::reset_and_enable(); // Peripheral the peripheral let mut instance = Self { _peri: peripheral }; instance.reset(); diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs index de0c0875..2ab25e6f 100644 --- a/embassy-stm32/src/crc/v2v3.rs +++ b/embassy-stm32/src/crc/v2v3.rs @@ -69,16 +69,13 @@ impl<'d> Crc<'d> { /// Instantiates the CRC32 peripheral and initializes it to default values. pub fn new(peripheral: impl Peripheral

+ 'd, config: Config) -> Self { // Note: enable and reset come from RccPeripheral. - // enable CRC clock in RCC. - CRC::enable(); - // Reset CRC to default values. - CRC::reset(); + // reset to default values and enable CRC clock in RCC. + CRC::reset_and_enable(); into_ref!(peripheral); let mut instance = Self { _peripheral: peripheral, _config: config, }; - CRC::reset(); instance.reconfigure(); instance.reset(); instance diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 36f6612b..e93fca95 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -255,8 +255,7 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { ) -> Self { pin.set_as_analog(); into_ref!(peri, dma); - T::enable(); - T::reset(); + T::reset_and_enable(); let mut dac = Self { _peri: peri, dma }; @@ -366,8 +365,7 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { ) -> Self { pin.set_as_analog(); into_ref!(_peri, dma); - T::enable(); - T::reset(); + T::reset_and_enable(); let mut dac = Self { phantom: PhantomData, @@ -483,8 +481,7 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> { pin_ch1.set_as_analog(); pin_ch2.set_as_analog(); into_ref!(peri, dma_ch1, dma_ch2); - T::enable(); - T::reset(); + T::reset_and_enable(); let mut dac_ch1 = DacCh1 { _peri: peri, @@ -563,35 +560,30 @@ pub trait DacPin: crate::gpio::Pin + 'static {} foreach_peripheral!( (dac, $inst:ident) => { - // H7 uses single bit for both DAC1 and DAC2, this is a hack until a proper fix is implemented - #[cfg(any(rcc_h7, rcc_h7rm0433))] - impl crate::rcc::sealed::RccPeripheral for peripherals::$inst { - fn frequency() -> crate::time::Hertz { - critical_section::with(|_| unsafe { crate::rcc::get_freqs().apb1 }) - } + // H7 uses single bit for both DAC1 and DAC2, this is a hack until a proper fix is implemented + #[cfg(any(rcc_h7, rcc_h7rm0433))] + impl crate::rcc::sealed::RccPeripheral for peripherals::$inst { + fn frequency() -> crate::time::Hertz { + critical_section::with(|_| unsafe { crate::rcc::get_freqs().apb1 }) + } - fn reset() { - critical_section::with(|_| { - crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); - crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); - }) - } + fn reset_and_enable() { + critical_section::with(|_| { + crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); + crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); + crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); + }) + } - fn enable() { - critical_section::with(|_| { - crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); - }) - } + fn disable() { + critical_section::with(|_| { + crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)) + }) + } + } - fn disable() { - critical_section::with(|_| { - crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)) - }) - } - } - - #[cfg(any(rcc_h7, rcc_h7rm0433))] - impl crate::rcc::RccPeripheral for peripherals::$inst {} + #[cfg(any(rcc_h7, rcc_h7rm0433))] + impl crate::rcc::RccPeripheral for peripherals::$inst {} impl crate::dac::sealed::Instance for peripherals::$inst { fn regs() -> &'static crate::pac::dac::Dac { diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs index 7497f4aa..6a63e6ee 100644 --- a/embassy-stm32/src/dcmi.rs +++ b/embassy-stm32/src/dcmi.rs @@ -330,8 +330,7 @@ where use_embedded_synchronization: bool, edm: u8, ) -> Self { - T::reset(); - T::enable(); + T::reset_and_enable(); peri.regs().cr().modify(|r| { r.set_cm(true); // disable continuous mode (snapshot mode) diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs index 177e66a9..51c75aeb 100644 --- a/embassy-stm32/src/fmc.rs +++ b/embassy-stm32/src/fmc.rs @@ -19,8 +19,7 @@ where const REGISTERS: *const () = T::REGS.as_ptr() as *const _; fn enable(&mut self) { - ::enable(); - ::reset(); + T::reset_and_enable(); } fn memory_controller_enable(&mut self) { diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 58d17f12..9192f731 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -759,7 +759,7 @@ foreach_pin!( pub(crate) unsafe fn init() { #[cfg(afio)] - ::enable(); + ::reset_and_enable(); crate::_generated::init_gpio(); } diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs index c47b0c09..0c730ef7 100644 --- a/embassy-stm32/src/hrtim/mod.rs +++ b/embassy-stm32/src/hrtim/mod.rs @@ -157,8 +157,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> { fn new_inner(tim: impl Peripheral

+ 'd) -> Self { into_ref!(tim); - T::enable(); - ::reset(); + T::reset_and_enable(); #[cfg(stm32f334)] if unsafe { get_freqs() }.hrtim.is_some() { diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 0d2bfc06..cc2b23a7 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -56,8 +56,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { ) -> Self { into_ref!(scl, sda, tx_dma, rx_dma); - T::enable(); - T::reset(); + T::reset_and_enable(); scl.set_as_af_pull( scl.af_num(), diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 543d8f1b..1a49ecb2 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -86,8 +86,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { ) -> Self { into_ref!(peri, scl, sda, tx_dma, rx_dma); - T::enable(); - T::reset(); + T::reset_and_enable(); scl.set_as_af_pull( scl.af_num(), diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index e100ca5c..2e58fe62 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -93,8 +93,7 @@ pub struct Ipcc; impl Ipcc { pub fn enable(_config: Config) { - IPCC::enable(); - IPCC::reset(); + IPCC::reset_and_enable(); IPCC::set_cpu2(true); _configure_pwr(); diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 37c94f82..43849422 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -186,11 +186,11 @@ pub fn init(config: Config) -> Peripherals { } #[cfg(not(any(stm32f1, stm32wb, stm32wl)))] - peripherals::SYSCFG::enable(); + peripherals::SYSCFG::reset_and_enable(); #[cfg(not(any(stm32h5, stm32h7, stm32wb, stm32wl)))] - peripherals::PWR::enable(); + peripherals::PWR::reset_and_enable(); #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7)))] - peripherals::FLASH::enable(); + peripherals::FLASH::reset_and_enable(); unsafe { #[cfg(feature = "_split-pins-enabled")] diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 8fb7df64..1c8bcbae 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -177,8 +177,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { ) -> Self { into_ref!(peri, dma); - T::enable(); - T::reset(); + T::reset_and_enable(); while T::REGS.sr().read().busy() {} diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index a4078e38..1b6b5e85 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -296,7 +296,7 @@ pub(crate) unsafe fn init(config: Config) { // Enable and setup CRS if needed if let Some(crs_config) = crs_config { - crate::peripherals::CRS::enable(); + crate::peripherals::CRS::reset_and_enable(); let sync_src = match crs_config.sync_src { CrsSyncSource::Gpio => crate::pac::crs::vals::Syncsrc::GPIO, diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 695d4158..451e12fe 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -231,8 +231,7 @@ pub mod low_level { pub(crate) mod sealed { pub trait RccPeripheral { fn frequency() -> crate::time::Hertz; - fn reset(); - fn enable(); + fn reset_and_enable(); fn disable(); } } diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 2d7ffc62..0a3b966b 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -43,8 +43,7 @@ impl<'d, T: Instance> Rng<'d, T> { inner: impl Peripheral

+ 'd, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { - T::enable(); - T::reset(); + T::reset_and_enable(); into_ref!(inner); let mut random = Self { _inner: inner }; random.reset(); diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index cf34d219..2eb0cde1 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -184,7 +184,7 @@ impl Default for RtcCalibrationCyclePeriod { impl Rtc { pub fn new(_rtc: impl Peripheral

, rtc_config: RtcConfig) -> Self { #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] - ::enable(); + ::reset_and_enable(); let mut this = Self { #[cfg(feature = "low-power")] diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 4c3604e5..a394ba71 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs @@ -531,10 +531,13 @@ pub struct SubBlock<'d, T: Instance, C: Channel, W: word::Word> { pub struct SubBlockA {} pub struct SubBlockB {} +pub struct SubBlockAPeripheral<'d, T>(PeripheralRef<'d, T>); +pub struct SubBlockBPeripheral<'d, T>(PeripheralRef<'d, T>); + pub struct Sai<'d, T: Instance> { _peri: PeripheralRef<'d, T>, - sub_block_a_peri: Option>, - sub_block_b_peri: Option>, + sub_block_a_peri: Option>, + sub_block_b_peri: Option>, } // return the type for (sd, sck) @@ -577,17 +580,16 @@ fn get_ring_buffer<'d, T: Instance, C: Channel, W: word::Word>( impl<'d, T: Instance> Sai<'d, T> { pub fn new(peri: impl Peripheral

+ 'd) -> Self { - T::enable(); - T::reset(); + T::reset_and_enable(); Self { _peri: unsafe { peri.clone_unchecked().into_ref() }, - sub_block_a_peri: Some(unsafe { peri.clone_unchecked().into_ref() }), - sub_block_b_peri: Some(peri.into_ref()), + sub_block_a_peri: Some(SubBlockAPeripheral(unsafe { peri.clone_unchecked().into_ref() })), + sub_block_b_peri: Some(SubBlockBPeripheral(peri.into_ref())), } } - pub fn take_sub_block_a(self: &mut Self) -> Option> { + pub fn take_sub_block_a(self: &mut Self) -> Option> { if self.sub_block_a_peri.is_some() { self.sub_block_a_peri.take() } else { @@ -595,7 +597,7 @@ impl<'d, T: Instance> Sai<'d, T> { } } - pub fn take_sub_block_b(self: &mut Self) -> Option> { + pub fn take_sub_block_b(self: &mut Self) -> Option> { if self.sub_block_b_peri.is_some() { self.sub_block_b_peri.take() } else { @@ -623,7 +625,7 @@ fn update_synchronous_config(config: &mut Config) { impl SubBlockA { pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>( - peri: impl Peripheral

+ 'd, + peri: SubBlockAPeripheral<'d, T>, sck: impl Peripheral

> + 'd, sd: impl Peripheral

> + 'd, fs: impl Peripheral

> + 'd, @@ -631,7 +633,7 @@ impl SubBlockA { dma: impl Peripheral

+ 'd, dma_buf: &'d mut [W], mut config: Config, - ) -> SubBlock + ) -> SubBlock<'d, T, C, W> where C: Channel + DmaA, { @@ -650,17 +652,18 @@ impl SubBlockA { } pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>( - peri: impl Peripheral

+ 'd, + peri: SubBlockAPeripheral<'d, T>, sck: impl Peripheral

> + 'd, sd: impl Peripheral

> + 'd, fs: impl Peripheral

> + 'd, dma: impl Peripheral

+ 'd, dma_buf: &'d mut [W], config: Config, - ) -> SubBlock + ) -> SubBlock<'d, T, C, W> where C: Channel + DmaA, { + let peri = peri.0; into_ref!(peri, dma, sck, sd, fs); let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); @@ -688,17 +691,18 @@ impl SubBlockA { } pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>( - peri: impl Peripheral

+ 'd, + peri: SubBlockAPeripheral<'d, T>, sd: impl Peripheral

> + 'd, dma: impl Peripheral

+ 'd, dma_buf: &'d mut [W], mut config: Config, - ) -> SubBlock + ) -> SubBlock<'d, T, C, W> where C: Channel + DmaA, { update_synchronous_config(&mut config); + let peri = peri.0; into_ref!(dma, peri, sd); let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); @@ -724,7 +728,7 @@ impl SubBlockA { impl SubBlockB { pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>( - peri: impl Peripheral

+ 'd, + peri: SubBlockBPeripheral<'d, T>, sck: impl Peripheral

> + 'd, sd: impl Peripheral

> + 'd, fs: impl Peripheral

> + 'd, @@ -732,7 +736,7 @@ impl SubBlockB { dma: impl Peripheral

+ 'd, dma_buf: &'d mut [W], mut config: Config, - ) -> SubBlock + ) -> SubBlock<'d, T, C, W> where C: Channel + DmaB, { @@ -751,17 +755,18 @@ impl SubBlockB { } pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>( - peri: impl Peripheral

+ 'd, + peri: SubBlockBPeripheral<'d, T>, sck: impl Peripheral

> + 'd, sd: impl Peripheral

> + 'd, fs: impl Peripheral

> + 'd, dma: impl Peripheral

+ 'd, dma_buf: &'d mut [W], config: Config, - ) -> SubBlock + ) -> SubBlock<'d, T, C, W> where C: Channel + DmaB, { + let peri = peri.0; into_ref!(dma, peri, sck, sd, fs); let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); @@ -790,17 +795,17 @@ impl SubBlockB { } pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>( - peri: impl Peripheral

+ 'd, + peri: SubBlockBPeripheral<'d, T>, sd: impl Peripheral

> + 'd, dma: impl Peripheral

+ 'd, dma_buf: &'d mut [W], mut config: Config, - ) -> SubBlock + ) -> SubBlock<'d, T, C, W> where C: Channel + DmaB, { update_synchronous_config(&mut config); - + let peri = peri.0; into_ref!(dma, peri, sd); let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); @@ -853,10 +858,6 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { ring_buffer: RingBuffer<'d, C, W>, config: Config, ) -> Self { - T::enable(); - - // can't reset here because the other sub-block might be in use - #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] { let ch = T::REGS.ch(sub_block as usize); @@ -959,8 +960,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { } pub fn reset() { - T::enable(); - T::reset(); + T::reset_and_enable(); } pub fn flush(&mut self) { diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 9fb380fd..595d2c19 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -452,8 +452,7 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { ) -> Self { into_ref!(sdmmc, dma); - T::enable(); - T::reset(); + T::reset_and_enable(); T::Interrupt::unpend(); unsafe { T::Interrupt::enable() }; diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index bd70342c..ea7132e0 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -230,8 +230,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let lsbfirst = config.raw_byte_order(); - T::enable(); - T::reset(); + T::reset_and_enable(); #[cfg(any(spi_v1, spi_f1))] { diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index e88198e6..1468d9b6 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -155,8 +155,7 @@ impl RtcDriver { fn init(&'static self) { let r = T::regs_gp16(); - ::enable(); - ::reset(); + ::reset_and_enable(); let timer_freq = T::frequency(); diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 0ab72734..3818cc03 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -64,8 +64,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { into_ref!(tim); - T::enable(); - ::reset(); + T::reset_and_enable(); let mut this = Self { inner: tim }; diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 15f2c3a7..ecc9fabc 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -55,8 +55,7 @@ impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> { fn new_inner(tim: impl Peripheral

+ 'd) -> Self { into_ref!(tim); - T::enable(); - ::reset(); + T::reset_and_enable(); // Configure TxC1 and TxC2 as captures T::regs_gp16().ccmr_input(0).modify(|w| { diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 2b3a069a..83c81277 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -63,8 +63,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { into_ref!(tim); - T::enable(); - ::reset(); + T::reset_and_enable(); let mut this = Self { inner: tim }; diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 445ca0ed..b4a74dc4 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -152,9 +152,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { config: Config, ) -> Result { // UartRx and UartTx have one refcount ea. - T::enable(); - T::enable(); - T::reset(); + T::reset_and_enable(); + T::reset_and_enable(); Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) } @@ -173,9 +172,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { into_ref!(cts, rts); // UartRx and UartTx have one refcount ea. - T::enable(); - T::enable(); - T::reset(); + T::reset_and_enable(); + T::reset_and_enable(); rts.set_as_af(rts.af_num(), AFType::OutputPushPull); cts.set_as_af(cts.af_num(), AFType::Input); @@ -201,9 +199,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { into_ref!(de); // UartRx and UartTx have one refcount ea. - T::enable(); - T::enable(); - T::reset(); + T::reset_and_enable(); + T::reset_and_enable(); de.set_as_af(de.af_num(), AFType::OutputPushPull); T::regs().cr3().write(|w| { diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 2eb2e4e8..93e21ccb 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -228,8 +228,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { tx_dma: impl Peripheral

+ 'd, config: Config, ) -> Result { - T::enable(); - T::reset(); + T::reset_and_enable(); Self::new_inner(peri, tx, tx_dma, config) } @@ -243,8 +242,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { ) -> Result { into_ref!(cts); - T::enable(); - T::reset(); + T::reset_and_enable(); cts.set_as_af(cts.af_num(), AFType::Input); T::regs().cr3().write(|w| { @@ -321,8 +319,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { rx_dma: impl Peripheral

+ 'd, config: Config, ) -> Result { - T::enable(); - T::reset(); + T::reset_and_enable(); Self::new_inner(peri, rx, rx_dma, config) } @@ -337,8 +334,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { ) -> Result { into_ref!(rts); - T::enable(); - T::reset(); + T::reset_and_enable(); rts.set_as_af(rts.af_num(), AFType::OutputPushPull); T::regs().cr3().write(|w| { @@ -695,9 +691,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { config: Config, ) -> Result { // UartRx and UartTx have one refcount ea. - T::enable(); - T::enable(); - T::reset(); + T::reset_and_enable(); + T::reset_and_enable(); Self::new_inner(peri, rx, tx, tx_dma, rx_dma, config) } @@ -716,9 +711,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { into_ref!(cts, rts); // UartRx and UartTx have one refcount ea. - T::enable(); - T::enable(); - T::reset(); + T::reset_and_enable(); + T::reset_and_enable(); rts.set_as_af(rts.af_num(), AFType::OutputPushPull); cts.set_as_af(cts.af_num(), AFType::Input); @@ -743,9 +737,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { into_ref!(de); // UartRx and UartTx have one refcount ea. - T::enable(); - T::enable(); - T::reset(); + T::reset_and_enable(); + T::reset_and_enable(); de.set_as_af(de.af_num(), AFType::OutputPushPull); T::regs().cr3().write(|w| { diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index b24fc74e..d05207d1 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -269,8 +269,7 @@ impl<'d, T: Instance> Driver<'d, T> { #[cfg(pwr_h5)] crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true)); - ::enable(); - ::reset(); + ::reset_and_enable(); regs.cntr().write(|w| { w.set_pdwn(false); diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index 1fe010bb..9edffa90 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs @@ -632,8 +632,7 @@ impl<'d, T: Instance> Bus<'d, T> { }); } - ::enable(); - ::reset(); + ::reset_and_enable(); T::Interrupt::unpend(); unsafe { T::Interrupt::enable() }; diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 933641ae..5f3afbaf 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -79,7 +79,7 @@ async fn dac_task1(mut dac: Dac1Type) { dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap(); dac.enable_channel().unwrap(); - TIM6::enable(); + TIM6::reset_and_enable(); TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); TIM6::regs().cr1().modify(|w| { @@ -118,7 +118,7 @@ async fn dac_task2(mut dac: Dac2Type) { error!("Reload value {} below threshold!", reload); } - TIM7::enable(); + TIM7::reset_and_enable(); TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); TIM7::regs().cr1().modify(|w| { diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index f4fa0690..757ee328 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -73,8 +73,7 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { ) -> Self { into_ref!(tim, ch1, ch2, ch3, ch4); - T::enable(); - ::reset(); + T::reset_and_enable(); ch1.set_speed(Speed::VeryHigh); ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index c27cc03e..83d48f22 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs @@ -51,7 +51,7 @@ async fn dac_task1(mut dac: Dac1Type) { dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap(); dac.enable_channel().unwrap(); - TIM6::enable(); + TIM6::reset_and_enable(); TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); TIM6::regs().cr1().modify(|w| { @@ -90,7 +90,7 @@ async fn dac_task2(mut dac: Dac2Type) { error!("Reload value {} below threshold!", reload); } - TIM7::enable(); + TIM7::reset_and_enable(); TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); TIM7::regs().cr1().modify(|w| { From d7d79f3068a4a2d883b078b8900ad194f7c98203 Mon Sep 17 00:00:00 2001 From: pbert Date: Wed, 11 Oct 2023 19:17:30 +0200 Subject: [PATCH 81/95] Remove workaround for adc v3 --- embassy-stm32/src/adc/mod.rs | 4 ++-- embassy-stm32/src/adc/v3.rs | 15 +-------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 365738a3..3e2980bf 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs @@ -74,9 +74,9 @@ pub(crate) mod sealed { } } -#[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v4, adc_f3)))] +#[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_g0)))] pub trait Instance: sealed::Instance + crate::Peripheral

{} -#[cfg(any(adc_f1, adc_v1, adc_v2, adc_v4, adc_f3))] +#[cfg(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_g0))] pub trait Instance: sealed::Instance + crate::Peripheral

+ crate::rcc::RccPeripheral {} pub trait AdcPin: sealed::AdcPin {} diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 011ecc28..e50e6482 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -9,19 +9,6 @@ pub const VREF_DEFAULT_MV: u32 = 3300; /// VREF voltage used for factory calibration of VREFINTCAL register. pub const VREF_CALIB_MV: u32 = 3000; -/// Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent ADC clock -/// configuration. -fn enable() { - critical_section::with(|_| { - #[cfg(any(stm32h7, stm32wl))] - crate::pac::RCC.apb2enr().modify(|w| w.set_adcen(true)); - #[cfg(stm32g0)] - crate::pac::RCC.apbenr2().modify(|w| w.set_adcen(true)); - #[cfg(any(stm32l4, stm32l5, stm32wb))] - crate::pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); - }); -} - pub struct VrefInt; impl AdcPin for VrefInt {} impl super::sealed::AdcPin for VrefInt { @@ -61,7 +48,7 @@ impl super::sealed::AdcPin for Vbat { impl<'d, T: Instance> Adc<'d, T> { pub fn new(adc: impl Peripheral

+ 'd, delay: &mut impl DelayUs) -> Self { into_ref!(adc); - enable(); + T::reset_and_enable(); T::regs().cr().modify(|reg| { #[cfg(not(adc_g0))] reg.set_deeppwd(false); From ecdd7c0e2f9dcc07e53e136557140d3ccc6a5ee1 Mon Sep 17 00:00:00 2001 From: pbert Date: Wed, 11 Oct 2023 21:38:41 +0200 Subject: [PATCH 82/95] enable clock first --- embassy-stm32/build.rs | 4 ++-- embassy-stm32/src/adc/f1.rs | 2 +- embassy-stm32/src/adc/f3.rs | 2 +- embassy-stm32/src/adc/v1.rs | 2 +- embassy-stm32/src/adc/v2.rs | 2 +- embassy-stm32/src/adc/v3.rs | 2 +- embassy-stm32/src/adc/v4.rs | 2 +- embassy-stm32/src/can/bxcan.rs | 2 +- embassy-stm32/src/crc/v1.rs | 2 +- embassy-stm32/src/crc/v2v3.rs | 2 +- embassy-stm32/src/dac/mod.rs | 8 ++++---- embassy-stm32/src/dcmi.rs | 2 +- embassy-stm32/src/fmc.rs | 2 +- embassy-stm32/src/gpio.rs | 2 +- embassy-stm32/src/hrtim/mod.rs | 2 +- embassy-stm32/src/i2c/v1.rs | 2 +- embassy-stm32/src/i2c/v2.rs | 2 +- embassy-stm32/src/ipcc.rs | 2 +- embassy-stm32/src/lib.rs | 6 +++--- embassy-stm32/src/qspi/mod.rs | 2 +- embassy-stm32/src/rcc/g4.rs | 2 +- embassy-stm32/src/rcc/mod.rs | 2 +- embassy-stm32/src/rng.rs | 2 +- embassy-stm32/src/rtc/mod.rs | 2 +- embassy-stm32/src/sai/mod.rs | 4 ++-- embassy-stm32/src/sdmmc/mod.rs | 2 +- embassy-stm32/src/spi/mod.rs | 2 +- embassy-stm32/src/time_driver.rs | 2 +- embassy-stm32/src/timer/complementary_pwm.rs | 2 +- embassy-stm32/src/timer/qei.rs | 2 +- embassy-stm32/src/timer/simple_pwm.rs | 2 +- embassy-stm32/src/usart/buffered.rs | 12 +++++------ embassy-stm32/src/usart/mod.rs | 20 +++++++++---------- embassy-stm32/src/usb/usb.rs | 2 +- embassy-stm32/src/usb_otg/usb.rs | 2 +- examples/stm32h7/src/bin/dac_dma.rs | 4 ++-- .../stm32h7/src/bin/low_level_timer_api.rs | 2 +- examples/stm32l4/src/bin/dac_dma.rs | 4 ++-- 38 files changed, 61 insertions(+), 61 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 719a52d1..63cf6b21 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -556,14 +556,14 @@ fn main() { fn frequency() -> crate::time::Hertz { #clock_frequency } - fn enable() { + fn enable_and_reset() { critical_section::with(|_cs| { #before_enable - #rst #[cfg(feature = "low-power")] crate::rcc::clock_refcount_add(_cs); crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); #after_enable + #rst }) } fn disable() { diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index 5f5bf4bf..ad0f1382 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs @@ -51,7 +51,7 @@ impl super::sealed::AdcPin for Temperature { impl<'d, T: Instance> Adc<'d, T> { pub fn new(adc: impl Peripheral

+ 'd, delay: &mut impl DelayUs) -> Self { into_ref!(adc); - T::reset_and_enable(); + T::enable_and_reset(); T::regs().cr2().modify(|reg| reg.set_adon(true)); // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’) diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs index e94f6141..6f59c230 100644 --- a/embassy-stm32/src/adc/f3.rs +++ b/embassy-stm32/src/adc/f3.rs @@ -64,7 +64,7 @@ impl<'d, T: Instance> Adc<'d, T> { into_ref!(adc); - T::reset_and_enable(); + T::enable_and_reset(); // Enable the adc regulator T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE)); diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index f03acdcf..852b027d 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs @@ -61,7 +61,7 @@ impl<'d, T: Instance> Adc<'d, T> { delay: &mut impl DelayUs, ) -> Self { into_ref!(adc); - T::reset_and_enable(); + T::enable_and_reset(); // Delay 1μs when using HSI14 as the ADC clock. // diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index 89e7616b..eda1324d 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs @@ -95,7 +95,7 @@ where { pub fn new(adc: impl Peripheral

+ 'd, delay: &mut impl DelayUs) -> Self { into_ref!(adc); - T::reset_and_enable(); + T::enable_and_reset(); let presc = Prescaler::from_pclk2(T::frequency()); T::common_regs().ccr().modify(|w| w.set_adcpre(presc.adcpre())); diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index e50e6482..281a99f7 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -48,7 +48,7 @@ impl super::sealed::AdcPin for Vbat { impl<'d, T: Instance> Adc<'d, T> { pub fn new(adc: impl Peripheral

+ 'd, delay: &mut impl DelayUs) -> Self { into_ref!(adc); - T::reset_and_enable(); + T::enable_and_reset(); T::regs().cr().modify(|reg| { #[cfg(not(adc_g0))] reg.set_deeppwd(false); diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index 6d86e5cd..d74617cb 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs @@ -127,7 +127,7 @@ impl Prescaler { impl<'d, T: Instance> Adc<'d, T> { pub fn new(adc: impl Peripheral

+ 'd, delay: &mut impl DelayUs) -> Self { embassy_hal_internal::into_ref!(adc); - T::reset_and_enable(); + T::enable_and_reset(); let prescaler = Prescaler::from_ker_ck(T::frequency()); diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 903f7e48..0d4bf692 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -136,7 +136,7 @@ impl<'d, T: Instance> Can<'d, T> { rx.set_as_af(rx.af_num(), AFType::Input); tx.set_as_af(tx.af_num(), AFType::OutputPushPull); - T::reset_and_enable(); + T::enable_and_reset(); { use crate::pac::can::vals::{Errie, Fmpie, Tmeie}; diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs index 282e1ad8..c0f58083 100644 --- a/embassy-stm32/src/crc/v1.rs +++ b/embassy-stm32/src/crc/v1.rs @@ -16,7 +16,7 @@ impl<'d> Crc<'d> { // Note: enable and reset come from RccPeripheral. // enable CRC clock in RCC. - CRC::reset_and_enable(); + CRC::enable_and_reset(); // Peripheral the peripheral let mut instance = Self { _peri: peripheral }; instance.reset(); diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs index 2ab25e6f..b36f6018 100644 --- a/embassy-stm32/src/crc/v2v3.rs +++ b/embassy-stm32/src/crc/v2v3.rs @@ -70,7 +70,7 @@ impl<'d> Crc<'d> { pub fn new(peripheral: impl Peripheral

+ 'd, config: Config) -> Self { // Note: enable and reset come from RccPeripheral. // reset to default values and enable CRC clock in RCC. - CRC::reset_and_enable(); + CRC::enable_and_reset(); into_ref!(peripheral); let mut instance = Self { _peripheral: peripheral, diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index e93fca95..6458572f 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -255,7 +255,7 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { ) -> Self { pin.set_as_analog(); into_ref!(peri, dma); - T::reset_and_enable(); + T::enable_and_reset(); let mut dac = Self { _peri: peri, dma }; @@ -365,7 +365,7 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { ) -> Self { pin.set_as_analog(); into_ref!(_peri, dma); - T::reset_and_enable(); + T::enable_and_reset(); let mut dac = Self { phantom: PhantomData, @@ -481,7 +481,7 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> { pin_ch1.set_as_analog(); pin_ch2.set_as_analog(); into_ref!(peri, dma_ch1, dma_ch2); - T::reset_and_enable(); + T::enable_and_reset(); let mut dac_ch1 = DacCh1 { _peri: peri, @@ -567,7 +567,7 @@ foreach_peripheral!( critical_section::with(|_| unsafe { crate::rcc::get_freqs().apb1 }) } - fn reset_and_enable() { + fn enable_and_reset() { critical_section::with(|_| { crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs index 6a63e6ee..b1223079 100644 --- a/embassy-stm32/src/dcmi.rs +++ b/embassy-stm32/src/dcmi.rs @@ -330,7 +330,7 @@ where use_embedded_synchronization: bool, edm: u8, ) -> Self { - T::reset_and_enable(); + T::enable_and_reset(); peri.regs().cr().modify(|r| { r.set_cm(true); // disable continuous mode (snapshot mode) diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs index 51c75aeb..d6e25996 100644 --- a/embassy-stm32/src/fmc.rs +++ b/embassy-stm32/src/fmc.rs @@ -19,7 +19,7 @@ where const REGISTERS: *const () = T::REGS.as_ptr() as *const _; fn enable(&mut self) { - T::reset_and_enable(); + T::enable_and_reset(); } fn memory_controller_enable(&mut self) { diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 9192f731..37fedf8e 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -759,7 +759,7 @@ foreach_pin!( pub(crate) unsafe fn init() { #[cfg(afio)] - ::reset_and_enable(); + ::enable_and_reset(); crate::_generated::init_gpio(); } diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs index 0c730ef7..17096d48 100644 --- a/embassy-stm32/src/hrtim/mod.rs +++ b/embassy-stm32/src/hrtim/mod.rs @@ -157,7 +157,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> { fn new_inner(tim: impl Peripheral

+ 'd) -> Self { into_ref!(tim); - T::reset_and_enable(); + T::enable_and_reset(); #[cfg(stm32f334)] if unsafe { get_freqs() }.hrtim.is_some() { diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index cc2b23a7..ab59f5ab 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -56,7 +56,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { ) -> Self { into_ref!(scl, sda, tx_dma, rx_dma); - T::reset_and_enable(); + T::enable_and_reset(); scl.set_as_af_pull( scl.af_num(), diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 1a49ecb2..b6d880d5 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -86,7 +86,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { ) -> Self { into_ref!(peri, scl, sda, tx_dma, rx_dma); - T::reset_and_enable(); + T::enable_and_reset(); scl.set_as_af_pull( scl.af_num(), diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 2e58fe62..1b1e182f 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -93,7 +93,7 @@ pub struct Ipcc; impl Ipcc { pub fn enable(_config: Config) { - IPCC::reset_and_enable(); + IPCC::enable_and_reset(); IPCC::set_cpu2(true); _configure_pwr(); diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 43849422..b93e5ee8 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -186,11 +186,11 @@ pub fn init(config: Config) -> Peripherals { } #[cfg(not(any(stm32f1, stm32wb, stm32wl)))] - peripherals::SYSCFG::reset_and_enable(); + peripherals::SYSCFG::enable_and_reset(); #[cfg(not(any(stm32h5, stm32h7, stm32wb, stm32wl)))] - peripherals::PWR::reset_and_enable(); + peripherals::PWR::enable_and_reset(); #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7)))] - peripherals::FLASH::reset_and_enable(); + peripherals::FLASH::enable_and_reset(); unsafe { #[cfg(feature = "_split-pins-enabled")] diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 1c8bcbae..4b0e8ece 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -177,7 +177,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { ) -> Self { into_ref!(peri, dma); - T::reset_and_enable(); + T::enable_and_reset(); while T::REGS.sr().read().busy() {} diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 1b6b5e85..afdf5cc7 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -296,7 +296,7 @@ pub(crate) unsafe fn init(config: Config) { // Enable and setup CRS if needed if let Some(crs_config) = crs_config { - crate::peripherals::CRS::reset_and_enable(); + crate::peripherals::CRS::enable_and_reset(); let sync_src = match crs_config.sync_src { CrsSyncSource::Gpio => crate::pac::crs::vals::Syncsrc::GPIO, diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 451e12fe..0263c97a 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -231,7 +231,7 @@ pub mod low_level { pub(crate) mod sealed { pub trait RccPeripheral { fn frequency() -> crate::time::Hertz; - fn reset_and_enable(); + fn enable_and_reset(); fn disable(); } } diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 0a3b966b..fc003ebe 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -43,7 +43,7 @@ impl<'d, T: Instance> Rng<'d, T> { inner: impl Peripheral

+ 'd, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { - T::reset_and_enable(); + T::enable_and_reset(); into_ref!(inner); let mut random = Self { _inner: inner }; random.reset(); diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 2eb0cde1..552dcc76 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -184,7 +184,7 @@ impl Default for RtcCalibrationCyclePeriod { impl Rtc { pub fn new(_rtc: impl Peripheral

, rtc_config: RtcConfig) -> Self { #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] - ::reset_and_enable(); + ::enable_and_reset(); let mut this = Self { #[cfg(feature = "low-power")] diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index a394ba71..a0b4ddac 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs @@ -580,7 +580,7 @@ fn get_ring_buffer<'d, T: Instance, C: Channel, W: word::Word>( impl<'d, T: Instance> Sai<'d, T> { pub fn new(peri: impl Peripheral

+ 'd) -> Self { - T::reset_and_enable(); + T::enable_and_reset(); Self { _peri: unsafe { peri.clone_unchecked().into_ref() }, @@ -960,7 +960,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { } pub fn reset() { - T::reset_and_enable(); + T::enable_and_reset(); } pub fn flush(&mut self) { diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 595d2c19..bc29fe54 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -452,7 +452,7 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { ) -> Self { into_ref!(sdmmc, dma); - T::reset_and_enable(); + T::enable_and_reset(); T::Interrupt::unpend(); unsafe { T::Interrupt::enable() }; diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index ea7132e0..211b5523 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -230,7 +230,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let lsbfirst = config.raw_byte_order(); - T::reset_and_enable(); + T::enable_and_reset(); #[cfg(any(spi_v1, spi_f1))] { diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 1468d9b6..baea20ae 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -155,7 +155,7 @@ impl RtcDriver { fn init(&'static self) { let r = T::regs_gp16(); - ::reset_and_enable(); + ::enable_and_reset(); let timer_freq = T::frequency(); diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 3818cc03..9349a6fa 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -64,7 +64,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { into_ref!(tim); - T::reset_and_enable(); + T::enable_and_reset(); let mut this = Self { inner: tim }; diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index ecc9fabc..01d028bf 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -55,7 +55,7 @@ impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> { fn new_inner(tim: impl Peripheral

+ 'd) -> Self { into_ref!(tim); - T::reset_and_enable(); + T::enable_and_reset(); // Configure TxC1 and TxC2 as captures T::regs_gp16().ccmr_input(0).modify(|w| { diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 83c81277..18ecc196 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -63,7 +63,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { into_ref!(tim); - T::reset_and_enable(); + T::enable_and_reset(); let mut this = Self { inner: tim }; diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index b4a74dc4..82d925a4 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -152,8 +152,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { config: Config, ) -> Result { // UartRx and UartTx have one refcount ea. - T::reset_and_enable(); - T::reset_and_enable(); + T::enable_and_reset(); + T::enable_and_reset(); Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) } @@ -172,8 +172,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { into_ref!(cts, rts); // UartRx and UartTx have one refcount ea. - T::reset_and_enable(); - T::reset_and_enable(); + T::enable_and_reset(); + T::enable_and_reset(); rts.set_as_af(rts.af_num(), AFType::OutputPushPull); cts.set_as_af(cts.af_num(), AFType::Input); @@ -199,8 +199,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { into_ref!(de); // UartRx and UartTx have one refcount ea. - T::reset_and_enable(); - T::reset_and_enable(); + T::enable_and_reset(); + T::enable_and_reset(); de.set_as_af(de.af_num(), AFType::OutputPushPull); T::regs().cr3().write(|w| { diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 93e21ccb..3b7f5184 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -228,7 +228,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { tx_dma: impl Peripheral

+ 'd, config: Config, ) -> Result { - T::reset_and_enable(); + T::enable_and_reset(); Self::new_inner(peri, tx, tx_dma, config) } @@ -242,7 +242,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { ) -> Result { into_ref!(cts); - T::reset_and_enable(); + T::enable_and_reset(); cts.set_as_af(cts.af_num(), AFType::Input); T::regs().cr3().write(|w| { @@ -319,7 +319,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { rx_dma: impl Peripheral

+ 'd, config: Config, ) -> Result { - T::reset_and_enable(); + T::enable_and_reset(); Self::new_inner(peri, rx, rx_dma, config) } @@ -334,7 +334,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { ) -> Result { into_ref!(rts); - T::reset_and_enable(); + T::enable_and_reset(); rts.set_as_af(rts.af_num(), AFType::OutputPushPull); T::regs().cr3().write(|w| { @@ -691,8 +691,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { config: Config, ) -> Result { // UartRx and UartTx have one refcount ea. - T::reset_and_enable(); - T::reset_and_enable(); + T::enable_and_reset(); + T::enable_and_reset(); Self::new_inner(peri, rx, tx, tx_dma, rx_dma, config) } @@ -711,8 +711,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { into_ref!(cts, rts); // UartRx and UartTx have one refcount ea. - T::reset_and_enable(); - T::reset_and_enable(); + T::enable_and_reset(); + T::enable_and_reset(); rts.set_as_af(rts.af_num(), AFType::OutputPushPull); cts.set_as_af(cts.af_num(), AFType::Input); @@ -737,8 +737,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { into_ref!(de); // UartRx and UartTx have one refcount ea. - T::reset_and_enable(); - T::reset_and_enable(); + T::enable_and_reset(); + T::enable_and_reset(); de.set_as_af(de.af_num(), AFType::OutputPushPull); T::regs().cr3().write(|w| { diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index d05207d1..9269ddd8 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -269,7 +269,7 @@ impl<'d, T: Instance> Driver<'d, T> { #[cfg(pwr_h5)] crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true)); - ::reset_and_enable(); + ::enable_and_reset(); regs.cntr().write(|w| { w.set_pdwn(false); diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index 9edffa90..e45e4ac4 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs @@ -632,7 +632,7 @@ impl<'d, T: Instance> Bus<'d, T> { }); } - ::reset_and_enable(); + ::enable_and_reset(); T::Interrupt::unpend(); unsafe { T::Interrupt::enable() }; diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 5f3afbaf..334986a0 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -79,7 +79,7 @@ async fn dac_task1(mut dac: Dac1Type) { dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap(); dac.enable_channel().unwrap(); - TIM6::reset_and_enable(); + TIM6::enable_and_reset(); TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); TIM6::regs().cr1().modify(|w| { @@ -118,7 +118,7 @@ async fn dac_task2(mut dac: Dac2Type) { error!("Reload value {} below threshold!", reload); } - TIM7::reset_and_enable(); + TIM7::enable_and_reset(); TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); TIM7::regs().cr1().modify(|w| { diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index 757ee328..5841efb2 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -73,7 +73,7 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { ) -> Self { into_ref!(tim, ch1, ch2, ch3, ch4); - T::reset_and_enable(); + T::enable_and_reset(); ch1.set_speed(Speed::VeryHigh); ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index 83d48f22..98f37f90 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs @@ -51,7 +51,7 @@ async fn dac_task1(mut dac: Dac1Type) { dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap(); dac.enable_channel().unwrap(); - TIM6::reset_and_enable(); + TIM6::enable_and_reset(); TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); TIM6::regs().cr1().modify(|w| { @@ -90,7 +90,7 @@ async fn dac_task2(mut dac: Dac2Type) { error!("Reload value {} below threshold!", reload); } - TIM7::reset_and_enable(); + TIM7::enable_and_reset(); TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); TIM7::regs().cr1().modify(|w| { From 65f81a1f577f2f1b9de78246f2f8fd495a3b4354 Mon Sep 17 00:00:00 2001 From: pbert Date: Thu, 12 Oct 2023 10:50:47 +0200 Subject: [PATCH 83/95] Remove critical section for reset --- embassy-stm32/build.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 63cf6b21..bbdb1250 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -452,10 +452,8 @@ fn main() { let rst_reg = format_ident!("{}", rst.register.to_ascii_lowercase()); let set_rst_field = format_ident!("set_{}", rst.field.to_ascii_lowercase()); quote! { - critical_section::with(|_| { - crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(true)); - crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(false)); - }); + crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(true)); + crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(false)); } } None => TokenStream::new(), From f0d6ee69bcac6a22213c06f303176daf9f5445ff Mon Sep 17 00:00:00 2001 From: Andres Oliva Date: Thu, 12 Oct 2023 11:25:44 +0200 Subject: [PATCH 84/95] Add some builds without time feature to CI --- ci.sh | 6 ++++++ ci_stable.sh | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/ci.sh b/ci.sh index 4098743f..c246e6a9 100755 --- a/ci.sh +++ b/ci.sh @@ -83,6 +83,12 @@ cargo batch \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits,time \ diff --git a/ci_stable.sh b/ci_stable.sh index 61b02175..1fe4e3a1 100755 --- a/ci_stable.sh +++ b/ci_stable.sh @@ -35,6 +35,11 @@ cargo batch \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features unstable-traits,log \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features qspi-as-gpio \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits,time \ From 97ca0e77bf6e6f36aae18cb57fbfa8e583597327 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 12 Oct 2023 00:34:47 +0200 Subject: [PATCH 85/95] stm32: avoid creating many tiny critical sections in init. Saves 292 bytes on stm32f0 bilnky with max optimizations (from 3132 to 2840). --- embassy-hal-internal/src/interrupt.rs | 32 +++++- embassy-hal-internal/src/macros.rs | 10 +- embassy-stm32/build.rs | 28 +++-- embassy-stm32/src/dac/mod.rs | 16 ++- embassy-stm32/src/dma/bdma.rs | 4 +- embassy-stm32/src/dma/dma.rs | 4 +- embassy-stm32/src/dma/dmamux.rs | 2 +- embassy-stm32/src/dma/gpdma.rs | 4 +- embassy-stm32/src/dma/mod.rs | 9 +- embassy-stm32/src/exti.rs | 2 +- embassy-stm32/src/gpio.rs | 5 +- embassy-stm32/src/lib.rs | 147 +++++++++++++------------- embassy-stm32/src/rcc/mod.rs | 13 ++- embassy-stm32/src/time_driver.rs | 56 +++++----- 14 files changed, 183 insertions(+), 149 deletions(-) diff --git a/embassy-hal-internal/src/interrupt.rs b/embassy-hal-internal/src/interrupt.rs index b970aa2c..19dabcf6 100644 --- a/embassy-hal-internal/src/interrupt.rs +++ b/embassy-hal-internal/src/interrupt.rs @@ -4,6 +4,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use cortex_m::interrupt::InterruptNumber; use cortex_m::peripheral::NVIC; +use critical_section::CriticalSection; /// Generate a standard `mod interrupt` for a HAL. #[macro_export] @@ -91,6 +92,12 @@ macro_rules! interrupt_mod { fn set_priority(prio: crate::interrupt::Priority) { Self::IRQ.set_priority(prio) } + + /// Set the interrupt priority with an already-acquired critical section + #[inline] + fn set_priority_with_cs(cs: critical_section::CriticalSection, prio: crate::interrupt::Priority) { + Self::IRQ.set_priority_with_cs(cs, prio) + } } $( @@ -195,10 +202,29 @@ pub unsafe trait InterruptExt: InterruptNumber + Copy { /// Set the interrupt priority. #[inline] fn set_priority(self, prio: Priority) { - critical_section::with(|_| unsafe { + unsafe { let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(()); - nvic.set_priority(self, prio.into()) - }) + + // On thumbv6, set_priority must do a RMW to change 8bit in a 32bit reg. + #[cfg(armv6m)] + critical_section::with(|_| nvic.set_priority(self, prio.into())); + // On thumbv7+, set_priority does an atomic 8bit write, so no CS needed. + #[cfg(not(armv6m))] + nvic.set_priority(self, prio.into()); + } + } + + /// Set the interrupt priority with an already-acquired critical section + /// + /// Equivalent to `set_priority`, except you pass a `CriticalSection` to prove + /// you've already acquired a critical section. This prevents acquiring another + /// one, which saves code size. + #[inline] + fn set_priority_with_cs(self, _cs: CriticalSection, prio: Priority) { + unsafe { + let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(()); + nvic.set_priority(self, prio.into()); + } } } diff --git a/embassy-hal-internal/src/macros.rs b/embassy-hal-internal/src/macros.rs index 0eea4b66..97df3895 100644 --- a/embassy-hal-internal/src/macros.rs +++ b/embassy-hal-internal/src/macros.rs @@ -48,17 +48,23 @@ macro_rules! peripherals_struct { ///Returns all the peripherals *once* #[inline] pub(crate) fn take() -> Self { + critical_section::with(Self::take_with_cs) + } + ///Returns all the peripherals *once* + #[inline] + pub(crate) fn take_with_cs(_cs: critical_section::CriticalSection) -> Self { #[no_mangle] static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false; - critical_section::with(|_| unsafe { + // safety: OK because we're inside a CS. + unsafe { if _EMBASSY_DEVICE_PERIPHERALS { panic!("init called more than once!") } _EMBASSY_DEVICE_PERIPHERALS = true; Self::steal() - }) + } } } diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index bbdb1250..8e680fb6 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -554,23 +554,19 @@ fn main() { fn frequency() -> crate::time::Hertz { #clock_frequency } - fn enable_and_reset() { - critical_section::with(|_cs| { - #before_enable - #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_add(_cs); - crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); - #after_enable - #rst - }) + fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { + #before_enable + #[cfg(feature = "low-power")] + crate::rcc::clock_refcount_add(_cs); + crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); + #after_enable + #rst } - fn disable() { - critical_section::with(|_cs| { - #before_disable - crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); - #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_sub(_cs); - }) + fn disable_with_cs(_cs: critical_section::CriticalSection) { + #before_disable + crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); + #[cfg(feature = "low-power")] + crate::rcc::clock_refcount_sub(_cs); } } diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 6458572f..a3c7823c 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -567,18 +567,14 @@ foreach_peripheral!( critical_section::with(|_| unsafe { crate::rcc::get_freqs().apb1 }) } - fn enable_and_reset() { - critical_section::with(|_| { - crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); - crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); - crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); - }) + fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { + crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); + crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); + crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); } - fn disable() { - critical_section::with(|_| { - crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)) - }) + fn disable_with_cs(_cs: critical_section::CriticalSection) { + crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)) } } diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 62eb65b1..a7422f66 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -77,10 +77,10 @@ impl State { static STATE: State = State::new(); /// safety: must be called only once -pub(crate) unsafe fn init(irq_priority: Priority) { +pub(crate) unsafe fn init(cs: critical_section::CriticalSection, irq_priority: Priority) { foreach_interrupt! { ($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => { - crate::interrupt::typelevel::$irq::set_priority(irq_priority); + crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, irq_priority); crate::interrupt::typelevel::$irq::enable(); }; } diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 5033ae47..cce0407c 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -154,10 +154,10 @@ impl State { static STATE: State = State::new(); /// safety: must be called only once -pub(crate) unsafe fn init(irq_priority: Priority) { +pub(crate) unsafe fn init(cs: critical_section::CriticalSection, irq_priority: Priority) { foreach_interrupt! { ($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => { - interrupt::typelevel::$irq::set_priority(irq_priority); + interrupt::typelevel::$irq::set_priority_with_cs(cs, irq_priority); interrupt::typelevel::$irq::enable(); }; } diff --git a/embassy-stm32/src/dma/dmamux.rs b/embassy-stm32/src/dma/dmamux.rs index 36fc0340..20601dc8 100644 --- a/embassy-stm32/src/dma/dmamux.rs +++ b/embassy-stm32/src/dma/dmamux.rs @@ -47,6 +47,6 @@ foreach_dma_channel! { } /// safety: must be called only once -pub(crate) unsafe fn init() { +pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) { crate::_generated::init_dmamux(); } diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index 97cc200d..b811da1f 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -53,10 +53,10 @@ impl State { static STATE: State = State::new(); /// safety: must be called only once -pub(crate) unsafe fn init(irq_priority: Priority) { +pub(crate) unsafe fn init(cs: critical_section::CriticalSection, irq_priority: Priority) { foreach_interrupt! { ($peri:ident, gpdma, $block:ident, $signal_name:ident, $irq:ident) => { - crate::interrupt::typelevel::$irq::set_priority(irq_priority); + crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, irq_priority); crate::interrupt::typelevel::$irq::enable(); }; } diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 4f1a58ae..29fced8f 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -56,16 +56,17 @@ pub(crate) fn slice_ptr_parts_mut(slice: *mut [T]) -> (usize, usize) { // safety: must be called only once at startup pub(crate) unsafe fn init( + cs: critical_section::CriticalSection, #[cfg(bdma)] bdma_priority: Priority, #[cfg(dma)] dma_priority: Priority, #[cfg(gpdma)] gpdma_priority: Priority, ) { #[cfg(bdma)] - bdma::init(bdma_priority); + bdma::init(cs, bdma_priority); #[cfg(dma)] - dma::init(dma_priority); + dma::init(cs, dma_priority); #[cfg(gpdma)] - gpdma::init(gpdma_priority); + gpdma::init(cs, gpdma_priority); #[cfg(dmamux)] - dmamux::init(); + dmamux::init(cs); } diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 62f32170..538791a5 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -367,7 +367,7 @@ macro_rules! enable_irq { } /// safety: must be called only once -pub(crate) unsafe fn init() { +pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) { use crate::interrupt::typelevel::Interrupt; foreach_exti_irq!(enable_irq); diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 37fedf8e..e1702b00 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -1,6 +1,7 @@ #![macro_use] use core::convert::Infallible; +use critical_section::CriticalSection; use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use crate::pac::gpio::{self, vals}; @@ -757,9 +758,9 @@ foreach_pin!( }; ); -pub(crate) unsafe fn init() { +pub(crate) unsafe fn init(_cs: CriticalSection) { #[cfg(afio)] - ::enable_and_reset(); + ::enable_and_reset_with_cs(_cs); crate::_generated::init_gpio(); } diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index b93e5ee8..372246f8 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -155,81 +155,82 @@ impl Default for Config { /// Initialize embassy. pub fn init(config: Config) -> Peripherals { - let p = Peripherals::take(); + critical_section::with(|cs| { + let p = Peripherals::take_with_cs(cs); - #[cfg(dbgmcu)] - if config.enable_debug_during_sleep { - crate::pac::DBGMCU.cr().modify(|cr| { - #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba))] - { - cr.set_dbg_stop(true); - cr.set_dbg_standby(true); - } - #[cfg(any( - dbgmcu_f1, dbgmcu_f2, dbgmcu_f3, dbgmcu_f4, dbgmcu_f7, dbgmcu_g4, dbgmcu_f7, dbgmcu_l0, dbgmcu_l1, - dbgmcu_l4, dbgmcu_wb, dbgmcu_wl - ))] - { - cr.set_dbg_sleep(true); - cr.set_dbg_stop(true); - cr.set_dbg_standby(true); - } - #[cfg(dbgmcu_h7)] - { - cr.set_d1dbgcken(true); - cr.set_d3dbgcken(true); - cr.set_dbgsleep_d1(true); - cr.set_dbgstby_d1(true); - cr.set_dbgstop_d1(true); - } - }); - } - - #[cfg(not(any(stm32f1, stm32wb, stm32wl)))] - peripherals::SYSCFG::enable_and_reset(); - #[cfg(not(any(stm32h5, stm32h7, stm32wb, stm32wl)))] - peripherals::PWR::enable_and_reset(); - #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7)))] - peripherals::FLASH::enable_and_reset(); - - unsafe { - #[cfg(feature = "_split-pins-enabled")] - crate::pac::SYSCFG.pmcr().modify(|pmcr| { - #[cfg(feature = "split-pa0")] - pmcr.set_pa0so(true); - #[cfg(feature = "split-pa1")] - pmcr.set_pa1so(true); - #[cfg(feature = "split-pc2")] - pmcr.set_pc2so(true); - #[cfg(feature = "split-pc3")] - pmcr.set_pc3so(true); - }); - - gpio::init(); - dma::init( - #[cfg(bdma)] - config.bdma_interrupt_priority, - #[cfg(dma)] - config.dma_interrupt_priority, - #[cfg(gpdma)] - config.gpdma_interrupt_priority, - ); - #[cfg(feature = "exti")] - exti::init(); - - rcc::init(config.rcc); - - // must be after rcc init - #[cfg(feature = "_time-driver")] - time_driver::init(); - - #[cfg(feature = "low-power")] - while !crate::rcc::low_power_ready() { - critical_section::with(|cs| { - crate::rcc::clock_refcount_sub(cs); + #[cfg(dbgmcu)] + if config.enable_debug_during_sleep { + crate::pac::DBGMCU.cr().modify(|cr| { + #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba))] + { + cr.set_dbg_stop(true); + cr.set_dbg_standby(true); + } + #[cfg(any( + dbgmcu_f1, dbgmcu_f2, dbgmcu_f3, dbgmcu_f4, dbgmcu_f7, dbgmcu_g4, dbgmcu_f7, dbgmcu_l0, dbgmcu_l1, + dbgmcu_l4, dbgmcu_wb, dbgmcu_wl + ))] + { + cr.set_dbg_sleep(true); + cr.set_dbg_stop(true); + cr.set_dbg_standby(true); + } + #[cfg(dbgmcu_h7)] + { + cr.set_d1dbgcken(true); + cr.set_d3dbgcken(true); + cr.set_dbgsleep_d1(true); + cr.set_dbgstby_d1(true); + cr.set_dbgstop_d1(true); + } }); } - } - p + #[cfg(not(any(stm32f1, stm32wb, stm32wl)))] + peripherals::SYSCFG::enable_and_reset_with_cs(cs); + #[cfg(not(any(stm32h5, stm32h7, stm32wb, stm32wl)))] + peripherals::PWR::enable_and_reset_with_cs(cs); + #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7)))] + peripherals::FLASH::enable_and_reset_with_cs(cs); + + unsafe { + #[cfg(feature = "_split-pins-enabled")] + crate::pac::SYSCFG.pmcr().modify(|pmcr| { + #[cfg(feature = "split-pa0")] + pmcr.set_pa0so(true); + #[cfg(feature = "split-pa1")] + pmcr.set_pa1so(true); + #[cfg(feature = "split-pc2")] + pmcr.set_pc2so(true); + #[cfg(feature = "split-pc3")] + pmcr.set_pc3so(true); + }); + + gpio::init(cs); + dma::init( + cs, + #[cfg(bdma)] + config.bdma_interrupt_priority, + #[cfg(dma)] + config.dma_interrupt_priority, + #[cfg(gpdma)] + config.gpdma_interrupt_priority, + ); + #[cfg(feature = "exti")] + exti::init(cs); + + rcc::init(config.rcc); + + // must be after rcc init + #[cfg(feature = "_time-driver")] + time_driver::init(cs); + + #[cfg(feature = "low-power")] + while !crate::rcc::low_power_ready() { + crate::rcc::clock_refcount_sub(cs); + } + } + + p + }) } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 0263c97a..edbae30d 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -229,10 +229,19 @@ pub mod low_level { } pub(crate) mod sealed { + use critical_section::CriticalSection; + pub trait RccPeripheral { fn frequency() -> crate::time::Hertz; - fn enable_and_reset(); - fn disable(); + fn enable_and_reset_with_cs(cs: CriticalSection); + fn disable_with_cs(cs: CriticalSection); + + fn enable_and_reset() { + critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) + } + fn disable() { + critical_section::with(|cs| Self::disable_with_cs(cs)) + } } } diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index baea20ae..add8be83 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -152,45 +152,43 @@ embassy_time::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver { }); impl RtcDriver { - fn init(&'static self) { + fn init(&'static self, cs: critical_section::CriticalSection) { let r = T::regs_gp16(); - ::enable_and_reset(); + ::enable_and_reset_with_cs(cs); let timer_freq = T::frequency(); - critical_section::with(|_| { - r.cr1().modify(|w| w.set_cen(false)); - r.cnt().write(|w| w.set_cnt(0)); + r.cr1().modify(|w| w.set_cen(false)); + r.cnt().write(|w| w.set_cnt(0)); - let psc = timer_freq.0 / TICK_HZ as u32 - 1; - let psc: u16 = match psc.try_into() { - Err(_) => panic!("psc division overflow: {}", psc), - Ok(n) => n, - }; + let psc = timer_freq.0 / TICK_HZ as u32 - 1; + let psc: u16 = match psc.try_into() { + Err(_) => panic!("psc division overflow: {}", psc), + Ok(n) => n, + }; - r.psc().write(|w| w.set_psc(psc)); - r.arr().write(|w| w.set_arr(u16::MAX)); + r.psc().write(|w| w.set_psc(psc)); + r.arr().write(|w| w.set_arr(u16::MAX)); - // Set URS, generate update and clear URS - r.cr1().modify(|w| w.set_urs(vals::Urs::COUNTERONLY)); - r.egr().write(|w| w.set_ug(true)); - r.cr1().modify(|w| w.set_urs(vals::Urs::ANYEVENT)); + // Set URS, generate update and clear URS + r.cr1().modify(|w| w.set_urs(vals::Urs::COUNTERONLY)); + r.egr().write(|w| w.set_ug(true)); + r.cr1().modify(|w| w.set_urs(vals::Urs::ANYEVENT)); - // Mid-way point - r.ccr(0).write(|w| w.set_ccr(0x8000)); + // Mid-way point + r.ccr(0).write(|w| w.set_ccr(0x8000)); - // Enable overflow and half-overflow interrupts - r.dier().write(|w| { - w.set_uie(true); - w.set_ccie(0, true); - }); + // Enable overflow and half-overflow interrupts + r.dier().write(|w| { + w.set_uie(true); + w.set_ccie(0, true); + }); - ::Interrupt::unpend(); - unsafe { ::Interrupt::enable() }; + ::Interrupt::unpend(); + unsafe { ::Interrupt::enable() }; - r.cr1().modify(|w| w.set_cen(true)); - }) + r.cr1().modify(|w| w.set_cen(true)); } fn on_interrupt(&self) { @@ -462,6 +460,6 @@ pub(crate) fn get_driver() -> &'static RtcDriver { &DRIVER } -pub(crate) fn init() { - DRIVER.init() +pub(crate) fn init(cs: CriticalSection) { + DRIVER.init(cs) } From 02d2c06b23d2c2359e8673a95a47b4a7b2dd98a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 12 Oct 2023 18:10:34 +0200 Subject: [PATCH 86/95] Release embassy-time 0.1.4 --- cyw43/Cargo.toml | 2 +- docs/modules/ROOT/examples/basic/Cargo.toml | 2 +- embassy-embedded-hal/Cargo.toml | 2 +- embassy-executor/Cargo.toml | 2 +- embassy-lora/Cargo.toml | 2 +- embassy-net-adin1110/Cargo.toml | 2 +- embassy-net-enc28j60/Cargo.toml | 2 +- embassy-net-esp-hosted/Cargo.toml | 2 +- embassy-net-wiznet/Cargo.toml | 2 +- embassy-net/Cargo.toml | 2 +- embassy-nrf/Cargo.toml | 2 +- embassy-rp/Cargo.toml | 2 +- embassy-stm32-wpan/Cargo.toml | 2 +- embassy-stm32/Cargo.toml | 2 +- embassy-time/CHANGELOG.md | 2 +- examples/boot/application/nrf/Cargo.toml | 2 +- examples/boot/application/rp/Cargo.toml | 2 +- examples/boot/application/stm32f3/Cargo.toml | 2 +- examples/boot/application/stm32f7/Cargo.toml | 2 +- examples/boot/application/stm32h7/Cargo.toml | 2 +- examples/boot/application/stm32l0/Cargo.toml | 2 +- examples/boot/application/stm32l1/Cargo.toml | 2 +- examples/boot/application/stm32l4/Cargo.toml | 2 +- examples/boot/application/stm32wl/Cargo.toml | 2 +- examples/nrf-rtos-trace/Cargo.toml | 2 +- examples/nrf52840-rtic/Cargo.toml | 2 +- examples/nrf52840/Cargo.toml | 2 +- examples/nrf5340/Cargo.toml | 2 +- examples/rp/Cargo.toml | 2 +- examples/std/Cargo.toml | 2 +- examples/stm32c0/Cargo.toml | 2 +- examples/stm32f0/Cargo.toml | 2 +- examples/stm32f1/Cargo.toml | 2 +- examples/stm32f2/Cargo.toml | 2 +- examples/stm32f3/Cargo.toml | 2 +- examples/stm32f4/Cargo.toml | 2 +- examples/stm32f7/Cargo.toml | 2 +- examples/stm32g0/Cargo.toml | 2 +- examples/stm32g4/Cargo.toml | 2 +- examples/stm32h5/Cargo.toml | 2 +- examples/stm32h7/Cargo.toml | 2 +- examples/stm32l0/Cargo.toml | 2 +- examples/stm32l1/Cargo.toml | 2 +- examples/stm32l4/Cargo.toml | 2 +- examples/stm32l5/Cargo.toml | 2 +- examples/stm32u5/Cargo.toml | 2 +- examples/stm32wb/Cargo.toml | 2 +- examples/stm32wba/Cargo.toml | 2 +- examples/stm32wl/Cargo.toml | 2 +- examples/wasm/Cargo.toml | 2 +- tests/nrf/Cargo.toml | 2 +- tests/perf-client/Cargo.toml | 2 +- tests/riscv32/Cargo.toml | 2 +- tests/rp/Cargo.toml | 2 +- tests/stm32/Cargo.toml | 2 +- 55 files changed, 55 insertions(+), 55 deletions(-) diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index c201405e..d7bba6b6 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml @@ -11,7 +11,7 @@ log = ["dep:log"] firmware-logs = [] [dependencies] -embassy-time = { version = "0.1.3", path = "../embassy-time"} +embassy-time = { version = "0.1.4", path = "../embassy-time"} embassy-sync = { version = "0.3.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"} diff --git a/docs/modules/ROOT/examples/basic/Cargo.toml b/docs/modules/ROOT/examples/basic/Cargo.toml index e94358a9..527ce2ed 100644 --- a/docs/modules/ROOT/examples/basic/Cargo.toml +++ b/docs/modules/ROOT/examples/basic/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-executor = { version = "0.3.0", path = "../../../../../embassy-executor", features = ["defmt", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } -embassy-time = { version = "0.1.0", path = "../../../../../embassy-time", features = ["defmt", "nightly"] } +embassy-time = { version = "0.1.4", path = "../../../../../embassy-time", features = ["defmt", "nightly"] } embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "nightly"] } defmt = "0.3" diff --git a/embassy-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml index 62a95ed9..040e2356 100644 --- a/embassy-embedded-hal/Cargo.toml +++ b/embassy-embedded-hal/Cargo.toml @@ -21,7 +21,7 @@ default = ["time"] [dependencies] embassy-futures = { version = "0.1.0", path = "../embassy-futures", optional = true } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [ "unproven", ] } diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 35944625..4869bf3e 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -59,7 +59,7 @@ rtos-trace = { version = "0.1.2", optional = true } futures-util = { version = "0.3.17", default-features = false } embassy-macros = { version = "0.2.1", path = "../embassy-macros" } -embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true} +embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true} atomic-polyfill = "1.0.1" critical-section = "1.1" static_cell = "1.1" diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml index 88f815cd..6cdacd9c 100644 --- a/embassy-lora/Cargo.toml +++ b/embassy-lora/Cargo.toml @@ -20,7 +20,7 @@ defmt = ["dep:defmt", "lorawan-device/defmt"] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } embedded-hal-async = { version = "=1.0.0-rc.1" } diff --git a/embassy-net-adin1110/Cargo.toml b/embassy-net-adin1110/Cargo.toml index 8de8eade..b93716d0 100644 --- a/embassy-net-adin1110/Cargo.toml +++ b/embassy-net-adin1110/Cargo.toml @@ -17,7 +17,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } embedded-hal-bus = { version = "=0.1.0-rc.1", features = ["async"] } embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } -embassy-time = { version = "0.1.3" } +embassy-time = { version = "0.1.4", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } bitfield = "0.14.0" diff --git a/embassy-net-enc28j60/Cargo.toml b/embassy-net-enc28j60/Cargo.toml index 161d055c..e50fd0e6 100644 --- a/embassy-net-enc28j60/Cargo.toml +++ b/embassy-net-enc28j60/Cargo.toml @@ -11,7 +11,7 @@ edition = "2021" embedded-hal = { version = "1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } -embassy-time = { version = "0.1.3", path = "../embassy-time" } +embassy-time = { version = "0.1.4", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } defmt = { version = "0.3", optional = true } diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index 54cd8859..a0f53c6a 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -embassy-time = { version = "0.1.3", path = "../embassy-time" } +embassy-time = { version = "0.1.4", path = "../embassy-time" } embassy-sync = { version = "0.3.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"} diff --git a/embassy-net-wiznet/Cargo.toml b/embassy-net-wiznet/Cargo.toml index afa0d5cd..31836e1d 100644 --- a/embassy-net-wiznet/Cargo.toml +++ b/embassy-net-wiznet/Cargo.toml @@ -11,7 +11,7 @@ edition = "2021" embedded-hal = { version = "1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } -embassy-time = { version = "0.1.3", path = "../embassy-time" } +embassy-time = { version = "0.1.4", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } defmt = { version = "0.3", optional = true } diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index a3c18046..8fcbef83 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -52,7 +52,7 @@ smoltcp = { version = "0.10.0", default-features = false, features = [ ] } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } -embassy-time = { version = "0.1.3", path = "../embassy-time" } +embassy-time = { version = "0.1.4", path = "../embassy-time" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embedded-io-async = { version = "0.6.0", optional = true } diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 7ef18306..bd96bc15 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -94,7 +94,7 @@ _gpio-p1 = [] _nrf52832_anomaly_109 = [] [dependencies] -embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 26ff0ce8..02b11e19 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -60,7 +60,7 @@ unstable-traits = ["embedded-hal-1", "embedded-hal-nb"] [dependencies] embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.3", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } +embassy-time = { version = "0.1.4", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 3b10b7c5..b9d7776e 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -13,7 +13,7 @@ features = ["stm32wb55rg"] [dependencies] embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" } embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index a2c5da2b..8af55272 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -33,7 +33,7 @@ flavors = [ [dependencies] embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } diff --git a/embassy-time/CHANGELOG.md b/embassy-time/CHANGELOG.md index e3b38455..0dd938c2 100644 --- a/embassy-time/CHANGELOG.md +++ b/embassy-time/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.1.4 - ??? +## 0.1.4 - 2023-10-12 - Added more tick rates diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 435a3391..4c570cf2 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly"] } embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly"] } embassy-boot = { version = "0.1.0", path = "../../../../embassy-boot/boot", features = ["nightly"] } embassy-boot-nrf = { version = "0.1.0", path = "../../../../embassy-boot/nrf", features = ["nightly"] } diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 01cfc599..330eac41 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly"] } embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", "unstable-traits", "nightly"] } embassy-boot-rp = { version = "0.1.0", path = "../../../../embassy-boot/rp", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index a0649cf8..0ee7241a 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index ca1c0c42..fdc02c28 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index e50c8c41..de309ae0 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index 1f1a0f3c..5bee7458 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 45b12813..cc0b4509 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index d0d0d0fb..85fff4bf 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index 3265b9f1..78d92468 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index e402e49f..01983005 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -18,7 +18,7 @@ log = [ [dependencies] embassy-sync = { version = "0.3.0", path = "../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time" } +embassy-time = { version = "0.1.4", path = "../../embassy-time" } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index c588b807..7428f85f 100644 --- a/examples/nrf52840-rtic/Cargo.toml +++ b/examples/nrf52840-rtic/Cargo.toml @@ -9,7 +9,7 @@ rtic = { version = "2", features = ["thumbv7-backend"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "generic-queue"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "generic-queue"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nightly", "unstable-traits", "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } defmt = "0.3" diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index ce68935f..7a3ef54f 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -31,7 +31,7 @@ nightly = [ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "msos-descriptor",], optional = true } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 9d9400c2..5824d57b 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -14,7 +14,7 @@ embassy-executor = { version = "0.3.0", path = "../../embassy-executor", feature "defmt", "integrated-timers", ] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = [ +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", ] } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index c998a3dc..6eeb1ceb 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime"] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "critical-section-impl"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 52e68381..444dd500 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["log"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["log", "std", "nightly"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["log", "std", "nightly"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" } embassy-net-ppp = { version = "0.1.0", path = "../../embassy-net-ppp", features = ["log"]} diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index 89ecc499..8d65a399 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index db9a24d7..750d5304 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -16,7 +16,7 @@ defmt-rtt = "0.4" panic-probe = "0.3" embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } static_cell = { version = "1.1", features = ["nightly"]} [profile.release] diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index b032ba81..664be1f9 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any", "unstable-traits" ] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index 1314b6b1..7330eef3 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 534e783d..6ff425fa 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 6ffa223b..b76238ee 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 19d08a8b..01549f11 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index b4b423d5..4d10e82d 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 59da0628..4b0b1084 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.6.0" diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index a69de965..bc6d5898 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 7bcdf2b3..adc99024 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "unstable-traits", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index 0aff9dbd..f70ecc06 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -14,7 +14,7 @@ nightly = ["embassy-stm32/nightly", "embassy-time/nightly", "embassy-time/unstab embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["time", "defmt"], optional = true } lora-phy = { version = "2", optional = true } lorawan-device = { version = "0.11.0", default-features = false, features = ["async", "external-lora-phy"], optional = true } diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index a75275a0..472e1b7a 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } defmt = "0.3" diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 07fcbed6..5456efe8 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5qi", "memory-x", "time-driver-any", "exti", "unstable-traits", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", "unstable-traits", "nightly"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", "unstable-traits", "nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" } diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index a82cdc61..cf8601da 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index e361856c..9c139c2e 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } defmt = "0.3" diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 320678dd..e0711ad0 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -10,7 +10,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } defmt = "0.3" diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 26fcce26..7effc09a 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } defmt = "0.3" diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index f47a9a90..c106d62b 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time", "defmt"] } lora-phy = { version = "2" } diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index 12b2e2bd..9136c81c 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib"] [dependencies] embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["log"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } wasm-logger = "0.2.0" wasm-bindgen = "0.2" diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 2b265fc4..32f296a1 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -10,7 +10,7 @@ teleprobe-meta = "1" embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt", "nightly"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nightly", "unstable-traits", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } embedded-io-async = { version = "0.6.0" } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml index 3284664d..daa8edfb 100644 --- a/tests/perf-client/Cargo.toml +++ b/tests/perf-client/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" [dependencies] embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3.0" diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index 490f037b..ddd83ec2 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" critical-section = { version = "1.1.1", features = ["restore-state-bool"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time" } +embassy-time = { version = "0.1.4", path = "../../embassy-time" } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } riscv-rt = "0.11" diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 9751fe8c..a1e4c085 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -9,7 +9,7 @@ teleprobe-meta = "1.1" embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index a1481c7c..fd18cd77 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -41,7 +41,7 @@ teleprobe-meta = "1" embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-any"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } From 7f6fe93f552ec34e260e37d404007848723823c7 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Thu, 12 Oct 2023 20:54:26 +0200 Subject: [PATCH 87/95] fix: remove unused ringbuffer code --- embassy-hal-internal/src/lib.rs | 1 - embassy-hal-internal/src/ring_buffer.rs | 136 ------------------------ 2 files changed, 137 deletions(-) delete mode 100644 embassy-hal-internal/src/ring_buffer.rs diff --git a/embassy-hal-internal/src/lib.rs b/embassy-hal-internal/src/lib.rs index 3640ea18..f3d59e58 100644 --- a/embassy-hal-internal/src/lib.rs +++ b/embassy-hal-internal/src/lib.rs @@ -10,7 +10,6 @@ pub mod drop; mod macros; mod peripheral; pub mod ratio; -pub mod ring_buffer; pub use peripheral::{Peripheral, PeripheralRef}; #[cfg(feature = "cortex-m")] diff --git a/embassy-hal-internal/src/ring_buffer.rs b/embassy-hal-internal/src/ring_buffer.rs deleted file mode 100644 index fcad68bb..00000000 --- a/embassy-hal-internal/src/ring_buffer.rs +++ /dev/null @@ -1,136 +0,0 @@ -pub struct RingBuffer<'a> { - buf: &'a mut [u8], - start: usize, - end: usize, - empty: bool, -} - -impl<'a> RingBuffer<'a> { - pub fn new(buf: &'a mut [u8]) -> Self { - Self { - buf, - start: 0, - end: 0, - empty: true, - } - } - - pub fn push_buf(&mut self) -> &mut [u8] { - if self.start == self.end && !self.empty { - trace!(" ringbuf: push_buf empty"); - return &mut self.buf[..0]; - } - - let n = if self.start <= self.end { - self.buf.len() - self.end - } else { - self.start - self.end - }; - - trace!(" ringbuf: push_buf {:?}..{:?}", self.end, self.end + n); - &mut self.buf[self.end..self.end + n] - } - - pub fn push(&mut self, n: usize) { - trace!(" ringbuf: push {:?}", n); - if n == 0 { - return; - } - - self.end = self.wrap(self.end + n); - self.empty = false; - } - - pub fn pop_buf(&mut self) -> &mut [u8] { - if self.empty { - trace!(" ringbuf: pop_buf empty"); - return &mut self.buf[..0]; - } - - let n = if self.end <= self.start { - self.buf.len() - self.start - } else { - self.end - self.start - }; - - trace!(" ringbuf: pop_buf {:?}..{:?}", self.start, self.start + n); - &mut self.buf[self.start..self.start + n] - } - - pub fn pop(&mut self, n: usize) { - trace!(" ringbuf: pop {:?}", n); - if n == 0 { - return; - } - - self.start = self.wrap(self.start + n); - self.empty = self.start == self.end; - } - - pub fn is_full(&self) -> bool { - self.start == self.end && !self.empty - } - - pub fn is_empty(&self) -> bool { - self.empty - } - - pub fn clear(&mut self) { - self.start = 0; - self.end = 0; - self.empty = true; - } - - fn wrap(&self, n: usize) -> usize { - assert!(n <= self.buf.len()); - if n == self.buf.len() { - 0 - } else { - n - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn push_pop() { - let mut b = [0; 4]; - let mut rb = RingBuffer::new(&mut b); - let buf = rb.push_buf(); - assert_eq!(4, buf.len()); - buf[0] = 1; - buf[1] = 2; - buf[2] = 3; - buf[3] = 4; - rb.push(4); - - let buf = rb.pop_buf(); - assert_eq!(4, buf.len()); - assert_eq!(1, buf[0]); - rb.pop(1); - - let buf = rb.pop_buf(); - assert_eq!(3, buf.len()); - assert_eq!(2, buf[0]); - rb.pop(1); - - let buf = rb.pop_buf(); - assert_eq!(2, buf.len()); - assert_eq!(3, buf[0]); - rb.pop(1); - - let buf = rb.pop_buf(); - assert_eq!(1, buf.len()); - assert_eq!(4, buf[0]); - rb.pop(1); - - let buf = rb.pop_buf(); - assert_eq!(0, buf.len()); - - let buf = rb.push_buf(); - assert_eq!(4, buf.len()); - } -} From 636958ff7054950c1adf8dce2ae96a9e981b8497 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Thu, 12 Oct 2023 20:54:38 +0200 Subject: [PATCH 88/95] fix: correct name in readme --- embassy-hal-internal/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-hal-internal/README.md b/embassy-hal-internal/README.md index d6539701..6b060d1c 100644 --- a/embassy-hal-internal/README.md +++ b/embassy-hal-internal/README.md @@ -1,4 +1,4 @@ -# embassy-macros +# embassy-hal-internal An [Embassy](https://embassy.dev) project. From a6bbb130c5469437f3a29845328e444d487ab17c Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Thu, 12 Oct 2023 22:57:44 +0100 Subject: [PATCH 89/95] make set_config concrete methods public again --- embassy-stm32/src/spi/mod.rs | 7 +++---- embassy-stm32/src/usart/buffered.rs | 6 +++--- embassy-stm32/src/usart/mod.rs | 4 ++-- embassy-stm32/src/usart/ringbuffered.rs | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 211b5523..c391e0a5 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -322,7 +322,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } /// Reconfigures it with the supplied config. - fn set_config(&mut self, config: Config) { + pub fn set_config(&mut self, config: &Config) -> Result<(), ()> { let cpha = config.raw_phase(); let cpol = config.raw_polarity(); @@ -351,6 +351,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { w.set_mbr(br); }); } + Ok(()) } pub fn get_current_config(&self) -> Config { @@ -1062,8 +1063,6 @@ impl<'d, T: Instance, Tx, Rx> SetConfig for Spi<'d, T, Tx, Rx> { type Config = Config; type ConfigError = (); fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(*config); - - Ok(()) + self.set_config(config) } } diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 82d925a4..cbc13a34 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -253,7 +253,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { (self.tx, self.rx) } - fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } } @@ -333,7 +333,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { } } - fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } } @@ -407,7 +407,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { } } - fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } } diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 3b7f5184..880ca416 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -274,7 +274,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { }) } - fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } @@ -373,7 +373,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { }) } - fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 535d1b1f..55489f2e 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -64,7 +64,7 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma> RingBufferedUartRx<'d, T, RxD Err(err) } - fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { self.teardown_uart(); reconfigure::(config) } From adc810d24ba25972bb8c886fce9c67ec7de4ac00 Mon Sep 17 00:00:00 2001 From: Ralf Date: Fri, 13 Oct 2023 17:38:40 +0200 Subject: [PATCH 90/95] STM32: Fix regression in advanced timer to enable output of PWM signal by partly reverting commit 74eb519 --- embassy-stm32/src/timer/mod.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 1e0999ed..9f37b805 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -173,7 +173,7 @@ pub(crate) mod sealed { } }); } - fn enable_outputs(&mut self, _enable: bool) {} + fn enable_outputs(&mut self, _enable: bool); fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { let r = Self::regs_gp16(); @@ -401,7 +401,9 @@ macro_rules! impl_32bit_timer { #[allow(unused)] macro_rules! impl_compare_capable_16bit { ($inst:ident) => { - impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { + fn enable_outputs(&mut self, _enable: bool) {} + } }; } @@ -450,7 +452,13 @@ foreach_interrupt! { impl CaptureCompare16bitInstance for crate::peripherals::$inst {} impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} impl AdvancedControlInstance for crate::peripherals::$inst {} - impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {} + impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { + fn enable_outputs(&mut self, enable: bool) { + use crate::timer::sealed::AdvancedControlInstance; + let r = Self::regs_advanced(); + r.bdtr().modify(|w| w.set_moe(enable)); + } + } impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { fn regs_gp16() -> crate::pac::timer::TimGp16 { From 9a7fda87b0335471e2944a57af684cf4b184ce07 Mon Sep 17 00:00:00 2001 From: Ralf Date: Fri, 13 Oct 2023 18:50:54 +0200 Subject: [PATCH 91/95] STM32: timer enable_output does not take bool, but just enables the output --- embassy-stm32/src/timer/complementary_pwm.rs | 2 +- embassy-stm32/src/timer/mod.rs | 8 ++++---- embassy-stm32/src/timer/simple_pwm.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 9349a6fa..e1baf6b2 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -71,7 +71,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { this.inner.set_frequency(freq); this.inner.start(); - this.inner.enable_outputs(true); + this.inner.enable_outputs(); this.inner .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1); diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 9f37b805..4b88834c 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -173,7 +173,7 @@ pub(crate) mod sealed { } }); } - fn enable_outputs(&mut self, _enable: bool); + fn enable_outputs(&mut self); fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { let r = Self::regs_gp16(); @@ -402,7 +402,7 @@ macro_rules! impl_32bit_timer { macro_rules! impl_compare_capable_16bit { ($inst:ident) => { impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { - fn enable_outputs(&mut self, _enable: bool) {} + fn enable_outputs(&mut self) {} } }; } @@ -453,10 +453,10 @@ foreach_interrupt! { impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} impl AdvancedControlInstance for crate::peripherals::$inst {} impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { - fn enable_outputs(&mut self, enable: bool) { + fn enable_outputs(&mut self) { use crate::timer::sealed::AdvancedControlInstance; let r = Self::regs_advanced(); - r.bdtr().modify(|w| w.set_moe(enable)); + r.bdtr().modify(|w| w.set_moe(true)); } } impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 18ecc196..01773ff3 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -70,7 +70,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { this.inner.set_frequency(freq); this.inner.start(); - this.inner.enable_outputs(true); + this.inner.enable_outputs(); this.inner .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1); From a57d383b1d2872759cf1a3ab7148cfa175ea7614 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Sat, 14 Oct 2023 04:20:59 +0200 Subject: [PATCH 92/95] embassy-usb: Add MIDI class --- embassy-usb/src/class/midi.rs | 227 ++++++++++++++++++++++++++++++++ embassy-usb/src/class/mod.rs | 1 + examples/rp/src/bin/usb_midi.rs | 110 ++++++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 embassy-usb/src/class/midi.rs create mode 100644 examples/rp/src/bin/usb_midi.rs diff --git a/embassy-usb/src/class/midi.rs b/embassy-usb/src/class/midi.rs new file mode 100644 index 00000000..c5cf8d87 --- /dev/null +++ b/embassy-usb/src/class/midi.rs @@ -0,0 +1,227 @@ +//! MIDI class implementation. + +use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; +use crate::Builder; + +/// This should be used as `device_class` when building the `UsbDevice`. +pub const USB_AUDIO_CLASS: u8 = 0x01; + +const USB_AUDIOCONTROL_SUBCLASS: u8 = 0x01; +const USB_MIDISTREAMING_SUBCLASS: u8 = 0x03; +const MIDI_IN_JACK_SUBTYPE: u8 = 0x02; +const MIDI_OUT_JACK_SUBTYPE: u8 = 0x03; +const EMBEDDED: u8 = 0x01; +const EXTERNAL: u8 = 0x02; +const CS_INTERFACE: u8 = 0x24; +const CS_ENDPOINT: u8 = 0x25; +const HEADER_SUBTYPE: u8 = 0x01; +const MS_HEADER_SUBTYPE: u8 = 0x01; +const MS_GENERAL: u8 = 0x01; +const PROTOCOL_NONE: u8 = 0x00; +const MIDI_IN_SIZE: u8 = 0x06; +const MIDI_OUT_SIZE: u8 = 0x09; + +/// Packet level implementation of a USB MIDI device. +/// +/// This class can be used directly and it has the least overhead due to directly reading and +/// writing USB packets with no intermediate buffers, but it will not act like a stream-like port. +/// The following constraints must be followed if you use this class directly: +/// +/// - `read_packet` must be called with a buffer large enough to hold max_packet_size bytes. +/// - `write_packet` must not be called with a buffer larger than max_packet_size bytes. +/// - If you write a packet that is exactly max_packet_size bytes long, it won't be processed by the +/// host operating system until a subsequent shorter packet is sent. A zero-length packet (ZLP) +/// can be sent if there is no other data to send. This is because USB bulk transactions must be +/// terminated with a short packet, even if the bulk endpoint is used for stream-like data. +pub struct MidiClass<'d, D: Driver<'d>> { + read_ep: D::EndpointOut, + write_ep: D::EndpointIn, +} + +impl<'d, D: Driver<'d>> MidiClass<'d, D> { + /// Creates a new MidiClass with the provided UsbBus, number of input and output jacks and max_packet_size in bytes. + /// For full-speed devices, max_packet_size has to be one of 8, 16, 32 or 64. + pub fn new(builder: &mut Builder<'d, D>, n_in_jacks: u8, n_out_jacks: u8, max_packet_size: u16) -> Self { + let mut func = builder.function(USB_AUDIO_CLASS, USB_AUDIOCONTROL_SUBCLASS, PROTOCOL_NONE); + + // Audio control interface + let mut iface = func.interface(); + let audio_if = iface.interface_number(); + let midi_if = u8::from(audio_if) + 1; + let mut alt = iface.alt_setting(USB_AUDIO_CLASS, USB_AUDIOCONTROL_SUBCLASS, PROTOCOL_NONE, None); + alt.descriptor(CS_INTERFACE, &[HEADER_SUBTYPE, 0x00, 0x01, 0x09, 0x00, 0x01, midi_if]); + + // MIDIStreaming interface + let mut iface = func.interface(); + let _midi_if = iface.interface_number(); + let mut alt = iface.alt_setting(USB_AUDIO_CLASS, USB_MIDISTREAMING_SUBCLASS, PROTOCOL_NONE, None); + + let midi_streaming_total_length = 7 + + (n_in_jacks + n_out_jacks) as usize * (MIDI_IN_SIZE + MIDI_OUT_SIZE) as usize + + 7 + + (4 + n_out_jacks as usize) + + 7 + + (4 + n_in_jacks as usize); + + alt.descriptor( + CS_INTERFACE, + &[ + MS_HEADER_SUBTYPE, + 0x00, + 0x01, + (midi_streaming_total_length & 0xFF) as u8, + ((midi_streaming_total_length >> 8) & 0xFF) as u8, + ], + ); + + // Calculates the index'th external midi in jack id + let in_jack_id_ext = |index| 2 * index + 1; + // Calculates the index'th embedded midi out jack id + let out_jack_id_emb = |index| 2 * index + 2; + // Calculates the index'th external midi out jack id + let out_jack_id_ext = |index| 2 * n_in_jacks + 2 * index + 1; + // Calculates the index'th embedded midi in jack id + let in_jack_id_emb = |index| 2 * n_in_jacks + 2 * index + 2; + + for i in 0..n_in_jacks { + alt.descriptor(CS_INTERFACE, &[MIDI_IN_JACK_SUBTYPE, EXTERNAL, in_jack_id_ext(i), 0x00]); + } + + for i in 0..n_out_jacks { + alt.descriptor(CS_INTERFACE, &[MIDI_IN_JACK_SUBTYPE, EMBEDDED, in_jack_id_emb(i), 0x00]); + } + + for i in 0..n_out_jacks { + alt.descriptor( + CS_INTERFACE, + &[ + MIDI_OUT_JACK_SUBTYPE, + EXTERNAL, + out_jack_id_ext(i), + 0x01, + in_jack_id_emb(i), + 0x01, + 0x00, + ], + ); + } + + for i in 0..n_in_jacks { + alt.descriptor( + CS_INTERFACE, + &[ + MIDI_OUT_JACK_SUBTYPE, + EMBEDDED, + out_jack_id_emb(i), + 0x01, + in_jack_id_ext(i), + 0x01, + 0x00, + ], + ); + } + + let mut endpoint_data = [ + MS_GENERAL, 0, // Number of jacks + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Jack mappings + ]; + endpoint_data[1] = n_out_jacks; + for i in 0..n_out_jacks { + endpoint_data[2 + i as usize] = in_jack_id_emb(i); + } + let read_ep = alt.endpoint_bulk_out(max_packet_size); + alt.descriptor(CS_ENDPOINT, &endpoint_data[0..2 + n_out_jacks as usize]); + + endpoint_data[1] = n_in_jacks; + for i in 0..n_in_jacks { + endpoint_data[2 + i as usize] = out_jack_id_emb(i); + } + let write_ep = alt.endpoint_bulk_in(max_packet_size); + alt.descriptor(CS_ENDPOINT, &endpoint_data[0..2 + n_in_jacks as usize]); + + MidiClass { read_ep, write_ep } + } + + /// Gets the maximum packet size in bytes. + pub fn max_packet_size(&self) -> u16 { + // The size is the same for both endpoints. + self.read_ep.info().max_packet_size + } + + /// Writes a single packet into the IN endpoint. + pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> { + self.write_ep.write(data).await + } + + /// Reads a single packet from the OUT endpoint. + pub async fn read_packet(&mut self, data: &mut [u8]) -> Result { + self.read_ep.read(data).await + } + + /// Waits for the USB host to enable this interface + pub async fn wait_connection(&mut self) { + self.read_ep.wait_enabled().await + } + + /// Split the class into a sender and receiver. + /// + /// This allows concurrently sending and receiving packets from separate tasks. + pub fn split(self) -> (Sender<'d, D>, Receiver<'d, D>) { + ( + Sender { + write_ep: self.write_ep, + }, + Receiver { read_ep: self.read_ep }, + ) + } +} + +/// Midi class packet sender. +/// +/// You can obtain a `Sender` with [`MidiClass::split`] +pub struct Sender<'d, D: Driver<'d>> { + write_ep: D::EndpointIn, +} + +impl<'d, D: Driver<'d>> Sender<'d, D> { + /// Gets the maximum packet size in bytes. + pub fn max_packet_size(&self) -> u16 { + // The size is the same for both endpoints. + self.write_ep.info().max_packet_size + } + + /// Writes a single packet. + pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> { + self.write_ep.write(data).await + } + + /// Waits for the USB host to enable this interface + pub async fn wait_connection(&mut self) { + self.write_ep.wait_enabled().await + } +} + +/// Midi class packet receiver. +/// +/// You can obtain a `Receiver` with [`MidiClass::split`] +pub struct Receiver<'d, D: Driver<'d>> { + read_ep: D::EndpointOut, +} + +impl<'d, D: Driver<'d>> Receiver<'d, D> { + /// Gets the maximum packet size in bytes. + pub fn max_packet_size(&self) -> u16 { + // The size is the same for both endpoints. + self.read_ep.info().max_packet_size + } + + /// Reads a single packet. + pub async fn read_packet(&mut self, data: &mut [u8]) -> Result { + self.read_ep.read(data).await + } + + /// Waits for the USB host to enable this interface + pub async fn wait_connection(&mut self) { + self.read_ep.wait_enabled().await + } +} diff --git a/embassy-usb/src/class/mod.rs b/embassy-usb/src/class/mod.rs index b23e03d4..452eedf1 100644 --- a/embassy-usb/src/class/mod.rs +++ b/embassy-usb/src/class/mod.rs @@ -2,3 +2,4 @@ pub mod cdc_acm; pub mod cdc_ncm; pub mod hid; +pub mod midi; diff --git a/examples/rp/src/bin/usb_midi.rs b/examples/rp/src/bin/usb_midi.rs new file mode 100644 index 00000000..f0b03c81 --- /dev/null +++ b/examples/rp/src/bin/usb_midi.rs @@ -0,0 +1,110 @@ +//! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip. +//! +//! This creates a USB MIDI device that echoes MIDI messages back to the host. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::{info, panic}; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_rp::bind_interrupts; +use embassy_rp::peripherals::USB; +use embassy_rp::usb::{Driver, Instance, InterruptHandler}; +use embassy_usb::class::midi::MidiClass; +use embassy_usb::driver::EndpointError; +use embassy_usb::{Builder, Config}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Hello world!"); + + let p = embassy_rp::init(Default::default()); + + // Create the driver, from the HAL. + let driver = Driver::new(p.USB, Irqs); + + // Create embassy-usb Config + let mut config = Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Embassy"); + config.product = Some("USB-MIDI example"); + config.serial_number = Some("12345678"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + // Required for windows compatibility. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xEF; + config.device_sub_class = 0x02; + config.device_protocol = 0x01; + config.composite_with_iads = true; + + // Create embassy-usb DeviceBuilder using the driver and config. + // It needs some buffers for building the descriptors. + let mut device_descriptor = [0; 256]; + let mut config_descriptor = [0; 256]; + let mut bos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + + let mut builder = Builder::new( + driver, + config, + &mut device_descriptor, + &mut config_descriptor, + &mut bos_descriptor, + &mut control_buf, + ); + + // Create classes on the builder. + let mut class = MidiClass::new(&mut builder, 1, 1, 64); + + // The `MidiClass` can be split into `Sender` and `Receiver`, to be used in separate tasks. + // let (sender, receiver) = class.split(); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + + // Use the Midi class! + let midi_fut = async { + loop { + class.wait_connection().await; + info!("Connected"); + let _ = midi_echo(&mut class).await; + info!("Disconnected"); + } + }; + + // Run everything concurrently. + // If we had made everything `'static` above instead, we could do this using separate tasks instead. + join(usb_fut, midi_fut).await; +} + +struct Disconnected {} + +impl From for Disconnected { + fn from(val: EndpointError) -> Self { + match val { + EndpointError::BufferOverflow => panic!("Buffer overflow"), + EndpointError::Disabled => Disconnected {}, + } + } +} + +async fn midi_echo<'d, T: Instance + 'd>(class: &mut MidiClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { + let mut buf = [0; 64]; + loop { + let n = class.read_packet(&mut buf).await?; + let data = &buf[..n]; + info!("data: {:x}", data); + class.write_packet(data).await?; + } +} From 3264941c1bcad10efc96c017736391edf5d846ff Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 13 Oct 2023 23:06:32 -0500 Subject: [PATCH 93/95] rcc mux: update metapac --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/build.rs | 23 +++++++++-------------- embassy-stm32/src/rcc/h.rs | 28 ++++++++++++++++------------ embassy-stm32/src/rcc/mod.rs | 24 ++++++++++++++---------- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 8af55272..dbf5a69d 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -58,7 +58,7 @@ rand_core = "0.6.3" sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e4a769aa67aa82603448377daa579d67a789983a" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e4a769aa67aa82603448377daa579d67a789983a", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 8e680fb6..7ba3a6bd 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -5,7 +5,7 @@ use std::{env, fs}; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; -use stm32_metapac::metadata::ir::{BlockItemInner, Enum}; +use stm32_metapac::metadata::ir::{BlockItemInner, Enum, FieldSet}; use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA}; fn main() { @@ -400,29 +400,24 @@ fn main() { .ir; let rcc_blocks = rcc_registers.blocks.iter().find(|b| b.name == "Rcc").unwrap().items; + let rcc_fieldsets: HashMap<&str, &FieldSet> = rcc_registers.fieldsets.iter().map(|f| (f.name, f)).collect(); + let rcc_enums: HashMap<&str, &Enum> = rcc_registers.enums.iter().map(|e| (e.name, e)).collect(); - let rcc_block_item_map: HashMap<&str, &str> = rcc_blocks + rcc_blocks .iter() .filter_map(|b| match &b.inner { - BlockItemInner::Register(register) => register.fieldset.map(|f| (f, b.name)), + BlockItemInner::Register(register) => register.fieldset.map(|f| (b.name, f)), _ => None, }) - .collect(); - - let rcc_enum_map: HashMap<&str, &Enum> = rcc_registers.enums.iter().map(|e| (e.name, e)).collect(); - - rcc_registers - .fieldsets - .iter() - .filter_map(|f| { - rcc_block_item_map.get(f.name).map(|b| { + .filter_map(|(b, f)| { + rcc_fieldsets.get(f).map(|f| { ( - *b, + b, f.fields .iter() .filter_map(|f| { let enumm = f.enumm?; - let enumm = rcc_enum_map.get(enumm)?; + let enumm = rcc_enums.get(enumm)?; Some((f.name, *enumm)) }) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index d37dd45d..379d3179 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -457,8 +457,8 @@ pub(crate) unsafe fn init(config: Config) { AdcClockSource::SYSCLK => Some(sys), AdcClockSource::PLL2_R => pll2.r, AdcClockSource::HSE => hse, - AdcClockSource::HSI_KER => hsi, - AdcClockSource::CSI_KER => csi, + AdcClockSource::HSI => hsi, + AdcClockSource::CSI => csi, _ => unreachable!(), }; @@ -547,15 +547,25 @@ pub(crate) unsafe fn init(config: Config) { rtc, #[cfg(stm32h5)] - mux_rcc_pclk1: Some(apb1), + mux_apb1: Some(apb1), + #[cfg(stm32h5)] + mux_apb2: Some(apb2), + #[cfg(stm32h5)] + mux_apb3: Some(apb3), + #[cfg(stm32h5)] + mux_apb4: None, + + #[cfg(stm32h5)] + mux_rcc_hclk4: None, + #[cfg(stm32h5)] mux_pll2_q: None, #[cfg(stm32h5)] mux_pll3_q: None, #[cfg(stm32h5)] - mux_hsi_ker: None, + mux_hsi: None, #[cfg(stm32h5)] - mux_csi_ker: None, + mux_csi: None, #[cfg(stm32h5)] mux_lse: None, #[cfg(stm32h5)] @@ -574,20 +584,14 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(all(not(rcc_h5), stm32h5))] mux_pll3_r: None, #[cfg(stm32h5)] - mux_rcc_pclk3: Some(apb3), - #[cfg(stm32h5)] mux_pll3_1: None, #[cfg(stm32h5)] mux_hsi48_ker: None, #[cfg(stm32h5)] - mux_lsi_ker: None, + mux_lsi: None, #[cfg(stm32h5)] mux_pll2_r: pll2.r, #[cfg(stm32h5)] - mux_rcc_pclk2: Some(apb2), - #[cfg(stm32h5)] - mux_rcc_pclk4: None, - #[cfg(stm32h5)] mux_hse: hse, #[cfg(stm32h5)] diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index edbae30d..f7210e18 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -136,15 +136,25 @@ pub struct Clocks { pub rtc: Option, #[cfg(stm32h5)] - pub mux_rcc_pclk1: Option, + pub mux_apb1: Option, + #[cfg(stm32h5)] + pub mux_apb2: Option, + #[cfg(stm32h5)] + pub mux_apb3: Option, + #[cfg(stm32h5)] + pub mux_apb4: Option, + + #[cfg(stm32h5)] + pub mux_rcc_hclk4: Option, + #[cfg(stm32h5)] pub mux_pll2_q: Option, #[cfg(stm32h5)] pub mux_pll3_q: Option, #[cfg(stm32h5)] - pub mux_hsi_ker: Option, + pub mux_hsi: Option, #[cfg(stm32h5)] - pub mux_csi_ker: Option, + pub mux_csi: Option, #[cfg(stm32h5)] pub mux_lse: Option, @@ -162,20 +172,14 @@ pub struct Clocks { #[cfg(stm32h5)] pub mux_pll3_r: Option, #[cfg(stm32h5)] - pub mux_rcc_pclk3: Option, - #[cfg(stm32h5)] pub mux_pll3_1: Option, #[cfg(stm32h5)] pub mux_hsi48_ker: Option, #[cfg(stm32h5)] - pub mux_lsi_ker: Option, + pub mux_lsi: Option, #[cfg(stm32h5)] pub mux_pll2_r: Option, #[cfg(stm32h5)] - pub mux_rcc_pclk2: Option, - #[cfg(stm32h5)] - pub mux_rcc_pclk4: Option, - #[cfg(stm32h5)] pub mux_hse: Option, #[cfg(stm32h5)] From 69bb455c602571b45bc62a03c9e68bfd5ddcb838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Sat, 14 Oct 2023 13:35:53 +0200 Subject: [PATCH 94/95] Wake stack's task after queueing a DNS query --- embassy-net/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index ef67935e..a0ad33c6 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -509,7 +509,10 @@ impl Stack { self.with_mut(|s, i| { let socket = s.sockets.get_mut::(i.dns_socket); match socket.start_query(s.iface.context(), name, qtype) { - Ok(handle) => Poll::Ready(Ok(handle)), + Ok(handle) => { + s.waker.wake(); + Poll::Ready(Ok(handle)) + } Err(dns::StartQueryError::NoFreeSlot) => { i.dns_waker.register(cx.waker()); Poll::Pending From 824556c9c8d5a67e5149248df19e76c21c798330 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 14 Oct 2023 12:51:45 -0500 Subject: [PATCH 95/95] rcc: remove mux_prefix from clocks --- embassy-stm32/Cargo.toml | 4 +-- embassy-stm32/build.rs | 12 +++++-- embassy-stm32/src/rcc/h.rs | 62 ++++++++++++++++-------------------- embassy-stm32/src/rcc/mod.rs | 56 ++++++++++++-------------------- 4 files changed, 60 insertions(+), 74 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index dbf5a69d..b18cafb8 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -58,7 +58,7 @@ rand_core = "0.6.3" sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e4a769aa67aa82603448377daa579d67a789983a" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e6e51db6cdd7d533e52ca7a3237f7816a0486cd4" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e4a769aa67aa82603448377daa579d67a789983a", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e6e51db6cdd7d533e52ca7a3237f7816a0486cd4", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 7ba3a6bd..3e1c76f3 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -520,10 +520,16 @@ fn main() { let variant_name = format_ident!("{}", v.name); // temporary hack to restrict the scope of the implementation until clock names can be stabilized - let clock_name = format_ident!("mux_{}", v.name.to_ascii_lowercase()); + let clock_name = format_ident!("{}", v.name.to_ascii_lowercase()); - quote! { - #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() }, + if v.name.starts_with("AHB") || v.name.starts_with("APB") { + quote! { + #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name }, + } + } else { + quote! { + #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() }, + } } }) .collect(); diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 379d3179..a24f4d4e 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -541,61 +541,55 @@ pub(crate) unsafe fn init(config: Config) { apb3, #[cfg(stm32h7)] apb4, + #[cfg(stm32h5)] + apb4: Hertz(1), apb1_tim, apb2_tim, adc, rtc, #[cfg(stm32h5)] - mux_apb1: Some(apb1), + hsi: None, #[cfg(stm32h5)] - mux_apb2: Some(apb2), + hsi48: None, #[cfg(stm32h5)] - mux_apb3: Some(apb3), + lsi: None, #[cfg(stm32h5)] - mux_apb4: None, + csi: None, #[cfg(stm32h5)] - mux_rcc_hclk4: None, + lse: None, + #[cfg(stm32h5)] + hse: None, #[cfg(stm32h5)] - mux_pll2_q: None, + pll1_q: pll1.q, #[cfg(stm32h5)] - mux_pll3_q: None, + pll2_q: pll2.q, #[cfg(stm32h5)] - mux_hsi: None, + pll2_p: pll2.p, #[cfg(stm32h5)] - mux_csi: None, - #[cfg(stm32h5)] - mux_lse: None, - #[cfg(stm32h5)] - mux_pll1_q: pll1.q, - #[cfg(stm32h5)] - mux_pll2_p: pll2.p, + pll2_r: pll2.r, #[cfg(rcc_h5)] - mux_pll3_p: pll3.p, - #[cfg(stm32h5)] - mux_audioclk: None, - #[cfg(stm32h5)] - mux_per: None, - + pll3_p: pll3.p, #[cfg(rcc_h5)] - mux_pll3_r: pll3.r, - #[cfg(all(not(rcc_h5), stm32h5))] - mux_pll3_r: None, + pll3_q: pll3.q, + #[cfg(rcc_h5)] + pll3_r: pll3.r, #[cfg(stm32h5)] - mux_pll3_1: None, - #[cfg(stm32h5)] - mux_hsi48_ker: None, - #[cfg(stm32h5)] - mux_lsi: None, - #[cfg(stm32h5)] - mux_pll2_r: pll2.r, - #[cfg(stm32h5)] - mux_hse: hse, + pll3_1: None, + + #[cfg(rcc_h50)] + pll3_p: None, + #[cfg(rcc_h50)] + pll3_q: None, + #[cfg(rcc_h50)] + pll3_r: None, #[cfg(stm32h5)] - mux_hsi48: None, + audioclk: None, + #[cfg(stm32h5)] + per: None, }); } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index f7210e18..0904ddbd 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -56,7 +56,7 @@ pub struct Clocks { pub apb2_tim: Hertz, #[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_u5))] pub apb3: Hertz, - #[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab))] + #[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab, stm32h5))] pub apb4: Hertz, #[cfg(any(rcc_wba))] pub apb7: Hertz, @@ -136,54 +136,40 @@ pub struct Clocks { pub rtc: Option, #[cfg(stm32h5)] - pub mux_apb1: Option, + pub hsi: Option, #[cfg(stm32h5)] - pub mux_apb2: Option, + pub hsi48: Option, #[cfg(stm32h5)] - pub mux_apb3: Option, + pub lsi: Option, #[cfg(stm32h5)] - pub mux_apb4: Option, + pub csi: Option, #[cfg(stm32h5)] - pub mux_rcc_hclk4: Option, + pub lse: Option, + #[cfg(stm32h5)] + pub hse: Option, #[cfg(stm32h5)] - pub mux_pll2_q: Option, + pub pll1_q: Option, #[cfg(stm32h5)] - pub mux_pll3_q: Option, + pub pll2_q: Option, #[cfg(stm32h5)] - pub mux_hsi: Option, + pub pll2_p: Option, #[cfg(stm32h5)] - pub mux_csi: Option, + pub pll2_r: Option, #[cfg(stm32h5)] - pub mux_lse: Option, + pub pll3_p: Option, + #[cfg(stm32h5)] + pub pll3_q: Option, + #[cfg(stm32h5)] + pub pll3_r: Option, + #[cfg(stm32h5)] + pub pll3_1: Option, #[cfg(stm32h5)] - pub mux_pll1_q: Option, + pub audioclk: Option, #[cfg(stm32h5)] - pub mux_pll2_p: Option, - #[cfg(rcc_h5)] - pub mux_pll3_p: Option, - #[cfg(stm32h5)] - pub mux_audioclk: Option, - #[cfg(stm32h5)] - pub mux_per: Option, - - #[cfg(stm32h5)] - pub mux_pll3_r: Option, - #[cfg(stm32h5)] - pub mux_pll3_1: Option, - #[cfg(stm32h5)] - pub mux_hsi48_ker: Option, - #[cfg(stm32h5)] - pub mux_lsi: Option, - #[cfg(stm32h5)] - pub mux_pll2_r: Option, - #[cfg(stm32h5)] - pub mux_hse: Option, - - #[cfg(stm32h5)] - pub mux_hsi48: Option, + pub per: Option, } #[cfg(feature = "low-power")]