From 561126b0d6068d189477af18461bf1e467532516 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Sun, 1 Oct 2023 23:09:01 +0200 Subject: [PATCH 001/188] stm32: Add the ability to center-align timers --- embassy-stm32/src/timer/complementary_pwm.rs | 6 ++- embassy-stm32/src/timer/mod.rs | 49 +++++++++++++++++++- embassy-stm32/src/timer/simple_pwm.rs | 6 ++- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 4f033e3a..bfe5137e 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -57,11 +57,12 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { _ch4: Option>, _ch4n: Option>, freq: Hertz, + counting_mode: CountingMode, ) -> Self { - Self::new_inner(tim, freq) + Self::new_inner(tim, freq, counting_mode) } - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { + fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz, counting_mode: CountingMode) -> Self { into_ref!(tim); T::enable(); @@ -70,6 +71,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { let mut this = Self { inner: tim }; this.inner.set_frequency(freq); + this.inner.set_counting_mode(counting_mode); this.inner.start(); this.inner.enable_outputs(true); diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index d88fbcfd..52d1dc11 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -75,8 +75,16 @@ pub(crate) mod sealed { pub trait GeneralPurpose16bitInstance: Basic16bitInstance { fn regs_gp16() -> crate::pac::timer::TimGp16; - fn set_count_direction(&mut self, direction: vals::Dir) { - Self::regs_gp16().cr1().modify(|r| r.set_dir(direction)); + fn set_counting_mode(&mut self, mode: CountingMode) { + let (cms, dir) = mode.values(); + + let timer_enabled = Self::regs().cr1().read().cen(); + // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. + // Changing direction is discouraged while the timer is running. + assert!(timer_enabled); + + Self::regs_gp16().cr1().modify(|r| r.set_dir(dir)); + Self::regs_gp16().cr1().modify(|r| r.set_cms(cms)) } fn set_clock_division(&mut self, ckd: vals::Ckd) { @@ -265,6 +273,43 @@ impl From for stm32_metapac::timer::vals::CcmrInputCcs { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum CountingMode { + #[default] + /// The timer counts up to the reload value and then resets back to 0. + EdgeAlignedUp, + /// The timer counts down to 0 and then resets back to the reload value. + EdgeAlignedDown, + /// The timer counts up to the reload value and then counts back to 0. + /// + /// The output compare interrupt flags of channels configured in output are + /// set when the counter is counting down. + CenterAlignedDownInterrupts, + /// The timer counts up to the reload value and then counts back to 0. + /// + /// The output compare interrupt flags of channels configured in output are + /// set when the counter is counting up. + CenterAlignedUpInterrupts, + /// The timer counts up to the reload value and then counts back to 0. + /// + /// The output compare interrupt flags of channels configured in output are + /// set when the counter is counting both up or down. + CenterAlignedBothInterrupts, +} + +impl CountingMode { + /// Get the register values to set the timer mode to the current variant + pub fn values(&self) -> (vals::Cms, vals::Dir) { + match self { + CountingMode::EdgeAlignedUp => (vals::Cms::EDGEALIGNED, vals::Dir::UP), + CountingMode::EdgeAlignedDown => (vals::Cms::EDGEALIGNED, vals::Dir::DOWN), + CountingMode::CenterAlignedDownInterrupts => (vals::Cms::CENTERALIGNED1, vals::Dir::UP), + CountingMode::CenterAlignedUpInterrupts => (vals::Cms::CENTERALIGNED2, vals::Dir::UP), + CountingMode::CenterAlignedBothInterrupts => (vals::Cms::CENTERALIGNED3, vals::Dir::UP), + } + } +} + #[derive(Clone, Copy)] pub enum OutputCompareMode { Frozen, diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 9e28878b..cdf12189 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -56,11 +56,12 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { _ch3: Option>, _ch4: Option>, freq: Hertz, + counting_mode: CountingMode, ) -> Self { - Self::new_inner(tim, freq) + Self::new_inner(tim, freq, counting_mode) } - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { + fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz, counting_mode: CountingMode) -> Self { into_ref!(tim); T::enable(); @@ -69,6 +70,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { let mut this = Self { inner: tim }; this.inner.set_frequency(freq); + this.inner.set_counting_mode(counting_mode); this.inner.start(); this.inner.enable_outputs(true); From 05a9b113165dd1b124e7a0ac6462b6850bebedf2 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Sun, 1 Oct 2023 23:39:53 +0200 Subject: [PATCH 002/188] Fix examples --- examples/stm32f4/src/bin/pwm.rs | 2 +- examples/stm32f4/src/bin/pwm_complementary.rs | 1 + examples/stm32g4/src/bin/pwm.rs | 2 +- examples/stm32h7/src/bin/pwm.rs | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs index 1013a844..139b8de7 100644 --- a/examples/stm32f4/src/bin/pwm.rs +++ b/examples/stm32f4/src/bin/pwm.rs @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull); - let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); + let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10), Default::default()); let max = pwm.get_max_duty(); pwm.enable(Channel::Ch1); diff --git a/examples/stm32f4/src/bin/pwm_complementary.rs b/examples/stm32f4/src/bin/pwm_complementary.rs index 83a3c753..dabbbf9a 100644 --- a/examples/stm32f4/src/bin/pwm_complementary.rs +++ b/examples/stm32f4/src/bin/pwm_complementary.rs @@ -30,6 +30,7 @@ async fn main(_spawner: Spawner) { None, None, khz(10), + Default::default(), ); let max = pwm.get_max_duty(); diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs index 01e9cb47..c62b11d1 100644 --- a/examples/stm32g4/src/bin/pwm.rs +++ b/examples/stm32g4/src/bin/pwm.rs @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let ch1 = PwmPin::new_ch1(p.PC0, OutputType::PushPull); - let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); + let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10), Default::default()); let max = pwm.get_max_duty(); pwm.enable(Channel::Ch1); diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs index 5c8e57aa..84e7df26 100644 --- a/examples/stm32h7/src/bin/pwm.rs +++ b/examples/stm32h7/src/bin/pwm.rs @@ -39,7 +39,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let ch1 = PwmPin::new_ch1(p.PA6, OutputType::PushPull); - let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10)); + let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10), Default::default()); let max = pwm.get_max_duty(); pwm.enable(Channel::Ch1); From 137e47f98db224815231460766386d9a88b3d88a Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 2 Oct 2023 21:14:44 +0200 Subject: [PATCH 003/188] Do affect the frequency --- embassy-stm32/src/timer/complementary_pwm.rs | 9 ++++- embassy-stm32/src/timer/mod.rs | 41 ++++++++++++++++++-- embassy-stm32/src/timer/simple_pwm.rs | 9 ++++- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index bfe5137e..72ff84b6 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -70,8 +70,8 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { let mut this = Self { inner: tim }; - this.inner.set_frequency(freq); this.inner.set_counting_mode(counting_mode); + this.set_freq(freq); this.inner.start(); this.inner.enable_outputs(true); @@ -98,7 +98,12 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { } pub fn set_freq(&mut self, freq: Hertz) { - self.inner.set_frequency(freq); + let multiplier = if self.inner.get_counting_mode().is_center_aligned() { + 2u8 + } else { + 1u8 + }; + self.inner.set_frequency(freq * multiplier); } pub fn get_max_duty(&self) -> u16 { diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 52d1dc11..b8e63288 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -76,7 +76,7 @@ pub(crate) mod sealed { fn regs_gp16() -> crate::pac::timer::TimGp16; fn set_counting_mode(&mut self, mode: CountingMode) { - let (cms, dir) = mode.values(); + let (cms, dir) = mode.into(); let timer_enabled = Self::regs().cr1().read().cen(); // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. @@ -87,6 +87,11 @@ pub(crate) mod sealed { Self::regs_gp16().cr1().modify(|r| r.set_cms(cms)) } + fn get_counting_mode(&self) -> CountingMode { + let cr1 = Self::regs_gp16().cr1().read(); + (cr1.cms(), cr1.dir()).into() + } + fn set_clock_division(&mut self, ckd: vals::Ckd) { Self::regs_gp16().cr1().modify(|r| r.set_ckd(ckd)); } @@ -273,6 +278,7 @@ impl From for stm32_metapac::timer::vals::CcmrInputCcs { } } +#[repr(u8)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub enum CountingMode { #[default] @@ -298,9 +304,26 @@ pub enum CountingMode { } impl CountingMode { - /// Get the register values to set the timer mode to the current variant - pub fn values(&self) -> (vals::Cms, vals::Dir) { + pub fn is_edge_aligned(&self) -> bool { match self { + CountingMode::EdgeAlignedUp | CountingMode::EdgeAlignedDown => true, + _ => false, + } + } + + pub fn is_center_aligned(&self) -> bool { + match self { + CountingMode::CenterAlignedDownInterrupts + | CountingMode::CenterAlignedUpInterrupts + | CountingMode::CenterAlignedBothInterrupts => true, + _ => false, + } + } +} + +impl From for (vals::Cms, vals::Dir) { + fn from(value: CountingMode) -> Self { + match value { CountingMode::EdgeAlignedUp => (vals::Cms::EDGEALIGNED, vals::Dir::UP), CountingMode::EdgeAlignedDown => (vals::Cms::EDGEALIGNED, vals::Dir::DOWN), CountingMode::CenterAlignedDownInterrupts => (vals::Cms::CENTERALIGNED1, vals::Dir::UP), @@ -310,6 +333,18 @@ impl CountingMode { } } +impl From<(vals::Cms, vals::Dir)> for CountingMode { + fn from(value: (vals::Cms, vals::Dir)) -> Self { + match value { + (vals::Cms::EDGEALIGNED, vals::Dir::UP) => CountingMode::EdgeAlignedUp, + (vals::Cms::EDGEALIGNED, vals::Dir::DOWN) => CountingMode::EdgeAlignedDown, + (vals::Cms::CENTERALIGNED1, _) => CountingMode::CenterAlignedDownInterrupts, + (vals::Cms::CENTERALIGNED2, _) => CountingMode::CenterAlignedUpInterrupts, + (vals::Cms::CENTERALIGNED3, _) => CountingMode::CenterAlignedBothInterrupts, + } + } +} + #[derive(Clone, Copy)] pub enum OutputCompareMode { Frozen, diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index cdf12189..b54f8cb0 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -69,8 +69,8 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { let mut this = Self { inner: tim }; - this.inner.set_frequency(freq); this.inner.set_counting_mode(counting_mode); + this.set_freq(freq); this.inner.start(); this.inner.enable_outputs(true); @@ -95,7 +95,12 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { } pub fn set_freq(&mut self, freq: Hertz) { - self.inner.set_frequency(freq); + let multiplier = if self.inner.get_counting_mode().is_center_aligned() { + 2u8 + } else { + 1u8 + }; + self.inner.set_frequency(freq * multiplier); } pub fn get_max_duty(&self) -> u16 { From a9dc887060244403a1fe65611a1210f506e2858a Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 2 Oct 2023 21:41:30 +0200 Subject: [PATCH 004/188] Added clarifying comment --- embassy-stm32/src/timer/mod.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index b8e63288..755c2780 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -29,10 +29,17 @@ pub(crate) mod sealed { Self::regs().cr1().modify(|r| r.set_cen(false)); } + /// Reset the counter value to 0 fn reset(&mut self) { Self::regs().cnt().write(|r| r.set_cnt(0)); } + /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. + /// + /// This means that in the default edge-aligned mode, + /// the timer counter will wrap around at the same frequency as is being set. + /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved + /// because it needs to count up and down. fn set_frequency(&mut self, frequency: Hertz) { let f = frequency.0; let timer_f = Self::frequency().0; @@ -515,9 +522,5 @@ foreach_interrupt! { crate::pac::$inst } } - - - - }; } From 62d6bb6c8a5cee402c917dbad5d3b7d900239aab Mon Sep 17 00:00:00 2001 From: Ilya Epifanov Date: Fri, 6 Oct 2023 14:29:12 +0200 Subject: [PATCH 005/188] added sampling frequency setting to adc capture methods on rp2040 --- embassy-rp/src/adc.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs index bac45574..5b913f15 100644 --- a/embassy-rp/src/adc.rs +++ b/embassy-rp/src/adc.rs @@ -213,6 +213,7 @@ impl<'d> Adc<'d, Async> { ch: &mut Channel<'_>, buf: &mut [W], fcs_err: bool, + div: u16, dma: impl Peripheral

, ) -> Result<(), Error> { let r = Self::regs(); @@ -258,6 +259,7 @@ impl<'d> Adc<'d, Async> { // start conversions and wait for dma to finish. we can't report errors early // because there's no interrupt to signal them, and inspecting every element // of the fifo is too costly to do here. + r.div().write_set(|w| w.set_int(div)); r.cs().write_set(|w| w.set_start_many(true)); dma.await; mem::drop(auto_reset); @@ -275,9 +277,10 @@ impl<'d> Adc<'d, Async> { &mut self, ch: &mut Channel<'_>, buf: &mut [S], + div: u16, dma: impl Peripheral

, ) -> Result<(), Error> { - self.read_many_inner(ch, buf, false, dma).await + self.read_many_inner(ch, buf, false, div, dma).await } #[inline] @@ -285,11 +288,12 @@ impl<'d> Adc<'d, Async> { &mut self, ch: &mut Channel<'_>, buf: &mut [Sample], + div: u16, dma: impl Peripheral

, ) { // errors are reported in individual samples let _ = self - .read_many_inner(ch, unsafe { mem::transmute::<_, &mut [u16]>(buf) }, true, dma) + .read_many_inner(ch, unsafe { mem::transmute::<_, &mut [u16]>(buf) }, true, div, dma) .await; } } From 0c97ce2fcc715ffe954d34bfa5b927038e913560 Mon Sep 17 00:00:00 2001 From: Ilya Epifanov Date: Mon, 9 Oct 2023 11:00:40 +0200 Subject: [PATCH 006/188] fixed rp adc tests --- tests/rp/src/bin/adc.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs index 0250fd5f..0c04a55f 100644 --- a/tests/rp/src/bin/adc.rs +++ b/tests/rp/src/bin/adc.rs @@ -93,6 +93,7 @@ async fn main(_spawner: Spawner) { adc.read_many( &mut Channel::new_pin(&mut p.PIN_29, Pull::Down), &mut low, + 1, &mut p.DMA_CH0, ) .await @@ -100,12 +101,18 @@ async fn main(_spawner: Spawner) { adc.read_many( &mut Channel::new_pin(&mut p.PIN_29, Pull::None), &mut none, + 1, &mut p.DMA_CH0, ) .await .unwrap(); - adc.read_many_raw(&mut Channel::new_pin(&mut p.PIN_29, Pull::Up), &mut up, &mut p.DMA_CH0) - .await; + adc.read_many_raw( + &mut Channel::new_pin(&mut p.PIN_29, Pull::Up), + &mut up, + 1, + &mut p.DMA_CH0, + ) + .await; defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16)); defmt::assert!(up.iter().all(|s| s.good())); defmt::assert!(none.iter().zip(up.iter()).all(|(n, u)| (*n as u16) < u.value())); @@ -115,6 +122,7 @@ async fn main(_spawner: Spawner) { adc.read_many( &mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), &mut temp, + 1, &mut p.DMA_CH0, ) .await From c8fdbe19f91a02b86008c73ba021d8e7d2f4986b Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 15 Oct 2023 00:31:32 +0100 Subject: [PATCH 007/188] time: Add convenience methods for Timer::after_secs/millis/micros/ticks --- embassy-time/src/timer.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/embassy-time/src/timer.rs b/embassy-time/src/timer.rs index 07ddf473..ee2423da 100644 --- a/embassy-time/src/timer.rs +++ b/embassy-time/src/timer.rs @@ -64,6 +64,42 @@ impl Timer { yielded_once: false, } } + + /// Expire after the specified number of ticks. + /// + /// This method is a convenience wrapper for calling `Timer::after(Duration::from_ticks())`. + /// For more details, refer to [`Timer::after()`] and [`Duration::from_ticks()`]. + #[inline] + pub fn after_ticks(ticks: u64) -> Self { + Self::after(Duration::from_ticks(ticks)) + } + + /// Expire after the specified number of microseconds. + /// + /// This method is a convenience wrapper for calling `Timer::after(Duration::from_micros())`. + /// For more details, refer to [`Timer::after()`] and [`Duration::from_micros()`]. + #[inline] + pub fn after_micros(micros: u64) -> Self { + Self::after(Duration::from_micros(micros)) + } + + /// Expire after the specified number of milliseconds. + /// + /// This method is a convenience wrapper for calling `Timer::after(Duration::from_millis())`. + /// For more details, refer to [`Timer::after`] and [`Duration::from_millis()`]. + #[inline] + pub fn after_millis(millis: u64) -> Self { + Self::after(Duration::from_millis(millis)) + } + + /// Expire after the specified number of seconds. + /// + /// This method is a convenience wrapper for calling `Timer::after(Duration::from_secs())`. + /// For more details, refer to [`Timer::after`] and [`Duration::from_secs()`]. + #[inline] + pub fn after_secs(secs: u64) -> Self { + Self::after(Duration::from_secs(secs)) + } } impl Unpin for Timer {} From 7559f9e5834799b041d899767ef4305dcfdf0181 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 15 Oct 2023 00:45:42 +0100 Subject: [PATCH 008/188] time: Update documentation to use new after_x convenience methods --- README.md | 4 ++-- docs/modules/ROOT/pages/runtime.adoc | 2 +- embassy-executor/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c4c01dfb..e5a97062 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,9 @@ async fn blink(pin: AnyPin) { loop { // Timekeeping is globally available, no need to mess with hardware timers. led.set_high(); - Timer::after(Duration::from_millis(150)).await; + Timer::after_millis(150).await; led.set_low(); - Timer::after(Duration::from_millis(150)).await; + Timer::after_millis(150).await; } } diff --git a/docs/modules/ROOT/pages/runtime.adoc b/docs/modules/ROOT/pages/runtime.adoc index cb8afef2..8f4921f6 100644 --- a/docs/modules/ROOT/pages/runtime.adoc +++ b/docs/modules/ROOT/pages/runtime.adoc @@ -6,7 +6,7 @@ The Embassy executor is an async/await executor designed for embedded usage alon * No `alloc`, no heap needed. Task are statically allocated. * No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. -* Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`. +* Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. * 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. diff --git a/embassy-executor/README.md b/embassy-executor/README.md index 47d0cb8a..3c1448a1 100644 --- a/embassy-executor/README.md +++ b/embassy-executor/README.md @@ -4,7 +4,7 @@ An async/await executor designed for embedded usage. - No `alloc`, no heap needed. Task futures are statically allocated. - No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. -- Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`. +- Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. - 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. From 3bfbf2697f591d9d26ebd676a4df36ac443054ba Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 15 Oct 2023 01:48:27 +0200 Subject: [PATCH 009/188] stm32/rcc: remove unused lse/lsi fields in h7 --- embassy-stm32/src/rcc/h.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index a24f4d4e..9132df7e 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -163,10 +163,6 @@ 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, @@ -199,10 +195,6 @@ 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, From 0621e957a0ddc7010d46b3ea3ddc8b9852bc8333 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 15 Oct 2023 00:57:25 +0100 Subject: [PATCH 010/188] time: Update examples, tests, and other code to use new Timer::after_x convenience methods --- cyw43/src/bus.rs | 6 +-- cyw43/src/control.rs | 24 +++++----- cyw43/src/runner.rs | 4 +- .../src/shared_bus/asynch/spi.rs | 8 +--- embassy-lora/src/lib.rs | 2 +- embassy-net-adin1110/src/lib.rs | 6 +-- embassy-net-esp-hosted/src/lib.rs | 4 +- embassy-net-wiznet/src/lib.rs | 6 +-- embassy-rp/src/uart/buffered.rs | 4 +- embassy-rp/src/uart/mod.rs | 4 +- embassy-time/src/delay.rs | 4 +- examples/boot/application/nrf/src/bin/b.rs | 6 +-- examples/boot/application/rp/src/bin/a.rs | 4 +- examples/boot/application/rp/src/bin/b.rs | 6 +-- .../boot/application/stm32f3/src/bin/b.rs | 6 +-- .../boot/application/stm32f7/src/bin/b.rs | 8 ++-- .../boot/application/stm32h7/src/bin/b.rs | 8 ++-- .../boot/application/stm32l0/src/bin/a.rs | 4 +- .../boot/application/stm32l0/src/bin/b.rs | 6 +-- .../boot/application/stm32l1/src/bin/a.rs | 4 +- .../boot/application/stm32l1/src/bin/b.rs | 6 +-- .../boot/application/stm32l4/src/bin/b.rs | 6 +-- .../boot/application/stm32wl/src/bin/b.rs | 6 +-- examples/nrf-rtos-trace/src/bin/rtos_trace.rs | 4 +- examples/nrf52840-rtic/src/bin/blinky.rs | 6 +-- examples/nrf52840/src/bin/blinky.rs | 6 +-- examples/nrf52840/src/bin/channel.rs | 6 +-- .../src/bin/channel_sender_receiver.rs | 6 +-- .../src/bin/executor_fairness_test.rs | 4 +- examples/nrf52840/src/bin/lora_cad.rs | 6 +-- examples/nrf52840/src/bin/lora_p2p_receive.rs | 6 +-- .../src/bin/lora_p2p_receive_duty_cycle.rs | 6 +-- .../src/bin/manually_create_executor.rs | 6 +-- examples/nrf52840/src/bin/multiprio.rs | 8 ++-- examples/nrf52840/src/bin/mutex.rs | 8 ++-- examples/nrf52840/src/bin/nvmc.rs | 4 +- examples/nrf52840/src/bin/pdm.rs | 6 +-- examples/nrf52840/src/bin/pubsub.rs | 8 ++-- examples/nrf52840/src/bin/pwm.rs | 4 +- .../nrf52840/src/bin/pwm_double_sequence.rs | 4 +- examples/nrf52840/src/bin/pwm_sequence.rs | 4 +- .../nrf52840/src/bin/pwm_sequence_ws2812b.rs | 4 +- examples/nrf52840/src/bin/pwm_servo.rs | 14 +++--- examples/nrf52840/src/bin/qspi_lowpower.rs | 4 +- examples/nrf52840/src/bin/raw_spawn.rs | 6 +-- examples/nrf52840/src/bin/saadc.rs | 4 +- examples/nrf52840/src/bin/saadc_continuous.rs | 3 +- examples/nrf52840/src/bin/self_spawn.rs | 4 +- .../src/bin/self_spawn_current_executor.rs | 4 +- examples/nrf52840/src/bin/temp.rs | 4 +- examples/nrf52840/src/bin/timer.rs | 6 +-- examples/nrf52840/src/bin/twim_lowpower.rs | 4 +- examples/nrf52840/src/bin/usb_hid_mouse.rs | 4 +- examples/nrf5340/src/bin/blinky.rs | 6 +-- examples/rp/src/bin/adc.rs | 4 +- examples/rp/src/bin/blinky.rs | 6 +-- .../rp/src/bin/ethernet_w5500_tcp_client.rs | 2 +- examples/rp/src/bin/flash.rs | 4 +- examples/rp/src/bin/gpio_async.rs | 4 +- examples/rp/src/bin/gpout.rs | 6 +-- examples/rp/src/bin/i2c_async.rs | 4 +- examples/rp/src/bin/i2c_blocking.rs | 4 +- examples/rp/src/bin/i2c_slave.rs | 6 +-- examples/rp/src/bin/lora_p2p_receive.rs | 4 +- .../rp/src/bin/lora_p2p_send_multicore.rs | 4 +- examples/rp/src/bin/multicore.rs | 6 +-- examples/rp/src/bin/multiprio.rs | 8 ++-- examples/rp/src/bin/pio_hd44780.rs | 4 +- examples/rp/src/bin/pio_ws2812.rs | 4 +- examples/rp/src/bin/pwm.rs | 4 +- examples/rp/src/bin/rtc.rs | 6 +-- examples/rp/src/bin/spi_async.rs | 4 +- examples/rp/src/bin/uart_buffered_split.rs | 4 +- examples/rp/src/bin/uart_unidir.rs | 4 +- examples/rp/src/bin/usb_logger.rs | 4 +- examples/rp/src/bin/watchdog.rs | 10 ++--- examples/rp/src/bin/wifi_tcp_server.rs | 2 +- examples/std/src/bin/tcp_accept.rs | 2 +- examples/std/src/bin/tick.rs | 4 +- examples/stm32c0/src/bin/blinky.rs | 6 +-- examples/stm32f0/src/bin/adc.rs | 4 +- examples/stm32f0/src/bin/blinky.rs | 6 +-- .../src/bin/button_controlled_blink.rs | 4 +- examples/stm32f0/src/bin/hello.rs | 4 +- examples/stm32f0/src/bin/multiprio.rs | 8 ++-- examples/stm32f0/src/bin/wdg.rs | 4 +- examples/stm32f1/src/bin/adc.rs | 4 +- examples/stm32f1/src/bin/blinky.rs | 6 +-- examples/stm32f1/src/bin/hello.rs | 4 +- examples/stm32f1/src/bin/usb_serial.rs | 4 +- examples/stm32f2/src/bin/blinky.rs | 6 +-- examples/stm32f2/src/bin/pll.rs | 4 +- examples/stm32f3/src/bin/blinky.rs | 6 +-- examples/stm32f3/src/bin/button_events.rs | 4 +- examples/stm32f3/src/bin/hello.rs | 4 +- examples/stm32f3/src/bin/multiprio.rs | 8 ++-- examples/stm32f3/src/bin/usb_serial.rs | 4 +- examples/stm32f334/src/bin/adc.rs | 4 +- examples/stm32f334/src/bin/button.rs | 6 +-- examples/stm32f334/src/bin/hello.rs | 4 +- examples/stm32f334/src/bin/opamp.rs | 4 +- examples/stm32f334/src/bin/pwm.rs | 6 +-- examples/stm32f4/src/bin/adc.rs | 4 +- examples/stm32f4/src/bin/blinky.rs | 6 +-- examples/stm32f4/src/bin/eth.rs | 6 +-- examples/stm32f4/src/bin/flash_async.rs | 6 +-- examples/stm32f4/src/bin/hello.rs | 4 +- examples/stm32f4/src/bin/mco.rs | 6 +-- examples/stm32f4/src/bin/multiprio.rs | 8 ++-- examples/stm32f4/src/bin/pwm.rs | 10 ++--- examples/stm32f4/src/bin/pwm_complementary.rs | 10 ++--- examples/stm32f4/src/bin/rtc.rs | 4 +- examples/stm32f4/src/bin/wdt.rs | 6 +-- examples/stm32f7/src/bin/adc.rs | 4 +- examples/stm32f7/src/bin/blinky.rs | 6 +-- examples/stm32f7/src/bin/can.rs | 2 +- examples/stm32f7/src/bin/eth.rs | 6 +-- examples/stm32f7/src/bin/flash.rs | 4 +- examples/stm32f7/src/bin/hello.rs | 4 +- examples/stm32g0/src/bin/blinky.rs | 6 +-- examples/stm32g0/src/bin/spi_neopixel.rs | 6 +-- examples/stm32g4/src/bin/adc.rs | 4 +- examples/stm32g4/src/bin/blinky.rs | 6 +-- examples/stm32g4/src/bin/pll.rs | 4 +- examples/stm32g4/src/bin/pwm.rs | 10 ++--- examples/stm32h5/src/bin/blinky.rs | 6 +-- examples/stm32h5/src/bin/eth.rs | 6 +-- examples/stm32h7/src/bin/adc.rs | 4 +- examples/stm32h7/src/bin/blinky.rs | 6 +-- examples/stm32h7/src/bin/camera.rs | 12 ++--- examples/stm32h7/src/bin/eth.rs | 6 +-- examples/stm32h7/src/bin/eth_client.rs | 6 +-- examples/stm32h7/src/bin/flash.rs | 4 +- examples/stm32h7/src/bin/fmc.rs | 4 +- .../stm32h7/src/bin/low_level_timer_api.rs | 10 ++--- examples/stm32h7/src/bin/mco.rs | 6 +-- examples/stm32h7/src/bin/pwm.rs | 10 ++--- examples/stm32h7/src/bin/rtc.rs | 4 +- examples/stm32h7/src/bin/signal.rs | 4 +- examples/stm32h7/src/bin/wdg.rs | 4 +- examples/stm32l0/src/bin/blinky.rs | 6 +-- examples/stm32l0/src/bin/lora_cad.rs | 6 +-- examples/stm32l0/src/bin/lora_p2p_receive.rs | 6 +-- examples/stm32l0/src/bin/raw_spawn.rs | 6 +-- examples/stm32l1/src/bin/blinky.rs | 6 +-- examples/stm32l4/src/bin/blinky.rs | 6 +-- examples/stm32l4/src/bin/mco.rs | 6 +-- examples/stm32l4/src/bin/rtc.rs | 4 +- .../src/bin/spe_adin1110_http_server.rs | 4 +- examples/stm32l5/src/bin/usb_hid_mouse.rs | 4 +- examples/stm32u5/src/bin/blinky.rs | 6 +-- examples/stm32wb/src/bin/blinky.rs | 6 +-- examples/stm32wb/src/bin/tl_mbox.rs | 4 +- examples/stm32wba/src/bin/blinky.rs | 6 +-- examples/stm32wl/src/bin/blinky.rs | 6 +-- examples/stm32wl/src/bin/lora_p2p_receive.rs | 6 +-- examples/stm32wl/src/bin/rtc.rs | 4 +- examples/wasm/src/lib.rs | 4 +- tests/nrf/src/bin/buffered_uart_spam.rs | 4 +- tests/nrf/src/bin/timer.rs | 4 +- tests/perf-client/src/lib.rs | 2 +- tests/rp/src/bin/bootsel.rs | 4 +- tests/rp/src/bin/flash.rs | 4 +- tests/rp/src/bin/float.rs | 4 +- tests/rp/src/bin/gpio_async.rs | 12 ++--- tests/rp/src/bin/pwm.rs | 44 +++++++++---------- tests/rp/src/bin/uart.rs | 10 ++--- tests/rp/src/bin/uart_buffered.rs | 10 ++--- tests/rp/src/bin/uart_dma.rs | 12 ++--- tests/stm32/src/bin/dac.rs | 6 +-- tests/stm32/src/bin/rtc.rs | 4 +- tests/stm32/src/bin/stop.rs | 6 +-- tests/stm32/src/bin/timer.rs | 4 +- tests/stm32/src/bin/usart_rx_ringbuffered.rs | 8 ++-- 174 files changed, 496 insertions(+), 501 deletions(-) diff --git a/cyw43/src/bus.rs b/cyw43/src/bus.rs index 0b5632cf..01410903 100644 --- a/cyw43/src/bus.rs +++ b/cyw43/src/bus.rs @@ -1,5 +1,5 @@ use embassy_futures::yield_now; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_1::digital::OutputPin; use futures::FutureExt; @@ -51,9 +51,9 @@ where pub async fn init(&mut self) { // Reset self.pwr.set_low().unwrap(); - Timer::after(Duration::from_millis(20)).await; + Timer::after_millis(20).await; self.pwr.set_high().unwrap(); - Timer::after(Duration::from_millis(250)).await; + Timer::after_millis(250).await; while self .read32_swapped(REG_BUS_TEST_RO) diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index a6d1f0bf..2585b31d 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs @@ -2,7 +2,7 @@ use core::cmp::{max, min}; use ch::driver::LinkState; use embassy_net_driver_channel as ch; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; pub use crate::bus::SpiBusCyw43; use crate::consts::*; @@ -87,22 +87,22 @@ impl<'a> Control<'a> { self.set_iovar("country", &country_info.to_bytes()).await; // set country takes some time, next ioctls fail if we don't wait. - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; // Set antenna to chip antenna self.ioctl_set_u32(IOCTL_CMD_ANTDIV, 0, 0).await; self.set_iovar_u32("bus:txglom", 0).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; //self.set_iovar_u32("apsta", 1).await; // this crashes, also we already did it before...?? - //Timer::after(Duration::from_millis(100)).await; + //Timer::after_millis(100).await; self.set_iovar_u32("ampdu_ba_wsize", 8).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; self.set_iovar_u32("ampdu_mpdu", 4).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; //self.set_iovar_u32("ampdu_rx_factor", 0).await; // this crashes - //Timer::after(Duration::from_millis(100)).await; + //Timer::after_millis(100).await; // evts let mut evts = EventMask { @@ -121,17 +121,17 @@ impl<'a> Control<'a> { self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; // set wifi up self.up().await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; self.state_ch.set_ethernet_address(mac_addr); @@ -185,7 +185,7 @@ impl<'a> Control<'a> { self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await; self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; let mut pfi = PassphraseInfo { len: passphrase.len() as _, @@ -297,7 +297,7 @@ impl<'a> Control<'a> { if security != Security::OPEN { self.set_iovar_u32x2("bsscfg:wpa_auth", 0, 0x0084).await; // wpa_auth = WPA2_AUTH_PSK | WPA_AUTH_PSK - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; // Set passphrase let mut pfi = PassphraseInfo { diff --git a/cyw43/src/runner.rs b/cyw43/src/runner.rs index 1c187faa..83aee6b4 100644 --- a/cyw43/src/runner.rs +++ b/cyw43/src/runner.rs @@ -555,14 +555,14 @@ where self.bus.bp_write8(base + AI_RESETCTRL_OFFSET, 0).await; - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; self.bus .bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN) .await; let _ = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await; - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } async fn core_is_up(&mut self, core: Core) -> bool { diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index b2a9f1e3..5d3cf658 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs @@ -76,9 +76,7 @@ where #[cfg(not(feature = "time"))] Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), #[cfg(feature = "time")] - Operation::DelayUs(us) => { - embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await - } + Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await, } } }; @@ -143,9 +141,7 @@ where #[cfg(not(feature = "time"))] Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), #[cfg(feature = "time")] - Operation::DelayUs(us) => { - embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await - } + Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await, } } }; diff --git a/embassy-lora/src/lib.rs b/embassy-lora/src/lib.rs index 0a9cea16..5637802b 100644 --- a/embassy-lora/src/lib.rs +++ b/embassy-lora/src/lib.rs @@ -34,6 +34,6 @@ impl lorawan_device::async_device::radio::Timer for LoraTimer { } async fn delay_ms(&mut self, millis: u64) { - Timer::after(Duration::from_millis(millis)).await + Timer::after_millis(millis).await } } diff --git a/embassy-net-adin1110/src/lib.rs b/embassy-net-adin1110/src/lib.rs index 53f36128..edee3438 100644 --- a/embassy-net-adin1110/src/lib.rs +++ b/embassy-net-adin1110/src/lib.rs @@ -20,7 +20,7 @@ pub use crc32::ETH_FCS; use crc8::crc8; use embassy_futures::select::{select, Either}; use embassy_net_driver_channel as ch; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_1::digital::OutputPin; use embedded_hal_async::digital::Wait; use embedded_hal_async::spi::{Error, Operation, SpiDevice}; @@ -609,12 +609,12 @@ pub async fn new ! { debug!("resetting..."); self.reset.set_low().unwrap(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; self.reset.set_high().unwrap(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; let mut tx_buf = [0u8; MAX_SPI_BUFFER_SIZE]; let mut rx_buf = [0u8; MAX_SPI_BUFFER_SIZE]; diff --git a/embassy-net-wiznet/src/lib.rs b/embassy-net-wiznet/src/lib.rs index 3030dfb9..48d17cac 100644 --- a/embassy-net-wiznet/src/lib.rs +++ b/embassy-net-wiznet/src/lib.rs @@ -8,7 +8,7 @@ mod device; use embassy_futures::select::{select, Either}; use embassy_net_driver_channel as ch; use embassy_net_driver_channel::driver::LinkState; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal::digital::OutputPin; use embedded_hal_async::digital::Wait; use embedded_hal_async::spi::SpiDevice; @@ -95,12 +95,12 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevi // Reset the chip. reset.set_low().ok(); // Ensure the reset is registered. - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; reset.set_high().ok(); // Wait for PLL lock. Some chips are slower than others. // Slowest is w5100s which is 100ms, so let's just wait that. - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; let mac = WiznetDevice::new(spi_dev, mac_addr).await.unwrap(); diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index 645d703d..9f638761 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs @@ -5,7 +5,7 @@ use core::task::Poll; use atomic_polyfill::{AtomicU8, Ordering}; use embassy_hal_internal::atomic_ring_buffer::RingBuffer; use embassy_sync::waitqueue::AtomicWaker; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use super::*; use crate::clocks::clk_peri_freq; @@ -435,7 +435,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { Self::flush().await.unwrap(); while self.busy() {} regs.uartlcr_h().write_set(|w| w.set_brk(true)); - Timer::after(Duration::from_micros(wait_usecs)).await; + Timer::after_micros(wait_usecs).await; regs.uartlcr_h().write_clear(|w| w.set_brk(true)); } } diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 202b0883..461986c8 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -6,7 +6,7 @@ use atomic_polyfill::{AtomicU16, Ordering}; use embassy_futures::select::{select, Either}; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use pac::uart::regs::Uartris; use crate::clocks::clk_peri_freq; @@ -187,7 +187,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { self.blocking_flush().unwrap(); while self.busy() {} regs.uartlcr_h().write_set(|w| w.set_brk(true)); - Timer::after(Duration::from_micros(wait_usecs)).await; + Timer::after_micros(wait_usecs).await; regs.uartlcr_h().write_clear(|w| w.set_brk(true)); } } diff --git a/embassy-time/src/delay.rs b/embassy-time/src/delay.rs index cf191872..be962747 100644 --- a/embassy-time/src/delay.rs +++ b/embassy-time/src/delay.rs @@ -36,11 +36,11 @@ mod eha { impl embedded_hal_async::delay::DelayUs for Delay { async fn delay_us(&mut self, micros: u32) { - Timer::after(Duration::from_micros(micros as _)).await + Timer::after_micros(micros as _).await } async fn delay_ms(&mut self, millis: u32) { - Timer::after(Duration::from_millis(millis as _)).await + Timer::after_millis(millis as _).await } } } diff --git a/examples/boot/application/nrf/src/bin/b.rs b/examples/boot/application/nrf/src/bin/b.rs index 15ebce5f..a88c3c56 100644 --- a/examples/boot/application/nrf/src/bin/b.rs +++ b/examples/boot/application/nrf/src/bin/b.rs @@ -5,7 +5,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -19,8 +19,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/boot/application/rp/src/bin/a.rs b/examples/boot/application/rp/src/bin/a.rs index a4602a7e..6fd5d7f6 100644 --- a/examples/boot/application/rp/src/bin/a.rs +++ b/examples/boot/application/rp/src/bin/a.rs @@ -41,7 +41,7 @@ async fn main(_s: Spawner) { let mut aligned = AlignedBuffer([0; 1]); let mut updater = BlockingFirmwareUpdater::new(config, &mut aligned.0); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; watchdog.feed(); led.set_high(); let mut offset = 0; @@ -61,7 +61,7 @@ async fn main(_s: Spawner) { watchdog.feed(); defmt::info!("firmware written, marking update"); updater.mark_updated().unwrap(); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; led.set_low(); defmt::info!("update marked, resetting"); cortex_m::peripheral::SCB::sys_reset(); diff --git a/examples/boot/application/rp/src/bin/b.rs b/examples/boot/application/rp/src/bin/b.rs index 47dec329..1eca5b4a 100644 --- a/examples/boot/application/rp/src/bin/b.rs +++ b/examples/boot/application/rp/src/bin/b.rs @@ -4,7 +4,7 @@ use embassy_executor::Spawner; use embassy_rp::gpio; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use gpio::{Level, Output}; use {defmt_rtt as _, panic_reset as _}; @@ -15,9 +15,9 @@ async fn main(_s: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; led.set_low(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/boot/application/stm32f3/src/bin/b.rs b/examples/boot/application/stm32f3/src/bin/b.rs index a5862b1b..8411f384 100644 --- a/examples/boot/application/stm32f3/src/bin/b.rs +++ b/examples/boot/application/stm32f3/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32f7/src/bin/b.rs b/examples/boot/application/stm32f7/src/bin/b.rs index 16c94d84..4c2ad06a 100644 --- a/examples/boot/application/stm32f7/src/bin/b.rs +++ b/examples/boot/application/stm32f7/src/bin/b.rs @@ -6,21 +6,21 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut led = Output::new(p.PB7, Level::High, Speed::Low); led.set_high(); loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32h7/src/bin/b.rs b/examples/boot/application/stm32h7/src/bin/b.rs index 34799279..5c03e2d0 100644 --- a/examples/boot/application/stm32h7/src/bin/b.rs +++ b/examples/boot/application/stm32h7/src/bin/b.rs @@ -6,21 +6,21 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut led = Output::new(p.PB14, Level::High, Speed::Low); led.set_high(); loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs index b4cdcd44..42e1a71e 100644 --- a/examples/boot/application/stm32l0/src/bin/a.rs +++ b/examples/boot/application/stm32l0/src/bin/a.rs @@ -11,7 +11,7 @@ use embassy_stm32::exti::ExtiInput; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embassy_sync::mutex::Mutex; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[cfg(feature = "skip-include")] @@ -46,6 +46,6 @@ async fn main(_spawner: Spawner) { updater.mark_updated().await.unwrap(); led.set_low(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; cortex_m::peripheral::SCB::sys_reset(); } diff --git a/examples/boot/application/stm32l0/src/bin/b.rs b/examples/boot/application/stm32l0/src/bin/b.rs index ee40274f..52d42395 100644 --- a/examples/boot/application/stm32l0/src/bin/b.rs +++ b/examples/boot/application/stm32l0/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs index b4cdcd44..42e1a71e 100644 --- a/examples/boot/application/stm32l1/src/bin/a.rs +++ b/examples/boot/application/stm32l1/src/bin/a.rs @@ -11,7 +11,7 @@ use embassy_stm32::exti::ExtiInput; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embassy_sync::mutex::Mutex; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[cfg(feature = "skip-include")] @@ -46,6 +46,6 @@ async fn main(_spawner: Spawner) { updater.mark_updated().await.unwrap(); led.set_low(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; cortex_m::peripheral::SCB::sys_reset(); } diff --git a/examples/boot/application/stm32l1/src/bin/b.rs b/examples/boot/application/stm32l1/src/bin/b.rs index ee40274f..52d42395 100644 --- a/examples/boot/application/stm32l1/src/bin/b.rs +++ b/examples/boot/application/stm32l1/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32l4/src/bin/b.rs b/examples/boot/application/stm32l4/src/bin/b.rs index a5862b1b..8411f384 100644 --- a/examples/boot/application/stm32l4/src/bin/b.rs +++ b/examples/boot/application/stm32l4/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32wl/src/bin/b.rs b/examples/boot/application/stm32wl/src/bin/b.rs index f9f0ffc6..1ca3c6ea 100644 --- a/examples/boot/application/stm32wl/src/bin/b.rs +++ b/examples/boot/application/stm32wl/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/nrf-rtos-trace/src/bin/rtos_trace.rs b/examples/nrf-rtos-trace/src/bin/rtos_trace.rs index cf8b2f80..88837569 100644 --- a/examples/nrf-rtos-trace/src/bin/rtos_trace.rs +++ b/examples/nrf-rtos-trace/src/bin/rtos_trace.rs @@ -6,7 +6,7 @@ use core::future::poll_fn; use core::task::Poll; use embassy_executor::Spawner; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; #[cfg(feature = "log")] use log::*; use panic_probe as _; @@ -34,7 +34,7 @@ async fn run1() { info!("DING DONG"); #[cfg(not(feature = "log"))] rtos_trace::trace::marker(13); - Timer::after(Duration::from_ticks(16000)).await; + Timer::after_ticks(16000).await; } } diff --git a/examples/nrf52840-rtic/src/bin/blinky.rs b/examples/nrf52840-rtic/src/bin/blinky.rs index a682c193..060bb9eb 100644 --- a/examples/nrf52840-rtic/src/bin/blinky.rs +++ b/examples/nrf52840-rtic/src/bin/blinky.rs @@ -9,7 +9,7 @@ mod app { use defmt::info; use embassy_nrf::gpio::{Level, Output, OutputDrive}; use embassy_nrf::peripherals; - use embassy_time::{Duration, Timer}; + use embassy_time::Timer; #[shared] struct Shared {} @@ -34,10 +34,10 @@ mod app { loop { info!("off!"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("on!"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } } diff --git a/examples/nrf52840/src/bin/blinky.rs b/examples/nrf52840/src/bin/blinky.rs index 513f6cd8..d3d1a712 100644 --- a/examples/nrf52840/src/bin/blinky.rs +++ b/examples/nrf52840/src/bin/blinky.rs @@ -4,7 +4,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,8 +14,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/nrf52840/src/bin/channel.rs b/examples/nrf52840/src/bin/channel.rs index bd9c909d..d3c7b47d 100644 --- a/examples/nrf52840/src/bin/channel.rs +++ b/examples/nrf52840/src/bin/channel.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; enum LedState { @@ -21,9 +21,9 @@ static CHANNEL: Channel = Channel::new(); async fn my_task() { loop { CHANNEL.send(LedState::On).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; CHANNEL.send(LedState::Off).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/channel_sender_receiver.rs b/examples/nrf52840/src/bin/channel_sender_receiver.rs index ec4f1d80..79d2c404 100644 --- a/examples/nrf52840/src/bin/channel_sender_receiver.rs +++ b/examples/nrf52840/src/bin/channel_sender_receiver.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::channel::{Channel, Receiver, Sender}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -22,9 +22,9 @@ static CHANNEL: StaticCell> = StaticCell::new async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) { loop { sender.send(LedState::On).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; sender.send(LedState::Off).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/executor_fairness_test.rs b/examples/nrf52840/src/bin/executor_fairness_test.rs index 2a28f276..f111b272 100644 --- a/examples/nrf52840/src/bin/executor_fairness_test.rs +++ b/examples/nrf52840/src/bin/executor_fairness_test.rs @@ -7,14 +7,14 @@ use core::task::Poll; use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] async fn run1() { loop { info!("DING DONG"); - Timer::after(Duration::from_ticks(16000)).await; + Timer::after_ticks(16000).await; } } diff --git a/examples/nrf52840/src/bin/lora_cad.rs b/examples/nrf52840/src/bin/lora_cad.rs index 3a98133c..38e6d619 100644 --- a/examples/nrf52840/src/bin/lora_cad.rs +++ b/examples/nrf52840/src/bin/lora_cad.rs @@ -11,7 +11,7 @@ use embassy_executor::Spawner; use embassy_lora::iv::GenericSx126xInterfaceVariant; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; use embassy_nrf::{bind_interrupts, peripherals, spim}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mdltn_params = { @@ -89,7 +89,7 @@ async fn main(_spawner: Spawner) { info!("cad successful without activity detected") } debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } Err(err) => info!("cad unsuccessful = {}", err), diff --git a/examples/nrf52840/src/bin/lora_p2p_receive.rs b/examples/nrf52840/src/bin/lora_p2p_receive.rs index 1d293c6b..4f41e124 100644 --- a/examples/nrf52840/src/bin/lora_p2p_receive.rs +++ b/examples/nrf52840/src/bin/lora_p2p_receive.rs @@ -11,7 +11,7 @@ use embassy_executor::Spawner; use embassy_lora::iv::GenericSx126xInterfaceVariant; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; use embassy_nrf::{bind_interrupts, peripherals, spim}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mut receiving_buffer = [00u8; 100]; @@ -107,7 +107,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet"); diff --git a/examples/nrf52840/src/bin/lora_p2p_receive_duty_cycle.rs b/examples/nrf52840/src/bin/lora_p2p_receive_duty_cycle.rs index eee4d20e..3d34f6ae 100644 --- a/examples/nrf52840/src/bin/lora_p2p_receive_duty_cycle.rs +++ b/examples/nrf52840/src/bin/lora_p2p_receive_duty_cycle.rs @@ -11,7 +11,7 @@ use embassy_executor::Spawner; use embassy_lora::iv::GenericSx126xInterfaceVariant; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; use embassy_nrf::{bind_interrupts, peripherals, spim}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mut receiving_buffer = [00u8; 100]; @@ -116,7 +116,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet") diff --git a/examples/nrf52840/src/bin/manually_create_executor.rs b/examples/nrf52840/src/bin/manually_create_executor.rs index 12ce660f..80364d34 100644 --- a/examples/nrf52840/src/bin/manually_create_executor.rs +++ b/examples/nrf52840/src/bin/manually_create_executor.rs @@ -8,7 +8,7 @@ use cortex_m_rt::entry; use defmt::{info, unwrap}; use embassy_executor::Executor; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -16,7 +16,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run1() { loop { info!("BIG INFREQUENT TICK"); - Timer::after(Duration::from_ticks(64000)).await; + Timer::after_ticks(64000).await; } } @@ -24,7 +24,7 @@ async fn run1() { async fn run2() { loop { info!("tick"); - Timer::after(Duration::from_ticks(13000)).await; + Timer::after_ticks(13000).await; } } diff --git a/examples/nrf52840/src/bin/multiprio.rs b/examples/nrf52840/src/bin/multiprio.rs index aab81911..352f62bf 100644 --- a/examples/nrf52840/src/bin/multiprio.rs +++ b/examples/nrf52840/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::{info, unwrap}; use embassy_executor::{Executor, InterruptExecutor}; use embassy_nrf::interrupt; use embassy_nrf::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { info!(" [high] tick!"); - Timer::after(Duration::from_ticks(27374)).await; + Timer::after_ticks(27374).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() / 33; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(23421)).await; + Timer::after_ticks(23421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() / 33; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(32983)).await; + Timer::after_ticks(32983).await; } } diff --git a/examples/nrf52840/src/bin/mutex.rs b/examples/nrf52840/src/bin/mutex.rs index c402c6ba..11b47d99 100644 --- a/examples/nrf52840/src/bin/mutex.rs +++ b/examples/nrf52840/src/bin/mutex.rs @@ -6,7 +6,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::mutex::Mutex; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; static MUTEX: Mutex = Mutex::new(0); @@ -20,11 +20,11 @@ async fn my_task() { *m += 1000; // Hold the mutex for a long time. - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("end long operation: count = {}", *m); } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } @@ -34,7 +34,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(my_task())); loop { - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut m = MUTEX.lock().await; *m += 1; info!("short operation: count = {}", *m); diff --git a/examples/nrf52840/src/bin/nvmc.rs b/examples/nrf52840/src/bin/nvmc.rs index 31c6fe4b..62482986 100644 --- a/examples/nrf52840/src/bin/nvmc.rs +++ b/examples/nrf52840/src/bin/nvmc.rs @@ -5,7 +5,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_nrf::nvmc::Nvmc; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; use {defmt_rtt as _, panic_probe as _}; @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { info!("Hello NVMC!"); // probe-rs run breaks without this, I'm not sure why. - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; let mut f = Nvmc::new(p.NVMC); const ADDR: u32 = 0x80000; diff --git a/examples/nrf52840/src/bin/pdm.rs b/examples/nrf52840/src/bin/pdm.rs index 444b9137..bff32397 100644 --- a/examples/nrf52840/src/bin/pdm.rs +++ b/examples/nrf52840/src/bin/pdm.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_nrf::pdm::{self, Config, Pdm}; use embassy_nrf::{bind_interrupts, peripherals}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use fixed::types::I7F1; use num_integer::Roots; use {defmt_rtt as _, panic_probe as _}; @@ -28,7 +28,7 @@ async fn main(_p: Spawner) { pdm.start().await; // wait some time till the microphon settled - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; const SAMPLES: usize = 2048; let mut buf = [0i16; SAMPLES]; @@ -51,7 +51,7 @@ async fn main(_p: Spawner) { info!("samples: {:?}", &buf); pdm.stop().await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } } diff --git a/examples/nrf52840/src/bin/pubsub.rs b/examples/nrf52840/src/bin/pubsub.rs index cca60ebc..17d90222 100644 --- a/examples/nrf52840/src/bin/pubsub.rs +++ b/examples/nrf52840/src/bin/pubsub.rs @@ -6,7 +6,7 @@ use defmt::unwrap; use embassy_executor::Spawner; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::pubsub::{DynSubscriber, PubSubChannel, Subscriber}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; /// Create the message bus. It has a queue of 4, supports 3 subscribers and 1 publisher @@ -39,7 +39,7 @@ async fn main(spawner: Spawner) { let mut index = 0; loop { - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; let message = match index % 3 { 0 => Message::A, @@ -81,7 +81,7 @@ async fn fast_logger(mut messages: Subscriber<'static, ThreadModeRawMutex, Messa async fn slow_logger(mut messages: DynSubscriber<'static, Message>) { loop { // Do some work - Timer::after(Duration::from_millis(2000)).await; + Timer::after_millis(2000).await; // If the publisher has used the `publish_immediate` function, then we may receive a lag message here let message = messages.next_message().await; @@ -98,7 +98,7 @@ async fn slow_logger(mut messages: DynSubscriber<'static, Message>) { async fn slow_logger_pure(mut messages: DynSubscriber<'static, Message>) { loop { // Do some work - Timer::after(Duration::from_millis(2000)).await; + Timer::after_millis(2000).await; // Instead of receiving lags here, we just ignore that and read the next message let message = messages.next_message_pure().await; diff --git a/examples/nrf52840/src/bin/pwm.rs b/examples/nrf52840/src/bin/pwm.rs index 1698c0bc..9750935c 100644 --- a/examples/nrf52840/src/bin/pwm.rs +++ b/examples/nrf52840/src/bin/pwm.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_nrf::pwm::{Prescaler, SimplePwm}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // for i in range(1024): print(int((math.sin(i/512*math.pi)*0.4+0.5)**2*32767), ', ', end='') @@ -84,6 +84,6 @@ async fn main(_spawner: Spawner) { pwm.set_duty(1, DUTY[(i + 256) % 1024]); pwm.set_duty(2, DUTY[(i + 512) % 1024]); pwm.set_duty(3, DUTY[(i + 768) % 1024]); - Timer::after(Duration::from_millis(3)).await; + Timer::after_millis(3).await; } } diff --git a/examples/nrf52840/src/bin/pwm_double_sequence.rs b/examples/nrf52840/src/bin/pwm_double_sequence.rs index 16e50e90..1bfe6e15 100644 --- a/examples/nrf52840/src/bin/pwm_double_sequence.rs +++ b/examples/nrf52840/src/bin/pwm_double_sequence.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_nrf::pwm::{ Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, Sequencer, StartSequence, }; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -36,6 +36,6 @@ async fn main(_spawner: Spawner) { // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped // when it goes out of scope - Timer::after(Duration::from_millis(40000)).await; + Timer::after_millis(40000).await; info!("pwm stopped early!"); } diff --git a/examples/nrf52840/src/bin/pwm_sequence.rs b/examples/nrf52840/src/bin/pwm_sequence.rs index b9aca9aa..f282cf91 100644 --- a/examples/nrf52840/src/bin/pwm_sequence.rs +++ b/examples/nrf52840/src/bin/pwm_sequence.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -31,6 +31,6 @@ async fn main(_spawner: Spawner) { // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped // when it goes out of scope - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; info!("pwm stopped early!"); } diff --git a/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs b/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs index 711c8a17..8596e654 100644 --- a/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs +++ b/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_nrf::pwm::{ Config, Prescaler, SequenceConfig, SequenceLoad, SequencePwm, SingleSequenceMode, SingleSequencer, }; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // WS2812B LED light demonstration. Drives just one light. @@ -52,7 +52,7 @@ async fn main(_spawner: Spawner) { let sequences = SingleSequencer::new(&mut pwm, &seq_words, seq_config.clone()); unwrap!(sequences.start(SingleSequenceMode::Times(1))); - Timer::after(Duration::from_millis(50)).await; + Timer::after_millis(50).await; if bit_value == T0H { if color_bit == 20 { diff --git a/examples/nrf52840/src/bin/pwm_servo.rs b/examples/nrf52840/src/bin/pwm_servo.rs index 19228f43..92ded1f8 100644 --- a/examples/nrf52840/src/bin/pwm_servo.rs +++ b/examples/nrf52840/src/bin/pwm_servo.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_nrf::pwm::{Prescaler, SimplePwm}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -19,29 +19,29 @@ async fn main(_spawner: Spawner) { pwm.set_max_duty(2500); info!("pwm initialized!"); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; // 1ms 0deg (1/.008=125), 1.5ms 90deg (1.5/.008=187.5), 2ms 180deg (2/.008=250), loop { info!("45 deg"); // poor mans inverting, subtract our value from max_duty pwm.set_duty(0, 2500 - 156); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; info!("90 deg"); pwm.set_duty(0, 2500 - 187); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; info!("135 deg"); pwm.set_duty(0, 2500 - 218); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; info!("180 deg"); pwm.set_duty(0, 2500 - 250); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; info!("0 deg"); pwm.set_duty(0, 2500 - 125); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; } } diff --git a/examples/nrf52840/src/bin/qspi_lowpower.rs b/examples/nrf52840/src/bin/qspi_lowpower.rs index 22a5c0c6..42b5454e 100644 --- a/examples/nrf52840/src/bin/qspi_lowpower.rs +++ b/examples/nrf52840/src/bin/qspi_lowpower.rs @@ -8,7 +8,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_nrf::qspi::Frequency; use embassy_nrf::{bind_interrupts, peripherals, qspi}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // Workaround for alignment requirements. @@ -79,6 +79,6 @@ async fn main(_p: Spawner) { // Sleep for 1 second. The executor ensures the core sleeps with a WFE when it has nothing to do. // During this sleep, the nRF chip should only use ~3uA - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/raw_spawn.rs b/examples/nrf52840/src/bin/raw_spawn.rs index 1b067f5e..717b0faa 100644 --- a/examples/nrf52840/src/bin/raw_spawn.rs +++ b/examples/nrf52840/src/bin/raw_spawn.rs @@ -7,21 +7,21 @@ use cortex_m_rt::entry; use defmt::{info, unwrap}; use embassy_executor::raw::TaskStorage; use embassy_executor::Executor; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; async fn run1() { loop { info!("BIG INFREQUENT TICK"); - Timer::after(Duration::from_ticks(64000)).await; + Timer::after_ticks(64000).await; } } async fn run2() { loop { info!("tick"); - Timer::after(Duration::from_ticks(13000)).await; + Timer::after_ticks(13000).await; } } diff --git a/examples/nrf52840/src/bin/saadc.rs b/examples/nrf52840/src/bin/saadc.rs index ffd9a7f4..d651834f 100644 --- a/examples/nrf52840/src/bin/saadc.rs +++ b/examples/nrf52840/src/bin/saadc.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_nrf::saadc::{ChannelConfig, Config, Saadc}; use embassy_nrf::{bind_interrupts, saadc}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -24,6 +24,6 @@ async fn main(_p: Spawner) { let mut buf = [0; 1]; saadc.sample(&mut buf).await; info!("sample: {=i16}", &buf[0]); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/nrf52840/src/bin/saadc_continuous.rs b/examples/nrf52840/src/bin/saadc_continuous.rs index a25e1746..a5f8a4dd 100644 --- a/examples/nrf52840/src/bin/saadc_continuous.rs +++ b/examples/nrf52840/src/bin/saadc_continuous.rs @@ -7,7 +7,6 @@ use embassy_executor::Spawner; use embassy_nrf::saadc::{CallbackResult, ChannelConfig, Config, Saadc}; use embassy_nrf::timer::Frequency; use embassy_nrf::{bind_interrupts, saadc}; -use embassy_time::Duration; use {defmt_rtt as _, panic_probe as _}; // Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer @@ -32,7 +31,7 @@ async fn main(_p: Spawner) { // This delay demonstrates that starting the timer prior to running // the task sampler is benign given the calibration that follows. - embassy_time::Timer::after(Duration::from_millis(500)).await; + embassy_time::Timer::after_millis(500).await; saadc.calibrate().await; let mut bufs = [[[0; 3]; 500]; 2]; diff --git a/examples/nrf52840/src/bin/self_spawn.rs b/examples/nrf52840/src/bin/self_spawn.rs index 31ea6c81..8a58396a 100644 --- a/examples/nrf52840/src/bin/self_spawn.rs +++ b/examples/nrf52840/src/bin/self_spawn.rs @@ -4,7 +4,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; mod config { @@ -13,7 +13,7 @@ mod config { #[embassy_executor::task(pool_size = config::MY_TASK_POOL_SIZE)] async fn my_task(spawner: Spawner, n: u32) { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("Spawning self! {}", n); unwrap!(spawner.spawn(my_task(spawner, n + 1))); } diff --git a/examples/nrf52840/src/bin/self_spawn_current_executor.rs b/examples/nrf52840/src/bin/self_spawn_current_executor.rs index 8a179886..65d50f8c 100644 --- a/examples/nrf52840/src/bin/self_spawn_current_executor.rs +++ b/examples/nrf52840/src/bin/self_spawn_current_executor.rs @@ -4,12 +4,12 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task(pool_size = 2)] async fn my_task(n: u32) { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("Spawning self! {}", n); unwrap!(Spawner::for_current_executor().await.spawn(my_task(n + 1))); } diff --git a/examples/nrf52840/src/bin/temp.rs b/examples/nrf52840/src/bin/temp.rs index 70957548..d94dea38 100644 --- a/examples/nrf52840/src/bin/temp.rs +++ b/examples/nrf52840/src/bin/temp.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_nrf::temp::Temp; use embassy_nrf::{bind_interrupts, temp}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -21,6 +21,6 @@ async fn main(_spawner: Spawner) { loop { let value = temp.read().await; info!("temperature: {}℃", value.to_num::()); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/timer.rs b/examples/nrf52840/src/bin/timer.rs index c22b5acd..9b9bb3eb 100644 --- a/examples/nrf52840/src/bin/timer.rs +++ b/examples/nrf52840/src/bin/timer.rs @@ -4,14 +4,14 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] async fn run1() { loop { info!("BIG INFREQUENT TICK"); - Timer::after(Duration::from_ticks(64000)).await; + Timer::after_ticks(64000).await; } } @@ -19,7 +19,7 @@ async fn run1() { async fn run2() { loop { info!("tick"); - Timer::after(Duration::from_ticks(13000)).await; + Timer::after_ticks(13000).await; } } diff --git a/examples/nrf52840/src/bin/twim_lowpower.rs b/examples/nrf52840/src/bin/twim_lowpower.rs index 0970d3c3..bf9f966e 100644 --- a/examples/nrf52840/src/bin/twim_lowpower.rs +++ b/examples/nrf52840/src/bin/twim_lowpower.rs @@ -14,7 +14,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_nrf::twim::{self, Twim}; use embassy_nrf::{bind_interrupts, peripherals}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x50; @@ -48,6 +48,6 @@ async fn main(_p: Spawner) { // Sleep for 1 second. The executor ensures the core sleeps with a WFE when it has nothing to do. // During this sleep, the nRF chip should only use ~3uA - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs index edf634a5..96fcf8a6 100644 --- a/examples/nrf52840/src/bin/usb_hid_mouse.rs +++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs @@ -10,7 +10,7 @@ use embassy_futures::join::join; use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; use embassy_nrf::usb::Driver; use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Config}; @@ -83,7 +83,7 @@ async fn main(_spawner: Spawner) { let hid_fut = async { let mut y: i8 = 5; loop { - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; y = -y; let report = MouseReport { diff --git a/examples/nrf5340/src/bin/blinky.rs b/examples/nrf5340/src/bin/blinky.rs index 3422cedf..b784564a 100644 --- a/examples/nrf5340/src/bin/blinky.rs +++ b/examples/nrf5340/src/bin/blinky.rs @@ -4,7 +4,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,8 +14,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/rp/src/bin/adc.rs b/examples/rp/src/bin/adc.rs index 02bc493b..a579be13 100644 --- a/examples/rp/src/bin/adc.rs +++ b/examples/rp/src/bin/adc.rs @@ -10,7 +10,7 @@ use embassy_executor::Spawner; use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler}; use embassy_rp::bind_interrupts; use embassy_rp::gpio::Pull; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -36,7 +36,7 @@ async fn main(_spawner: Spawner) { info!("Pin 28 ADC: {}", level); let temp = adc.read(&mut ts).await.unwrap(); info!("Temp: {} degrees", convert_to_celsius(temp)); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/blinky.rs b/examples/rp/src/bin/blinky.rs index 295b000f..66c8773f 100644 --- a/examples/rp/src/bin/blinky.rs +++ b/examples/rp/src/bin/blinky.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::gpio; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use gpio::{Level, Output}; use {defmt_rtt as _, panic_probe as _}; @@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) { loop { info!("led on!"); led.set_high(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("led off!"); led.set_low(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index e593acae..b19362fc 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs @@ -111,7 +111,7 @@ async fn main(spawner: Spawner) { break; } info!("txd: {}", core::str::from_utf8(msg).unwrap()); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/rp/src/bin/flash.rs b/examples/rp/src/bin/flash.rs index 911a657e..129a8497 100644 --- a/examples/rp/src/bin/flash.rs +++ b/examples/rp/src/bin/flash.rs @@ -8,7 +8,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::flash::{Async, ERASE_SIZE, FLASH_BASE}; use embassy_rp::peripherals::FLASH; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; const ADDR_OFFSET: u32 = 0x100000; @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { // 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; + Timer::after_millis(10).await; let mut flash = embassy_rp::flash::Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0); diff --git a/examples/rp/src/bin/gpio_async.rs b/examples/rp/src/bin/gpio_async.rs index bf58044d..98209fe4 100644 --- a/examples/rp/src/bin/gpio_async.rs +++ b/examples/rp/src/bin/gpio_async.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::gpio; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use gpio::{Input, Level, Output, Pull}; use {defmt_rtt as _, panic_probe as _}; @@ -36,6 +36,6 @@ async fn main(_spawner: Spawner) { info!("done wait_for_high. Turn off LED"); led.set_low(); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; } } diff --git a/examples/rp/src/bin/gpout.rs b/examples/rp/src/bin/gpout.rs index 0a3b5fa9..896cc15e 100644 --- a/examples/rp/src/bin/gpout.rs +++ b/examples/rp/src/bin/gpout.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::clocks; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -26,13 +26,13 @@ async fn main(_spawner: Spawner) { "Pin 25 is now outputing CLK_SYS/1000, should be toggling at {}", gpout3.get_freq() ); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; gpout3.set_src(clocks::GpoutSrc::Ref); info!( "Pin 25 is now outputing CLK_REF/1000, should be toggling at {}", gpout3.get_freq() ); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; } } diff --git a/examples/rp/src/bin/i2c_async.rs b/examples/rp/src/bin/i2c_async.rs index 93224bc4..7b53aae7 100644 --- a/examples/rp/src/bin/i2c_async.rs +++ b/examples/rp/src/bin/i2c_async.rs @@ -12,7 +12,7 @@ use embassy_executor::Spawner; use embassy_rp::bind_interrupts; use embassy_rp::i2c::{self, Config, InterruptHandler}; use embassy_rp::peripherals::I2C1; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_async::i2c::I2c; use {defmt_rtt as _, panic_probe as _}; @@ -106,6 +106,6 @@ async fn main(_spawner: Spawner) { } } - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/rp/src/bin/i2c_blocking.rs b/examples/rp/src/bin/i2c_blocking.rs index 1c8c2039..9ddb48d6 100644 --- a/examples/rp/src/bin/i2c_blocking.rs +++ b/examples/rp/src/bin/i2c_blocking.rs @@ -10,7 +10,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::i2c::{self, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_1::i2c::I2c; use {defmt_rtt as _, panic_probe as _}; @@ -70,6 +70,6 @@ async fn main(_spawner: Spawner) { info!("portb = {:02x}", portb[0]); val = !val; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/i2c_slave.rs b/examples/rp/src/bin/i2c_slave.rs index 7de300fb..151b083a 100644 --- a/examples/rp/src/bin/i2c_slave.rs +++ b/examples/rp/src/bin/i2c_slave.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::peripherals::{I2C0, I2C1}; use embassy_rp::{bind_interrupts, i2c, i2c_slave}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_async::i2c::I2c; use {defmt_rtt as _, panic_probe as _}; @@ -81,7 +81,7 @@ async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { Err(e) => error!("Error writing {}", e), } - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } match con.read(DEV_ADDR, &mut resp_buff).await { Ok(_) => info!("read response: {}", resp_buff), @@ -91,7 +91,7 @@ async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { Ok(_) => info!("write_read response: {}", resp_buff), Err(e) => error!("Error writing {}", e), } - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/rp/src/bin/lora_p2p_receive.rs b/examples/rp/src/bin/lora_p2p_receive.rs index 5891826f..d5843fdc 100644 --- a/examples/rp/src/bin/lora_p2p_receive.rs +++ b/examples/rp/src/bin/lora_p2p_receive.rs @@ -11,7 +11,7 @@ use embassy_executor::Spawner; use embassy_lora::iv::GenericSx126xInterfaceVariant; use embassy_rp::gpio::{Input, Level, Output, Pin, Pull}; use embassy_rp::spi::{Config, Spi}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -96,7 +96,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet"); diff --git a/examples/rp/src/bin/lora_p2p_send_multicore.rs b/examples/rp/src/bin/lora_p2p_send_multicore.rs index e31aa62a..ccf44987 100644 --- a/examples/rp/src/bin/lora_p2p_send_multicore.rs +++ b/examples/rp/src/bin/lora_p2p_send_multicore.rs @@ -15,7 +15,7 @@ use embassy_rp::peripherals::SPI1; use embassy_rp::spi::{Async, Config, Spi}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -59,7 +59,7 @@ async fn core0_task() { info!("Hello from core 0"); loop { CHANNEL.send([0x01u8, 0x02u8, 0x03u8]).await; - Timer::after(Duration::from_millis(60 * 1000)).await; + Timer::after_millis(60 * 1000).await; } } diff --git a/examples/rp/src/bin/multicore.rs b/examples/rp/src/bin/multicore.rs index bf017f6a..43eaf8b0 100644 --- a/examples/rp/src/bin/multicore.rs +++ b/examples/rp/src/bin/multicore.rs @@ -13,7 +13,7 @@ use embassy_rp::multicore::{spawn_core1, Stack}; use embassy_rp::peripherals::PIN_25; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -46,9 +46,9 @@ async fn core0_task() { info!("Hello from core 0"); loop { CHANNEL.send(LedState::On).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; CHANNEL.send(LedState::Off).await; - Timer::after(Duration::from_millis(400)).await; + Timer::after_millis(400).await; } } diff --git a/examples/rp/src/bin/multiprio.rs b/examples/rp/src/bin/multiprio.rs index 9ace4cd6..28f62143 100644 --- a/examples/rp/src/bin/multiprio.rs +++ b/examples/rp/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::{info, unwrap}; use embassy_executor::{Executor, InterruptExecutor}; use embassy_rp::interrupt; use embassy_rp::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer, TICK_HZ}; +use embassy_time::{Instant, Timer, TICK_HZ}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { info!(" [high] tick!"); - Timer::after(Duration::from_ticks(673740)).await; + Timer::after_ticks(673740).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() * 1000 / TICK_HZ; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(53421)).await; + Timer::after_ticks(53421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() * 1000 / TICK_HZ; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(82983)).await; + Timer::after_ticks(82983).await; } } diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index d80c5c24..5e5a6f9a 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -15,7 +15,7 @@ use embassy_rp::pio::{ }; use embassy_rp::pwm::{self, Pwm}; use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(pub struct Irqs { @@ -66,7 +66,7 @@ async fn main(_spawner: Spawner) { let mut buf = Buf([0; 16], 0); write!(buf, "up {}s", Instant::now().as_micros() as f32 / 1e6).unwrap(); hd.add_line(&buf.0[0..buf.1]).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/pio_ws2812.rs b/examples/rp/src/bin/pio_ws2812.rs index 5c0c6024..7b325953 100644 --- a/examples/rp/src/bin/pio_ws2812.rs +++ b/examples/rp/src/bin/pio_ws2812.rs @@ -13,7 +13,7 @@ use embassy_rp::pio::{ Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, }; use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use fixed::types::U24F8; use fixed_macro::fixed; use smart_leds::RGB8; @@ -153,7 +153,7 @@ async fn main(_spawner: Spawner) { } ws2812.write(&data).await; - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; } } } diff --git a/examples/rp/src/bin/pwm.rs b/examples/rp/src/bin/pwm.rs index 9d919287..a99e8800 100644 --- a/examples/rp/src/bin/pwm.rs +++ b/examples/rp/src/bin/pwm.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::pwm::{Config, Pwm}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { loop { info!("current LED duty cycle: {}/32768", c.compare_b); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; c.compare_b = c.compare_b.rotate_left(4); pwm.set_config(&c); } diff --git a/examples/rp/src/bin/rtc.rs b/examples/rp/src/bin/rtc.rs index 15aa8243..667876db 100644 --- a/examples/rp/src/bin/rtc.rs +++ b/examples/rp/src/bin/rtc.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::rtc::{DateTime, DayOfWeek, Rtc}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -31,7 +31,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now).unwrap(); } - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; if let Ok(dt) = rtc.now() { info!( @@ -41,6 +41,6 @@ async fn main(_spawner: Spawner) { } info!("Reboot."); - Timer::after(Duration::from_millis(200)).await; + Timer::after_millis(200).await; cortex_m::peripheral::SCB::sys_reset(); } diff --git a/examples/rp/src/bin/spi_async.rs b/examples/rp/src/bin/spi_async.rs index 328074e8..f5a2d334 100644 --- a/examples/rp/src/bin/spi_async.rs +++ b/examples/rp/src/bin/spi_async.rs @@ -8,7 +8,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::spi::{Config, Spi}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -27,6 +27,6 @@ async fn main(_spawner: Spawner) { let mut rx_buf = [0_u8; 6]; spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); info!("{:?}", rx_buf); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/uart_buffered_split.rs b/examples/rp/src/bin/uart_buffered_split.rs index d3e67c8e..14e8810a 100644 --- a/examples/rp/src/bin/uart_buffered_split.rs +++ b/examples/rp/src/bin/uart_buffered_split.rs @@ -13,7 +13,7 @@ use embassy_executor::Spawner; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::UART0; use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::{Read, Write}; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; @@ -42,7 +42,7 @@ async fn main(spawner: Spawner) { ]; info!("TX {:?}", data); tx.write_all(&data).await.unwrap(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/uart_unidir.rs b/examples/rp/src/bin/uart_unidir.rs index c1515a91..42c8b432 100644 --- a/examples/rp/src/bin/uart_unidir.rs +++ b/examples/rp/src/bin/uart_unidir.rs @@ -14,7 +14,7 @@ use embassy_executor::Spawner; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::UART1; use embassy_rp::uart::{Async, Config, InterruptHandler, UartRx, UartTx}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -35,7 +35,7 @@ async fn main(spawner: Spawner) { let data = [1u8, 2, 3, 4, 5, 6, 7, 8]; info!("TX {:?}", data); uart_tx.write(&data).await.unwrap(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/usb_logger.rs b/examples/rp/src/bin/usb_logger.rs index 9c5e6897..791f15e5 100644 --- a/examples/rp/src/bin/usb_logger.rs +++ b/examples/rp/src/bin/usb_logger.rs @@ -10,7 +10,7 @@ use embassy_executor::Spawner; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver, InterruptHandler}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -32,6 +32,6 @@ async fn main(spawner: Spawner) { loop { counter += 1; log::info!("Tick {}", counter); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/watchdog.rs b/examples/rp/src/bin/watchdog.rs index fe5eaf92..b6af518a 100644 --- a/examples/rp/src/bin/watchdog.rs +++ b/examples/rp/src/bin/watchdog.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { // Set the LED high for 2 seconds so we know when we're about to start the watchdog led.set_high(); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; // Set to watchdog to reset if it's not fed within 1.05 seconds, and start it watchdog.start(Duration::from_millis(1_050)); @@ -33,9 +33,9 @@ async fn main(_spawner: Spawner) { // Blink once a second for 5 seconds, feed the watchdog timer once a second to avoid a reset for _ in 1..=5 { led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("Feeding watchdog"); watchdog.feed(); } @@ -45,8 +45,8 @@ async fn main(_spawner: Spawner) { // The processor should reset in 1.05 seconds. loop { led.set_low(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; led.set_high(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 64cf9517..c00fff21 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs @@ -105,7 +105,7 @@ 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; + Timer::after_millis(100).await; } info!("DHCP is now up!"); diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 199e4c9e..79fa375c 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -100,7 +100,7 @@ async fn main_task(spawner: Spawner) { return; } - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } info!("Closing the connection"); socket.abort(); diff --git a/examples/std/src/bin/tick.rs b/examples/std/src/bin/tick.rs index b9de9d87..a3f99067 100644 --- a/examples/std/src/bin/tick.rs +++ b/examples/std/src/bin/tick.rs @@ -1,14 +1,14 @@ #![feature(type_alias_impl_trait)] use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use log::*; #[embassy_executor::task] async fn run() { loop { info!("tick"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32c0/src/bin/blinky.rs b/examples/stm32c0/src/bin/blinky.rs index 8a65b069..cbeb0dee 100644 --- a/examples/stm32c0/src/bin/blinky.rs +++ b/examples/stm32c0/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs index 1564ecfc..96f23440 100644 --- a/examples/stm32f0/src/bin/adc.rs +++ b/examples/stm32f0/src/bin/adc.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::peripherals::ADC; use embassy_stm32::{adc, bind_interrupts}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -36,6 +36,6 @@ async fn main(_spawner: Spawner) { loop { let v = adc.read(&mut pin).await; info!("--> {} - {} mV", v, convert_to_millivolts(v)); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/stm32f0/src/bin/blinky.rs b/examples/stm32f0/src/bin/blinky.rs index 9f923399..89939454 100644 --- a/examples/stm32f0/src/bin/blinky.rs +++ b/examples/stm32f0/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // main is itself an async function. @@ -19,10 +19,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs index f362c53f..306df175 100644 --- a/examples/stm32f0/src/bin/button_controlled_blink.rs +++ b/examples/stm32f0/src/bin/button_controlled_blink.rs @@ -10,7 +10,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; static BLINK_MS: AtomicU32 = AtomicU32::new(0); @@ -24,7 +24,7 @@ async fn led_task(led: AnyPin) { loop { let del = BLINK_MS.load(Ordering::Relaxed); info!("Value of del is {}", del); - Timer::after(Duration::from_millis(del.into())).await; + Timer::after_millis(del.into()).await; info!("LED toggling"); led.toggle(); } diff --git a/examples/stm32f0/src/bin/hello.rs b/examples/stm32f0/src/bin/hello.rs index db78233e..0f98d986 100644 --- a/examples/stm32f0/src/bin/hello.rs +++ b/examples/stm32f0/src/bin/hello.rs @@ -4,14 +4,14 @@ use defmt::info; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) -> ! { let _p = embassy_stm32::init(Default::default()); loop { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("Hello"); } } diff --git a/examples/stm32f0/src/bin/multiprio.rs b/examples/stm32f0/src/bin/multiprio.rs index 988ffeef..870c7c45 100644 --- a/examples/stm32f0/src/bin/multiprio.rs +++ b/examples/stm32f0/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::*; use embassy_executor::{Executor, InterruptExecutor}; use embassy_stm32::interrupt; use embassy_stm32::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { // info!(" [high] tick!"); - Timer::after(Duration::from_ticks(27374)).await; + Timer::after_ticks(27374).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() / 33; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(23421)).await; + Timer::after_ticks(23421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() / 33; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(32983)).await; + Timer::after_ticks(32983).await; } } diff --git a/examples/stm32f0/src/bin/wdg.rs b/examples/stm32f0/src/bin/wdg.rs index a44b1752..b51dee8e 100644 --- a/examples/stm32f0/src/bin/wdg.rs +++ b/examples/stm32f0/src/bin/wdg.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::wdg::IndependentWatchdog; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) { wdg.unleash(); loop { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; wdg.pet(); } } diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs index 30947c3c..1edac3d8 100644 --- a/examples/stm32f1/src/bin/adc.rs +++ b/examples/stm32f1/src/bin/adc.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::Adc; use embassy_stm32::peripherals::ADC1; use embassy_stm32::{adc, bind_interrupts}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -35,6 +35,6 @@ async fn main(_spawner: Spawner) { loop { let v = adc.read(&mut pin).await; info!("--> {} - {} mV", v, convert_to_millivolts(v)); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/stm32f1/src/bin/blinky.rs b/examples/stm32f1/src/bin/blinky.rs index b9b0ac23..3425b053 100644 --- a/examples/stm32f1/src/bin/blinky.rs +++ b/examples/stm32f1/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f1/src/bin/hello.rs b/examples/stm32f1/src/bin/hello.rs index 180b6aab..e63bcaae 100644 --- a/examples/stm32f1/src/bin/hello.rs +++ b/examples/stm32f1/src/bin/hello.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,6 +17,6 @@ async fn main(_spawner: Spawner) -> ! { loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs index 663099ff..60eb5d0e 100644 --- a/examples/stm32f1/src/bin/usb_serial.rs +++ b/examples/stm32f1/src/bin/usb_serial.rs @@ -9,7 +9,7 @@ use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; @@ -35,7 +35,7 @@ async fn main(_spawner: Spawner) { // This forced reset is needed only for development, without it host // will not reset your device when you upload new firmware. let _dp = Output::new(&mut p.PA12, Level::Low, Speed::Low); - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; } // Create the driver, from the HAL. diff --git a/examples/stm32f2/src/bin/blinky.rs b/examples/stm32f2/src/bin/blinky.rs index d8c89a51..f6d7a000 100644 --- a/examples/stm32f2/src/bin/blinky.rs +++ b/examples/stm32f2/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs index 62aaa980..56591b52 100644 --- a/examples/stm32f2/src/bin/pll.rs +++ b/examples/stm32f2/src/bin/pll.rs @@ -11,7 +11,7 @@ use embassy_stm32::rcc::{ }; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) { let _p = embassy_stm32::init(config); loop { - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("1s elapsed"); } } diff --git a/examples/stm32f3/src/bin/blinky.rs b/examples/stm32f3/src/bin/blinky.rs index 185785ce..e71031b3 100644 --- a/examples/stm32f3/src/bin/blinky.rs +++ b/examples/stm32f3/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs index 8e97e85e..9df6d680 100644 --- a/examples/stm32f3/src/bin/button_events.rs +++ b/examples/stm32f3/src/bin/button_events.rs @@ -65,11 +65,11 @@ impl<'a> Leds<'a> { for led in &mut self.leds { led.set_high(); } - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; for led in &mut self.leds { led.set_low(); } - Timer::after(Duration::from_millis(200)).await; + Timer::after_millis(200).await; } } diff --git a/examples/stm32f3/src/bin/hello.rs b/examples/stm32f3/src/bin/hello.rs index 65773210..b3285f3c 100644 --- a/examples/stm32f3/src/bin/hello.rs +++ b/examples/stm32f3/src/bin/hello.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,6 +18,6 @@ async fn main(_spawner: Spawner) -> ! { loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f3/src/bin/multiprio.rs b/examples/stm32f3/src/bin/multiprio.rs index 80bf59de..74f3bb1c 100644 --- a/examples/stm32f3/src/bin/multiprio.rs +++ b/examples/stm32f3/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::*; use embassy_executor::{Executor, InterruptExecutor}; use embassy_stm32::interrupt; use embassy_stm32::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { info!(" [high] tick!"); - Timer::after(Duration::from_ticks(27374)).await; + Timer::after_ticks(27374).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() / 33; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(23421)).await; + Timer::after_ticks(23421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() / 33; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(32983)).await; + Timer::after_ticks(32983).await; } } diff --git a/examples/stm32f3/src/bin/usb_serial.rs b/examples/stm32f3/src/bin/usb_serial.rs index f15f333b..a9537c77 100644 --- a/examples/stm32f3/src/bin/usb_serial.rs +++ b/examples/stm32f3/src/bin/usb_serial.rs @@ -9,7 +9,7 @@ use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::time::mhz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; @@ -33,7 +33,7 @@ async fn main(_spawner: Spawner) { // Needed for nucleo-stm32f303ze let mut dp_pullup = Output::new(p.PG6, Level::Low, Speed::Medium); - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; dp_pullup.set_high(); // Create the driver, from the HAL. diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs index a9286c44..f259135d 100644 --- a/examples/stm32f334/src/bin/adc.rs +++ b/examples/stm32f334/src/bin/adc.rs @@ -9,7 +9,7 @@ use embassy_stm32::peripherals::ADC1; use embassy_stm32::rcc::{AdcClockSource, Adcpres}; use embassy_stm32::time::mhz; use embassy_stm32::{adc, bind_interrupts, Config}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -51,6 +51,6 @@ async fn main(_spawner: Spawner) -> ! { let pin_mv = (pin as u32 * vrefint.value() as u32 / vref as u32) * 3300 / 4095; info!("computed pin mv: {}", pin_mv); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32f334/src/bin/button.rs b/examples/stm32f334/src/bin/button.rs index 599c0f27..501fb080 100644 --- a/examples/stm32f334/src/bin/button.rs +++ b/examples/stm32f334/src/bin/button.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,10 +17,10 @@ async fn main(_spawner: Spawner) { let mut out1 = Output::new(p.PA8, Level::Low, Speed::High); out1.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; out1.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("end program"); cortex_m::asm::bkpt(); diff --git a/examples/stm32f334/src/bin/hello.rs b/examples/stm32f334/src/bin/hello.rs index 65773210..b3285f3c 100644 --- a/examples/stm32f334/src/bin/hello.rs +++ b/examples/stm32f334/src/bin/hello.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,6 +18,6 @@ async fn main(_spawner: Spawner) -> ! { loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index fb5a85bc..128001bf 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs @@ -10,7 +10,7 @@ use embassy_stm32::peripherals::ADC2; use embassy_stm32::rcc::{AdcClockSource, Adcpres}; use embassy_stm32::time::mhz; use embassy_stm32::{adc, bind_interrupts, Config}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -54,6 +54,6 @@ async fn main(_spawner: Spawner) -> ! { 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; + Timer::after_millis(500).await; } } diff --git a/examples/stm32f334/src/bin/pwm.rs b/examples/stm32f334/src/bin/pwm.rs index aebc421b..8040c3f1 100644 --- a/examples/stm32f334/src/bin/pwm.rs +++ b/examples/stm32f334/src/bin/pwm.rs @@ -8,7 +8,7 @@ use embassy_stm32::hrtim::*; use embassy_stm32::rcc::HrtimClockSource; use embassy_stm32::time::{khz, mhz}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) { // .setr(0) // .modify(|w| w.set_sst(Activeeffect::SETACTIVE)); // - // Timer::after(Duration::from_millis(500)).await; + // Timer::after_millis(500).await; // // embassy_stm32::pac::HRTIM1 // .tim(0) @@ -65,7 +65,7 @@ async fn main(_spawner: Spawner) { buck_converter.start(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("end program"); diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs index dd10385c..f1932872 100644 --- a/examples/stm32f4/src/bin/adc.rs +++ b/examples/stm32f4/src/bin/adc.rs @@ -6,7 +6,7 @@ use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs; use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, Temperature, VrefInt}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -63,6 +63,6 @@ async fn main(_spawner: Spawner) { let v = adc.read(&mut vrefint); info!("VrefInt: {}", v); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/stm32f4/src/bin/blinky.rs b/examples/stm32f4/src/bin/blinky.rs index b27bee4c..4bfc5a50 100644 --- a/examples/stm32f4/src/bin/blinky.rs +++ b/examples/stm32f4/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 6a1d4b08..ddf8596a 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -12,7 +12,7 @@ use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; @@ -99,7 +99,7 @@ async fn main(spawner: Spawner) -> ! { let r = socket.connect(remote_endpoint).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; continue; } info!("connected!"); @@ -110,7 +110,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32f4/src/bin/flash_async.rs b/examples/stm32f4/src/bin/flash_async.rs index 6c9689d9..f0a65a72 100644 --- a/examples/stm32f4/src/bin/flash_async.rs +++ b/examples/stm32f4/src/bin/flash_async.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::bind_interrupts; use embassy_stm32::flash::{Flash, InterruptHandler}; use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -35,11 +35,11 @@ async fn blinky(p: AnyPin) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/hello.rs b/examples/stm32f4/src/bin/hello.rs index c409703f..27ee83aa 100644 --- a/examples/stm32f4/src/bin/hello.rs +++ b/examples/stm32f4/src/bin/hello.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,6 +17,6 @@ async fn main(_spawner: Spawner) -> ! { loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f4/src/bin/mco.rs b/examples/stm32f4/src/bin/mco.rs index 5144a78c..3315e765 100644 --- a/examples/stm32f4/src/bin/mco.rs +++ b/examples/stm32f4/src/bin/mco.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::rcc::{Mco, Mco1Source, Mco2Source, McoPrescaler}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/multiprio.rs b/examples/stm32f4/src/bin/multiprio.rs index 80bf59de..74f3bb1c 100644 --- a/examples/stm32f4/src/bin/multiprio.rs +++ b/examples/stm32f4/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::*; use embassy_executor::{Executor, InterruptExecutor}; use embassy_stm32::interrupt; use embassy_stm32::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { info!(" [high] tick!"); - Timer::after(Duration::from_ticks(27374)).await; + Timer::after_ticks(27374).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() / 33; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(23421)).await; + Timer::after_ticks(23421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() / 33; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(32983)).await; + Timer::after_ticks(32983).await; } } diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs index 1013a844..538427e8 100644 --- a/examples/stm32f4/src/bin/pwm.rs +++ b/examples/stm32f4/src/bin/pwm.rs @@ -8,7 +8,7 @@ use embassy_stm32::gpio::OutputType; use embassy_stm32::time::khz; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -26,12 +26,12 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/pwm_complementary.rs b/examples/stm32f4/src/bin/pwm_complementary.rs index 83a3c753..a8211f6e 100644 --- a/examples/stm32f4/src/bin/pwm_complementary.rs +++ b/examples/stm32f4/src/bin/pwm_complementary.rs @@ -9,7 +9,7 @@ use embassy_stm32::time::khz; use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; use embassy_stm32::timer::simple_pwm::PwmPin; use embassy_stm32::timer::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -42,12 +42,12 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs index e95ad577..44b4303c 100644 --- a/examples/stm32f4/src/bin/rtc.rs +++ b/examples/stm32f4/src/bin/rtc.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -31,6 +31,6 @@ async fn main(_spawner: Spawner) { info!("{}", now.timestamp()); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32f4/src/bin/wdt.rs b/examples/stm32f4/src/bin/wdt.rs index e5d122af..0443b61c 100644 --- a/examples/stm32f4/src/bin/wdt.rs +++ b/examples/stm32f4/src/bin/wdt.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::wdg::IndependentWatchdog; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -24,11 +24,11 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; // Pet watchdog for 5 iterations and then stop. // MCU should restart in 1 second after the last pet. diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs index bc4ed289..48c59eaf 100644 --- a/examples/stm32f7/src/bin/adc.rs +++ b/examples/stm32f7/src/bin/adc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::Adc; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -29,6 +29,6 @@ async fn main(_spawner: Spawner) { loop { let v = adc.read(&mut pin); info!("--> {} - {} mV", v, convert_to_millivolts(v)); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/stm32f7/src/bin/blinky.rs b/examples/stm32f7/src/bin/blinky.rs index b27bee4c..4bfc5a50 100644 --- a/examples/stm32f7/src/bin/blinky.rs +++ b/examples/stm32f7/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f7/src/bin/can.rs b/examples/stm32f7/src/bin/can.rs index e9650f23..78b21cea 100644 --- a/examples/stm32f7/src/bin/can.rs +++ b/examples/stm32f7/src/bin/can.rs @@ -26,7 +26,7 @@ pub async fn send_can_message(tx: &'static mut CanTx<'static, 'static, CAN3>) { loop { let frame = Frame::new_data(unwrap!(StandardId::new(0 as _)), [0]); tx.write(&frame).await; - embassy_time::Timer::after(embassy_time::Duration::from_secs(1)).await; + embassy_time::Timer::after_secs(1).await; } } diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 7c9ee159..d50473b9 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -12,7 +12,7 @@ use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use rand_core::RngCore; use static_cell::make_static; @@ -100,7 +100,7 @@ async fn main(spawner: Spawner) -> ! { let r = socket.connect(remote_endpoint).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; continue; } info!("connected!"); @@ -111,7 +111,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32f7/src/bin/flash.rs b/examples/stm32f7/src/bin/flash.rs index 35d3059b..06a94f1c 100644 --- a/examples/stm32f7/src/bin/flash.rs +++ b/examples/stm32f7/src/bin/flash.rs @@ -5,7 +5,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_stm32::flash::Flash; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) { const ADDR: u32 = 0x8_0000; // This is the offset into the third region, the absolute address is 4x32K + 128K + 0x8_0000. // wait a bit before accessing the flash - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank1_region3; diff --git a/examples/stm32f7/src/bin/hello.rs b/examples/stm32f7/src/bin/hello.rs index c409703f..27ee83aa 100644 --- a/examples/stm32f7/src/bin/hello.rs +++ b/examples/stm32f7/src/bin/hello.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,6 +17,6 @@ async fn main(_spawner: Spawner) -> ! { loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32g0/src/bin/blinky.rs b/examples/stm32g0/src/bin/blinky.rs index b27bee4c..4bfc5a50 100644 --- a/examples/stm32g0/src/bin/blinky.rs +++ b/examples/stm32g0/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32g0/src/bin/spi_neopixel.rs b/examples/stm32g0/src/bin/spi_neopixel.rs index ee7aaf33..214462d0 100644 --- a/examples/stm32g0/src/bin/spi_neopixel.rs +++ b/examples/stm32g0/src/bin/spi_neopixel.rs @@ -8,7 +8,7 @@ use embassy_stm32::dma::word::U5; use embassy_stm32::dma::NoDma; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; const NR_PIXELS: usize = 15; @@ -96,8 +96,8 @@ async fn main(_spawner: Spawner) { cnt += 1; // start sending the neopixel bit patters over spi to the neopixel string spi.write(&neopixels.bitbuffer).await.ok(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index 30a112b7..9daf4e4c 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSrc}; use embassy_stm32::Config; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -36,6 +36,6 @@ async fn main(_spawner: Spawner) { loop { let measured = adc.read(&mut p.PA7); info!("measured: {}", measured); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32g4/src/bin/blinky.rs b/examples/stm32g4/src/bin/blinky.rs index 8a65b069..cbeb0dee 100644 --- a/examples/stm32g4/src/bin/blinky.rs +++ b/examples/stm32g4/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs index f8159cb5..43242647 100644 --- a/examples/stm32g4/src/bin/pll.rs +++ b/examples/stm32g4/src/bin/pll.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSrc}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -29,7 +29,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); loop { - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("1s elapsed"); } } diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs index 01e9cb47..eed0b6ad 100644 --- a/examples/stm32g4/src/bin/pwm.rs +++ b/examples/stm32g4/src/bin/pwm.rs @@ -8,7 +8,7 @@ use embassy_stm32::gpio::OutputType; use embassy_stm32::time::khz; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -26,12 +26,12 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32h5/src/bin/blinky.rs b/examples/stm32h5/src/bin/blinky.rs index f9bf90d2..1394f03f 100644 --- a/examples/stm32h5/src/bin/blinky.rs +++ b/examples/stm32h5/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 2535c6a6..6e40f0ac 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -15,7 +15,7 @@ use embassy_stm32::rcc::{ use embassy_stm32::rng::Rng; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use rand_core::RngCore; use static_cell::make_static; @@ -121,7 +121,7 @@ async fn main(spawner: Spawner) -> ! { let r = socket.connect(remote_endpoint).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(3)).await; + Timer::after_secs(3).await; continue; } info!("connected!"); @@ -131,7 +131,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs index 7859b86d..4a358a35 100644 --- a/examples/stm32h7/src/bin/adc.rs +++ b/examples/stm32h7/src/bin/adc.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::Config; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -55,6 +55,6 @@ async fn main(_spawner: Spawner) { info!("vrefint: {}", vrefint); let measured = adc.read(&mut p.PC0); info!("measured: {}", measured); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32h7/src/bin/blinky.rs b/examples/stm32h7/src/bin/blinky.rs index 12f08c0f..a9cab1ff 100644 --- a/examples/stm32h7/src/bin/blinky.rs +++ b/examples/stm32h7/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index 40ef16cf..8195430b 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs @@ -9,7 +9,7 @@ use embassy_stm32::i2c::I2c; 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}; +use embassy_time::Timer; use ov7725::*; use {defmt_rtt as _, panic_probe as _}; @@ -86,11 +86,11 @@ async fn main(_spawner: Spawner) { loop { defmt::info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; defmt::info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } @@ -99,7 +99,7 @@ mod ov7725 { use defmt::Format; use embassy_stm32::rcc::{Mco, McoInstance}; - use embassy_time::{Duration, Timer}; + use embassy_time::Timer; use embedded_hal_async::i2c::I2c; #[repr(u8)] @@ -210,9 +210,9 @@ mod ov7725 { } pub async fn init(&mut self) -> Result<(), Error> { - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; self.reset_regs().await?; - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; self.set_pixformat().await?; self.set_resolution().await?; Ok(()) diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 6fbf4344..81d9c734 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -11,7 +11,7 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use rand_core::RngCore; use static_cell::make_static; @@ -118,7 +118,7 @@ async fn main(spawner: Spawner) -> ! { let r = socket.connect(remote_endpoint).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; continue; } info!("connected!"); @@ -128,7 +128,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 09d27cdb..33813706 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -11,7 +11,7 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; use rand_core::RngCore; @@ -115,7 +115,7 @@ async fn main(spawner: Spawner) -> ! { let r = client.connect(addr).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; continue; } let mut connection = r.unwrap(); @@ -126,7 +126,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32h7/src/bin/flash.rs b/examples/stm32h7/src/bin/flash.rs index f66df770..89c0c8a6 100644 --- a/examples/stm32h7/src/bin/flash.rs +++ b/examples/stm32h7/src/bin/flash.rs @@ -5,7 +5,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_stm32::flash::Flash; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) { const ADDR: u32 = 0; // This is the offset into bank 2, the absolute address is 0x8_0000 // wait a bit before accessing the flash - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank2_region; diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs index 7ae87b02..cffd4709 100644 --- a/examples/stm32h7/src/bin/fmc.rs +++ b/examples/stm32h7/src/bin/fmc.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::fmc::Fmc; use embassy_stm32::Config; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -212,6 +212,6 @@ async fn main(_spawner: Spawner) { info!("Assertions succeeded."); loop { - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index 5841efb2..0355ac07 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -9,7 +9,7 @@ use embassy_stm32::gpio::Speed; use embassy_stm32::time::{khz, Hertz}; use embassy_stm32::timer::*; use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -49,13 +49,13 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { diff --git a/examples/stm32h7/src/bin/mco.rs b/examples/stm32h7/src/bin/mco.rs index de89aee2..c023f458 100644 --- a/examples/stm32h7/src/bin/mco.rs +++ b/examples/stm32h7/src/bin/mco.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs index 37e4c92c..3bf373c7 100644 --- a/examples/stm32h7/src/bin/pwm.rs +++ b/examples/stm32h7/src/bin/pwm.rs @@ -9,7 +9,7 @@ use embassy_stm32::time::khz; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::Channel; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -48,12 +48,12 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32h7/src/bin/rtc.rs b/examples/stm32h7/src/bin/rtc.rs index f2a19af8..78cea9c8 100644 --- a/examples/stm32h7/src/bin/rtc.rs +++ b/examples/stm32h7/src/bin/rtc.rs @@ -8,7 +8,7 @@ use embassy_executor::Spawner; use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now.into()).expect("datetime not set"); // In reality the delay would be much longer - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; let then: NaiveDateTime = rtc.now().unwrap().into(); info!("Got RTC! {:?}", then.timestamp()); diff --git a/examples/stm32h7/src/bin/signal.rs b/examples/stm32h7/src/bin/signal.rs index 6d7c168d..b5f58328 100644 --- a/examples/stm32h7/src/bin/signal.rs +++ b/examples/stm32h7/src/bin/signal.rs @@ -6,7 +6,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::signal::Signal; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; static SIGNAL: Signal = Signal::new(); @@ -16,7 +16,7 @@ async fn my_sending_task() { let mut counter: u32 = 0; loop { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; SIGNAL.signal(counter); diff --git a/examples/stm32h7/src/bin/wdg.rs b/examples/stm32h7/src/bin/wdg.rs index 9181dfd6..76fd9dfc 100644 --- a/examples/stm32h7/src/bin/wdg.rs +++ b/examples/stm32h7/src/bin/wdg.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::wdg::IndependentWatchdog; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) { wdg.unleash(); loop { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; wdg.pet(); } } diff --git a/examples/stm32l0/src/bin/blinky.rs b/examples/stm32l0/src/bin/blinky.rs index 07fad07c..ea40bfc4 100644 --- a/examples/stm32l0/src/bin/blinky.rs +++ b/examples/stm32l0/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32l0/src/bin/lora_cad.rs b/examples/stm32l0/src/bin/lora_cad.rs index 900848fd..987cdba0 100644 --- a/examples/stm32l0/src/bin/lora_cad.rs +++ b/examples/stm32l0/src/bin/lora_cad.rs @@ -12,7 +12,7 @@ use embassy_stm32::exti::{Channel, ExtiInput}; use embassy_stm32::gpio::{Input, Level, Output, Pin, Pull, Speed}; use embassy_stm32::spi; use embassy_stm32::time::khz; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1276_7_8_9::SX1276_7_8_9; use lora_phy::LoRa; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.PB6, Level::Low, Speed::Low); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mdltn_params = { @@ -89,7 +89,7 @@ async fn main(_spawner: Spawner) { info!("cad successful without activity detected") } debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } Err(err) => info!("cad unsuccessful = {}", err), diff --git a/examples/stm32l0/src/bin/lora_p2p_receive.rs b/examples/stm32l0/src/bin/lora_p2p_receive.rs index edd14bb8..06e2744a 100644 --- a/examples/stm32l0/src/bin/lora_p2p_receive.rs +++ b/examples/stm32l0/src/bin/lora_p2p_receive.rs @@ -12,7 +12,7 @@ use embassy_stm32::exti::{Channel, ExtiInput}; use embassy_stm32::gpio::{Input, Level, Output, Pin, Pull, Speed}; use embassy_stm32::spi; use embassy_stm32::time::khz; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1276_7_8_9::SX1276_7_8_9; use lora_phy::LoRa; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.PB6, Level::Low, Speed::Low); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mut receiving_buffer = [00u8; 100]; @@ -107,7 +107,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet"); diff --git a/examples/stm32l0/src/bin/raw_spawn.rs b/examples/stm32l0/src/bin/raw_spawn.rs index edc17304..29c7e0dc 100644 --- a/examples/stm32l0/src/bin/raw_spawn.rs +++ b/examples/stm32l0/src/bin/raw_spawn.rs @@ -7,21 +7,21 @@ use cortex_m_rt::entry; use defmt::*; use embassy_executor::raw::TaskStorage; use embassy_executor::Executor; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; async fn run1() { loop { info!("BIG INFREQUENT TICK"); - Timer::after(Duration::from_ticks(64000)).await; + Timer::after_ticks(64000).await; } } async fn run2() { loop { info!("tick"); - Timer::after(Duration::from_ticks(13000)).await; + Timer::after_ticks(13000).await; } } diff --git a/examples/stm32l1/src/bin/blinky.rs b/examples/stm32l1/src/bin/blinky.rs index 8a345d23..06f732eb 100644 --- a/examples/stm32l1/src/bin/blinky.rs +++ b/examples/stm32l1/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32l4/src/bin/blinky.rs b/examples/stm32l4/src/bin/blinky.rs index 033292ff..6202fe2f 100644 --- a/examples/stm32l4/src/bin/blinky.rs +++ b/examples/stm32l4/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,8 +17,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32l4/src/bin/mco.rs b/examples/stm32l4/src/bin/mco.rs index 8d35af78..2833bb63 100644 --- a/examples/stm32l4/src/bin/mco.rs +++ b/examples/stm32l4/src/bin/mco.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::rcc::{Mco, McoPrescaler, McoSource}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -20,8 +20,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index 33efc76b..f5d46e95 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -9,7 +9,7 @@ use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, PllMul, PllPreDiv, PllRD use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -39,7 +39,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now.into()).expect("datetime not set"); // In reality the delay would be much longer - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; let then: NaiveDateTime = rtc.now().unwrap().into(); info!("Got RTC! {:?}", then.timestamp()); diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 7193d1f1..e2ac22d0 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -306,7 +306,7 @@ async fn temp_task(temp_dev_i2c: TempSensI2c, mut led: Output<'static, periphera loop { led.set_low(); - match select(temp_sens.read_temp(), Timer::after(Duration::from_millis(500))).await { + match select(temp_sens.read_temp(), Timer::after_millis(500)).await { Either::First(i2c_ret) => match i2c_ret { Ok(value) => { led.set_high(); @@ -424,7 +424,7 @@ where // Start: One shot let cfg = 0b01 << 5; self.write_cfg(cfg).await?; - Timer::after(Duration::from_millis(250)).await; + Timer::after_millis(250).await; self.bus .write_read(self.addr, &[Registers::Temp_MSB as u8], &mut buffer) .await diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index db6a9c76..0d06c94a 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -8,7 +8,7 @@ use embassy_futures::join::join; use embassy_stm32::rcc::*; use embassy_stm32::usb::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::Builder; @@ -76,7 +76,7 @@ async fn main(_spawner: Spawner) { let hid_fut = async { let mut y: i8 = 5; loop { - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; y = -y; let report = MouseReport { diff --git a/examples/stm32u5/src/bin/blinky.rs b/examples/stm32u5/src/bin/blinky.rs index 976fb0b9..4b44cb12 100644 --- a/examples/stm32u5/src/bin/blinky.rs +++ b/examples/stm32u5/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) -> ! { loop { defmt::info!("on!"); led.set_low(); - Timer::after(Duration::from_millis(200)).await; + Timer::after_millis(200).await; defmt::info!("off!"); led.set_high(); - Timer::after(Duration::from_millis(200)).await; + Timer::after_millis(200).await; } } diff --git a/examples/stm32wb/src/bin/blinky.rs b/examples/stm32wb/src/bin/blinky.rs index f9bf90d2..1394f03f 100644 --- a/examples/stm32wb/src/bin/blinky.rs +++ b/examples/stm32wb/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs index 2f53f5df..9d0e0070 100644 --- a/examples/stm32wb/src/bin/tl_mbox.rs +++ b/examples/stm32wb/src/bin/tl_mbox.rs @@ -8,7 +8,7 @@ use embassy_stm32::bind_interrupts; use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; use embassy_stm32::rcc::WPAN_DEFAULT; use embassy_stm32_wpan::TlMbox; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs{ @@ -71,7 +71,7 @@ async fn main(_spawner: Spawner) { } } - Timer::after(Duration::from_millis(50)).await; + Timer::after_millis(50).await; } info!("Test OK"); diff --git a/examples/stm32wba/src/bin/blinky.rs b/examples/stm32wba/src/bin/blinky.rs index 53074629..6b9635e6 100644 --- a/examples/stm32wba/src/bin/blinky.rs +++ b/examples/stm32wba/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32wl/src/bin/blinky.rs b/examples/stm32wl/src/bin/blinky.rs index 6af5099c..5bd5745f 100644 --- a/examples/stm32wl/src/bin/blinky.rs +++ b/examples/stm32wl/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32wl/src/bin/lora_p2p_receive.rs b/examples/stm32wl/src/bin/lora_p2p_receive.rs index 19b0d853..be33f39c 100644 --- a/examples/stm32wl/src/bin/lora_p2p_receive.rs +++ b/examples/stm32wl/src/bin/lora_p2p_receive.rs @@ -11,7 +11,7 @@ use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant}; use embassy_stm32::bind_interrupts; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::spi::Spi; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -51,7 +51,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.PB15, Level::Low, Speed::Low); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mut receiving_buffer = [00u8; 100]; @@ -103,7 +103,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet"); diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index a6bb2801..9ebb05f2 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs @@ -8,7 +8,7 @@ use embassy_executor::Spawner; use embassy_stm32::rcc::{ClockSrc, LsConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now.into()).expect("datetime not set"); // In reality the delay would be much longer - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; let then: NaiveDateTime = rtc.now().unwrap().into(); info!("Got RTC! {:?}", then.timestamp()); diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs index edfe8baf..1141096f 100644 --- a/examples/wasm/src/lib.rs +++ b/examples/wasm/src/lib.rs @@ -1,7 +1,7 @@ #![feature(type_alias_impl_trait)] use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; #[embassy_executor::task] async fn ticker() { @@ -19,7 +19,7 @@ async fn ticker() { log::info!("tick {}", counter); counter += 1; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index 8abeae6d..65b9d76d 100644 --- a/tests/nrf/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs @@ -13,7 +13,7 @@ use embassy_nrf::gpio::{Level, Output, OutputDrive}; use embassy_nrf::ppi::{Event, Ppi, Task}; use embassy_nrf::uarte::Uarte; use embassy_nrf::{bind_interrupts, pac, peripherals, uarte}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -50,7 +50,7 @@ async fn main(_spawner: Spawner) { info!("uarte initialized!"); // uarte needs some quiet time to start rxing properly. - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; // Tx spam in a loop. const NSPAM: usize = 17; diff --git a/tests/nrf/src/bin/timer.rs b/tests/nrf/src/bin/timer.rs index c00f35fd..5723acb0 100644 --- a/tests/nrf/src/bin/timer.rs +++ b/tests/nrf/src/bin/timer.rs @@ -5,7 +5,7 @@ teleprobe_meta::target!(b"nrf52840-dk"); use defmt::{assert, info}; use embassy_executor::Spawner; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let start = Instant::now(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; let end = Instant::now(); let ms = (end - start).as_millis(); info!("slept for {} ms", ms); diff --git a/tests/perf-client/src/lib.rs b/tests/perf-client/src/lib.rs index d709c7bd..54762379 100644 --- a/tests/perf-client/src/lib.rs +++ b/tests/perf-client/src/lib.rs @@ -16,7 +16,7 @@ pub struct Expected { pub async fn run(stack: &Stack, expected: Expected) { info!("Waiting for DHCP up..."); while stack.config_v4().is_none() { - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } info!("IP addressing up!"); diff --git a/tests/rp/src/bin/bootsel.rs b/tests/rp/src/bin/bootsel.rs index df1ed8d2..4678775e 100644 --- a/tests/rp/src/bin/bootsel.rs +++ b/tests/rp/src/bin/bootsel.rs @@ -5,7 +5,7 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { // 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; + Timer::after_millis(10).await; assert_eq!(p.BOOTSEL.is_pressed(), false); diff --git a/tests/rp/src/bin/flash.rs b/tests/rp/src/bin/flash.rs index 75be2bf0..2d85135d 100644 --- a/tests/rp/src/bin/flash.rs +++ b/tests/rp/src/bin/flash.rs @@ -6,7 +6,7 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::*; use embassy_executor::Spawner; use embassy_rp::flash::{Async, ERASE_SIZE, FLASH_BASE}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; const ADDR_OFFSET: u32 = 0x8000; @@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) { // 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; + Timer::after_millis(10).await; let mut flash = embassy_rp::flash::Flash::<_, Async, { 2 * 1024 * 1024 }>::new(p.FLASH, p.DMA_CH0); diff --git a/tests/rp/src/bin/float.rs b/tests/rp/src/bin/float.rs index 2874aa91..1e89c10f 100644 --- a/tests/rp/src/bin/float.rs +++ b/tests/rp/src/bin/float.rs @@ -6,7 +6,7 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::*; use embassy_executor::Spawner; use embassy_rp::pac; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) { rad_d + PI_D, rad_d % PI_D ); - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; } let rom_accesses = pac::BUSCTRL.perfctr(0).read().perfctr(); diff --git a/tests/rp/src/bin/gpio_async.rs b/tests/rp/src/bin/gpio_async.rs index 60c65b7a..26582f74 100644 --- a/tests/rp/src/bin/gpio_async.rs +++ b/tests/rp/src/bin/gpio_async.rs @@ -27,7 +27,7 @@ async fn main(_spawner: Spawner) { let set_high_future = async { // Allow time for wait_for_high_future to await wait_for_high(). - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_high(); }; let wait_for_high_future = async { @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_high(), "input was expected to be high"); let set_low_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_low(); }; let wait_for_low_future = async { @@ -67,7 +67,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_low(), "input was expected to be low"); let set_high_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_high(); }; let wait_for_rising_edge_future = async { @@ -87,7 +87,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_high(), "input was expected to be high"); let set_low_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_low(); }; let wait_for_falling_edge_future = async { @@ -107,7 +107,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_high(), "input was expected to be high"); let set_low_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_low(); }; let wait_for_any_edge_future = async { @@ -127,7 +127,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_low(), "input was expected to be low"); let set_high_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_high(); }; let wait_for_any_edge_future = async { diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs index 8c02b844..8c9db115 100644 --- a/tests/rp/src/bin/pwm.rs +++ b/tests/rp/src/bin/pwm.rs @@ -7,7 +7,7 @@ use defmt::{assert, assert_eq, assert_ne, *}; use embassy_executor::Spawner; use embassy_rp::gpio::{Input, Level, Output, Pull}; use embassy_rp::pwm::{Config, InputMode, Pwm}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -48,13 +48,13 @@ async fn main(_spawner: Spawner) { { let pin1 = Input::new(&mut p9, Pull::None); let _pwm = Pwm::new_output_a(&mut p.PWM_CH3, &mut p6, cfg.clone()); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pin1.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_high(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_high(), invert_a); } @@ -62,13 +62,13 @@ async fn main(_spawner: Spawner) { { let pin2 = Input::new(&mut p11, Pull::None); let _pwm = Pwm::new_output_b(&mut p.PWM_CH3, &mut p7, cfg.clone()); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_ne!(pin2.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_ne!(pin2.is_high(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_ne!(pin2.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_ne!(pin2.is_high(), invert_a); } @@ -77,16 +77,16 @@ async fn main(_spawner: Spawner) { let pin1 = Input::new(&mut p9, Pull::None); let pin2 = Input::new(&mut p11, Pull::None); let _pwm = Pwm::new_output_ab(&mut p.PWM_CH3, &mut p6, &mut p7, cfg.clone()); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pin1.is_low(), invert_a); assert_ne!(pin2.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_high(), invert_a); assert_ne!(pin2.is_high(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_low(), invert_a); assert_ne!(pin2.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_high(), invert_a); assert_ne!(pin2.is_high(), invert_a); } @@ -97,14 +97,14 @@ async fn main(_spawner: Spawner) { let mut pin2 = Output::new(&mut p11, Level::Low); let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::Level, cfg.clone()); assert_eq!(pwm.counter(), 0); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); pin2.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; pin2.set_low(); let ctr = pwm.counter(); assert!(ctr >= 1000); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pwm.counter(), ctr); } @@ -113,13 +113,13 @@ async fn main(_spawner: Spawner) { let mut pin2 = Output::new(&mut p11, Level::Low); let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::RisingEdge, cfg.clone()); assert_eq!(pwm.counter(), 0); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); pin2.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; pin2.set_low(); assert_eq!(pwm.counter(), 1); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pwm.counter(), 1); } @@ -128,13 +128,13 @@ async fn main(_spawner: Spawner) { let mut pin2 = Output::new(&mut p11, Level::High); let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::FallingEdge, cfg.clone()); assert_eq!(pwm.counter(), 0); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); pin2.set_low(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; pin2.set_high(); assert_eq!(pwm.counter(), 1); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pwm.counter(), 1); } diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs index 00f3e194..8d351a3a 100644 --- a/tests/rp/src/bin/uart.rs +++ b/tests/rp/src/bin/uart.rs @@ -7,7 +7,7 @@ use defmt::{assert_eq, *}; use embassy_executor::Spawner; use embassy_rp::gpio::{Level, Output}; use embassy_rp::uart::{Blocking, Config, Error, Instance, Parity, Uart, UartRx}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; fn read(uart: &mut Uart<'_, impl Instance, Blocking>) -> Result<[u8; N], Error> { @@ -24,14 +24,14 @@ fn read1(uart: &mut UartRx<'_, impl Instance, Blocking>) -> Resu async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option) { pin.set_low(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; for i in 0..8 { if v & (1 << i) == 0 { pin.set_low(); } else { pin.set_high(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } if let Some(b) = parity { if b { @@ -39,10 +39,10 @@ async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: O } else { pin.set_low(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } pin.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } #[embassy_executor::main] diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs index 6ab7de29..6a9c910f 100644 --- a/tests/rp/src/bin/uart_buffered.rs +++ b/tests/rp/src/bin/uart_buffered.rs @@ -9,7 +9,7 @@ use embassy_rp::bind_interrupts; use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::UART0; use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config, Error, Instance, Parity}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::{Read, ReadExactError, Write}; use {defmt_rtt as _, panic_probe as _}; @@ -39,14 +39,14 @@ async fn read1(uart: &mut BufferedUartRx<'_, impl Instance>) -> async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option) { pin.set_low(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; for i in 0..8 { if v & (1 << i) == 0 { pin.set_low(); } else { pin.set_high(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } if let Some(b) = parity { if b { @@ -54,10 +54,10 @@ async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: O } else { pin.set_low(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } pin.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } #[embassy_executor::main] diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs index cd4af1ef..e79fcde6 100644 --- a/tests/rp/src/bin/uart_dma.rs +++ b/tests/rp/src/bin/uart_dma.rs @@ -9,7 +9,7 @@ use embassy_rp::bind_interrupts; use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::UART0; use embassy_rp::uart::{Async, Config, Error, Instance, InterruptHandler, Parity, Uart, UartRx}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -30,14 +30,14 @@ async fn read1(uart: &mut UartRx<'_, impl Instance, Async>) -> R async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option) { pin.set_low(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; for i in 0..8 { if v & (1 << i) == 0 { pin.set_low(); } else { pin.set_high(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } if let Some(b) = parity { if b { @@ -45,10 +45,10 @@ async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: O } else { pin.set_low(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } pin.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } #[embassy_executor::main] @@ -105,7 +105,7 @@ async fn main(_spawner: Spawner) { // new data is accepted, latest overrunning byte first assert_eq!(read(&mut uart).await, Ok([3])); uart.blocking_write(&[8, 9]).unwrap(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(read(&mut uart).await, Ok([8, 9])); } diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs index fb7a84b1..10e3c3e8 100644 --- a/tests/stm32/src/bin/dac.rs +++ b/tests/stm32/src/bin/dac.rs @@ -12,7 +12,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::Adc; use embassy_stm32::dac::{DacCh1, DacChannel, Value}; use embassy_stm32::dma::NoDma; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) { unwrap!(dac.set(Value::Bit8(0))); // Now wait a little to obtain a stable value - Timer::after(Duration::from_millis(30)).await; + Timer::after_millis(30).await; let offset = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); for v in 0..=255 { @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { unwrap!(dac.set(Value::Bit8(dac_output_val))); // Now wait a little to obtain a stable value - Timer::after(Duration::from_millis(30)).await; + Timer::after_millis(30).await; // Need to steal the peripherals here because PA4 is obviously in use already let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs index 46fdbfae..64f1122a 100644 --- a/tests/stm32/src/bin/rtc.rs +++ b/tests/stm32/src/bin/rtc.rs @@ -12,7 +12,7 @@ use defmt::assert; use embassy_executor::Spawner; use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; #[embassy_executor::main] async fn main(_spawner: Spawner) { @@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now.into()).expect("datetime not set"); info!("Waiting 5 seconds"); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; let then: NaiveDateTime = rtc.now().unwrap().into(); let seconds = (then - now).num_seconds(); diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 929869bc..f38924c9 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs @@ -14,7 +14,7 @@ use embassy_stm32::low_power::{stop_with_rtc, Executor}; use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::make_static; #[entry] @@ -28,7 +28,7 @@ fn main() -> ! { async fn task_1() { for _ in 0..9 { info!("task 1: waiting for 500ms..."); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } @@ -36,7 +36,7 @@ async fn task_1() { async fn task_2() { for _ in 0..5 { info!("task 2: waiting for 1000ms..."); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } info!("Test OK"); diff --git a/tests/stm32/src/bin/timer.rs b/tests/stm32/src/bin/timer.rs index f8b453cd..4efeb0a4 100644 --- a/tests/stm32/src/bin/timer.rs +++ b/tests/stm32/src/bin/timer.rs @@ -7,7 +7,7 @@ mod common; use common::*; use defmt::assert; use embassy_executor::Spawner; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; #[embassy_executor::main] async fn main(_spawner: Spawner) { @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let start = Instant::now(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; let end = Instant::now(); let ms = (end - start).as_millis(); info!("slept for {} ms", ms); diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs index 1ee7e596..7e15f64b 100644 --- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs +++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs @@ -10,7 +10,7 @@ use common::*; use defmt::{assert_eq, panic}; use embassy_executor::Spawner; use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use rand_chacha::ChaCha8Rng; use rand_core::{RngCore, SeedableRng}; @@ -54,7 +54,7 @@ async fn main(spawner: Spawner) { #[embassy_executor::task] async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) { // workaround https://github.com/embassy-rs/embassy/issues/1426 - Timer::after(Duration::from_millis(100) as _).await; + Timer::after_millis(100).await; let mut rng = ChaCha8Rng::seed_from_u64(1337); @@ -70,7 +70,7 @@ async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) } tx.write(&buf[..len]).await.unwrap(); - Timer::after(Duration::from_micros((rng.next_u32() % 1000) as _)).await; + Timer::after_micros((rng.next_u32() % 1000) as _).await; } } @@ -98,7 +98,7 @@ async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART, peris::UA } if received < max_len { - Timer::after(Duration::from_micros((rng.next_u32() % 1000) as _)).await; + Timer::after_micros((rng.next_u32() % 1000) as _).await; } i += received; From 8a10948ce97fa3b3c29cf55c91585789dd0f360c Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 15 Oct 2023 03:08:14 +0200 Subject: [PATCH 011/188] stm32/rcc: port L4 to the "flattened" API like h5/h7. --- embassy-stm32/src/rcc/l4.rs | 371 ++++++++++-------- examples/stm32l4/src/bin/rng.rs | 20 +- examples/stm32l4/src/bin/rtc.rs | 28 +- .../src/bin/spe_adin1110_http_server.rs | 19 +- examples/stm32l4/src/bin/usb_serial.rs | 11 +- tests/stm32/src/common.rs | 20 +- 6 files changed, 275 insertions(+), 194 deletions(-) diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 1e5733d3..020f4e20 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -1,9 +1,8 @@ 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, + Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, }; -use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -11,42 +10,47 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// System clock mux source #[derive(Clone, Copy)] -pub enum ClockSrc { - MSI(MSIRange), - PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option), - HSE(Hertz), - HSI16, -} +pub struct Pll { + /// PLL pre-divider (DIVM). + pub prediv: PllPreDiv, -/// PLL clock input source -#[derive(Clone, Copy)] -pub enum PLLSource { - HSI16, - HSE(Hertz), - MSI(MSIRange), -} + /// PLL multiplication factor. + pub mul: PllMul, -impl From for Pllsrc { - fn from(val: PLLSource) -> Pllsrc { - match val { - PLLSource::HSI16 => Pllsrc::HSI16, - PLLSource::HSE(_) => Pllsrc::HSE, - PLLSource::MSI(_) => Pllsrc::MSI, - } - } + /// PLL P division factor. If None, PLL P output is disabled. + 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, } /// Clocks configutation pub struct Config { + // base clock sources + pub msi: Option, + pub hsi16: bool, + pub hse: Option, + #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] + pub hsi48: bool, + + // pll + pub pll_src: PLLSource, + pub pll: Option, + pub pllsai1: Option, + #[cfg(any( + stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx + ))] + pub pllsai2: Option, + + // sysclk, buses. pub mux: ClockSrc, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, - pub pllsai1: Option<(PllMul, PllPreDiv, Option, Option, Option)>, - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - pub hsi48: bool, + + // low speed LSI/LSE/RTC pub ls: super::LsConfig, } @@ -54,11 +58,20 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::MSI(MSIRange::RANGE4M), + hse: None, + hsi16: false, + msi: Some(MSIRange::RANGE4M), + mux: ClockSrc::MSI, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, + pll_src: PLLSource::NONE, + pll: None, pllsai1: None, + #[cfg(any( + stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx + ))] + pllsai2: None, #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] hsi48: false, ls: Default::default(), @@ -80,154 +93,204 @@ pub(crate) unsafe fn init(config: Config) { // Wait until MSI is running while !RCC.cr().read().msirdy() {} } - if RCC.cfgr().read().sws() != Sw::MSI { + if RCC.cfgr().read().sws() != ClockSrc::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 {} + while RCC.cfgr().read().sws() != ClockSrc::MSI {} } let rtc = config.ls.init(); - let (sys_clk, sw) = match config.mux { - ClockSrc::MSI(range) => { - // Enable MSI - RCC.cr().write(|w| { - w.set_msirange(range); - w.set_msirgsel(true); - w.set_msion(true); + let msi = config.msi.map(|range| { + // Enable MSI + RCC.cr().write(|w| { + w.set_msirange(range); + w.set_msirgsel(true); + w.set_msion(true); - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(config.ls.lse.is_some()); - }); - while !RCC.cr().read().msirdy() {} + // If LSE is enabled, enable calibration of MSI + w.set_msipllen(config.ls.lse.is_some()); + }); + while !RCC.cr().read().msirdy() {} - // Enable as clock source for USB, RNG if running at 48 MHz - if range == MSIRange::RANGE48M { - RCC.ccipr().modify(|w| { - w.set_clk48sel(0b11); - }); - } - (msirange_to_hertz(range), Sw::MSI) + // Enable as clock source for USB, RNG if running at 48 MHz + if range == MSIRange::RANGE48M { + RCC.ccipr().modify(|w| w.set_clk48sel(0b11)); } - ClockSrc::HSI16 => { - // Enable HSI16 - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - (HSI_FREQ, Sw::HSI16) - } - ClockSrc::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} + msirange_to_hertz(range) + }); - (freq, Sw::HSE) - } - 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 - } - PLLSource::HSI16 => { - // Enable HSI - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - HSI_FREQ - } - PLLSource::MSI(range) => { - // Enable MSI - RCC.cr().write(|w| { - w.set_msirange(range); - w.set_msipllen(false); // should be turned on if LSE is started - w.set_msirgsel(true); - w.set_msion(true); - }); - while !RCC.cr().read().msirdy() {} + let hsi16 = config.hsi16.then(|| { + RCC.cr().write(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} - msirange_to_hertz(range) - } - }; + HSI_FREQ + }); - // Disable PLL - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} + let hse = config.hse.map(|freq| { + RCC.cr().write(|w| w.set_hseon(true)); + while !RCC.cr().read().hserdy() {} - let freq = src_freq / prediv * mul / divr; - - #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] - assert!(freq.0 <= 120_000_000); - #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))] - assert!(freq.0 <= 80_000_000); - - RCC.pllcfgr().write(move |w| { - 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(divq) = divq { - let freq = src_freq / prediv * mul / divq; - assert!(freq.0 == 48_000_000); - RCC.ccipr().modify(|w| { - w.set_clk48sel(0b10); - }); - } - - if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { - RCC.pllsai1cfgr().write(move |w| { - w.set_plln(mul); - w.set_pllm(prediv); - if let Some(r_div) = r_div { - w.set_pllr(r_div); - w.set_pllren(true); - } - if let Some(q_div) = q_div { - 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_pllp(p_div); - w.set_pllpen(true); - } - }); - - RCC.cr().modify(|w| w.set_pllsai1on(true)); - } - - // Enable PLL - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - RCC.pllcfgr().modify(|w| w.set_pllren(true)); - - (freq, Sw::PLL) - } - }; + freq + }); #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - if config.hsi48 { + let _hsi48 = config.hsi48.then(|| { RCC.crrcr().modify(|w| w.set_hsi48on(true)); while !RCC.crrcr().read().hsi48rdy() {} // Enable as clock source for USB, RNG and SDMMC RCC.ccipr().modify(|w| w.set_clk48sel(0)); + + Hertz(48_000_000) + }); + + let pll_src = match config.pll_src { + PLLSource::NONE => None, + PLLSource::HSE => hse, + PLLSource::HSI16 => hsi16, + PLLSource::MSI => msi, + }; + + let mut _pllp = None; + let mut _pllq = None; + let mut _pllr = None; + if let Some(pll) = config.pll { + let pll_src = pll_src.unwrap(); + + // Disable PLL + RCC.cr().modify(|w| w.set_pllon(false)); + while RCC.cr().read().pllrdy() {} + + let vco_freq = pll_src / pll.prediv * pll.mul; + + _pllp = pll.divp.map(|div| vco_freq / div); + _pllq = pll.divq.map(|div| vco_freq / div); + _pllr = pll.divr.map(|div| vco_freq / div); + + RCC.pllcfgr().write(move |w| { + w.set_plln(pll.mul); + w.set_pllm(pll.prediv); + w.set_pllsrc(config.pll_src); + if let Some(divp) = pll.divp { + w.set_pllp(divp); + w.set_pllpen(true); + } + if let Some(divq) = pll.divq { + w.set_pllq(divq); + w.set_pllqen(true); + } + if let Some(divr) = pll.divr { + w.set_pllr(divr); + w.set_pllren(true); + } + }); + + if _pllq == Some(Hertz(48_000_000)) { + RCC.ccipr().modify(|w| w.set_clk48sel(0b10)); + } + + // Enable PLL + RCC.cr().modify(|w| w.set_pllon(true)); + while !RCC.cr().read().pllrdy() {} + } else { + // even if we're not using the main pll, set the source for pllsai + RCC.pllcfgr().write(move |w| { + w.set_pllsrc(config.pll_src); + }); } + if let Some(pll) = config.pllsai1 { + let pll_src = pll_src.unwrap(); + + // Disable PLL + RCC.cr().modify(|w| w.set_pllsai1on(false)); + while RCC.cr().read().pllsai1rdy() {} + + let vco_freq = pll_src / pll.prediv * pll.mul; + + let _pllp = pll.divp.map(|div| vco_freq / div); + let _pllq = pll.divq.map(|div| vco_freq / div); + let _pllr = pll.divr.map(|div| vco_freq / div); + + RCC.pllsai1cfgr().write(move |w| { + w.set_plln(pll.mul); + w.set_pllm(pll.prediv); + if let Some(divp) = pll.divp { + w.set_pllp(divp); + w.set_pllpen(true); + } + if let Some(divq) = pll.divq { + w.set_pllq(divq); + w.set_pllqen(true); + } + if let Some(divr) = pll.divr { + w.set_pllr(divr); + w.set_pllren(true); + } + }); + + if _pllq == Some(Hertz(48_000_000)) { + RCC.ccipr().modify(|w| w.set_clk48sel(0b01)); + } + + // Enable PLL + RCC.cr().modify(|w| w.set_pllsai1on(true)); + while !RCC.cr().read().pllsai1rdy() {} + } + + #[cfg(any( + stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx + ))] + if let Some(pll) = config.pllsai2 { + let pll_src = pll_src.unwrap(); + + // Disable PLL + RCC.cr().modify(|w| w.set_pllsai2on(false)); + while RCC.cr().read().pllsai2rdy() {} + + let vco_freq = pll_src / pll.prediv * pll.mul; + + let _pllp = pll.divp.map(|div| vco_freq / div); + let _pllq = pll.divq.map(|div| vco_freq / div); + let _pllr = pll.divr.map(|div| vco_freq / div); + + RCC.pllsai2cfgr().write(move |w| { + w.set_plln(pll.mul); + w.set_pllm(pll.prediv); + if let Some(divp) = pll.divp { + w.set_pllp(divp); + w.set_pllpen(true); + } + if let Some(divq) = pll.divq { + w.set_pllq(divq); + w.set_pllqen(true); + } + if let Some(divr) = pll.divr { + w.set_pllr(divr); + w.set_pllren(true); + } + }); + + // Enable PLL + RCC.cr().modify(|w| w.set_pllsai2on(true)); + while !RCC.cr().read().pllsai2rdy() {} + } + + let sys_clk = match config.mux { + ClockSrc::HSE => hse.unwrap(), + ClockSrc::HSI16 => hsi16.unwrap(), + ClockSrc::MSI => msi.unwrap(), + ClockSrc::PLL => _pllr.unwrap(), + }; + + #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] + assert!(sys_clk.0 <= 120_000_000); + #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))] + assert!(sys_clk.0 <= 80_000_000); + // Set flash wait states FLASH.acr().modify(|w| { w.set_latency(match sys_clk.0 { @@ -240,7 +303,7 @@ pub(crate) unsafe fn init(config: Config) { }); RCC.cfgr().modify(|w| { - w.set_sw(sw); + w.set_sw(config.mux); w.set_hpre(config.ahb_pre); w.set_ppre1(config.apb1_pre); w.set_ppre2(config.apb2_pre); @@ -277,7 +340,7 @@ pub(crate) unsafe fn init(config: Config) { }); } -fn msirange_to_hertz(range: Msirange) -> Hertz { +fn msirange_to_hertz(range: MSIRange) -> Hertz { match range { MSIRange::RANGE100K => Hertz(100_000), MSIRange::RANGE200K => Hertz(200_000), diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index d0208d8a..94251c12 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, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -16,14 +16,16 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - // 72Mhz clock (16 / 1 * 18 / 4) - config.rcc.mux = ClockSrc::PLL( - PLLSource::HSI16, - PllRDiv::DIV4, - PllPreDiv::DIV1, - PllMul::MUL18, - Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) - ); + config.rcc.mux = ClockSrc::PLL; + config.rcc.hsi16 = true; + config.rcc.pll_src = PLLSource::HSI16; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL18, + divp: None, + divq: Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) + divr: Some(PllRDiv::DIV4), // sysclk 72Mhz clock (16 / 1 * 18 / 4) + }); let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index f5d46e95..cd9f72ff 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::{ClockSrc, LsConfig, PLLSource, PllMul, PllPreDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; @@ -14,18 +14,20 @@ use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let p = { - let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL( - PLLSource::HSE(Hertz::mhz(8)), - PllRDiv::DIV2, - PllPreDiv::DIV1, - PllMul::MUL20, - None, - ); - config.rcc.ls = LsConfig::default_lse(); - embassy_stm32::init(config) - }; + let mut config = Config::default(); + config.rcc.mux = ClockSrc::PLL; + config.rcc.hse = Some(Hertz::mhz(8)); + config.rcc.pll_src = PLLSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) + }); + 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/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index e2ac22d0..c1a27cf8 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -48,7 +48,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, PLLSource, PllMul, PllPreDiv, PllRDiv}; +use hal::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; use hal::spi::{Config as SPI_Config, Spi}; use hal::time::Hertz; @@ -77,13 +77,16 @@ async fn main(spawner: Spawner) { // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) // 80MHz highest frequency for flash 0 wait. - config.rcc.mux = ClockSrc::PLL( - PLLSource::HSE(Hertz(8_000_000)), - PllRDiv::DIV2, - PllPreDiv::DIV1, - PllMul::MUL20, - None, - ); + config.rcc.mux = ClockSrc::PLL; + config.rcc.hse = Some(Hertz::mhz(8)); + config.rcc.pll_src = PLLSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) + }); config.rcc.hsi48 = true; // needed for rng let dp = embassy_stm32::init(config); diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index dc0d98ad..8f6eeef3 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -23,8 +23,17 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); config.rcc.hsi48 = true; + config.rcc.mux = ClockSrc::PLL; + config.rcc.hsi16 = true; + config.rcc.pll_src = PLLSource::HSI16; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2) + }); let p = embassy_stm32::init(config); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 2bf50079..e1d7855f 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -284,17 +284,19 @@ pub fn config() -> Config { config.rcc.adc_clock_source = AdcClockSource::PLL2_P; } - #[cfg(any(feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] + #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::PLL( - // 72Mhz clock (16 / 1 * 18 / 4) - PLLSource::HSI16, - PllRDiv::DIV4, - PllPreDiv::DIV1, - PllMul::MUL18, - Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) - ); + config.rcc.mux = ClockSrc::PLL; + config.rcc.hsi16 = true; + config.rcc.pll_src = PLLSource::HSI16; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL18, + divp: None, + divq: Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) + divr: Some(PllRDiv::DIV4), // sysclk 72Mhz clock (16 / 1 * 18 / 4) + }); } #[cfg(any(feature = "stm32l552ze"))] From 4a156df7a1e3ed9513cc61cb063d7af86b5cc2fb Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 14 Oct 2023 23:33:57 -0500 Subject: [PATCH 012/188] stm32: expand rcc mux to g4 and h7 --- embassy-stm32/Cargo.toml | 4 +-- embassy-stm32/build.rs | 43 +++++++++++++----------------- embassy-stm32/src/rcc/g4.rs | 17 ++++++------ embassy-stm32/src/rcc/h.rs | 33 ++++++++++++----------- embassy-stm32/src/rcc/mod.rs | 47 ++++++++++++++++++--------------- examples/stm32g4/src/bin/adc.rs | 2 +- 6 files changed, 72 insertions(+), 74 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index b18cafb8..0629bc09 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-e6e51db6cdd7d533e52ca7a3237f7816a0486cd4" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7dafe9d8bbc739be48199185f0caa1582b1da3f7" } 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-e6e51db6cdd7d533e52ca7a3237f7816a0486cd4", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7dafe9d8bbc739be48199185f0caa1582b1da3f7", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 3e1c76f3..45aad027 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -388,20 +388,21 @@ fn main() { }); } + // ======== + // Extract the rcc registers + let rcc_registers = METADATA + .peripherals + .iter() + .filter_map(|p| p.registers.as_ref()) + .find(|r| r.kind == "rcc") + .unwrap(); + // ======== // 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_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_blocks = rcc_registers.ir.blocks.iter().find(|b| b.name == "Rcc").unwrap().items; + let rcc_fieldsets: HashMap<&str, &FieldSet> = rcc_registers.ir.fieldsets.iter().map(|f| (f.name, f)).collect(); + let rcc_enums: HashMap<&str, &Enum> = rcc_registers.ir.enums.iter().map(|e| (e.name, e)).collect(); rcc_blocks .iter() @@ -494,8 +495,10 @@ fn main() { }; let mux_for = |mux: Option<&'static PeripheralRccRegister>| { - // temporary hack to restrict the scope of the implementation to h5 - if !&chip_name.starts_with("stm32h5") { + let checked_rccs = HashSet::from(["h5", "h50", "h7", "h7ab", "h7rm0433", "g4"]); + + // restrict mux implementation to supported versions + if !checked_rccs.contains(rcc_registers.version) { return None; } @@ -518,11 +521,9 @@ fn main() { .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!("{}", v.name.to_ascii_lowercase()); - if v.name.starts_with("AHB") || v.name.starts_with("APB") { + if v.name.starts_with("AHB") || v.name.starts_with("APB") || v.name == "SYS" { quote! { #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name }, } @@ -1013,15 +1014,7 @@ 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 { + for e in rcc_registers.ir.enums { fn is_rcc_name(e: &str) -> bool { match e { "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true, diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index afdf5cc7..581bf9e0 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -119,8 +119,8 @@ impl Default for Config { low_power_run: false, pll: None, clock_48mhz_src: None, - adc12_clock_source: Adcsel::NOCLK, - adc345_clock_source: Adcsel::NOCLK, + adc12_clock_source: Adcsel::DISABLE, + adc345_clock_source: Adcsel::DISABLE, ls: Default::default(), } } @@ -326,16 +326,16 @@ pub(crate) unsafe fn init(config: Config) { RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source)); let adc12_ck = match config.adc12_clock_source { - AdcClockSource::NOCLK => None, - AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p, - AdcClockSource::SYSCLK => Some(sys_clk), + AdcClockSource::DISABLE => None, + AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p, + AdcClockSource::SYS => Some(sys_clk), _ => unreachable!(), }; let adc345_ck = match config.adc345_clock_source { - AdcClockSource::NOCLK => None, - AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p, - AdcClockSource::SYSCLK => Some(sys_clk), + AdcClockSource::DISABLE => None, + AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p, + AdcClockSource::SYS => Some(sys_clk), _ => unreachable!(), }; @@ -356,6 +356,7 @@ pub(crate) unsafe fn init(config: Config) { apb2_tim: apb2_tim_freq, adc: adc12_ck, adc34: adc345_ck, + pll1_p: None, rtc, }); } diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 9132df7e..bbbbc9c1 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -446,7 +446,7 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(stm32h5)] let adc = match config.adc_clock_source { AdcClockSource::HCLK => Some(hclk), - AdcClockSource::SYSCLK => Some(sys), + AdcClockSource::SYS => Some(sys), AdcClockSource::PLL2_R => pll2.r, AdcClockSource::HSE => hse, AdcClockSource::HSI => hsi, @@ -540,36 +540,34 @@ pub(crate) unsafe fn init(config: Config) { adc, rtc, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] hsi: None, #[cfg(stm32h5)] hsi48: None, #[cfg(stm32h5)] lsi: None, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] csi: None, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] lse: None, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] hse: None, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] pll1_q: pll1.q, - #[cfg(stm32h5)] - pll2_q: pll2.q, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] pll2_p: pll2.p, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] + pll2_q: pll2.q, + #[cfg(any(stm32h5, stm32h7))] pll2_r: pll2.r, - #[cfg(rcc_h5)] + #[cfg(any(rcc_h5, stm32h7))] pll3_p: pll3.p, - #[cfg(rcc_h5)] + #[cfg(any(rcc_h5, stm32h7))] pll3_q: pll3.q, - #[cfg(rcc_h5)] + #[cfg(any(rcc_h5, stm32h7))] pll3_r: pll3.r, - #[cfg(stm32h5)] - pll3_1: None, #[cfg(rcc_h50)] pll3_p: None, @@ -580,8 +578,11 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(stm32h5)] audioclk: None, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] per: None, + + #[cfg(stm32h7)] + rcc_pclk_d3: None, }); } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 0904ddbd..1603a2c3 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -113,6 +113,23 @@ pub struct Clocks { #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pub pllsai: Option, + #[cfg(stm32g4)] + pub pll1_p: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll1_q: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll2_q: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll2_p: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll2_r: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll3_p: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll3_q: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll3_r: Option, + #[cfg(any( rcc_f1, rcc_f100, @@ -135,41 +152,27 @@ pub struct Clocks { pub rtc: Option, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] pub hsi: Option, #[cfg(stm32h5)] pub hsi48: Option, #[cfg(stm32h5)] pub lsi: Option, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] pub csi: Option, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] pub lse: Option, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] pub hse: Option, - #[cfg(stm32h5)] - pub pll1_q: Option, - #[cfg(stm32h5)] - pub pll2_q: Option, - #[cfg(stm32h5)] - pub pll2_p: Option, - #[cfg(stm32h5)] - pub pll2_r: Option, - #[cfg(stm32h5)] - 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 audioclk: Option, - #[cfg(stm32h5)] + #[cfg(any(stm32h5, stm32h7))] pub per: Option, + + #[cfg(stm32h7)] + pub rcc_pclk_d3: Option, } #[cfg(feature = "low-power")] diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index 9daf4e4c..db7f6ecb 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::SYS; config.rcc.mux = ClockSrc::PLL; let mut p = embassy_stm32::init(config); From 2aaf4bf96b960d6379b4c089145031d18c065aa3 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Sun, 15 Oct 2023 19:14:34 +0200 Subject: [PATCH 013/188] fix typo in build.rs that caused fmc ClkPin to not be implemented --- embassy-stm32/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 8e680fb6..710e1185 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -797,7 +797,7 @@ fn main() { (("fmc", "NCE"), quote!(crate::fmc::NCEPin)), (("fmc", "NOE"), quote!(crate::fmc::NOEPin)), (("fmc", "NWE"), quote!(crate::fmc::NWEPin)), - (("fmc", "Clk"), quote!(crate::fmc::ClkPin)), + (("fmc", "CLK"), quote!(crate::fmc::ClkPin)), (("fmc", "BA0"), quote!(crate::fmc::BA0Pin)), (("fmc", "BA1"), quote!(crate::fmc::BA1Pin)), (("timer", "CH1"), quote!(crate::timer::Channel1Pin)), From 1fc35c753b93ee2b5ebe25e5c20ed24e850f995f Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 15 Oct 2023 15:10:42 -0500 Subject: [PATCH 014/188] rcc: update pll clock naming --- embassy-stm32/src/i2s.rs | 2 +- embassy-stm32/src/rcc/f2.rs | 2 +- embassy-stm32/src/rcc/f4.rs | 10 +++++++--- embassy-stm32/src/rcc/f7.rs | 2 +- embassy-stm32/src/rcc/mod.rs | 17 +++++++++-------- embassy-stm32/src/sdmmc/mod.rs | 6 +++--- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index 8fd3a8c6..67d40c47 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs @@ -170,7 +170,7 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> { let spi = Spi::new_internal(peri, txdma, rxdma, spi_cfg); #[cfg(all(rcc_f4, not(stm32f410)))] - let pclk = unsafe { get_freqs() }.plli2s.unwrap(); + let pclk = unsafe { get_freqs() }.plli2s1_q.unwrap(); #[cfg(stm32f410)] let pclk = T::frequency(); diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index ab588233..34720e83 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -314,7 +314,7 @@ pub(crate) unsafe fn init(config: Config) { apb1_tim: apb1_tim_freq, apb2: apb2_freq, apb2_tim: apb2_tim_freq, - pll48: Some(pll_clocks.pll48_freq), + pll1_q: Some(pll_clocks.pll48_freq), rtc, }); } diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index 79c2d2f6..91ad81b2 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -350,13 +350,17 @@ pub(crate) unsafe fn init(config: Config) { ahb2: Hertz(hclk), ahb3: Hertz(hclk), - pll48: plls.pll48clk.map(Hertz), + pll1_q: plls.pll48clk.map(Hertz), #[cfg(not(stm32f410))] - plli2s: plls.plli2sclk.map(Hertz), + plli2s1_q: plls.plli2sclk.map(Hertz), + #[cfg(not(stm32f410))] + plli2s1_r: None, #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - pllsai: plls.pllsaiclk.map(Hertz), + pllsai1_q: plls.pllsaiclk.map(Hertz), + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + pllsai1_r: None, rtc, }); diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs index 0a0a1cf2..f0e01149 100644 --- a/embassy-stm32/src/rcc/f7.rs +++ b/embassy-stm32/src/rcc/f7.rs @@ -269,7 +269,7 @@ pub(crate) unsafe fn init(config: Config) { ahb2: Hertz(hclk), ahb3: Hertz(hclk), - pll48: plls.pll48clk.map(Hertz), + pll1_q: plls.pll48clk.map(Hertz), rtc, }); diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 1603a2c3..0cc9e6a6 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -104,24 +104,25 @@ pub struct Clocks { #[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))] - pub pll48: Option, - #[cfg(all(rcc_f4, not(stm32f410)))] - pub plli2s: Option, + pub plli2s1_q: Option, + #[cfg(all(rcc_f4, not(stm32f410)))] + pub plli2s1_r: Option, #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - pub pllsai: Option, + pub pllsai1_q: Option, + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + pub pllsai1_r: Option, #[cfg(stm32g4)] pub pll1_p: Option, - #[cfg(any(stm32h5, stm32h7))] + #[cfg(any(stm32h5, stm32h7, rcc_f2, rcc_f4, rcc_f410, rcc_f7))] pub pll1_q: Option, #[cfg(any(stm32h5, stm32h7))] - pub pll2_q: Option, - #[cfg(any(stm32h5, stm32h7))] pub pll2_p: Option, #[cfg(any(stm32h5, stm32h7))] + pub pll2_q: Option, + #[cfg(any(stm32h5, stm32h7))] pub pll2_r: Option, #[cfg(any(stm32h5, stm32h7))] pub pll3_p: Option, diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index bc29fe54..11ff2464 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -1457,7 +1457,7 @@ cfg_if::cfg_if! { macro_rules! kernel_clk { ($inst:ident) => { critical_section::with(|_| unsafe { - crate::rcc::get_freqs().pll48 + crate::rcc::get_freqs().pll1_q }).expect("PLL48 is required for SDIO") } } @@ -1469,7 +1469,7 @@ cfg_if::cfg_if! { if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { crate::rcc::get_freqs().sys } else { - crate::rcc::get_freqs().pll48.expect("PLL48 is required for SDMMC") + crate::rcc::get_freqs().pll1_q.expect("PLL48 is required for SDMMC") } }) }; @@ -1479,7 +1479,7 @@ cfg_if::cfg_if! { if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { crate::rcc::get_freqs().sys } else { - crate::rcc::get_freqs().pll48.expect("PLL48 is required for SDMMC") + crate::rcc::get_freqs().pll1_q.expect("PLL48 is required for SDMMC") } }) }; From eeedaf2e763c79a5758460936ba32f23ceb7956c Mon Sep 17 00:00:00 2001 From: Rafael Bachmann Date: Sun, 15 Oct 2023 22:11:30 +0200 Subject: [PATCH 015/188] Constify Config::new --- embassy-usb/src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 6b68bcd7..8860f9ee 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs @@ -99,7 +99,7 @@ pub struct Config<'a> { impl<'a> Config<'a> { /// Create default configuration with the provided vid and pid values. - pub fn new(vid: u16, pid: u16) -> Self { + pub const fn new(vid: u16, pid: u16) -> Self { Self { device_class: 0x00, device_sub_class: 0x00, From 66e62e999409fd6967ab959a061f7eae660102d0 Mon Sep 17 00:00:00 2001 From: Rafael Bachmann Date: Sun, 15 Oct 2023 22:25:35 +0200 Subject: [PATCH 016/188] Fix clippy --- embassy-usb/src/class/cdc_acm.rs | 8 +++++++- embassy-usb/src/class/cdc_ncm/mod.rs | 15 ++++++++------- embassy-usb/src/class/hid.rs | 16 +++++++++++----- embassy-usb/src/descriptor.rs | 2 +- embassy-usb/src/lib.rs | 13 +++++-------- 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index 0c708464..790f6faa 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs @@ -39,6 +39,12 @@ pub struct State<'a> { shared: ControlShared, } +impl<'a> Default for State<'a> { + fn default() -> Self { + Self::new() + } +} + impl<'a> State<'a> { /// Create a new `State`. pub fn new() -> Self { @@ -242,7 +248,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { &[ CDC_TYPE_UNION, // bDescriptorSubtype comm_if.into(), // bControlInterface - data_if.into(), // bSubordinateInterface + data_if, // bSubordinateInterface ], ); diff --git a/embassy-usb/src/class/cdc_ncm/mod.rs b/embassy-usb/src/class/cdc_ncm/mod.rs index 830e9b76..27716b37 100644 --- a/embassy-usb/src/class/cdc_ncm/mod.rs +++ b/embassy-usb/src/class/cdc_ncm/mod.rs @@ -121,6 +121,12 @@ pub struct State<'a> { shared: ControlShared, } +impl<'a> Default for State<'a> { + fn default() -> Self { + Self::new() + } +} + impl<'a> State<'a> { /// Create a new `State`. pub fn new() -> Self { @@ -132,16 +138,11 @@ impl<'a> State<'a> { } /// Shared data between Control and CdcAcmClass +#[derive(Default)] struct ControlShared { mac_addr: [u8; 6], } -impl Default for ControlShared { - fn default() -> Self { - ControlShared { mac_addr: [0; 6] } - } -} - struct Control<'a> { mac_addr_string: StringIndex, shared: &'a ControlShared, @@ -416,7 +417,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { self.write_ep.write(&buf[..self.max_packet_size]).await?; for chunk in d2.chunks(self.max_packet_size) { - self.write_ep.write(&chunk).await?; + self.write_ep.write(chunk).await?; } // Send ZLP if needed. diff --git a/embassy-usb/src/class/hid.rs b/embassy-usb/src/class/hid.rs index 889d66ec..0da29b1a 100644 --- a/embassy-usb/src/class/hid.rs +++ b/embassy-usb/src/class/hid.rs @@ -79,6 +79,12 @@ pub struct State<'d> { out_report_offset: AtomicUsize, } +impl<'d> Default for State<'d> { + fn default() -> Self { + Self::new() + } +} + impl<'d> State<'d> { /// Create a new `State`. pub fn new() -> Self { @@ -171,7 +177,7 @@ impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWrit } /// Waits for both IN and OUT endpoints to be enabled. - pub async fn ready(&mut self) -> () { + pub async fn ready(&mut self) { self.reader.ready().await; self.writer.ready().await; } @@ -251,7 +257,7 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> { } /// Waits for the interrupt in endpoint to be enabled. - pub async fn ready(&mut self) -> () { + pub async fn ready(&mut self) { self.ep_in.wait_enabled().await } @@ -286,7 +292,7 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> { impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> { /// Waits for the interrupt out endpoint to be enabled. - pub async fn ready(&mut self) -> () { + pub async fn ready(&mut self) { self.ep_out.wait_enabled().await } @@ -466,7 +472,7 @@ impl<'d> Handler for Control<'d> { HID_REQ_SET_IDLE => { if let Some(handler) = self.request_handler { let id = req.value as u8; - let id = (id != 0).then(|| ReportId::In(id)); + let id = (id != 0).then_some(ReportId::In(id)); let dur = u32::from(req.value >> 8); let dur = if dur == 0 { u32::MAX } else { 4 * dur }; handler.set_idle_ms(id, dur); @@ -522,7 +528,7 @@ impl<'d> Handler for Control<'d> { HID_REQ_GET_IDLE => { if let Some(handler) = self.request_handler { let id = req.value as u8; - let id = (id != 0).then(|| ReportId::In(id)); + let id = (id != 0).then_some(ReportId::In(id)); if let Some(dur) = handler.get_idle_ms(id) { let dur = u8::try_from(dur / 4).unwrap_or(0); buf[0] = dur; diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index ae38e26c..16c5f9d9 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs @@ -281,7 +281,7 @@ pub struct BosWriter<'a> { impl<'a> BosWriter<'a> { pub(crate) fn new(writer: DescriptorWriter<'a>) -> Self { Self { - writer: writer, + writer, num_caps_mark: None, } } diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 1180b9b6..2e859e3d 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -294,7 +294,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { /// After dropping the future, [`UsbDevice::disable()`] should be called /// before calling any other `UsbDevice` methods to fully reset the /// peripheral. - pub async fn run_until_suspend(&mut self) -> () { + pub async fn run_until_suspend(&mut self) { while !self.inner.suspended { let control_fut = self.control.setup(); let bus_fut = self.inner.bus.poll(); @@ -372,18 +372,15 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { // a full-length packet is a short packet, thinking we're done sending data. // See https://github.com/hathach/tinyusb/issues/184 const DEVICE_DESCRIPTOR_LEN: usize = 18; - if self.inner.address == 0 - && max_packet_size < DEVICE_DESCRIPTOR_LEN - && (max_packet_size as usize) < resp_length - { + if self.inner.address == 0 && max_packet_size < DEVICE_DESCRIPTOR_LEN && max_packet_size < resp_length { trace!("received control req while not addressed: capping response to 1 packet."); resp_length = max_packet_size; } - match self.inner.handle_control_in(req, &mut self.control_buf) { + match self.inner.handle_control_in(req, self.control_buf) { InResponse::Accepted(data) => { let len = data.len().min(resp_length); - let need_zlp = len != resp_length && (len % usize::from(max_packet_size)) == 0; + let need_zlp = len != resp_length && (len % max_packet_size) == 0; let chunks = data[0..len] .chunks(max_packet_size) @@ -706,7 +703,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { } fn handle_control_in_delegated<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> { - unsafe fn extend_lifetime<'x, 'y>(r: InResponse<'x>) -> InResponse<'y> { + unsafe fn extend_lifetime<'y>(r: InResponse<'_>) -> InResponse<'y> { core::mem::transmute(r) } From 31d4516516940720101300a40d0d6d2bb8d1728e Mon Sep 17 00:00:00 2001 From: Rafael Bachmann Date: Sun, 15 Oct 2023 23:45:44 +0200 Subject: [PATCH 017/188] Apply Pedantic Clippy Lints --- embassy-usb/build.rs | 8 +++-- embassy-usb/src/builder.rs | 42 ++++++++++++------------ embassy-usb/src/class/cdc_acm.rs | 45 +++++++++++++------------- embassy-usb/src/class/cdc_ncm/mod.rs | 48 ++++++++++++---------------- embassy-usb/src/class/hid.rs | 20 ++++++------ embassy-usb/src/class/midi.rs | 16 +++++----- embassy-usb/src/control.rs | 2 +- embassy-usb/src/descriptor.rs | 32 +++++++++---------- embassy-usb/src/descriptor_reader.rs | 6 ++-- embassy-usb/src/lib.rs | 41 ++++++++++-------------- embassy-usb/src/msos.rs | 2 +- embassy-usb/src/types.rs | 4 +-- 12 files changed, 123 insertions(+), 143 deletions(-) diff --git a/embassy-usb/build.rs b/embassy-usb/build.rs index 33d32f7d..5e3bec48 100644 --- a/embassy-usb/build.rs +++ b/embassy-usb/build.rs @@ -70,9 +70,11 @@ fn main() { // envvars take priority. if !cfg.seen_env { - if cfg.seen_feature { - panic!("multiple values set for feature {}: {} and {}", name, cfg.value, value); - } + assert!( + !cfg.seen_feature, + "multiple values set for feature {}: {} and {}", + name, cfg.value, value + ); cfg.value = value; cfg.seen_feature = true; diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 8860f9ee..b4ddccd7 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs @@ -1,17 +1,17 @@ use heapless::Vec; -use crate::config::*; +use crate::config::MAX_HANDLER_COUNT; use crate::descriptor::{BosWriter, DescriptorWriter}; use crate::driver::{Driver, Endpoint, EndpointType}; #[cfg(feature = "msos-descriptor")] use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter}; -use crate::types::*; +use crate::types::{InterfaceNumber, StringIndex}; use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START}; #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[non_exhaustive] -/// Configuration used when creating [UsbDevice]. +/// Configuration used when creating [`UsbDevice`]. pub struct Config<'a> { pub(crate) vendor_id: u16, pub(crate) product_id: u16, @@ -159,9 +159,10 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { panic!("if composite_with_iads is set, you must set device_class = 0xEF, device_sub_class = 0x02, device_protocol = 0x01"); } - if config.max_power > 500 { - panic!("The maximum allowed value for `max_power` is 500mA"); - } + assert!( + config.max_power <= 500, + "The maximum allowed value for `max_power` is 500mA" + ); match config.max_packet_size_0 { 8 | 16 | 32 | 64 => {} @@ -260,12 +261,11 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { /// The Handler is called on some USB bus events, and to handle all control requests not already /// handled by the USB stack. pub fn handler(&mut self, handler: &'d mut dyn Handler) { - if self.handlers.push(handler).is_err() { - panic!( - "embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}", - MAX_HANDLER_COUNT - ) - } + assert!( + self.handlers.push(handler).is_ok(), + "embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}", + MAX_HANDLER_COUNT + ); } /// Allocates a new string index. @@ -332,12 +332,10 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> { num_alt_settings: 0, }; - if self.builder.interfaces.push(iface).is_err() { - panic!( - "embassy-usb: interface list full. Increase the `max_interface_count` compile-time setting. Current value: {}", - MAX_INTERFACE_COUNT - ) - } + assert!(self.builder.interfaces.push(iface).is_ok(), + "embassy-usb: interface list full. Increase the `max_interface_count` compile-time setting. Current value: {}", + MAX_INTERFACE_COUNT + ); InterfaceBuilder { builder: self.builder, @@ -371,7 +369,7 @@ pub struct InterfaceBuilder<'a, 'd, D: Driver<'d>> { impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> { /// Get the interface number. - pub fn interface_number(&self) -> InterfaceNumber { + pub const fn interface_number(&self) -> InterfaceNumber { self.interface_number } @@ -422,12 +420,12 @@ pub struct InterfaceAltBuilder<'a, 'd, D: Driver<'d>> { impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> { /// Get the interface number. - pub fn interface_number(&self) -> InterfaceNumber { + pub const fn interface_number(&self) -> InterfaceNumber { self.interface_number } /// Get the alternate setting number. - pub fn alt_setting_number(&self) -> u8 { + pub const fn alt_setting_number(&self) -> u8 { self.alt_setting_number } @@ -436,7 +434,7 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> { /// Descriptors are written in the order builder functions are called. Note that some /// classes care about the order. pub fn descriptor(&mut self, descriptor_type: u8, descriptor: &[u8]) { - self.builder.config_descriptor.write(descriptor_type, descriptor) + self.builder.config_descriptor.write(descriptor_type, descriptor); } fn endpoint_in(&mut self, ep_type: EndpointType, max_packet_size: u16, interval_ms: u8) -> D::EndpointIn { diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index 790f6faa..f1066d2f 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs @@ -11,7 +11,7 @@ use embassy_sync::waitqueue::WakerRegistration; use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType}; use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; -use crate::types::*; +use crate::types::InterfaceNumber; use crate::{Builder, Handler}; /// This should be used as `device_class` when building the `UsbDevice`. @@ -50,7 +50,7 @@ impl<'a> State<'a> { pub fn new() -> Self { Self { control: MaybeUninit::uninit(), - shared: Default::default(), + shared: ControlShared::default(), } } } @@ -61,9 +61,9 @@ impl<'a> State<'a> { /// writing USB packets with no intermediate buffers, but it will not act like a stream-like serial /// 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 +/// - `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. @@ -109,17 +109,16 @@ impl Default for ControlShared { impl ControlShared { async fn changed(&self) { - poll_fn(|cx| match self.changed.load(Ordering::Relaxed) { - true => { + poll_fn(|cx| { + if self.changed.load(Ordering::Relaxed) { self.changed.store(false, Ordering::Relaxed); Poll::Ready(()) - } - false => { + } else { self.waker.borrow_mut().register(cx.waker()); Poll::Pending } }) - .await + .await; } } @@ -198,7 +197,7 @@ impl<'d> Handler for Control<'d> { // REQ_GET_ENCAPSULATED_COMMAND is not really supported - it will be rejected below. REQ_GET_LINE_CODING if req.length == 7 => { debug!("Sending line coding"); - let coding = self.shared().line_coding.lock(|x| x.get()); + let coding = self.shared().line_coding.lock(Cell::get); assert!(buf.len() >= 7); buf[0..4].copy_from_slice(&coding.data_rate.to_le_bytes()); buf[4] = coding.stop_bits as u8; @@ -212,8 +211,8 @@ impl<'d> Handler for Control<'d> { } impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { - /// Creates a new CdcAcmClass with the provided UsbBus and max_packet_size in bytes. For - /// full-speed devices, max_packet_size has to be one of 8, 16, 32 or 64. + /// Creates a new CdcAcmClass with the provided UsbBus 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>, state: &'d mut State<'d>, max_packet_size: u16) -> Self { assert!(builder.control_buf_len() >= 7); @@ -289,7 +288,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { /// Gets the current line coding. The line coding contains information that's mainly relevant /// for USB to UART serial port emulators, and can be ignored if not relevant. pub fn line_coding(&self) -> LineCoding { - self.control.line_coding.lock(|x| x.get()) + self.control.line_coding.lock(Cell::get) } /// Gets the DTR (data terminal ready) state @@ -314,7 +313,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.read_ep.wait_enabled().await + self.read_ep.wait_enabled().await; } /// Split the class into a sender and receiver. @@ -362,7 +361,7 @@ pub struct ControlChanged<'d> { impl<'d> ControlChanged<'d> { /// Return a future for when the control settings change pub async fn control_changed(&self) { - self.control.changed().await + self.control.changed().await; } } @@ -384,7 +383,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { /// Gets the current line coding. The line coding contains information that's mainly relevant /// for USB to UART serial port emulators, and can be ignored if not relevant. pub fn line_coding(&self) -> LineCoding { - self.control.line_coding.lock(|x| x.get()) + self.control.line_coding.lock(Cell::get) } /// Gets the DTR (data terminal ready) state @@ -404,7 +403,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.write_ep.wait_enabled().await + self.write_ep.wait_enabled().await; } } @@ -426,7 +425,7 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { /// Gets the current line coding. The line coding contains information that's mainly relevant /// for USB to UART serial port emulators, and can be ignored if not relevant. pub fn line_coding(&self) -> LineCoding { - self.control.line_coding.lock(|x| x.get()) + self.control.line_coding.lock(Cell::get) } /// Gets the DTR (data terminal ready) state @@ -446,7 +445,7 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.read_ep.wait_enabled().await + self.read_ep.wait_enabled().await; } } @@ -520,17 +519,17 @@ impl LineCoding { } /// Gets the number of data bits for UART communication. - pub fn data_bits(&self) -> u8 { + pub const fn data_bits(&self) -> u8 { self.data_bits } /// Gets the parity type for UART communication. - pub fn parity_type(&self) -> ParityType { + pub const fn parity_type(&self) -> ParityType { self.parity_type } /// Gets the data rate in bits per second for UART communication. - pub fn data_rate(&self) -> u32 { + pub const fn data_rate(&self) -> u32 { self.data_rate } } diff --git a/embassy-usb/src/class/cdc_ncm/mod.rs b/embassy-usb/src/class/cdc_ncm/mod.rs index 27716b37..bea9dac2 100644 --- a/embassy-usb/src/class/cdc_ncm/mod.rs +++ b/embassy-usb/src/class/cdc_ncm/mod.rs @@ -16,10 +16,11 @@ use core::intrinsics::copy_nonoverlapping; use core::mem::{size_of, MaybeUninit}; +use core::ptr::addr_of; use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType}; use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; -use crate::types::*; +use crate::types::{InterfaceNumber, StringIndex}; use crate::{Builder, Handler}; pub mod embassy_net; @@ -62,9 +63,9 @@ const REQ_SET_NTB_INPUT_SIZE: u8 = 0x86; //const NOTIF_POLL_INTERVAL: u8 = 20; const NTB_MAX_SIZE: usize = 2048; -const SIG_NTH: u32 = 0x484d434e; -const SIG_NDP_NO_FCS: u32 = 0x304d434e; -const SIG_NDP_WITH_FCS: u32 = 0x314d434e; +const SIG_NTH: u32 = 0x484d_434e; +const SIG_NDP_NO_FCS: u32 = 0x304d_434e; +const SIG_NDP_WITH_FCS: u32 = 0x314d_434e; const ALTERNATE_SETTING_DISABLED: u8 = 0x00; const ALTERNATE_SETTING_ENABLED: u8 = 0x01; @@ -111,7 +112,7 @@ struct NtbParametersDir { fn byteify(buf: &mut [u8], data: T) -> &[u8] { let len = size_of::(); - unsafe { copy_nonoverlapping(&data as *const _ as *const u8, buf.as_mut_ptr(), len) } + unsafe { copy_nonoverlapping(addr_of!(data).cast(), buf.as_mut_ptr(), len) } &buf[..len] } @@ -132,12 +133,12 @@ impl<'a> State<'a> { pub fn new() -> Self { Self { control: MaybeUninit::uninit(), - shared: Default::default(), + shared: ControlShared::default(), } } } -/// Shared data between Control and CdcAcmClass +/// Shared data between Control and `CdcAcmClass` #[derive(Default)] struct ControlShared { mac_addr: [u8; 6], @@ -378,12 +379,12 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { /// /// This waits until the packet is successfully stored in the CDC-NCM endpoint buffers. pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> { - let seq = self.seq; - self.seq = self.seq.wrapping_add(1); - const OUT_HEADER_LEN: usize = 28; const ABS_MAX_PACKET_SIZE: usize = 512; + let seq = self.seq; + self.seq = self.seq.wrapping_add(1); + let header = NtbOutHeader { nth_sig: SIG_NTH, nth_len: 0x0c, @@ -460,12 +461,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { let ntb = &ntb[..pos]; // Process NTB header (NTH) - let nth = match ntb.get(..12) { - Some(x) => x, - None => { - warn!("Received too short NTB"); - continue; - } + let Some(nth) = ntb.get(..12) else { + warn!("Received too short NTB"); + continue; }; let sig = u32::from_le_bytes(nth[0..4].try_into().unwrap()); if sig != SIG_NTH { @@ -475,12 +473,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { let ndp_idx = u16::from_le_bytes(nth[10..12].try_into().unwrap()) as usize; // Process NTB Datagram Pointer (NDP) - let ndp = match ntb.get(ndp_idx..ndp_idx + 12) { - Some(x) => x, - None => { - warn!("NTH has an NDP pointer out of range."); - continue; - } + let Some(ndp) = ntb.get(ndp_idx..ndp_idx + 12) else { + warn!("NTH has an NDP pointer out of range."); + continue; }; let sig = u32::from_le_bytes(ndp[0..4].try_into().unwrap()); if sig != SIG_NDP_NO_FCS && sig != SIG_NDP_WITH_FCS { @@ -496,12 +491,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { } // Process actual datagram, finally. - let datagram = match ntb.get(datagram_index..datagram_index + datagram_len) { - Some(x) => x, - None => { - warn!("NDP has a datagram pointer out of range."); - continue; - } + let Some(datagram) = ntb.get(datagram_index..datagram_index + datagram_len) else { + warn!("NDP has a datagram pointer out of range."); + continue; }; buf[..datagram_len].copy_from_slice(datagram); diff --git a/embassy-usb/src/class/hid.rs b/embassy-usb/src/class/hid.rs index 0da29b1a..0000b5b2 100644 --- a/embassy-usb/src/class/hid.rs +++ b/embassy-usb/src/class/hid.rs @@ -63,7 +63,7 @@ pub enum ReportId { } impl ReportId { - fn try_from(value: u16) -> Result { + const fn try_from(value: u16) -> Result { match value >> 8 { 1 => Ok(ReportId::In(value as u8)), 2 => Ok(ReportId::Out(value as u8)), @@ -87,7 +87,7 @@ impl<'d> Default for State<'d> { impl<'d> State<'d> { /// Create a new `State`. - pub fn new() -> Self { + pub const fn new() -> Self { State { control: MaybeUninit::uninit(), out_report_offset: AtomicUsize::new(0), @@ -154,7 +154,7 @@ fn build<'d, D: Driver<'d>>( } impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWriter<'d, D, READ_N, WRITE_N> { - /// Creates a new HidReaderWriter. + /// Creates a new `HidReaderWriter`. /// /// This will allocate one IN and one OUT endpoints. If you only need writing (sending) /// HID reports, consider using [`HidWriter::new`] instead, which allocates an IN endpoint only. @@ -230,7 +230,7 @@ pub enum ReadError { impl From for ReadError { fn from(val: EndpointError) -> Self { - use EndpointError::*; + use EndpointError::{BufferOverflow, Disabled}; match val { BufferOverflow => ReadError::BufferOverflow, Disabled => ReadError::Disabled, @@ -258,16 +258,15 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> { /// Waits for the interrupt in endpoint to be enabled. pub async fn ready(&mut self) { - self.ep_in.wait_enabled().await + self.ep_in.wait_enabled().await; } /// Writes an input report by serializing the given report structure. #[cfg(feature = "usbd-hid")] pub async fn write_serialize(&mut self, r: &IR) -> Result<(), EndpointError> { let mut buf: [u8; N] = [0; N]; - let size = match serialize(&mut buf, r) { - Ok(size) => size, - Err(_) => return Err(EndpointError::BufferOverflow), + let Ok(size) = serialize(&mut buf, r) else { + return Err(EndpointError::BufferOverflow); }; self.write(&buf[0..size]).await } @@ -293,7 +292,7 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> { impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> { /// Waits for the interrupt out endpoint to be enabled. pub async fn ready(&mut self) { - self.ep_out.wait_enabled().await + self.ep_out.wait_enabled().await; } /// Delivers output reports from the Interrupt Out pipe to `handler`. @@ -350,9 +349,8 @@ impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> { if size < max_packet_size || total == N { self.offset.store(0, Ordering::Release); break; - } else { - self.offset.store(total, Ordering::Release); } + self.offset.store(total, Ordering::Release); } Err(err) => { self.offset.store(0, Ordering::Release); diff --git a/embassy-usb/src/class/midi.rs b/embassy-usb/src/class/midi.rs index c5cf8d87..52a96f27 100644 --- a/embassy-usb/src/class/midi.rs +++ b/embassy-usb/src/class/midi.rs @@ -27,9 +27,9 @@ const MIDI_OUT_SIZE: u8 = 0x09; /// 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 +/// - `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. @@ -39,8 +39,8 @@ pub struct MidiClass<'d, D: Driver<'d>> { } 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. + /// 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); @@ -160,7 +160,7 @@ impl<'d, D: Driver<'d>> MidiClass<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.read_ep.wait_enabled().await + self.read_ep.wait_enabled().await; } /// Split the class into a sender and receiver. @@ -197,7 +197,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.write_ep.wait_enabled().await + self.write_ep.wait_enabled().await; } } @@ -222,6 +222,6 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.read_ep.wait_enabled().await + self.read_ep.wait_enabled().await; } } diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index ceccfd85..79f73630 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs @@ -120,7 +120,7 @@ impl Request { } /// Gets the descriptor type and index from the value field of a GET_DESCRIPTOR request. - pub fn descriptor_type_index(&self) -> (u8, u8) { + pub const fn descriptor_type_index(&self) -> (u8, u8) { ((self.value >> 8) as u8, self.value as u8) } } diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index 16c5f9d9..fa83ef58 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs @@ -2,7 +2,7 @@ use crate::builder::Config; use crate::driver::EndpointInfo; -use crate::types::*; +use crate::types::{InterfaceNumber, StringIndex}; use crate::CONFIGURATION_VALUE; /// Standard descriptor types @@ -59,7 +59,7 @@ impl<'a> DescriptorWriter<'a> { } /// Gets the current position in the buffer, i.e. the number of bytes written so far. - pub fn position(&self) -> usize { + pub const fn position(&self) -> usize { self.position } @@ -67,9 +67,10 @@ impl<'a> DescriptorWriter<'a> { pub fn write(&mut self, descriptor_type: u8, descriptor: &[u8]) { let length = descriptor.len(); - if (self.position + 2 + length) > self.buf.len() || (length + 2) > 255 { - panic!("Descriptor buffer full"); - } + assert!( + (self.position + 2 + length) <= self.buf.len() && (length + 2) <= 255, + "Descriptor buffer full" + ); self.buf[self.position] = (length + 2) as u8; self.buf[self.position + 1] = descriptor_type; @@ -102,7 +103,7 @@ impl<'a> DescriptorWriter<'a> { config.serial_number.map_or(0, |_| 3), // iSerialNumber 1, // bNumConfigurations ], - ) + ); } pub(crate) fn configuration(&mut self, config: &Config) { @@ -120,7 +121,7 @@ impl<'a> DescriptorWriter<'a> { | if config.supports_remote_wakeup { 0x20 } else { 0x00 }, // bmAttributes (config.max_power / 2) as u8, // bMaxPower ], - ) + ); } #[allow(unused)] @@ -248,9 +249,7 @@ impl<'a> DescriptorWriter<'a> { pub(crate) fn string(&mut self, string: &str) { let mut pos = self.position; - if pos + 2 > self.buf.len() { - panic!("Descriptor buffer full"); - } + assert!(pos + 2 <= self.buf.len(), "Descriptor buffer full"); self.buf[pos] = 0; // length placeholder self.buf[pos + 1] = descriptor_type::STRING; @@ -258,9 +257,7 @@ impl<'a> DescriptorWriter<'a> { pos += 2; for c in string.encode_utf16() { - if pos >= self.buf.len() { - panic!("Descriptor buffer full"); - } + assert!(pos < self.buf.len(), "Descriptor buffer full"); self.buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes()); pos += 2; @@ -279,7 +276,7 @@ pub struct BosWriter<'a> { } impl<'a> BosWriter<'a> { - pub(crate) fn new(writer: DescriptorWriter<'a>) -> Self { + pub(crate) const fn new(writer: DescriptorWriter<'a>) -> Self { Self { writer, num_caps_mark: None, @@ -314,9 +311,10 @@ impl<'a> BosWriter<'a> { let mut start = self.writer.position; let blen = data.len(); - if (start + blen + 3) > self.writer.buf.len() || (blen + 3) > 255 { - panic!("Descriptor buffer full"); - } + assert!( + (start + blen + 3) <= self.writer.buf.len() && (blen + 3) <= 255, + "Descriptor buffer full" + ); self.writer.buf[start] = (blen + 3) as u8; self.writer.buf[start + 1] = descriptor_type::CAPABILITY; diff --git a/embassy-usb/src/descriptor_reader.rs b/embassy-usb/src/descriptor_reader.rs index 05adcce6..abb4b379 100644 --- a/embassy-usb/src/descriptor_reader.rs +++ b/embassy-usb/src/descriptor_reader.rs @@ -11,11 +11,11 @@ pub struct Reader<'a> { } impl<'a> Reader<'a> { - pub fn new(data: &'a [u8]) -> Self { + pub const fn new(data: &'a [u8]) -> Self { Self { data } } - pub fn eof(&self) -> bool { + pub const fn eof(&self) -> bool { self.data.is_empty() } @@ -102,7 +102,7 @@ pub fn foreach_endpoint(data: &[u8], mut f: impl FnMut(EndpointInfo)) -> Result< } descriptor_type::ENDPOINT => { ep.ep_address = EndpointAddress::from(r.read_u8()?); - f(ep) + f(ep); } _ => {} } diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 2e859e3d..88d88cad 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -24,12 +24,12 @@ use embassy_futures::select::{select, Either}; use heapless::Vec; pub use crate::builder::{Builder, Config, FunctionBuilder, InterfaceAltBuilder, InterfaceBuilder}; -use crate::config::*; -use crate::control::*; -use crate::descriptor::*; +use crate::config::{MAX_HANDLER_COUNT, MAX_INTERFACE_COUNT}; +use crate::control::{InResponse, OutResponse, Recipient, Request, RequestType}; +use crate::descriptor::{descriptor_type, lang_id}; use crate::descriptor_reader::foreach_endpoint; use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event}; -use crate::types::*; +use crate::types::{InterfaceNumber, StringIndex}; /// The global state of the USB device. /// @@ -364,6 +364,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { } async fn handle_control_in(&mut self, req: Request) { + const DEVICE_DESCRIPTOR_LEN: usize = 18; + let mut resp_length = req.length as usize; let max_packet_size = self.control.max_packet_size(); @@ -371,7 +373,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { // The host doesn't know our EP0 max packet size yet, and might assume // a full-length packet is a short packet, thinking we're done sending data. // See https://github.com/hathach/tinyusb/issues/184 - const DEVICE_DESCRIPTOR_LEN: usize = 18; if self.inner.address == 0 && max_packet_size < DEVICE_DESCRIPTOR_LEN && max_packet_size < resp_length { trace!("received control req while not addressed: capping response to 1 packet."); resp_length = max_packet_size; @@ -432,7 +433,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { self.control.accept_set_address(self.inner.address).await; self.inner.set_address_pending = false; } else { - self.control.accept().await + self.control.accept().await; } } OutResponse::Rejected => self.control.reject().await, @@ -545,9 +546,8 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { OutResponse::Accepted } - (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state { - UsbDeviceState::Default => OutResponse::Accepted, - _ => { + (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => { + if self.device_state != UsbDeviceState::Default { debug!("SET_CONFIGURATION: unconfigured"); self.device_state = UsbDeviceState::Addressed; @@ -561,17 +561,15 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { for h in &mut self.handlers { h.configured(false); } - - OutResponse::Accepted } - }, + OutResponse::Accepted + } _ => OutResponse::Rejected, }, (RequestType::Standard, Recipient::Interface) => { let iface_num = InterfaceNumber::new(req.index as _); - let iface = match self.interfaces.get_mut(iface_num.0 as usize) { - Some(iface) => iface, - None => return OutResponse::Rejected, + let Some(iface) = self.interfaces.get_mut(iface_num.0 as usize) else { + return OutResponse::Rejected; }; match req.request { @@ -647,9 +645,8 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { _ => InResponse::Rejected, }, (RequestType::Standard, Recipient::Interface) => { - let iface = match self.interfaces.get_mut(req.index as usize) { - Some(iface) => iface, - None => return InResponse::Rejected, + let Some(iface) = self.interfaces.get_mut(req.index as usize) else { + return InResponse::Rejected; }; match req.request { @@ -753,16 +750,12 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { }; if let Some(s) = s { - if buf.len() < 2 { - panic!("control buffer too small"); - } + assert!(buf.len() >= 2, "control buffer too small"); buf[1] = descriptor_type::STRING; let mut pos = 2; for c in s.encode_utf16() { - if pos + 2 >= buf.len() { - panic!("control buffer too small"); - } + assert!(pos + 2 < buf.len(), "control buffer too small"); buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes()); pos += 2; diff --git a/embassy-usb/src/msos.rs b/embassy-usb/src/msos.rs index 847338e5..13d5d7c4 100644 --- a/embassy-usb/src/msos.rs +++ b/embassy-usb/src/msos.rs @@ -6,7 +6,7 @@ use core::mem::size_of; -use super::{capability_type, BosWriter}; +use crate::descriptor::{capability_type, BosWriter}; use crate::types::InterfaceNumber; /// A serialized Microsoft OS 2.0 Descriptor set. diff --git a/embassy-usb/src/types.rs b/embassy-usb/src/types.rs index c7a47f7e..cb9fe257 100644 --- a/embassy-usb/src/types.rs +++ b/embassy-usb/src/types.rs @@ -7,7 +7,7 @@ pub struct InterfaceNumber(pub u8); impl InterfaceNumber { - pub(crate) fn new(index: u8) -> InterfaceNumber { + pub(crate) const fn new(index: u8) -> InterfaceNumber { InterfaceNumber(index) } } @@ -25,7 +25,7 @@ impl From for u8 { pub struct StringIndex(pub u8); impl StringIndex { - pub(crate) fn new(index: u8) -> StringIndex { + pub(crate) const fn new(index: u8) -> StringIndex { StringIndex(index) } } From b24520579a9fc8ec46c10d066c24231de0e124c1 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 15 Oct 2023 19:51:35 -0500 Subject: [PATCH 018/188] rcc: ahb/apb -> hclk/pclk --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/build.rs | 10 ++++++++-- embassy-stm32/src/dac/mod.rs | 2 +- embassy-stm32/src/eth/v1/mod.rs | 2 +- embassy-stm32/src/eth/v2/mod.rs | 2 +- embassy-stm32/src/rcc/bd.rs | 8 ++++---- embassy-stm32/src/rcc/c0.rs | 6 +++--- embassy-stm32/src/rcc/f0.rs | 10 +++++----- embassy-stm32/src/rcc/f1.rs | 10 +++++----- embassy-stm32/src/rcc/f2.rs | 14 +++++++------- embassy-stm32/src/rcc/f3.rs | 10 +++++----- embassy-stm32/src/rcc/f4.rs | 14 +++++++------- embassy-stm32/src/rcc/f7.rs | 14 +++++++------- embassy-stm32/src/rcc/g0.rs | 10 +++++----- embassy-stm32/src/rcc/g4.rs | 20 ++++++++++---------- embassy-stm32/src/rcc/h.rs | 26 +++++++++++++------------- embassy-stm32/src/rcc/l0l1.rs | 10 +++++----- embassy-stm32/src/rcc/l4.rs | 14 +++++++------- embassy-stm32/src/rcc/l5.rs | 14 +++++++------- embassy-stm32/src/rcc/mod.rs | 22 +++++++++++----------- embassy-stm32/src/rcc/u5.rs | 16 ++++++++-------- embassy-stm32/src/rcc/wb.rs | 14 +++++++------- embassy-stm32/src/rcc/wba.rs | 16 ++++++++-------- embassy-stm32/src/rcc/wl.rs | 16 ++++++++-------- 24 files changed, 145 insertions(+), 139 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 0629bc09..290bcf6a 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-7dafe9d8bbc739be48199185f0caa1582b1da3f7" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-01a757e40df688efcda23607185640e1c2396ba9" } 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-7dafe9d8bbc739be48199185f0caa1582b1da3f7", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-01a757e40df688efcda23607185640e1c2396ba9", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 45aad027..d118b851 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -466,7 +466,13 @@ fn main() { let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" }; let pname = format_ident!("{}", p.name); - let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase()); + let clk = format_ident!( + "{}", + rcc.clock + .to_ascii_lowercase() + .replace("ahb", "hclk") + .replace("apb", "pclk") + ); let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); @@ -523,7 +529,7 @@ fn main() { let variant_name = format_ident!("{}", v.name); let clock_name = format_ident!("{}", v.name.to_ascii_lowercase()); - if v.name.starts_with("AHB") || v.name.starts_with("APB") || v.name == "SYS" { + if v.name.starts_with("HCLK") || v.name.starts_with("PCLK") || v.name == "SYS" { quote! { #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name }, } diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index a3c7823c..3d1a820e 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -564,7 +564,7 @@ foreach_peripheral!( #[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 }) + critical_section::with(|_| unsafe { crate::rcc::get_freqs().pclk1 }) } fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index 631a9377..13e53f68 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs @@ -191,7 +191,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { // TODO MTU size setting not found for v1 ethernet, check if correct // NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called - let hclk = unsafe { crate::rcc::get_freqs() }.ahb1; + let hclk = unsafe { crate::rcc::get_freqs() }.hclk1; let hclk_mhz = hclk.0 / 1_000_000; // Set the MDC clock frequency in the range 1MHz - 2.5MHz diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 12cf618a..c77155fe 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -164,7 +164,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { }); // NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called - let hclk = unsafe { crate::rcc::get_freqs() }.ahb1; + let hclk = unsafe { crate::rcc::get_freqs() }.hclk1; let hclk_mhz = hclk.0 / 1_000_000; // Set the MDC clock frequency in the range 1MHz - 2.5MHz diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index a7c4b4f9..d20f5818 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -106,7 +106,7 @@ impl LsConfig { pub const fn off() -> Self { Self { - rtc: RtcClockSource::NOCLOCK, + rtc: RtcClockSource::DISABLE, lsi: false, lse: None, } @@ -133,7 +133,7 @@ impl LsConfig { Some(LSI_FREQ) } RtcClockSource::LSE => Some(self.lse.as_ref().unwrap().frequency), - RtcClockSource::NOCLOCK => None, + RtcClockSource::DISABLE => None, _ => todo!(), }; @@ -180,7 +180,7 @@ impl LsConfig { ok &= reg.rtcsel() == self.rtc; #[cfg(not(rcc_wba))] { - ok &= reg.rtcen() == (self.rtc != RtcClockSource::NOCLOCK); + ok &= reg.rtcen() == (self.rtc != RtcClockSource::DISABLE); } ok &= reg.lseon() == lse_en; ok &= reg.lsebyp() == lse_byp; @@ -225,7 +225,7 @@ impl LsConfig { while !bdcr().read().lserdy() {} } - if self.rtc != RtcClockSource::NOCLOCK { + if self.rtc != RtcClockSource::DISABLE { 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."); diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index eeb6418a..e357f067 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -135,9 +135,9 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - apb1: apb_freq, - apb1_tim: apb_tim_freq, + hclk1: ahb_freq, + pclk1: apb_freq, + pclk1_tim: apb_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/f0.rs b/embassy-stm32/src/rcc/f0.rs index cc712e87..f7d605fd 100644 --- a/embassy-stm32/src/rcc/f0.rs +++ b/embassy-stm32/src/rcc/f0.rs @@ -162,11 +162,11 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: Hertz(real_sysclk), - apb1: Hertz(pclk), - apb2: Hertz(pclk), - apb1_tim: Hertz(pclk * timer_mul), - apb2_tim: Hertz(pclk * timer_mul), - ahb1: Hertz(hclk), + pclk1: Hertz(pclk), + pclk2: Hertz(pclk), + pclk1_tim: Hertz(pclk * timer_mul), + pclk2_tim: Hertz(pclk * timer_mul), + hclk1: Hertz(hclk), rtc, }); } diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs index 56c49cd8..b2ae56db 100644 --- a/embassy-stm32/src/rcc/f1.rs +++ b/embassy-stm32/src/rcc/f1.rs @@ -180,11 +180,11 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: Hertz(real_sysclk), - apb1: Hertz(pclk1), - apb2: Hertz(pclk2), - apb1_tim: Hertz(pclk1 * timer_mul1), - apb2_tim: Hertz(pclk2 * timer_mul2), - ahb1: Hertz(hclk), + pclk1: Hertz(pclk1), + pclk2: Hertz(pclk2), + pclk1_tim: Hertz(pclk1 * timer_mul1), + pclk2_tim: Hertz(pclk2 * timer_mul2), + hclk1: Hertz(hclk), adc: Some(Hertz(adcclk)), rtc, }); diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 34720e83..06ea7e4f 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -307,13 +307,13 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - ahb3: ahb_freq, - apb1: apb1_freq, - apb1_tim: apb1_tim_freq, - apb2: apb2_freq, - apb2_tim: apb2_tim_freq, + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk3: ahb_freq, + pclk1: apb1_freq, + pclk1_tim: apb1_tim_freq, + pclk2: apb2_freq, + pclk2_tim: apb2_tim_freq, pll1_q: Some(pll_clocks.pll48_freq), rtc, }); diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 2aa79cec..3a314009 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -281,11 +281,11 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sysclk, - apb1: pclk1, - apb2: pclk2, - apb1_tim: pclk1 * timer_mul1, - apb2_tim: pclk2 * timer_mul2, - ahb1: hclk, + pclk1: pclk1, + pclk2: pclk2, + pclk1_tim: pclk1 * timer_mul1, + pclk2_tim: pclk2 * timer_mul2, + hclk1: hclk, #[cfg(rcc_f3)] adc: adc, #[cfg(all(rcc_f3, adc3_common))] diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index 91ad81b2..b0585153 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -340,15 +340,15 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: Hertz(sysclk), - apb1: Hertz(pclk1), - apb2: Hertz(pclk2), + pclk1: Hertz(pclk1), + pclk2: Hertz(pclk2), - apb1_tim: Hertz(pclk1 * timer_mul1), - apb2_tim: Hertz(pclk2 * timer_mul2), + pclk1_tim: Hertz(pclk1 * timer_mul1), + pclk2_tim: Hertz(pclk2 * timer_mul2), - ahb1: Hertz(hclk), - ahb2: Hertz(hclk), - ahb3: Hertz(hclk), + hclk1: Hertz(hclk), + hclk2: Hertz(hclk), + hclk3: Hertz(hclk), pll1_q: plls.pll48clk.map(Hertz), diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs index f0e01149..5ed74fe9 100644 --- a/embassy-stm32/src/rcc/f7.rs +++ b/embassy-stm32/src/rcc/f7.rs @@ -259,15 +259,15 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: Hertz(sysclk), - apb1: Hertz(pclk1), - apb2: Hertz(pclk2), + pclk1: Hertz(pclk1), + pclk2: Hertz(pclk2), - apb1_tim: Hertz(pclk1 * timer_mul1), - apb2_tim: Hertz(pclk2 * timer_mul2), + pclk1_tim: Hertz(pclk1 * timer_mul1), + pclk2_tim: Hertz(pclk2 * timer_mul2), - ahb1: Hertz(hclk), - ahb2: Hertz(hclk), - ahb3: Hertz(hclk), + hclk1: Hertz(hclk), + hclk2: Hertz(hclk), + hclk3: Hertz(hclk), pll1_q: plls.pll48clk.map(Hertz), diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 962b1dc0..85ebd32e 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -89,7 +89,7 @@ impl Default for Config { impl PllConfig { pub(crate) fn init(self) -> Hertz { let (src, input_freq) = match self.source { - PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ), + PllSrc::HSI16 => (vals::Pllsrc::HSI, HSI_FREQ), PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq), }; @@ -186,7 +186,7 @@ pub(crate) unsafe fn init(config: Config) { } ClockSrc::PLL(pll) => { let freq = pll.init(); - (freq, Sw::PLLRCLK) + (freq, Sw::PLL1_R) } ClockSrc::LSI => { // Enable LSI @@ -275,9 +275,9 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - apb1: apb_freq, - apb1_tim: apb_tim_freq, + hclk1: ahb_freq, + pclk1: apb_freq, + pclk1_tim: apb_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 581bf9e0..32d14d2f 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -33,7 +33,7 @@ impl Into for PllSrc { fn into(self) -> Pllsrc { match self { PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI16, + PllSrc::HSI16 => Pllsrc::HSI, } } } @@ -201,7 +201,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - (HSI_FREQ, Sw::HSI16) + (HSI_FREQ, Sw::HSI) } ClockSrc::HSE(freq) => { // Enable HSE @@ -249,7 +249,7 @@ pub(crate) unsafe fn init(config: Config) { } } - (Hertz(freq), Sw::PLLRCLK) + (Hertz(freq), Sw::PLL1_R) } }; @@ -286,7 +286,7 @@ pub(crate) unsafe fn init(config: Config) { let pllq_freq = pll_freq.as_ref().and_then(|f| f.pll_q); assert!(pllq_freq.is_some() && pllq_freq.unwrap().0 == 48_000_000); - crate::pac::rcc::vals::Clk48sel::PLLQCLK + crate::pac::rcc::vals::Clk48sel::PLL1_Q } Clock48MhzSrc::Hsi48(crs_config) => { // Enable HSI48 @@ -348,12 +348,12 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { 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, + hclk1: ahb_freq, + hclk2: ahb_freq, + pclk1: apb1_freq, + pclk1_tim: apb1_tim_freq, + pclk2: apb2_freq, + pclk2_tim: apb2_tim_freq, adc: adc12_ck, adc34: adc345_ck, pll1_p: None, diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index bbbbc9c1..86136d43 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -387,7 +387,7 @@ pub(crate) unsafe fn init(config: Config) { Sysclk::HSI => (unwrap!(hsi), Sw::HSI), Sysclk::HSE => (unwrap!(hse), Sw::HSE), Sysclk::CSI => (unwrap!(csi), Sw::CSI), - Sysclk::Pll1P => (unwrap!(pll1.p), Sw::PLL1), + Sysclk::Pll1P => (unwrap!(pll1.p), Sw::PLL1_P), }; // Check limits. @@ -445,7 +445,7 @@ pub(crate) unsafe fn init(config: Config) { }; #[cfg(stm32h5)] let adc = match config.adc_clock_source { - AdcClockSource::HCLK => Some(hclk), + AdcClockSource::HCLK1 => Some(hclk), AdcClockSource::SYS => Some(sys), AdcClockSource::PLL2_R => pll2.r, AdcClockSource::HSE => hse, @@ -524,19 +524,19 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys, - ahb1: hclk, - ahb2: hclk, - ahb3: hclk, - ahb4: hclk, - apb1, - apb2, - apb3, + hclk1: hclk, + hclk2: hclk, + hclk3: hclk, + hclk4: hclk, + pclk1: apb1, + pclk2: apb2, + pclk3: apb3, #[cfg(stm32h7)] - apb4, + pclk4: apb4, #[cfg(stm32h5)] - apb4: Hertz(1), - apb1_tim, - apb2_tim, + pclk4: Hertz(1), + pclk1_tim: apb1_tim, + pclk2_tim: apb2_tim, adc, rtc, diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index d8a1fc10..308b75ae 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -209,11 +209,11 @@ pub(crate) unsafe fn init(config: Config) { 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, + hclk1: ahb_freq, + pclk1: apb1_freq, + pclk2: apb2_freq, + pclk1_tim: apb1_tim_freq, + pclk2_tim: apb2_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 020f4e20..43c29281 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -329,13 +329,13 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { 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, + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk3: ahb_freq, + pclk1: apb1_freq, + pclk2: apb2_freq, + pclk1_tim: apb1_tim_freq, + pclk2_tim: apb2_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index 1f4e0034..289217b1 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs @@ -261,13 +261,13 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { 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, + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk3: ahb_freq, + pclk1: apb1_freq, + pclk2: apb2_freq, + pclk1_tim: apb1_tim_freq, + pclk2_tim: apb2_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 0cc9e6a6..9df40baa 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -48,21 +48,21 @@ pub struct Clocks { pub sys: Hertz, // APB - pub apb1: Hertz, - pub apb1_tim: Hertz, + pub pclk1: Hertz, + pub pclk1_tim: Hertz, #[cfg(not(any(rcc_c0, rcc_g0)))] - pub apb2: Hertz, + pub pclk2: Hertz, #[cfg(not(any(rcc_c0, rcc_g0)))] - pub apb2_tim: Hertz, + pub pclk2_tim: Hertz, #[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_u5))] - pub apb3: Hertz, + pub pclk3: Hertz, #[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab, stm32h5))] - pub apb4: Hertz, + pub pclk4: Hertz, #[cfg(any(rcc_wba))] - pub apb7: Hertz, + pub pclk7: Hertz, // AHB - pub ahb1: Hertz, + pub hclk1: Hertz, #[cfg(any( rcc_l4, rcc_l5, @@ -82,7 +82,7 @@ pub struct Clocks { rcc_wl5, rcc_wle ))] - pub ahb2: Hertz, + pub hclk2: Hertz, #[cfg(any( rcc_l4, rcc_l5, @@ -100,9 +100,9 @@ pub struct Clocks { rcc_wl5, rcc_wle ))] - pub ahb3: Hertz, + pub hclk3: Hertz, #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_wba))] - pub ahb4: Hertz, + pub hclk4: Hertz, #[cfg(all(rcc_f4, not(stm32f410)))] pub plli2s1_q: Option, diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 68a8d3a3..fb9c163e 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -436,14 +436,14 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { 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, + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk3: ahb_freq, + pclk1: apb1_freq, + pclk2: apb2_freq, + pclk3: apb3_freq, + pclk1_tim: apb1_tim_freq, + pclk2_tim: apb2_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index 181e6bb5..a6cf118a 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -236,13 +236,13 @@ pub(crate) unsafe fn init(config: Config) { 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, + hclk1: ahb1_clk, + hclk2: ahb2_clk, + hclk3: ahb3_clk, + pclk1: apb1_clk, + pclk2: apb2_clk, + pclk1_tim: apb1_tim_clk, + pclk2_tim: apb2_tim_clk, rtc, }) } diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index ff5669ec..72f65361 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -142,14 +142,14 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - ahb4: ahb_freq, - apb1: apb1_freq, - apb2: apb2_freq, - apb7: apb7_freq, - apb1_tim: apb1_tim_freq, - apb2_tim: apb2_tim_freq, + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk4: ahb_freq, + pclk1: apb1_freq, + pclk2: apb2_freq, + pclk7: apb7_freq, + pclk1_tim: apb1_tim_freq, + pclk2_tim: apb2_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 366ca136..c1f6a6b1 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -145,14 +145,14 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { 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, + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk3: shd_ahb_freq, + pclk1: apb1_freq, + pclk2: apb2_freq, + pclk3: shd_ahb_freq, + pclk1_tim: apb1_tim_freq, + pclk2_tim: apb2_tim_freq, rtc, }); } From 5c5e6818195b364199e583eb559b0042d392b3e7 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 16 Oct 2023 03:09:33 +0200 Subject: [PATCH 019/188] stm32/rcc: add better support for L4/L4+ differences. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/l4.rs | 333 ++++++++++-------- embassy-stm32/src/rcc/l5.rs | 8 +- embassy-stm32/src/rcc/mod.rs | 4 +- examples/stm32l4/src/bin/adc.rs | 2 +- examples/stm32l4/src/bin/rng.rs | 2 +- examples/stm32l4/src/bin/rtc.rs | 2 +- .../src/bin/spe_adin1110_http_server.rs | 2 +- examples/stm32l4/src/bin/usb_serial.rs | 2 +- tests/stm32/src/common.rs | 2 +- 10 files changed, 206 insertions(+), 155 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 290bcf6a..50ccd793 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-01a757e40df688efcda23607185640e1c2396ba9" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73e3f8a965a01fd5a168c3543b93ce49d475e130" } 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-01a757e40df688efcda23607185640e1c2396ba9", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73e3f8a965a01fd5a168c3543b93ce49d475e130", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 43c29281..aceafc49 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs @@ -1,7 +1,8 @@ use crate::pac::rcc::regs::Cfgr; +use crate::pac::rcc::vals::Msirgsel; 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, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, + Clk48sel as Clk48Src, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, + Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, }; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -12,6 +13,9 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); #[derive(Clone, Copy)] pub struct Pll { + /// PLL source + pub source: PLLSource, + /// PLL pre-divider (DIVM). pub prediv: PllPreDiv, @@ -32,11 +36,10 @@ pub struct Config { pub msi: Option, pub hsi16: bool, pub hse: Option, - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] + #[cfg(not(any(stm32l47x, stm32l48x)))] pub hsi48: bool, // pll - pub pll_src: PLLSource, pub pll: Option, pub pllsai1: Option, #[cfg(any( @@ -50,6 +53,9 @@ pub struct Config { pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, + // muxes + pub clk48_src: Clk48Src, + // low speed LSI/LSE/RTC pub ls: super::LsConfig, } @@ -65,7 +71,6 @@ impl Default for Config { ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, - pll_src: PLLSource::NONE, pll: None, pllsai1: None, #[cfg(any( @@ -73,7 +78,8 @@ impl Default for Config { ))] pllsai2: None, #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - hsi48: false, + hsi48: true, + clk48_src: Clk48Src::HSI48, ls: Default::default(), } } @@ -84,7 +90,7 @@ pub(crate) unsafe fn init(config: Config) { 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_msirgsel(Msirgsel::CR); w.set_msirange(MSIRange::RANGE4M); w.set_msipllen(false); w.set_msion(true) @@ -106,7 +112,7 @@ pub(crate) unsafe fn init(config: Config) { // Enable MSI RCC.cr().write(|w| { w.set_msirange(range); - w.set_msirgsel(true); + w.set_msirgsel(Msirgsel::CR); w.set_msion(true); // If LSE is enabled, enable calibration of MSI @@ -115,9 +121,7 @@ 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 range == MSIRange::RANGE48M { - RCC.ccipr().modify(|w| w.set_clk48sel(0b11)); - } + if range == MSIRange::RANGE48M {} msirange_to_hertz(range) }); @@ -136,154 +140,66 @@ pub(crate) unsafe fn init(config: Config) { freq }); - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - let _hsi48 = config.hsi48.then(|| { + #[cfg(not(any(stm32l47x, stm32l48x)))] + let hsi48 = config.hsi48.then(|| { RCC.crrcr().modify(|w| w.set_hsi48on(true)); while !RCC.crrcr().read().hsi48rdy() {} - // Enable as clock source for USB, RNG and SDMMC - RCC.ccipr().modify(|w| w.set_clk48sel(0)); - Hertz(48_000_000) }); + #[cfg(any(stm32l47x, stm32l48x))] + let hsi48 = None; - let pll_src = match config.pll_src { - PLLSource::NONE => None, - PLLSource::HSE => hse, - PLLSource::HSI16 => hsi16, - PLLSource::MSI => msi, + let _plls = [ + &config.pll, + &config.pllsai1, + #[cfg(any( + stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx + ))] + &config.pllsai2, + ]; + + // L4 has shared PLLSRC, PLLM, check it's equal in all PLLs. + #[cfg(all(stm32l4, not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))))] + match get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) { + Err(()) => panic!("Source must be equal across all enabled PLLs."), + Ok(None) => {} + Ok(Some((source, prediv))) => RCC.pllcfgr().write(|w| { + w.set_pllm(prediv); + w.set_pllsrc(source); + }), }; - let mut _pllp = None; - let mut _pllq = None; - let mut _pllr = None; - if let Some(pll) = config.pll { - let pll_src = pll_src.unwrap(); - - // Disable PLL - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} - - let vco_freq = pll_src / pll.prediv * pll.mul; - - _pllp = pll.divp.map(|div| vco_freq / div); - _pllq = pll.divq.map(|div| vco_freq / div); - _pllr = pll.divr.map(|div| vco_freq / div); - - RCC.pllcfgr().write(move |w| { - w.set_plln(pll.mul); - w.set_pllm(pll.prediv); - w.set_pllsrc(config.pll_src); - if let Some(divp) = pll.divp { - w.set_pllp(divp); - w.set_pllpen(true); - } - if let Some(divq) = pll.divq { - w.set_pllq(divq); - w.set_pllqen(true); - } - if let Some(divr) = pll.divr { - w.set_pllr(divr); - w.set_pllren(true); - } - }); - - if _pllq == Some(Hertz(48_000_000)) { - RCC.ccipr().modify(|w| w.set_clk48sel(0b10)); - } - - // Enable PLL - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - } else { - // even if we're not using the main pll, set the source for pllsai - RCC.pllcfgr().write(move |w| { - w.set_pllsrc(config.pll_src); - }); - } - - if let Some(pll) = config.pllsai1 { - let pll_src = pll_src.unwrap(); - - // Disable PLL - RCC.cr().modify(|w| w.set_pllsai1on(false)); - while RCC.cr().read().pllsai1rdy() {} - - let vco_freq = pll_src / pll.prediv * pll.mul; - - let _pllp = pll.divp.map(|div| vco_freq / div); - let _pllq = pll.divq.map(|div| vco_freq / div); - let _pllr = pll.divr.map(|div| vco_freq / div); - - RCC.pllsai1cfgr().write(move |w| { - w.set_plln(pll.mul); - w.set_pllm(pll.prediv); - if let Some(divp) = pll.divp { - w.set_pllp(divp); - w.set_pllpen(true); - } - if let Some(divq) = pll.divq { - w.set_pllq(divq); - w.set_pllqen(true); - } - if let Some(divr) = pll.divr { - w.set_pllr(divr); - w.set_pllren(true); - } - }); - - if _pllq == Some(Hertz(48_000_000)) { - RCC.ccipr().modify(|w| w.set_clk48sel(0b01)); - } - - // Enable PLL - RCC.cr().modify(|w| w.set_pllsai1on(true)); - while !RCC.cr().read().pllsai1rdy() {} - } + // L4+ has shared PLLSRC, check it's equal in all PLLs. + #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] + match get_equal(_plls.into_iter().flatten().map(|p| p.source)) { + Err(()) => panic!("Source must be equal across all enabled PLLs."), + Ok(None) => {} + Ok(Some(source)) => RCC.pllcfgr().write(|w| { + w.set_pllsrc(source); + }), + }; + let pll_input = PllInput { hse, hsi16, msi }; + let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); + let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); #[cfg(any( stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx ))] - if let Some(pll) = config.pllsai2 { - let pll_src = pll_src.unwrap(); - - // Disable PLL - RCC.cr().modify(|w| w.set_pllsai2on(false)); - while RCC.cr().read().pllsai2rdy() {} - - let vco_freq = pll_src / pll.prediv * pll.mul; - - let _pllp = pll.divp.map(|div| vco_freq / div); - let _pllq = pll.divq.map(|div| vco_freq / div); - let _pllr = pll.divr.map(|div| vco_freq / div); - - RCC.pllsai2cfgr().write(move |w| { - w.set_plln(pll.mul); - w.set_pllm(pll.prediv); - if let Some(divp) = pll.divp { - w.set_pllp(divp); - w.set_pllpen(true); - } - if let Some(divq) = pll.divq { - w.set_pllq(divq); - w.set_pllqen(true); - } - if let Some(divr) = pll.divr { - w.set_pllr(divr); - w.set_pllren(true); - } - }); - - // Enable PLL - RCC.cr().modify(|w| w.set_pllsai2on(true)); - while !RCC.cr().read().pllsai2rdy() {} - } + let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); let sys_clk = match config.mux { ClockSrc::HSE => hse.unwrap(), ClockSrc::HSI16 => hsi16.unwrap(), ClockSrc::MSI => msi.unwrap(), - ClockSrc::PLL => _pllr.unwrap(), + ClockSrc::PLL => pll._r.unwrap(), + }; + + let _clk48 = match config.clk48_src { + Clk48Src::HSI48 => hsi48, + Clk48Src::MSI => msi, + Clk48Src::PLLSAI1_Q => pllsai1._q, + Clk48Src::PLL_Q => pll._q, }; #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] @@ -357,3 +273,136 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz { _ => unreachable!(), } } + +fn get_equal(mut iter: impl Iterator) -> Result, ()> { + let Some(x) = iter.next() else { return Ok(None) }; + if !iter.all(|y| y == x) { + return Err(()); + } + return Ok(Some(x)); +} + +struct PllInput { + hsi16: Option, + hse: Option, + msi: Option, +} + +#[derive(Default)] +struct PllOutput { + _p: Option, + _q: Option, + _r: Option, +} + +#[derive(PartialEq, Eq, Clone, Copy)] +enum PllInstance { + Pll, + Pllsai1, + #[cfg(any( + stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx + ))] + Pllsai2, +} + +fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + match instance { + PllInstance::Pll => { + RCC.cr().modify(|w| w.set_pllon(false)); + while RCC.cr().read().pllrdy() {} + } + PllInstance::Pllsai1 => { + RCC.cr().modify(|w| w.set_pllsai1on(false)); + while RCC.cr().read().pllsai1rdy() {} + } + #[cfg(any( + stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx + ))] + PllInstance::Pllsai2 => { + RCC.cr().modify(|w| w.set_pllsai2on(false)); + while RCC.cr().read().pllsai2rdy() {} + } + } + + let Some(pll) = config else { return PllOutput::default() }; + + let pll_src = match pll.source { + PLLSource::NONE => panic!("must not select PLL source as NONE"), + PLLSource::HSE => input.hse, + PLLSource::HSI16 => input.hsi16, + PLLSource::MSI => input.msi, + }; + + let pll_src = pll_src.unwrap(); + + let vco_freq = pll_src / pll.prediv * pll.mul; + + let p = pll.divp.map(|div| vco_freq / div); + let q = pll.divq.map(|div| vco_freq / div); + let r = pll.divr.map(|div| vco_freq / div); + + macro_rules! write_fields { + ($w:ident) => { + $w.set_plln(pll.mul); + if let Some(divp) = pll.divp { + $w.set_pllp(divp); + $w.set_pllpen(true); + } + if let Some(divq) = pll.divq { + $w.set_pllq(divq); + $w.set_pllqen(true); + } + if let Some(divr) = pll.divr { + $w.set_pllr(divr); + $w.set_pllren(true); + } + }; + } + + match instance { + PllInstance::Pll => RCC.pllcfgr().write(|w| { + w.set_pllm(pll.prediv); + w.set_pllsrc(pll.source); + write_fields!(w); + }), + PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { + #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx, stm32l5))] + w.set_pllm(pll.prediv); + #[cfg(stm32l5)] + w.set_pllsrc(pll.source); + write_fields!(w); + }), + #[cfg(any( + stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx + ))] + PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| { + #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx, stm32l5))] + w.set_pllm(pll.prediv); + #[cfg(stm32l5)] + w.set_pllsrc(pll.source); + write_fields!(w); + }), + } + + // Enable PLL + match instance { + PllInstance::Pll => { + RCC.cr().modify(|w| w.set_pllon(true)); + while !RCC.cr().read().pllrdy() {} + } + PllInstance::Pllsai1 => { + RCC.cr().modify(|w| w.set_pllsai1on(true)); + while !RCC.cr().read().pllsai1rdy() {} + } + #[cfg(any( + stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx + ))] + PllInstance::Pllsai2 => { + RCC.cr().modify(|w| w.set_pllsai2on(true)); + while !RCC.cr().read().pllsai2rdy() {} + } + } + + PllOutput { _p: p, _q: q, _r: r } +} diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index 289217b1..7e095a6b 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs @@ -104,7 +104,7 @@ pub(crate) unsafe fn init(config: Config) { // Enable as clock source for USB, RNG if running at 48 MHz if range == MSIRange::RANGE48M { RCC.ccipr1().modify(|w| { - w.set_clk48msel(0b11); + w.set_clk48sel(0b11); }); } (msirange_to_hertz(range), Sw::MSI) @@ -173,7 +173,7 @@ pub(crate) unsafe fn init(config: Config) { let freq = src_freq / prediv * mul / divq; assert!(freq.0 == 48_000_000); RCC.ccipr1().modify(|w| { - w.set_clk48msel(0b10); + w.set_clk48sel(0b10); }); } @@ -191,7 +191,7 @@ pub(crate) unsafe fn init(config: Config) { let freq = src_freq / prediv * mul / q_div; if freq.0 == 48_000_000 { RCC.ccipr1().modify(|w| { - w.set_clk48msel(0b1); + w.set_clk48sel(0b1); }); } } @@ -218,7 +218,7 @@ pub(crate) unsafe fn init(config: Config) { while !RCC.crrcr().read().hsi48rdy() {} // Enable as clock source for USB, RNG and SDMMC - RCC.ccipr1().modify(|w| w.set_clk48msel(0)); + RCC.ccipr1().modify(|w| w.set_clk48sel(0)); } // Set flash wait states diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 9df40baa..76c9f34b 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -20,7 +20,7 @@ pub use mco::*; #[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(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] -#[cfg_attr(rcc_l4, path = "l4.rs")] +#[cfg_attr(any(rcc_l4, rcc_l4plus), path = "l4.rs")] #[cfg_attr(rcc_l5, path = "l5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wb, path = "wb.rs")] @@ -65,6 +65,7 @@ pub struct Clocks { pub hclk1: Hertz, #[cfg(any( rcc_l4, + rcc_l4plus, rcc_l5, rcc_f2, rcc_f4, @@ -85,6 +86,7 @@ pub struct Clocks { pub hclk2: Hertz, #[cfg(any( rcc_l4, + rcc_l4plus, rcc_l5, rcc_f2, rcc_f4, diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs index 1771e520..3d0c623f 100644 --- a/examples/stm32l4/src/bin/adc.rs +++ b/examples/stm32l4/src/bin/adc.rs @@ -13,7 +13,7 @@ fn main() -> ! { info!("Hello World!"); pac::RCC.ccipr().modify(|w| { - w.set_adcsel(0b11); + w.set_adcsel(pac::rcc::vals::Adcsel::SYSCLK); }); pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index 94251c12..d184bcf7 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs @@ -18,8 +18,8 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.mux = ClockSrc::PLL; config.rcc.hsi16 = true; - config.rcc.pll_src = PLLSource::HSI16; config.rcc.pll = Some(Pll { + source: PLLSource::HSI16, prediv: PllPreDiv::DIV1, mul: PllMul::MUL18, divp: None, diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index cd9f72ff..a1b41f84 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -17,8 +17,8 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.mux = ClockSrc::PLL; config.rcc.hse = Some(Hertz::mhz(8)); - config.rcc.pll_src = PLLSource::HSE; config.rcc.pll = Some(Pll { + source: PLLSource::HSE, prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None, diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index c1a27cf8..278d6543 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -79,8 +79,8 @@ async fn main(spawner: Spawner) { // 80MHz highest frequency for flash 0 wait. config.rcc.mux = ClockSrc::PLL; config.rcc.hse = Some(Hertz::mhz(8)); - config.rcc.pll_src = PLLSource::HSE; config.rcc.pll = Some(Pll { + source: PLLSource::HSE, prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None, diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 8f6eeef3..3785c689 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -26,8 +26,8 @@ async fn main(_spawner: Spawner) { config.rcc.hsi48 = true; config.rcc.mux = ClockSrc::PLL; config.rcc.hsi16 = true; - config.rcc.pll_src = PLLSource::HSI16; config.rcc.pll = Some(Pll { + source: PLLSource::HSI16, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index e1d7855f..c5a24044 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -289,8 +289,8 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::PLL; config.rcc.hsi16 = true; - config.rcc.pll_src = PLLSource::HSI16; config.rcc.pll = Some(Pll { + source: PLLSource::HSI16, prediv: PllPreDiv::DIV1, mul: PllMul::MUL18, divp: None, From 18e96898eab47840951305481cc669b8b221bdda Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 16 Oct 2023 03:47:54 +0200 Subject: [PATCH 020/188] stm32/rcc: unify L4 and L5. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/{l4.rs => l4l5.rs} | 69 ++--- embassy-stm32/src/rcc/l5.rs | 291 ---------------------- embassy-stm32/src/rcc/mod.rs | 3 +- examples/stm32l5/src/bin/rng.rs | 20 +- examples/stm32l5/src/bin/usb_ethernet.rs | 13 +- examples/stm32l5/src/bin/usb_hid_mouse.rs | 13 +- examples/stm32l5/src/bin/usb_serial.rs | 13 +- tests/stm32/src/common.rs | 17 +- 9 files changed, 97 insertions(+), 346 deletions(-) rename embassy-stm32/src/rcc/{l4.rs => l4l5.rs} (87%) delete mode 100644 embassy-stm32/src/rcc/l5.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 50ccd793..1eff1070 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-73e3f8a965a01fd5a168c3543b93ce49d475e130" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-5ecc410f93477d3d9314723ec26e637aa0c63b8f" } 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-73e3f8a965a01fd5a168c3543b93ce49d475e130", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-5ecc410f93477d3d9314723ec26e637aa0c63b8f", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4l5.rs similarity index 87% rename from embassy-stm32/src/rcc/l4.rs rename to embassy-stm32/src/rcc/l4l5.rs index aceafc49..1a8974ff 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -42,9 +42,7 @@ pub struct Config { // pll pub pll: Option, pub pllsai1: Option, - #[cfg(any( - stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx - ))] + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pub pllsai2: Option, // sysclk, buses. @@ -73,9 +71,7 @@ impl Default for Config { apb2_pre: APBPrescaler::DIV1, pll: None, pllsai1: None, - #[cfg(any( - stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx - ))] + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pllsai2: None, #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] hsi48: true, @@ -106,6 +102,11 @@ pub(crate) unsafe fn init(config: Config) { while RCC.cfgr().read().sws() != ClockSrc::MSI {} } + #[cfg(stm32l5)] + crate::pac::PWR.cr1().modify(|w| { + w.set_vos(crate::pac::pwr::vals::Vos::RANGE0); + }); + let rtc = config.ls.init(); let msi = config.msi.map(|range| { @@ -153,14 +154,12 @@ pub(crate) unsafe fn init(config: Config) { let _plls = [ &config.pll, &config.pllsai1, - #[cfg(any( - stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx - ))] + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] &config.pllsai2, ]; // L4 has shared PLLSRC, PLLM, check it's equal in all PLLs. - #[cfg(all(stm32l4, not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))))] + #[cfg(all(stm32l4, not(rcc_l4plus)))] match get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) { Err(()) => panic!("Source must be equal across all enabled PLLs."), Ok(None) => {} @@ -171,7 +170,7 @@ pub(crate) unsafe fn init(config: Config) { }; // L4+ has shared PLLSRC, check it's equal in all PLLs. - #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] + #[cfg(any(rcc_l4plus))] match get_equal(_plls.into_iter().flatten().map(|p| p.source)) { Err(()) => panic!("Source must be equal across all enabled PLLs."), Ok(None) => {} @@ -183,9 +182,7 @@ pub(crate) unsafe fn init(config: Config) { let pll_input = PllInput { hse, hsi16, msi }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); - #[cfg(any( - stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx - ))] + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); let sys_clk = match config.mux { @@ -202,12 +199,13 @@ pub(crate) unsafe fn init(config: Config) { Clk48Src::PLL_Q => pll._q, }; - #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] + #[cfg(rcc_l4plus)] assert!(sys_clk.0 <= 120_000_000); - #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))] + #[cfg(all(stm32l4, not(rcc_l4plus)))] assert!(sys_clk.0 <= 80_000_000); // Set flash wait states + #[cfg(stm32l4)] FLASH.acr().modify(|w| { w.set_latency(match sys_clk.0 { 0..=16_000_000 => 0, @@ -217,6 +215,18 @@ pub(crate) unsafe fn init(config: Config) { _ => 4, }) }); + // VCORE Range 0 (performance), others TODO + #[cfg(stm32l5)] + FLASH.acr().modify(|w| { + w.set_latency(match sys_clk.0 { + 0..=20_000_000 => 0, + 0..=40_000_000 => 1, + 0..=60_000_000 => 2, + 0..=80_000_000 => 3, + 0..=100_000_000 => 4, + _ => 5, + }) + }); RCC.cfgr().modify(|w| { w.set_sw(config.mux); @@ -274,6 +284,7 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz { } } +#[allow(unused)] fn get_equal(mut iter: impl Iterator) -> Result, ()> { let Some(x) = iter.next() else { return Ok(None) }; if !iter.all(|y| y == x) { @@ -299,9 +310,7 @@ struct PllOutput { enum PllInstance { Pll, Pllsai1, - #[cfg(any( - stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx - ))] + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] Pllsai2, } @@ -316,9 +325,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll RCC.cr().modify(|w| w.set_pllsai1on(false)); while RCC.cr().read().pllsai1rdy() {} } - #[cfg(any( - stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx - ))] + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] PllInstance::Pllsai2 => { RCC.cr().modify(|w| w.set_pllsai2on(false)); while RCC.cr().read().pllsai2rdy() {} @@ -342,6 +349,12 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let q = pll.divq.map(|div| vco_freq / div); let r = pll.divr.map(|div| vco_freq / div); + #[cfg(stm32l5)] + if instance == PllInstance::Pllsai2 { + assert!(q.is_none(), "PLLSAI2_Q is not available on L5"); + assert!(r.is_none(), "PLLSAI2_R is not available on L5"); + } + macro_rules! write_fields { ($w:ident) => { $w.set_plln(pll.mul); @@ -367,17 +380,15 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll write_fields!(w); }), PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { - #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx, stm32l5))] + #[cfg(any(rcc_l4plus, stm32l5))] w.set_pllm(pll.prediv); #[cfg(stm32l5)] w.set_pllsrc(pll.source); write_fields!(w); }), - #[cfg(any( - stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx - ))] + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| { - #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx, stm32l5))] + #[cfg(any(rcc_l4plus, stm32l5))] w.set_pllm(pll.prediv); #[cfg(stm32l5)] w.set_pllsrc(pll.source); @@ -395,9 +406,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll RCC.cr().modify(|w| w.set_pllsai1on(true)); while !RCC.cr().read().pllsai1rdy() {} } - #[cfg(any( - stm32l47x, stm32l48x, stm32l49x, stm32l4ax, stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx - ))] + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] PllInstance::Pllsai2 => { RCC.cr().modify(|w| w.set_pllsai2on(true)); while !RCC.cr().read().pllsai2rdy() {} diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs deleted file mode 100644 index 7e095a6b..00000000 --- a/embassy-stm32/src/rcc/l5.rs +++ /dev/null @@ -1,291 +0,0 @@ -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::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - MSI(MSIRange), - PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option), - HSE(Hertz), - HSI16, -} - -/// PLL clock input source -#[derive(Clone, Copy)] -pub enum PLLSource { - HSI16, - HSE(Hertz), - MSI(MSIRange), -} - -impl From for Pllsrc { - fn from(val: PLLSource) -> Pllsrc { - match val { - PLLSource::HSI16 => Pllsrc::HSI16, - PLLSource::HSE(_) => Pllsrc::HSE, - PLLSource::MSI(_) => Pllsrc::MSI, - } - } -} - -/// Clocks configutation -pub struct Config { - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - pub pllsai1: Option<(PllMul, PllPreDiv, Option, Option, Option)>, - pub hsi48: bool, - pub ls: super::LsConfig, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - mux: ClockSrc::MSI(MSIRange::RANGE4M), - ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - pllsai1: None, - hsi48: false, - ls: Default::default(), - } - } -} - -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 {} - } - - 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 { - ClockSrc::MSI(range) => { - // Enable MSI - RCC.cr().write(|w| { - w.set_msirange(range); - w.set_msirgsel(true); - w.set_msion(true); - - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(config.ls.lse.is_some()); - }); - while !RCC.cr().read().msirdy() {} - - // Enable as clock source for USB, RNG if running at 48 MHz - if range == MSIRange::RANGE48M { - RCC.ccipr1().modify(|w| { - w.set_clk48sel(0b11); - }); - } - (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, Sw::HSI16) - } - ClockSrc::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - - (freq, Sw::HSE) - } - 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 - } - PLLSource::HSI16 => { - // Enable HSI - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - HSI_FREQ - } - PLLSource::MSI(range) => { - // Enable MSI - RCC.cr().write(|w| { - w.set_msirange(range); - w.set_msipllen(false); // should be turned on if LSE is started - w.set_msirgsel(true); - w.set_msion(true); - }); - while !RCC.cr().read().msirdy() {} - - msirange_to_hertz(range) - } - }; - - // Disable PLL - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} - - let freq = src_freq / prediv * mul / divr; - - RCC.pllcfgr().write(move |w| { - 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(divq) = divq { - let freq = src_freq / prediv * mul / divq; - assert!(freq.0 == 48_000_000); - RCC.ccipr1().modify(|w| { - w.set_clk48sel(0b10); - }); - } - - if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { - RCC.pllsai1cfgr().write(move |w| { - w.set_plln(mul); - w.set_pllm(prediv); - if let Some(r_div) = r_div { - w.set_pllr(r_div); - w.set_pllren(true); - } - if let Some(q_div) = q_div { - 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_clk48sel(0b1); - }); - } - } - if let Some(p_div) = p_div { - w.set_pllp(p_div); - w.set_pllpen(true); - } - }); - - RCC.cr().modify(|w| w.set_pllsai1on(true)); - } - - // Enable PLL - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - RCC.pllcfgr().modify(|w| w.set_pllren(true)); - - (freq, Sw::PLL) - } - }; - - if config.hsi48 { - RCC.crrcr().modify(|w| w.set_hsi48on(true)); - while !RCC.crrcr().read().hsi48rdy() {} - - // Enable as clock source for USB, RNG and SDMMC - RCC.ccipr1().modify(|w| w.set_clk48sel(0)); - } - - // Set flash wait states - // VCORE Range 0 (performance), others TODO - FLASH.acr().modify(|w| { - w.set_latency(match sys_clk.0 { - 0..=20_000_000 => 0, - 0..=40_000_000 => 1, - 0..=60_000_000 => 2, - 0..=80_000_000 => 3, - 0..=100_000_000 => 4, - _ => 5, - }) - }); - - 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) - } - }; - - set_freqs(Clocks { - sys: sys_clk, - hclk1: ahb_freq, - hclk2: ahb_freq, - hclk3: ahb_freq, - pclk1: apb1_freq, - pclk2: apb2_freq, - pclk1_tim: apb1_tim_freq, - pclk2_tim: apb2_tim_freq, - rtc, - }); -} - -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 76c9f34b..8df6deaa 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -20,8 +20,7 @@ pub use mco::*; #[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(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] -#[cfg_attr(any(rcc_l4, rcc_l4plus), path = "l4.rs")] -#[cfg_attr(rcc_l5, path = "l5.rs")] +#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5), path = "l4l5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wb, path = "wb.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index cc3c99b5..e6233dbe 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, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -16,13 +16,17 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL( - PLLSource::HSI16, - PllRDiv::DIV2, - PllPreDiv::DIV1, - PllMul::MUL8, - Some(PllQDiv::DIV2), - ); + config.rcc.hsi16 = true; + config.rcc.mux = ClockSrc::PLL; + config.rcc.pll = Some(Pll { + // 64Mhz clock (16 / 1 * 8 / 2) + source: PLLSource::HSI16, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL8, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 498147f9..baa86640 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -45,8 +45,17 @@ 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, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); - config.rcc.hsi48 = true; + config.rcc.hsi16 = true; + config.rcc.mux = ClockSrc::PLL; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PLLSource::HSI16, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index 0d06c94a..1ce7e3e4 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -22,8 +22,17 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); - config.rcc.hsi48 = true; + config.rcc.hsi16 = true; + config.rcc.mux = ClockSrc::PLL; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PLLSource::HSI16, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index e19ecbf0..03d277a2 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -20,8 +20,17 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); - config.rcc.hsi48 = true; + config.rcc.hsi16 = true; + config.rcc.mux = ClockSrc::PLL; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PLLSource::HSI16, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index c5a24044..6dc1b300 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -302,14 +302,17 @@ pub fn config() -> Config { #[cfg(any(feature = "stm32l552ze"))] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::PLL( + config.rcc.hsi16 = true; + config.rcc.mux = ClockSrc::PLL; + config.rcc.pll = Some(Pll { // 110Mhz clock (16 / 4 * 55 / 2) - PLLSource::HSI16, - PllRDiv::DIV2, - PllPreDiv::DIV4, - PllMul::MUL55, - None, - ); + source: PLLSource::HSI16, + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL55, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); } #[cfg(feature = "stm32u585ai")] From aff77d2b65952368ea464f1b6950896afa093677 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 16 Oct 2023 04:54:48 +0200 Subject: [PATCH 021/188] stm32/rng: add test. --- embassy-stm32/Cargo.toml | 4 +-- embassy-stm32/src/rcc/g4.rs | 2 +- embassy-stm32/src/rcc/l4l5.rs | 4 +++ embassy-stm32/src/rcc/u5.rs | 2 +- embassy-stm32/src/rcc/wb.rs | 10 +++++++ embassy-stm32/src/rng.rs | 2 +- tests/stm32/Cargo.toml | 42 ++++++++++++++++------------- tests/stm32/src/bin/rng.rs | 50 +++++++++++++++++++++++++++++++++++ 8 files changed, 93 insertions(+), 23 deletions(-) create mode 100644 tests/stm32/src/bin/rng.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 1eff1070..a380fb21 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-5ecc410f93477d3d9314723ec26e637aa0c63b8f" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9330e31117668350a62572fdcd2598ec17d08042" } 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-5ecc410f93477d3d9314723ec26e637aa0c63b8f", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9330e31117668350a62572fdcd2598ec17d08042", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 32d14d2f..ba2a5e19 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -118,7 +118,7 @@ impl Default for Config { apb2_pre: APBPrescaler::DIV1, low_power_run: false, pll: None, - clock_48mhz_src: None, + clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(None)), adc12_clock_source: Adcsel::DISABLE, adc345_clock_source: Adcsel::DISABLE, ls: Default::default(), diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 1a8974ff..90c8923c 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -192,6 +192,10 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::PLL => pll._r.unwrap(), }; + #[cfg(stm32l4)] + RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); + #[cfg(stm32l5)] + RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); let _clk48 = match config.clk48_src { Clk48Src::HSI48 => hsi48, Clk48Src::MSI => msi, diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index fb9c163e..aba5ca83 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -188,7 +188,7 @@ impl Default for Config { apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, apb3_pre: APBPrescaler::DIV1, - hsi48: false, + hsi48: true, voltage_range: VoltageScale::RANGE3, ls: Default::default(), } diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index a6cf118a..64173fea 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -40,6 +40,7 @@ pub struct Config { pub hse: Option, pub sys: Sysclk, pub mux: Option, + pub hsi48: bool, pub pll: Option, pub pllsai: Option, @@ -63,6 +64,7 @@ pub const WPAN_DEFAULT: Config = Config { source: PllSource::HSE, prediv: Pllm::DIV2, }), + hsi48: true, ls: super::LsConfig::default_lse(), @@ -90,6 +92,7 @@ impl Default for Config { mux: None, pll: None, pllsai: None, + hsi48: true, ls: Default::default(), @@ -222,6 +225,13 @@ pub(crate) unsafe fn init(config: Config) { _ => {} } + let _hsi48 = config.hsi48.then(|| { + rcc.crrcr().modify(|w| w.set_hsi48on(true)); + while !rcc.crrcr().read().hsi48rdy() {} + + Hertz(48_000_000) + }); + rcc.cfgr().modify(|w| { w.set_sw(config.sys.into()); w.set_hpre(config.ahb1_pre); diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index fc003ebe..5e6922e9 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -85,7 +85,7 @@ impl<'d, T: Instance> Rng<'d, T> { reg.set_ie(false); reg.set_rngen(true); }); - T::regs().cr().write(|reg| { + T::regs().cr().modify(|reg| { reg.set_ced(false); }); // wait for CONDRST to be set diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index fd18cd77..9adff596 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -6,26 +6,27 @@ license = "MIT OR Apache-2.0" autobins = false [features] -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", "chrono", "not-gpdma"] # Nucleo -stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo -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", "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", "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 +stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] +stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin", "rng"] +stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] +stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] +stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma", "rng"] +stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin", "rng"] +stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] +stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng"] +stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng"] +stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma", "rng"] +stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] +stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng"] +stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] +stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng"] +stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] +stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth", "rng"] +stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] +stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] eth = [] +rng = [] sdmmc = [] stop = ["embassy-stm32/low-power"] chrono = ["embassy-stm32/chrono", "dep:chrono"] @@ -86,6 +87,11 @@ name = "gpio" path = "src/bin/gpio.rs" required-features = [] +[[bin]] +name = "rng" +path = "src/bin/rng.rs" +required-features = [ "rng",] + [[bin]] name = "rtc" path = "src/bin/rtc.rs" diff --git a/tests/stm32/src/bin/rng.rs b/tests/stm32/src/bin/rng.rs new file mode 100644 index 00000000..65da737d --- /dev/null +++ b/tests/stm32/src/bin/rng.rs @@ -0,0 +1,50 @@ +// required-features: rng +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[path = "../common.rs"] +mod common; +use common::*; +use embassy_executor::Spawner; +use embassy_stm32::rng::Rng; +use embassy_stm32::{bind_interrupts, peripherals, rng}; +use {defmt_rtt as _, panic_probe as _}; + +#[cfg(any(feature = "stm32l4a6zg", feature = "stm32h755zi", feature = "stm32f429zi"))] +bind_interrupts!(struct Irqs { + HASH_RNG => rng::InterruptHandler; +}); +#[cfg(any(feature = "stm32l073rz"))] +bind_interrupts!(struct Irqs { + RNG_LPUART1 => rng::InterruptHandler; +}); +#[cfg(not(any( + feature = "stm32l4a6zg", + feature = "stm32l073rz", + feature = "stm32h755zi", + feature = "stm32f429zi" +)))] +bind_interrupts!(struct Irqs { + RNG => rng::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); + + let mut rng = Rng::new(p.RNG, Irqs); + + let mut buf1 = [0u8; 16]; + unwrap!(rng.async_fill_bytes(&mut buf1).await); + info!("random bytes: {:02x}", buf1); + + let mut buf2 = [0u8; 16]; + unwrap!(rng.async_fill_bytes(&mut buf2).await); + info!("random bytes: {:02x}", buf2); + + defmt::assert!(buf1 != buf2); + + info!("Test OK"); + cortex_m::asm::bkpt(); +} From ea0e83a7f9579ba002929d2180b118722e89850a Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 16 Oct 2023 19:35:34 +0200 Subject: [PATCH 022/188] nrf/pac: reeport s and ns peripherals always independently of the current mode. You sometimes need this, for example for using nrf91 modem from S mode you need to acces IPC_NS. --- embassy-nrf/src/chips/nrf5340_app.rs | 316 ++++++++++++++------------- embassy-nrf/src/chips/nrf5340_net.rs | 5 +- embassy-nrf/src/chips/nrf9160.rs | 244 +++++++++++---------- 3 files changed, 297 insertions(+), 268 deletions(-) diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index afc2c4a7..5e9a8ed0 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs @@ -6,10 +6,13 @@ pub mod pac { // To avoid cfg spam, we remove _ns or _s suffixes here. pub use nrf5340_app_pac::NVIC_PRIO_BITS; - + + #[cfg(feature="rt")] + #[doc(no_inline)] + pub use nrf5340_app_pac::interrupt; + #[doc(no_inline)] pub use nrf5340_app_pac::{ - interrupt, Interrupt, Peripherals, @@ -60,156 +63,167 @@ pub mod pac { wdt0_ns as wdt0, }; - #[cfg(feature = "nrf5340-app-ns")] - #[doc(no_inline)] - pub use nrf5340_app_pac::{ - CLOCK_NS as CLOCK, - COMP_NS as COMP, - CTRLAP_NS as CTRLAP, - DCNF_NS as DCNF, - DPPIC_NS as DPPIC, - EGU0_NS as EGU0, - EGU1_NS as EGU1, - EGU2_NS as EGU2, - EGU3_NS as EGU3, - EGU4_NS as EGU4, - EGU5_NS as EGU5, - FPU_NS as FPU, - GPIOTE1_NS as GPIOTE1, - I2S0_NS as I2S0, - IPC_NS as IPC, - KMU_NS as KMU, - LPCOMP_NS as LPCOMP, - MUTEX_NS as MUTEX, - NFCT_NS as NFCT, - NVMC_NS as NVMC, - OSCILLATORS_NS as OSCILLATORS, - P0_NS as P0, - P1_NS as P1, - PDM0_NS as PDM0, - POWER_NS as POWER, - PWM0_NS as PWM0, - PWM1_NS as PWM1, - PWM2_NS as PWM2, - PWM3_NS as PWM3, - QDEC0_NS as QDEC0, - QDEC1_NS as QDEC1, - QSPI_NS as QSPI, - REGULATORS_NS as REGULATORS, - RESET_NS as RESET, - RTC0_NS as RTC0, - RTC1_NS as RTC1, - SAADC_NS as SAADC, - SPIM0_NS as SPIM0, - SPIM1_NS as SPIM1, - SPIM2_NS as SPIM2, - SPIM3_NS as SPIM3, - SPIM4_NS as SPIM4, - SPIS0_NS as SPIS0, - SPIS1_NS as SPIS1, - SPIS2_NS as SPIS2, - SPIS3_NS as SPIS3, - TIMER0_NS as TIMER0, - TIMER1_NS as TIMER1, - TIMER2_NS as TIMER2, - TWIM0_NS as TWIM0, - TWIM1_NS as TWIM1, - TWIM2_NS as TWIM2, - TWIM3_NS as TWIM3, - TWIS0_NS as TWIS0, - TWIS1_NS as TWIS1, - TWIS2_NS as TWIS2, - TWIS3_NS as TWIS3, - UARTE0_NS as UARTE0, - UARTE1_NS as UARTE1, - UARTE2_NS as UARTE2, - UARTE3_NS as UARTE3, - USBD_NS as USBD, - USBREGULATOR_NS as USBREGULATOR, - VMC_NS as VMC, - WDT0_NS as WDT0, - WDT1_NS as WDT1, - }; + /// Non-Secure mode (NS) peripherals + pub mod ns { + #[cfg(feature = "nrf5340-app-ns")] + #[doc(no_inline)] + pub use nrf5340_app_pac::{ + CLOCK_NS as CLOCK, + COMP_NS as COMP, + CTRLAP_NS as CTRLAP, + DCNF_NS as DCNF, + DPPIC_NS as DPPIC, + EGU0_NS as EGU0, + EGU1_NS as EGU1, + EGU2_NS as EGU2, + EGU3_NS as EGU3, + EGU4_NS as EGU4, + EGU5_NS as EGU5, + FPU_NS as FPU, + GPIOTE1_NS as GPIOTE1, + I2S0_NS as I2S0, + IPC_NS as IPC, + KMU_NS as KMU, + LPCOMP_NS as LPCOMP, + MUTEX_NS as MUTEX, + NFCT_NS as NFCT, + NVMC_NS as NVMC, + OSCILLATORS_NS as OSCILLATORS, + P0_NS as P0, + P1_NS as P1, + PDM0_NS as PDM0, + POWER_NS as POWER, + PWM0_NS as PWM0, + PWM1_NS as PWM1, + PWM2_NS as PWM2, + PWM3_NS as PWM3, + QDEC0_NS as QDEC0, + QDEC1_NS as QDEC1, + QSPI_NS as QSPI, + REGULATORS_NS as REGULATORS, + RESET_NS as RESET, + RTC0_NS as RTC0, + RTC1_NS as RTC1, + SAADC_NS as SAADC, + SPIM0_NS as SPIM0, + SPIM1_NS as SPIM1, + SPIM2_NS as SPIM2, + SPIM3_NS as SPIM3, + SPIM4_NS as SPIM4, + SPIS0_NS as SPIS0, + SPIS1_NS as SPIS1, + SPIS2_NS as SPIS2, + SPIS3_NS as SPIS3, + TIMER0_NS as TIMER0, + TIMER1_NS as TIMER1, + TIMER2_NS as TIMER2, + TWIM0_NS as TWIM0, + TWIM1_NS as TWIM1, + TWIM2_NS as TWIM2, + TWIM3_NS as TWIM3, + TWIS0_NS as TWIS0, + TWIS1_NS as TWIS1, + TWIS2_NS as TWIS2, + TWIS3_NS as TWIS3, + UARTE0_NS as UARTE0, + UARTE1_NS as UARTE1, + UARTE2_NS as UARTE2, + UARTE3_NS as UARTE3, + USBD_NS as USBD, + USBREGULATOR_NS as USBREGULATOR, + VMC_NS as VMC, + WDT0_NS as WDT0, + WDT1_NS as WDT1, + }; + } - #[cfg(feature = "nrf5340-app-s")] - #[doc(no_inline)] - pub use nrf5340_app_pac::{ - CACHEDATA_S as CACHEDATA, - CACHEINFO_S as CACHEINFO, - CACHE_S as CACHE, - CLOCK_S as CLOCK, - COMP_S as COMP, - CRYPTOCELL_S as CRYPTOCELL, - CTI_S as CTI, - CTRLAP_S as CTRLAP, - DCNF_S as DCNF, - DPPIC_S as DPPIC, - EGU0_S as EGU0, - EGU1_S as EGU1, - EGU2_S as EGU2, - EGU3_S as EGU3, - EGU4_S as EGU4, - EGU5_S as EGU5, - FICR_S as FICR, - FPU_S as FPU, - GPIOTE0_S as GPIOTE0, - I2S0_S as I2S0, - IPC_S as IPC, - KMU_S as KMU, - LPCOMP_S as LPCOMP, - MUTEX_S as MUTEX, - NFCT_S as NFCT, - NVMC_S as NVMC, - OSCILLATORS_S as OSCILLATORS, - P0_S as P0, - P1_S as P1, - PDM0_S as PDM0, - POWER_S as POWER, - PWM0_S as PWM0, - PWM1_S as PWM1, - PWM2_S as PWM2, - PWM3_S as PWM3, - QDEC0_S as QDEC0, - QDEC1_S as QDEC1, - QSPI_S as QSPI, - REGULATORS_S as REGULATORS, - RESET_S as RESET, - RTC0_S as RTC0, - RTC1_S as RTC1, - SAADC_S as SAADC, - SPIM0_S as SPIM0, - SPIM1_S as SPIM1, - SPIM2_S as SPIM2, - SPIM3_S as SPIM3, - SPIM4_S as SPIM4, - SPIS0_S as SPIS0, - SPIS1_S as SPIS1, - SPIS2_S as SPIS2, - SPIS3_S as SPIS3, - SPU_S as SPU, - TAD_S as TAD, - TIMER0_S as TIMER0, - TIMER1_S as TIMER1, - TIMER2_S as TIMER2, - TWIM0_S as TWIM0, - TWIM1_S as TWIM1, - TWIM2_S as TWIM2, - TWIM3_S as TWIM3, - TWIS0_S as TWIS0, - TWIS1_S as TWIS1, - TWIS2_S as TWIS2, - TWIS3_S as TWIS3, - UARTE0_S as UARTE0, - UARTE1_S as UARTE1, - UARTE2_S as UARTE2, - UARTE3_S as UARTE3, - UICR_S as UICR, - USBD_S as USBD, - USBREGULATOR_S as USBREGULATOR, - VMC_S as VMC, - WDT0_S as WDT0, - WDT1_S as WDT1, - }; + /// Secure mode (S) peripherals + pub mod s { + #[cfg(feature = "nrf5340-app-s")] + #[doc(no_inline)] + pub use nrf5340_app_pac::{ + CACHEDATA_S as CACHEDATA, + CACHEINFO_S as CACHEINFO, + CACHE_S as CACHE, + CLOCK_S as CLOCK, + COMP_S as COMP, + CRYPTOCELL_S as CRYPTOCELL, + CTI_S as CTI, + CTRLAP_S as CTRLAP, + DCNF_S as DCNF, + DPPIC_S as DPPIC, + EGU0_S as EGU0, + EGU1_S as EGU1, + EGU2_S as EGU2, + EGU3_S as EGU3, + EGU4_S as EGU4, + EGU5_S as EGU5, + FICR_S as FICR, + FPU_S as FPU, + GPIOTE0_S as GPIOTE0, + I2S0_S as I2S0, + IPC_S as IPC, + KMU_S as KMU, + LPCOMP_S as LPCOMP, + MUTEX_S as MUTEX, + NFCT_S as NFCT, + NVMC_S as NVMC, + OSCILLATORS_S as OSCILLATORS, + P0_S as P0, + P1_S as P1, + PDM0_S as PDM0, + POWER_S as POWER, + PWM0_S as PWM0, + PWM1_S as PWM1, + PWM2_S as PWM2, + PWM3_S as PWM3, + QDEC0_S as QDEC0, + QDEC1_S as QDEC1, + QSPI_S as QSPI, + REGULATORS_S as REGULATORS, + RESET_S as RESET, + RTC0_S as RTC0, + RTC1_S as RTC1, + SAADC_S as SAADC, + SPIM0_S as SPIM0, + SPIM1_S as SPIM1, + SPIM2_S as SPIM2, + SPIM3_S as SPIM3, + SPIM4_S as SPIM4, + SPIS0_S as SPIS0, + SPIS1_S as SPIS1, + SPIS2_S as SPIS2, + SPIS3_S as SPIS3, + SPU_S as SPU, + TAD_S as TAD, + TIMER0_S as TIMER0, + TIMER1_S as TIMER1, + TIMER2_S as TIMER2, + TWIM0_S as TWIM0, + TWIM1_S as TWIM1, + TWIM2_S as TWIM2, + TWIM3_S as TWIM3, + TWIS0_S as TWIS0, + TWIS1_S as TWIS1, + TWIS2_S as TWIS2, + TWIS3_S as TWIS3, + UARTE0_S as UARTE0, + UARTE1_S as UARTE1, + UARTE2_S as UARTE2, + UARTE3_S as UARTE3, + UICR_S as UICR, + USBD_S as USBD, + USBREGULATOR_S as USBREGULATOR, + VMC_S as VMC, + WDT0_S as WDT0, + WDT1_S as WDT1, + }; + } + + #[cfg(feature = "_ns")] + pub use ns::*; + #[cfg(feature = "_s")] + pub use s::*; } /// The maximum buffer size that the EasyDMA can send/recv in one operation. diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs index dee666a6..a7cf8287 100644 --- a/embassy-nrf/src/chips/nrf5340_net.rs +++ b/embassy-nrf/src/chips/nrf5340_net.rs @@ -7,9 +7,12 @@ pub mod pac { pub use nrf5340_net_pac::NVIC_PRIO_BITS; + #[cfg(feature="rt")] + #[doc(no_inline)] + pub use nrf5340_net_pac::interrupt; + #[doc(no_inline)] pub use nrf5340_net_pac::{ - interrupt, Interrupt, Peripherals, diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 495285ba..8b1356ef 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -7,9 +7,12 @@ pub mod pac { pub use nrf9160_pac::NVIC_PRIO_BITS; + #[cfg(feature="rt")] + #[doc(no_inline)] + pub use nrf9160_pac::interrupt; + #[doc(no_inline)] pub use nrf9160_pac::{ - interrupt, Interrupt, cc_host_rgf_s as cc_host_rgf, @@ -45,122 +48,131 @@ pub mod pac { wdt_ns as wdt, }; - #[cfg(feature = "nrf9160-ns")] - #[doc(no_inline)] - pub use nrf9160_pac::{ - CLOCK_NS as CLOCK, - DPPIC_NS as DPPIC, - EGU0_NS as EGU0, - EGU1_NS as EGU1, - EGU2_NS as EGU2, - EGU3_NS as EGU3, - EGU4_NS as EGU4, - EGU5_NS as EGU5, - FPU_NS as FPU, - GPIOTE1_NS as GPIOTE1, - I2S_NS as I2S, - IPC_NS as IPC, - KMU_NS as KMU, - NVMC_NS as NVMC, - P0_NS as P0, - PDM_NS as PDM, - POWER_NS as POWER, - PWM0_NS as PWM0, - PWM1_NS as PWM1, - PWM2_NS as PWM2, - PWM3_NS as PWM3, - REGULATORS_NS as REGULATORS, - RTC0_NS as RTC0, - RTC1_NS as RTC1, - SAADC_NS as SAADC, - SPIM0_NS as SPIM0, - SPIM1_NS as SPIM1, - SPIM2_NS as SPIM2, - SPIM3_NS as SPIM3, - SPIS0_NS as SPIS0, - SPIS1_NS as SPIS1, - SPIS2_NS as SPIS2, - SPIS3_NS as SPIS3, - TIMER0_NS as TIMER0, - TIMER1_NS as TIMER1, - TIMER2_NS as TIMER2, - TWIM0_NS as TWIM0, - TWIM1_NS as TWIM1, - TWIM2_NS as TWIM2, - TWIM3_NS as TWIM3, - TWIS0_NS as TWIS0, - TWIS1_NS as TWIS1, - TWIS2_NS as TWIS2, - TWIS3_NS as TWIS3, - UARTE0_NS as UARTE0, - UARTE1_NS as UARTE1, - UARTE2_NS as UARTE2, - UARTE3_NS as UARTE3, - VMC_NS as VMC, - WDT_NS as WDT, - }; + /// Non-Secure mode (NS) peripherals + pub mod ns { + #[doc(no_inline)] + pub use nrf9160_pac::{ + CLOCK_NS as CLOCK, + DPPIC_NS as DPPIC, + EGU0_NS as EGU0, + EGU1_NS as EGU1, + EGU2_NS as EGU2, + EGU3_NS as EGU3, + EGU4_NS as EGU4, + EGU5_NS as EGU5, + FPU_NS as FPU, + GPIOTE1_NS as GPIOTE1, + I2S_NS as I2S, + IPC_NS as IPC, + KMU_NS as KMU, + NVMC_NS as NVMC, + P0_NS as P0, + PDM_NS as PDM, + POWER_NS as POWER, + PWM0_NS as PWM0, + PWM1_NS as PWM1, + PWM2_NS as PWM2, + PWM3_NS as PWM3, + REGULATORS_NS as REGULATORS, + RTC0_NS as RTC0, + RTC1_NS as RTC1, + SAADC_NS as SAADC, + SPIM0_NS as SPIM0, + SPIM1_NS as SPIM1, + SPIM2_NS as SPIM2, + SPIM3_NS as SPIM3, + SPIS0_NS as SPIS0, + SPIS1_NS as SPIS1, + SPIS2_NS as SPIS2, + SPIS3_NS as SPIS3, + TIMER0_NS as TIMER0, + TIMER1_NS as TIMER1, + TIMER2_NS as TIMER2, + TWIM0_NS as TWIM0, + TWIM1_NS as TWIM1, + TWIM2_NS as TWIM2, + TWIM3_NS as TWIM3, + TWIS0_NS as TWIS0, + TWIS1_NS as TWIS1, + TWIS2_NS as TWIS2, + TWIS3_NS as TWIS3, + UARTE0_NS as UARTE0, + UARTE1_NS as UARTE1, + UARTE2_NS as UARTE2, + UARTE3_NS as UARTE3, + VMC_NS as VMC, + WDT_NS as WDT, + }; + } - #[cfg(feature = "nrf9160-s")] - #[doc(no_inline)] - pub use nrf9160_pac::{ - CC_HOST_RGF_S as CC_HOST_RGF, - CLOCK_S as CLOCK, - CRYPTOCELL_S as CRYPTOCELL, - CTRL_AP_PERI_S as CTRL_AP_PERI, - DPPIC_S as DPPIC, - EGU0_S as EGU0, - EGU1_S as EGU1, - EGU2_S as EGU2, - EGU3_S as EGU3, - EGU4_S as EGU4, - EGU5_S as EGU5, - FICR_S as FICR, - FPU_S as FPU, - GPIOTE0_S as GPIOTE0, - I2S_S as I2S, - IPC_S as IPC, - KMU_S as KMU, - NVMC_S as NVMC, - P0_S as P0, - PDM_S as PDM, - POWER_S as POWER, - PWM0_S as PWM0, - PWM1_S as PWM1, - PWM2_S as PWM2, - PWM3_S as PWM3, - REGULATORS_S as REGULATORS, - RTC0_S as RTC0, - RTC1_S as RTC1, - SAADC_S as SAADC, - SPIM0_S as SPIM0, - SPIM1_S as SPIM1, - SPIM2_S as SPIM2, - SPIM3_S as SPIM3, - SPIS0_S as SPIS0, - SPIS1_S as SPIS1, - SPIS2_S as SPIS2, - SPIS3_S as SPIS3, - SPU_S as SPU, - TAD_S as TAD, - TIMER0_S as TIMER0, - TIMER1_S as TIMER1, - TIMER2_S as TIMER2, - TWIM0_S as TWIM0, - TWIM1_S as TWIM1, - TWIM2_S as TWIM2, - TWIM3_S as TWIM3, - TWIS0_S as TWIS0, - TWIS1_S as TWIS1, - TWIS2_S as TWIS2, - TWIS3_S as TWIS3, - UARTE0_S as UARTE0, - UARTE1_S as UARTE1, - UARTE2_S as UARTE2, - UARTE3_S as UARTE3, - UICR_S as UICR, - VMC_S as VMC, - WDT_S as WDT, - }; + /// Secure mode (S) peripherals + pub mod s { + #[doc(no_inline)] + pub use nrf9160_pac::{ + CC_HOST_RGF_S as CC_HOST_RGF, + CLOCK_S as CLOCK, + CRYPTOCELL_S as CRYPTOCELL, + CTRL_AP_PERI_S as CTRL_AP_PERI, + DPPIC_S as DPPIC, + EGU0_S as EGU0, + EGU1_S as EGU1, + EGU2_S as EGU2, + EGU3_S as EGU3, + EGU4_S as EGU4, + EGU5_S as EGU5, + FICR_S as FICR, + FPU_S as FPU, + GPIOTE0_S as GPIOTE0, + I2S_S as I2S, + IPC_S as IPC, + KMU_S as KMU, + NVMC_S as NVMC, + P0_S as P0, + PDM_S as PDM, + POWER_S as POWER, + PWM0_S as PWM0, + PWM1_S as PWM1, + PWM2_S as PWM2, + PWM3_S as PWM3, + REGULATORS_S as REGULATORS, + RTC0_S as RTC0, + RTC1_S as RTC1, + SAADC_S as SAADC, + SPIM0_S as SPIM0, + SPIM1_S as SPIM1, + SPIM2_S as SPIM2, + SPIM3_S as SPIM3, + SPIS0_S as SPIS0, + SPIS1_S as SPIS1, + SPIS2_S as SPIS2, + SPIS3_S as SPIS3, + SPU_S as SPU, + TAD_S as TAD, + TIMER0_S as TIMER0, + TIMER1_S as TIMER1, + TIMER2_S as TIMER2, + TWIM0_S as TWIM0, + TWIM1_S as TWIM1, + TWIM2_S as TWIM2, + TWIM3_S as TWIM3, + TWIS0_S as TWIS0, + TWIS1_S as TWIS1, + TWIS2_S as TWIS2, + TWIS3_S as TWIS3, + UARTE0_S as UARTE0, + UARTE1_S as UARTE1, + UARTE2_S as UARTE2, + UARTE3_S as UARTE3, + UICR_S as UICR, + VMC_S as VMC, + WDT_S as WDT, + }; + } + + #[cfg(feature = "_ns")] + pub use ns::*; + #[cfg(feature = "_s")] + pub use s::*; } /// The maximum buffer size that the EasyDMA can send/recv in one operation. From 213b4c9dca2e541c00e702b4476db3612f4d62b9 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 16 Oct 2023 20:07:48 +0200 Subject: [PATCH 023/188] time: add `links` key, release v0.1.5. --- cyw43/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 | 7 +++++++ embassy-time/Cargo.toml | 8 +++++++- embassy-time/build.rs | 3 +++ 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 +- 56 files changed, 70 insertions(+), 54 deletions(-) create mode 100644 embassy-time/build.rs diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index d7bba6b6..30cb69be 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml @@ -11,7 +11,7 @@ log = ["dep:log"] firmware-logs = [] [dependencies] -embassy-time = { version = "0.1.4", path = "../embassy-time"} +embassy-time = { version = "0.1.5", 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-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml index 040e2356..55ef734e 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.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", 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 4869bf3e..a793a198 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.4", path = "../embassy-time", optional = true} +embassy-time = { version = "0.1.5", 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 6cdacd9c..846c3919 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.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", 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 b93716d0..34651bc2 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.4", path = "../embassy-time" } +embassy-time = { version = "0.1.5", 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 e50fd0e6..0edb0ef8 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.4", path = "../embassy-time" } +embassy-time = { version = "0.1.5", 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 a0f53c6a..b0e94b58 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.4", path = "../embassy-time" } +embassy-time = { version = "0.1.5", 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 31836e1d..0bfc7d47 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.4", path = "../embassy-time" } +embassy-time = { version = "0.1.5", 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 8fcbef83..f79dd839 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.4", path = "../embassy-time" } +embassy-time = { version = "0.1.5", 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 bd96bc15..360f77c1 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.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", 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 02b11e19..903dc25a 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.4", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } +embassy-time = { version = "0.1.5", 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 b9d7776e..3e3422f3 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.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", 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 a380fb21..a608fd24 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.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", 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 0dd938c2..6e79addf 100644 --- a/embassy-time/CHANGELOG.md +++ b/embassy-time/CHANGELOG.md @@ -5,6 +5,13 @@ 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.5 - 2023-10-16 + +- Added `links` key to Cargo.toml, to prevent multiple copies of this crate in the same binary. + Needed because different copies might get different tick rates, causing + wrong delays if the time driver is using one copy and user code is using another. + This is especially common when mixing crates from crates.io and git. + ## 0.1.4 - 2023-10-12 - Added more tick rates diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index e4b88d78..87b57d1e 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-time" -version = "0.1.4" +version = "0.1.5" edition = "2021" description = "Instant and Duration for embedded no-std systems, with async timer support" repository = "https://github.com/embassy-rs/embassy" @@ -13,6 +13,12 @@ categories = [ "asynchronous", ] +# Prevent multiple copies of this crate in the same binary. +# Needed because different copies might get different tick rates, causing +# wrong delays if the time driver is using one copy and user code is using another. +# This is especially common when mixing crates from crates.io and git. +links = "embassy-time" + [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-v$VERSION/embassy-time/src/" src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time/src/" diff --git a/embassy-time/build.rs b/embassy-time/build.rs new file mode 100644 index 00000000..5b009566 --- /dev/null +++ b/embassy-time/build.rs @@ -0,0 +1,3 @@ +// empty, needed to be able to use `links` in Cargo.toml. + +fn main() {} diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 4c570cf2..275367ff 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.4", path = "../../../../embassy-time", features = ["nightly"] } +embassy-time = { version = "0.1.5", 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 330eac41..da89f15d 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.4", path = "../../../../embassy-time", features = ["nightly"] } +embassy-time = { version = "0.1.5", 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 0ee7241a..147a5bcf 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.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 fdc02c28..3fa136ae 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.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 de309ae0..7ca767bd 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.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 5bee7458..3e3cbbd8 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.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 cc0b4509..5e77b7d5 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.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 85fff4bf..aa5c5cf9 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.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 78d92468..87b8a116 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.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 01983005..e5820f26 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.4", path = "../../embassy-time" } +embassy-time = { version = "0.1.5", 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 7428f85f..a81d43a2 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.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "generic-queue"] } +embassy-time = { version = "0.1.5", 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 7a3ef54f..56d01cf6 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.5", 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 5824d57b..4e583148 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.4", path = "../../embassy-time", features = [ +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", ] } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 6eeb1ceb..9c1d9483 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.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.5", 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 444dd500..cfa62566 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.4", path = "../../embassy-time", features = ["log", "std", "nightly"] } +embassy-time = { version = "0.1.5", 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 8d65a399..b80ccd30 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 750d5304..47a95ec1 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 664be1f9..34319fbd 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 7330eef3..fbf50836 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 6ff425fa..b3b2b123 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 b76238ee..76f7e2ca 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 01549f11..74616443 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 4d10e82d..d0b7d85f 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 4b0b1084..908c6d19 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 bc6d5898..bf2975b2 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 adc99024..9cb5747d 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 f70ecc06..03b6d600 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 472e1b7a..70058d49 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 5456efe8..d67f3c6a 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", "unstable-traits", "nightly"] } +embassy-time = { version = "0.1.5", 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 cf8601da..36480c2f 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 9c139c2e..de60b3b1 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 e0711ad0..3aa2375d 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 7effc09a..7f0f351d 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.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 c106d62b..6a338af4 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.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", 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 9136c81c..29339295 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.4", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } +embassy-time = { version = "0.1.5", 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 32f296a1..7fcda202 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.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.5", 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 daa8edfb..73cf78b2 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.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } +embassy-time = { version = "0.1.5", 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 ddd83ec2..3bb46d37 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.4", path = "../../embassy-time" } +embassy-time = { version = "0.1.5", 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 a1e4c085..c307e75c 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.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } +embassy-time = { version = "0.1.5", 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 9adff596..fba46c1a 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -42,7 +42,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.4", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.5", 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 40e4ca4751dd935a4c52f893e8e058cfa75db893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Sun, 15 Oct 2023 19:38:42 +0200 Subject: [PATCH 024/188] Prepare embassy-net(/-driver,/-driver-channel) 0.2.0 --- cyw43/Cargo.toml | 2 +- embassy-net-adin1110/Cargo.toml | 2 +- embassy-net-driver-channel/CHANGELOG.md | 18 ++++++++++++++ embassy-net-driver-channel/Cargo.toml | 4 ++-- embassy-net-driver/CHANGELOG.md | 17 ++++++++++++++ embassy-net-driver/Cargo.toml | 2 +- embassy-net-enc28j60/Cargo.toml | 2 +- embassy-net-esp-hosted/Cargo.toml | 2 +- embassy-net-ppp/Cargo.toml | 2 +- embassy-net-tuntap/Cargo.toml | 2 +- embassy-net-wiznet/Cargo.toml | 2 +- embassy-net/CHANGELOG.md | 31 +++++++++++++++++++++++++ embassy-net/Cargo.toml | 4 ++-- embassy-stm32-wpan/Cargo.toml | 2 +- embassy-stm32/Cargo.toml | 2 +- embassy-usb/Cargo.toml | 2 +- examples/nrf52840/Cargo.toml | 2 +- examples/nrf5340/Cargo.toml | 2 +- examples/rp/Cargo.toml | 2 +- examples/std/Cargo.toml | 2 +- examples/stm32f4/Cargo.toml | 2 +- examples/stm32f7/Cargo.toml | 2 +- examples/stm32h5/Cargo.toml | 2 +- examples/stm32h7/Cargo.toml | 2 +- examples/stm32l4/Cargo.toml | 2 +- examples/stm32l5/Cargo.toml | 2 +- examples/stm32wb/Cargo.toml | 2 +- examples/stm32wba/Cargo.toml | 2 +- tests/nrf/Cargo.toml | 2 +- tests/perf-client/Cargo.toml | 2 +- tests/rp/Cargo.toml | 2 +- tests/stm32/Cargo.toml | 2 +- 32 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 embassy-net-driver-channel/CHANGELOG.md create mode 100644 embassy-net-driver/CHANGELOG.md create mode 100644 embassy-net/CHANGELOG.md diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index 30cb69be..b19cabfe 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml @@ -14,7 +14,7 @@ firmware-logs = [] embassy-time = { version = "0.1.5", 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"} +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} defmt = { version = "0.3", optional = true } log = { version = "0.4.17", optional = true } diff --git a/embassy-net-adin1110/Cargo.toml b/embassy-net-adin1110/Cargo.toml index 34651bc2..a781f3bd 100644 --- a/embassy-net-adin1110/Cargo.toml +++ b/embassy-net-adin1110/Cargo.toml @@ -16,7 +16,7 @@ log = { version = "0.4", default-features = false, optional = true } 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-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } bitfield = "0.14.0" diff --git a/embassy-net-driver-channel/CHANGELOG.md b/embassy-net-driver-channel/CHANGELOG.md new file mode 100644 index 00000000..589996cf --- /dev/null +++ b/embassy-net-driver-channel/CHANGELOG.md @@ -0,0 +1,18 @@ +# Changelog + +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.2.0 - 2023-10-15 + +- Update embassy-net-driver +- `Runner::new` now takes an `embassy_net_driver::HardwareAddress` parameter +- Added `Runner::set_ieee802154_address`, `Runner::ieee802154_address` + +## 0.1.0 - 2023-06-29 + +- First release + + diff --git a/embassy-net-driver-channel/Cargo.toml b/embassy-net-driver-channel/Cargo.toml index 4588af02..2fd26a7c 100644 --- a/embassy-net-driver-channel/Cargo.toml +++ b/embassy-net-driver-channel/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-net-driver-channel" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT OR Apache-2.0" description = "High-level channel-based driver for the `embassy-net` async TCP/IP network stack." @@ -26,4 +26,4 @@ log = { version = "0.4.14", optional = true } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } diff --git a/embassy-net-driver/CHANGELOG.md b/embassy-net-driver/CHANGELOG.md new file mode 100644 index 00000000..7be62282 --- /dev/null +++ b/embassy-net-driver/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +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.2.0 - 2023-10-15 + +- Added `Driver::ieee802154_address` +- Added `Medium::Ieee802154` + +## 0.1.0 - 2023-06-29 + +- First release + + diff --git a/embassy-net-driver/Cargo.toml b/embassy-net-driver/Cargo.toml index e25950b6..9cd6a2ea 100644 --- a/embassy-net-driver/Cargo.toml +++ b/embassy-net-driver/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-net-driver" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT OR Apache-2.0" description = "Driver trait for the `embassy-net` async TCP/IP network stack." diff --git a/embassy-net-enc28j60/Cargo.toml b/embassy-net-enc28j60/Cargo.toml index 0edb0ef8..ea2ed1f7 100644 --- a/embassy-net-enc28j60/Cargo.toml +++ b/embassy-net-enc28j60/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] 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-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index b0e94b58..5f901bb9 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml @@ -10,7 +10,7 @@ log = { version = "0.4.14", optional = true } embassy-time = { version = "0.1.5", 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"} +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} embedded-hal = { version = "1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml index 453da436..bd992de0 100644 --- a/embassy-net-ppp/Cargo.toml +++ b/embassy-net-ppp/Cargo.toml @@ -16,7 +16,7 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } embedded-io-async = { version = "0.6.0" } -embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } ppproto = { version = "0.1.2"} embassy-sync = { version = "0.3.0", path = "../embassy-sync" } diff --git a/embassy-net-tuntap/Cargo.toml b/embassy-net-tuntap/Cargo.toml index 08d30968..4e374c36 100644 --- a/embassy-net-tuntap/Cargo.toml +++ b/embassy-net-tuntap/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" edition = "2021" [dependencies] -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } async-io = "1.6.0" log = "0.4.14" libc = "0.2.101" diff --git a/embassy-net-wiznet/Cargo.toml b/embassy-net-wiznet/Cargo.toml index 0bfc7d47..0cc086b7 100644 --- a/embassy-net-wiznet/Cargo.toml +++ b/embassy-net-wiznet/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] 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-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } defmt = { version = "0.3", optional = true } diff --git a/embassy-net/CHANGELOG.md b/embassy-net/CHANGELOG.md new file mode 100644 index 00000000..3e7c2877 --- /dev/null +++ b/embassy-net/CHANGELOG.md @@ -0,0 +1,31 @@ +# Changelog + +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.2.0 - 2023-10-15 + +- Re-export `smoltcp::wire::IpEndpoint` +- Add poll functions on UdpSocket +- Make dual-stack work in embassy-net +- Fix multicast support +- Allow ethernet and 802.15.4 to coexist +- Add IEEE802.15.4 address to embassy net Stack +- Use HardwareAddress in Driver +- Add async versions of smoltcp's `send` and `recv` closure based API +- add error translation to tcp errors +- Forward TCP/UDP socket capacity impls +- allow changing IP config at runtime +- allow non-'static drivers +- Remove impl_trait_projections +- update embedded-io, embedded-nal-async +- add support for dhcp hostname option +- Wake stack's task after queueing a DNS query + +## 0.1.0 - 2023-06-29 + +- First release + + diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index f79dd839..573d20fb 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-net" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT OR Apache-2.0" description = "Async TCP/IP network stack for embedded systems" @@ -51,7 +51,7 @@ smoltcp = { version = "0.10.0", default-features = false, features = [ "async", ] } -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-time = { version = "0.1.5", 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-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 3e3422f3..52ecf15d 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -17,7 +17,7 @@ embassy-time = { version = "0.1.5", 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" } -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver", optional=true } defmt = { version = "0.3", optional = true } cortex-m = "0.7.6" diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index a608fd24..1342b2ea 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -37,7 +37,7 @@ embassy-time = { version = "0.1.5", 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" } -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } embassy-executor = { version = "0.3.0", path = "../embassy-executor", optional = true } diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 0e7e0e70..9ae14499 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -42,7 +42,7 @@ max-handler-count-8 = [] embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 56d01cf6..75373350 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -33,7 +33,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", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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-net = { version = "0.2.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.6.0", features = ["defmt-03"] } embedded-io-async = { version = "0.6.0", optional = true, features = ["defmt-03"] } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 4e583148..24972a4f 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -27,7 +27,7 @@ embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = [ "gpiote", "unstable-pac", ] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = [ +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = [ "nightly", "defmt", "tcp", diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 9c1d9483..7386eeea 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -12,7 +12,7 @@ embassy-executor = { version = "0.3.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.5", 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"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index cfa62566..a5f4c871 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" 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.5", 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 = { version = "0.2.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.6.0" } diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 76f7e2ca..9b10e975 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/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", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 74616443..5cbaca46 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -10,7 +10,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" 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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.2.0", 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/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index bf2975b2..f5980d87 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -10,7 +10,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" 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.5", 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"] } +embassy-net = { version = "0.2.0", 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 9cb5747d..0855bdfc 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -10,7 +10,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" 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.5", 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"] } +embassy-net = { version = "0.2.0", 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/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index d67f3c6a..b420ad56 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -13,7 +13,7 @@ embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["de 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" } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "udp", "tcp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.2.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.6.0", features = ["defmt-03"] } embedded-io = { version = "0.6.0", features = ["defmt-03"] } diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 36480c2f..ecf88d7e 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/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.5", 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-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.6.0" diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 3aa2375d..fa2cc63f 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -11,7 +11,7 @@ embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", fea 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.5", 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 } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 7f0f351d..68ab5a46 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -9,7 +9,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" 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.5", 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 } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } defmt = "0.3" defmt-rtt = "0.4" diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 7fcda202..96a5871e 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -13,7 +13,7 @@ embassy-executor = { version = "0.3.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.5", 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"] } +embassy-net = { version = "0.2.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"] } embedded-hal-async = { version = "1.0.0-rc.1" } diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml index 73cf78b2..bab5ac49 100644 --- a/tests/perf-client/Cargo.toml +++ b/tests/perf-client/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } embassy-time = { version = "0.1.5", 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/rp/Cargo.toml b/tests/rp/Cargo.toml index c307e75c..1fb73857 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -12,7 +12,7 @@ embassy-executor = { version = "0.3.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.5", 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"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index fba46c1a..77991ead 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -46,7 +46,7 @@ embassy-time = { version = "0.1.5", 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"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } perf-client = { path = "../perf-client" } defmt = "0.3.0" From 5a1393aa0bb0f40a1e816b4e8779996978dcc002 Mon Sep 17 00:00:00 2001 From: Caleb Jamison Date: Mon, 16 Oct 2023 16:17:07 -0400 Subject: [PATCH 025/188] Add example to show useage of rp2040 rosc --- examples/rp/src/bin/rosc.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 examples/rp/src/bin/rosc.rs diff --git a/examples/rp/src/bin/rosc.rs b/examples/rp/src/bin/rosc.rs new file mode 100644 index 00000000..f841043b --- /dev/null +++ b/examples/rp/src/bin/rosc.rs @@ -0,0 +1,32 @@ +//! This example test the RP Pico on board LED. +//! +//! It does not work with the RP Pico W board. See wifi_blinky.rs. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_rp::{clocks, gpio}; +use embassy_time::Timer; +use gpio::{Level, Output}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = embassy_rp::config::Config::default(); + config.clocks = clocks::ClockConfig::rosc(); + let p = embassy_rp::init(config); + let mut led = Output::new(p.PIN_25, Level::Low); + + loop { + info!("led on!"); + led.set_high(); + Timer::after_secs(1).await; + + info!("led off!"); + led.set_low(); + Timer::after_secs(1).await; + } +} From e7aeb9b29feaf2ca4bf3ac2cac47583cd9468e88 Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Mon, 16 Oct 2023 19:23:01 -0500 Subject: [PATCH 026/188] stm32f1: Keep flash prefetch enabled --- embassy-stm32/src/rcc/f1.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs index b2ae56db..367c8832 100644 --- a/embassy-stm32/src/rcc/f1.rs +++ b/embassy-stm32/src/rcc/f1.rs @@ -102,7 +102,6 @@ pub(crate) unsafe fn init(config: Config) { assert!(pclk2 <= 72_000_000); - // Only needed for stm32f103? FLASH.acr().write(|w| { w.set_latency(if real_sysclk <= 24_000_000 { Latency::WS0 @@ -111,6 +110,8 @@ pub(crate) unsafe fn init(config: Config) { } else { Latency::WS2 }); + // the prefetch buffer is enabled by default, let's keep it enabled + w.set_prftbe(true); }); // the USB clock is only valid if an external crystal is used, the PLL is enabled, and the From a3574e519ad191c3c4c49fe9779a0a71d61cae3b Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 16 Oct 2023 20:04:10 -0500 Subject: [PATCH 027/188] stm32: update metapac --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/build.rs | 18 ++++++------------ embassy-stm32/src/rcc/c0.rs | 2 ++ embassy-stm32/src/rcc/l0l1.rs | 4 ++-- embassy-stm32/src/rcc/l4l5.rs | 25 +++++++++++++++++++++++++ embassy-stm32/src/rcc/mod.rs | 16 ++++++++++++---- examples/stm32l4/src/bin/adc.rs | 2 +- examples/stm32l4/src/bin/mco.rs | 2 +- examples/stm32l4/src/bin/rng.rs | 2 +- examples/stm32l4/src/bin/usb_serial.rs | 2 +- tests/stm32/src/common.rs | 2 +- 11 files changed, 54 insertions(+), 25 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 1342b2ea..861753bd 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-9330e31117668350a62572fdcd2598ec17d08042" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c20cbde88fdfaef4645361d09df0cb63a4dc6462" } 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-9330e31117668350a62572fdcd2598ec17d08042", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c20cbde88fdfaef4645361d09df0cb63a4dc6462", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index d118b851..f8908756 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -466,15 +466,9 @@ fn main() { let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" }; let pname = format_ident!("{}", p.name); - let clk = format_ident!( - "{}", - rcc.clock - .to_ascii_lowercase() - .replace("ahb", "hclk") - .replace("apb", "pclk") - ); - let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); - let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); + let clk = format_ident!("{}", rcc.clock); + let en_reg = format_ident!("{}", en.register); + let set_en_field = format_ident!("set_{}", en.field); let (before_enable, before_disable) = if refcounted_peripherals.contains(ptype) { let refcount_static = @@ -500,11 +494,11 @@ fn main() { (TokenStream::new(), TokenStream::new()) }; + let mux_supported = HashSet::from(["c0", "h5", "h50", "h7", "h7ab", "h7rm0433", "g4", "l4"]) + .contains(rcc_registers.version); let mux_for = |mux: Option<&'static PeripheralRccRegister>| { - let checked_rccs = HashSet::from(["h5", "h50", "h7", "h7ab", "h7rm0433", "g4"]); - // restrict mux implementation to supported versions - if !checked_rccs.contains(rcc_registers.version) { + if !mux_supported { return None; } diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index e357f067..68f029ca 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -134,6 +134,8 @@ pub(crate) unsafe fn init(config: Config) { }; set_freqs(Clocks { + hsi: None, + lse: None, sys: sys_clk, hclk1: ahb_freq, pclk1: apb_freq, diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index 308b75ae..333e9eea 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -31,7 +31,7 @@ pub enum PLLSource { impl From for Pllsrc { fn from(val: PLLSource) -> Pllsrc { match val { - PLLSource::HSI16 => Pllsrc::HSI16, + PLLSource::HSI16 => Pllsrc::HSI, PLLSource::HSE(_) => Pllsrc::HSE, } } @@ -88,7 +88,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().write(|w| w.set_hsi16on(true)); while !RCC.cr().read().hsi16rdy() {} - (HSI_FREQ, Sw::HSI16) + (HSI_FREQ, Sw::HSI) } ClockSrc::HSE(freq) => { // Enable HSE diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 90c8923c..d99bc45c 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -187,7 +187,10 @@ pub(crate) unsafe fn init(config: Config) { let sys_clk = match config.mux { ClockSrc::HSE => hse.unwrap(), + #[cfg(rcc_l5)] ClockSrc::HSI16 => hsi16.unwrap(), + #[cfg(not(rcc_l5))] + ClockSrc::HSI => hsi16.unwrap(), ClockSrc::MSI => msi.unwrap(), ClockSrc::PLL => pll._r.unwrap(), }; @@ -200,7 +203,10 @@ pub(crate) unsafe fn init(config: Config) { Clk48Src::HSI48 => hsi48, Clk48Src::MSI => msi, Clk48Src::PLLSAI1_Q => pllsai1._q, + #[cfg(rcc_l5)] Clk48Src::PLL_Q => pll._q, + #[cfg(not(rcc_l5))] + Clk48Src::PLL1_Q => pll._q, }; #[cfg(rcc_l4plus)] @@ -266,6 +272,22 @@ pub(crate) unsafe fn init(config: Config) { pclk2: apb2_freq, pclk1_tim: apb1_tim_freq, pclk2_tim: apb2_tim_freq, + #[cfg(rcc_l4)] + hsi: None, + #[cfg(rcc_l4)] + lse: None, + #[cfg(rcc_l4)] + pllsai1_p: None, + #[cfg(rcc_l4)] + pllsai2_p: None, + #[cfg(rcc_l4)] + pll1_p: None, + #[cfg(rcc_l4)] + pll1_q: None, + #[cfg(rcc_l4)] + sai1_extclk: None, + #[cfg(rcc_l4)] + sai2_extclk: None, rtc, }); } @@ -341,7 +363,10 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let pll_src = match pll.source { PLLSource::NONE => panic!("must not select PLL source as NONE"), PLLSource::HSE => input.hse, + #[cfg(rcc_l5)] PLLSource::HSI16 => input.hsi16, + #[cfg(not(rcc_l5))] + PLLSource::HSI => input.hsi16, PLLSource::MSI => input.msi, }; diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 8df6deaa..d587a198 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -110,14 +110,18 @@ pub struct Clocks { #[cfg(all(rcc_f4, not(stm32f410)))] pub plli2s1_r: Option, + #[cfg(rcc_l4)] + pub pllsai1_p: Option, #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pub pllsai1_q: Option, #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pub pllsai1_r: Option, + #[cfg(rcc_l4)] + pub pllsai2_p: Option, - #[cfg(stm32g4)] + #[cfg(any(stm32g4, rcc_l4))] pub pll1_p: Option, - #[cfg(any(stm32h5, stm32h7, rcc_f2, rcc_f4, rcc_f410, rcc_f7))] + #[cfg(any(stm32h5, stm32h7, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_l4))] pub pll1_q: Option, #[cfg(any(stm32h5, stm32h7))] pub pll2_p: Option, @@ -154,7 +158,7 @@ pub struct Clocks { pub rtc: Option, - #[cfg(any(stm32h5, stm32h7))] + #[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))] pub hsi: Option, #[cfg(stm32h5)] pub hsi48: Option, @@ -163,7 +167,7 @@ pub struct Clocks { #[cfg(any(stm32h5, stm32h7))] pub csi: Option, - #[cfg(any(stm32h5, stm32h7))] + #[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))] pub lse: Option, #[cfg(any(stm32h5, stm32h7))] pub hse: Option, @@ -175,6 +179,10 @@ pub struct Clocks { #[cfg(stm32h7)] pub rcc_pclk_d3: Option, + #[cfg(rcc_l4)] + pub sai1_extclk: Option, + #[cfg(rcc_l4)] + pub sai2_extclk: Option, } #[cfg(feature = "low-power")] diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs index 3d0c623f..a0ec5c33 100644 --- a/examples/stm32l4/src/bin/adc.rs +++ b/examples/stm32l4/src/bin/adc.rs @@ -13,7 +13,7 @@ fn main() -> ! { info!("Hello World!"); pac::RCC.ccipr().modify(|w| { - w.set_adcsel(pac::rcc::vals::Adcsel::SYSCLK); + w.set_adcsel(pac::rcc::vals::Adcsel::SYS); }); pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); diff --git a/examples/stm32l4/src/bin/mco.rs b/examples/stm32l4/src/bin/mco.rs index 2833bb63..50487988 100644 --- a/examples/stm32l4/src/bin/mco.rs +++ b/examples/stm32l4/src/bin/mco.rs @@ -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, McoSource::HSI16, McoPrescaler::DIV1); + let _mco = Mco::new(p.MCO, p.PA8, McoSource::HSI, McoPrescaler::DIV1); let mut led = Output::new(p.PB14, Level::High, Speed::Low); diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index d184bcf7..49ae15e6 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs @@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL; config.rcc.hsi16 = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI16, + source: PLLSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL18, divp: None, diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 3785c689..34361d11 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -27,7 +27,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL; config.rcc.hsi16 = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI16, + source: PLLSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 6dc1b300..a802cdfc 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -290,7 +290,7 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL; config.rcc.hsi16 = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI16, + source: PLLSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL18, divp: None, From 846f2fc6e4d30a12f4da676c5d12147d1910add1 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 17 Oct 2023 15:49:20 +0200 Subject: [PATCH 028/188] stm32/tests: add stm32wl hil. --- ci.sh | 1 + tests/stm32/Cargo.toml | 1 + tests/stm32/build.rs | 4 +++- tests/stm32/src/common.rs | 17 +++++++++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index c246e6a9..ece76349 100755 --- a/ci.sh +++ b/ci.sh @@ -204,6 +204,7 @@ cargo batch \ --- 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/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55jc --out-dir out/tests/stm32wl55jc \ --- 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/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 77991ead..b1b2f55c 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -24,6 +24,7 @@ stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth", "rng"] stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] +stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] eth = [] rng = [] diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs index 9aabf854..c5d0e40d 100644 --- a/tests/stm32/build.rs +++ b/tests/stm32/build.rs @@ -8,12 +8,14 @@ fn main() -> Result<(), Box> { println!("cargo:rustc-link-search={}", out.display()); println!("cargo:rustc-link-arg-bins=--nmagic"); - // too little RAM to run from RAM. if cfg!(any( + // too little RAM to run from RAM. feature = "stm32f103c8", feature = "stm32c031c6", feature = "stm32wb55rg", feature = "stm32l073rz", + // wrong ram size in stm32-data + feature = "stm32wl55jc", )) { println!("cargo:rustc-link-arg-bins=-Tlink.x"); println!("cargo:rerun-if-changed=link.x"); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index a802cdfc..52edae3a 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -42,6 +42,8 @@ teleprobe_meta::target!(b"nucleo-stm32f207zg"); teleprobe_meta::target!(b"nucleo-stm32f303ze"); #[cfg(feature = "stm32l496zg")] teleprobe_meta::target!(b"nucleo-stm32l496zg"); +#[cfg(feature = "stm32wl55jc")] +teleprobe_meta::target!(b"nucleo-stm32wl55jc"); macro_rules! define_peris { ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { @@ -181,6 +183,12 @@ define_peris!( 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;}, ); +#[cfg(feature = "stm32wl55jc")] +define_peris!( + UART = USART1, UART_TX = PB6, UART_RX = PB7, 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)] @@ -299,6 +307,15 @@ pub fn config() -> Config { }); } + #[cfg(feature = "stm32wl55jc")] + { + use embassy_stm32::rcc::*; + config.rcc.mux = ClockSrc::MSI(MSIRange::RANGE32M); + embassy_stm32::pac::RCC.ccipr().modify(|w| { + w.set_rngsel(0b11); // msi + }); + } + #[cfg(any(feature = "stm32l552ze"))] { use embassy_stm32::rcc::*; From b47864046381cccdef186321fc0d46a1dd2a45be Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 17 Oct 2023 15:51:46 +0200 Subject: [PATCH 029/188] fix clocks in stm32wl rng example. --- examples/stm32wl/src/bin/random.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 7c7e8a4e..70676c70 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -4,6 +4,7 @@ use defmt::*; use embassy_executor::Spawner; +use embassy_stm32::rcc::{ClockSrc, MSIRange}; use embassy_stm32::rng::{self, Rng}; use embassy_stm32::{bind_interrupts, pac, peripherals}; use {defmt_rtt as _, panic_probe as _}; @@ -15,12 +16,10 @@ 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::HSE; - + config.rcc.mux = ClockSrc::MSI(MSIRange::RANGE32M); let p = embassy_stm32::init(config); - pac::RCC.ccipr().modify(|w| { - w.set_rngsel(0b01); - }); + + pac::RCC.ccipr().modify(|w| w.set_rngsel(0b11)); // msi info!("Hello World!"); From 3f262a26036c84e41e8c0144f2ffae3e64614bd2 Mon Sep 17 00:00:00 2001 From: Riley Williams Date: Tue, 17 Oct 2023 19:05:35 -0400 Subject: [PATCH 030/188] Add docs to RP2040 PWM --- embassy-rp/src/pwm.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index c297d69a..ff19bcf4 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -10,16 +10,40 @@ use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Pin as GpioPin}; use crate::{pac, peripherals, RegExt}; +/// The configuration of a PWM slice. +///Note the period in clock cycles of a slice can be computed as: +/// (top + 1) * (phase_correct ? 1 : 2) * divider #[non_exhaustive] #[derive(Clone)] pub struct Config { + /// Inverts the PWM output signal on channel A. pub invert_a: bool, + /// Inverts the PWM output signal on channel B. pub invert_b: bool, + /// Enables phase-correct mode for PWM operation. + /// In phase-correct mode, the PWM signal is generated in such a way that + /// the pulse is always centered regardless of the duty cycle. + /// The output frequency is halved when phase-correct mode is enabled. pub phase_correct: bool, + /// Enables the PWM slice, allowing it to generate an output. + /// When disabled, the PWM slice will not produce any output. pub enable: bool, + /// A fractional clock divider, represented as a fixed-point number with + /// 8 integer bits and 4 fractional bits. It allows precise control over + /// the PWM output frequency by gating the PWM counter increment. + /// A higher value will result in a slower output frequency. pub divider: fixed::FixedU16, + /// The output on channel A goes high when `compare_a` is higher than the + /// counter. A compare of 0 will produce an always low output, while a + /// compare of `top` + 1 will produce an always high output. pub compare_a: u16, + /// The output on channel B goes high when `compare_b` is higher than the + /// counter. A compare of 0 will produce an always low output, while a + /// compare of `top` + 1 will produce an always high output. pub compare_b: u16, + /// The point at which the counter wraps, representing the maximum possible + /// period. The counter will either wrap to 0 or reverse depending on the + /// setting of `phase_correct`. pub top: u16, } @@ -173,6 +197,9 @@ impl<'d, T: Channel> Pwm<'d, T> { }); } + /// Advances a slice’s output phase by one count while it is running + /// by inserting or deleting pulses from the clock enable. The counter + /// will not count faster than once per cycle. #[inline] pub fn phase_advance(&mut self) { let p = self.inner.regs(); @@ -180,6 +207,9 @@ impl<'d, T: Channel> Pwm<'d, T> { while p.csr().read().ph_adv() {} } + /// Retards a slice’s output phase by one count while it is running + /// by deleting pulses from the clock enable. The counter will not + /// count backward when clock enable is permenantly low #[inline] pub fn phase_retard(&mut self) { let p = self.inner.regs(); From cb211f88d3e225a2200a8a08d2265f48b7b472db Mon Sep 17 00:00:00 2001 From: Riley Williams Date: Tue, 17 Oct 2023 19:17:29 -0400 Subject: [PATCH 031/188] Grammar and formatting --- embassy-rp/src/pwm.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index ff19bcf4..15655d24 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -11,8 +11,8 @@ use crate::gpio::{AnyPin, Pin as GpioPin}; use crate::{pac, peripherals, RegExt}; /// The configuration of a PWM slice. -///Note the period in clock cycles of a slice can be computed as: -/// (top + 1) * (phase_correct ? 1 : 2) * divider +/// Note the period in clock cycles of a slice can be computed as: +/// `(top + 1) * (phase_correct ? 1 : 2) * divider` #[non_exhaustive] #[derive(Clone)] pub struct Config { @@ -26,7 +26,6 @@ pub struct Config { /// The output frequency is halved when phase-correct mode is enabled. pub phase_correct: bool, /// Enables the PWM slice, allowing it to generate an output. - /// When disabled, the PWM slice will not produce any output. pub enable: bool, /// A fractional clock divider, represented as a fixed-point number with /// 8 integer bits and 4 fractional bits. It allows precise control over @@ -35,11 +34,11 @@ pub struct Config { pub divider: fixed::FixedU16, /// The output on channel A goes high when `compare_a` is higher than the /// counter. A compare of 0 will produce an always low output, while a - /// compare of `top` + 1 will produce an always high output. + /// compare of `top + 1` will produce an always high output. pub compare_a: u16, /// The output on channel B goes high when `compare_b` is higher than the /// counter. A compare of 0 will produce an always low output, while a - /// compare of `top` + 1 will produce an always high output. + /// compare of `top + 1` will produce an always high output. pub compare_b: u16, /// The point at which the counter wraps, representing the maximum possible /// period. The counter will either wrap to 0 or reverse depending on the @@ -198,7 +197,7 @@ impl<'d, T: Channel> Pwm<'d, T> { } /// Advances a slice’s output phase by one count while it is running - /// by inserting or deleting pulses from the clock enable. The counter + /// by inserting a pulse into the clock enable. The counter /// will not count faster than once per cycle. #[inline] pub fn phase_advance(&mut self) { @@ -208,8 +207,8 @@ impl<'d, T: Channel> Pwm<'d, T> { } /// Retards a slice’s output phase by one count while it is running - /// by deleting pulses from the clock enable. The counter will not - /// count backward when clock enable is permenantly low + /// by deleting a pulse from the clock enable. The counter will not + /// count backward when clock enable is permenantly low. #[inline] pub fn phase_retard(&mut self) { let p = self.inner.regs(); From 6906cc9c2532fd690f4f43a0d97ea58f887e673b Mon Sep 17 00:00:00 2001 From: Riley Williams Date: Tue, 17 Oct 2023 19:30:53 -0400 Subject: [PATCH 032/188] remove trailing spaces --- embassy-rp/src/pwm.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 15655d24..516b8254 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -33,15 +33,15 @@ pub struct Config { /// A higher value will result in a slower output frequency. pub divider: fixed::FixedU16, /// The output on channel A goes high when `compare_a` is higher than the - /// counter. A compare of 0 will produce an always low output, while a + /// counter. A compare of 0 will produce an always low output, while a /// compare of `top + 1` will produce an always high output. pub compare_a: u16, /// The output on channel B goes high when `compare_b` is higher than the - /// counter. A compare of 0 will produce an always low output, while a + /// counter. A compare of 0 will produce an always low output, while a /// compare of `top + 1` will produce an always high output. pub compare_b: u16, /// The point at which the counter wraps, representing the maximum possible - /// period. The counter will either wrap to 0 or reverse depending on the + /// period. The counter will either wrap to 0 or reverse depending on the /// setting of `phase_correct`. pub top: u16, } @@ -196,8 +196,8 @@ impl<'d, T: Channel> Pwm<'d, T> { }); } - /// Advances a slice’s output phase by one count while it is running - /// by inserting a pulse into the clock enable. The counter + /// Advances a slice’s output phase by one count while it is running + /// by inserting a pulse into the clock enable. The counter /// will not count faster than once per cycle. #[inline] pub fn phase_advance(&mut self) { @@ -206,7 +206,7 @@ impl<'d, T: Channel> Pwm<'d, T> { while p.csr().read().ph_adv() {} } - /// Retards a slice’s output phase by one count while it is running + /// Retards a slice’s output phase by one count while it is running /// by deleting a pulse from the clock enable. The counter will not /// count backward when clock enable is permenantly low. #[inline] From bbd12c9372049e3d586b1738642c768849d42471 Mon Sep 17 00:00:00 2001 From: xoviat Date: Tue, 17 Oct 2023 20:31:44 -0500 Subject: [PATCH 033/188] stm32: update metapac --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/src/rcc/f0.rs | 4 ++-- embassy-stm32/src/rcc/f1.rs | 9 ++++++++- embassy-stm32/src/rcc/f2.rs | 2 +- embassy-stm32/src/rcc/f3.rs | 4 ++-- embassy-stm32/src/rcc/f4.rs | 2 +- embassy-stm32/src/rcc/f7.rs | 2 +- embassy-stm32/src/rcc/l0l1.rs | 2 +- embassy-stm32/src/rcc/l4l5.rs | 14 ++++---------- examples/stm32l4/src/bin/rng.rs | 2 +- examples/stm32l4/src/bin/rtc.rs | 2 +- .../stm32l4/src/bin/spe_adin1110_http_server.rs | 2 +- examples/stm32l4/src/bin/usb_serial.rs | 2 +- examples/stm32l5/src/bin/rng.rs | 4 ++-- examples/stm32l5/src/bin/usb_ethernet.rs | 4 ++-- examples/stm32l5/src/bin/usb_hid_mouse.rs | 4 ++-- examples/stm32l5/src/bin/usb_serial.rs | 4 ++-- tests/stm32/src/common.rs | 13 ++++++++++--- 18 files changed, 44 insertions(+), 36 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 861753bd..ab7b9221 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-c20cbde88fdfaef4645361d09df0cb63a4dc6462" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6f7449303bf8af60a63704d35df9af46006c6148" } 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-c20cbde88fdfaef4645361d09df0cb63a4dc6462", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6f7449303bf8af60a63704d35df9af46006c6148", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/f0.rs b/embassy-stm32/src/rcc/f0.rs index f7d605fd..feaa2f4c 100644 --- a/embassy-stm32/src/rcc/f0.rs +++ b/embassy-stm32/src/rcc/f0.rs @@ -127,7 +127,7 @@ pub(crate) unsafe fn init(config: Config) { } if config.usb_pll { - RCC.cfgr3().modify(|w| w.set_usbsw(Usbsw::PLLCLK)); + RCC.cfgr3().modify(|w| w.set_usbsw(Usbsw::PLL1_P)); } // TODO: Option to use CRS (Clock Recovery) @@ -140,7 +140,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_ppre(Ppre::from_bits(ppre_bits)); w.set_hpre(Hpre::from_bits(hpre_bits)); - w.set_sw(Sw::PLL) + w.set_sw(Sw::PLL1_P) }); } else { RCC.cfgr().modify(|w| { diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs index 367c8832..8d315f7b 100644 --- a/embassy-stm32/src/rcc/f1.rs +++ b/embassy-stm32/src/rcc/f1.rs @@ -169,7 +169,14 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(not(rcc_f100))] w.set_usbpre(Usbpre::from_bits(usbpre as u8)); w.set_sw(if pllmul_bits.is_some() { - Sw::PLL + #[cfg(not(rcc_f1cl))] + { + Sw::PLL1_P + } + #[cfg(rcc_f1cl)] + { + Sw::PLL + } } else if config.hse.is_some() { Sw::HSE } else { diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 06ea7e4f..9a66e75a 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -256,7 +256,7 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::PLL => { RCC.cr().modify(|w| w.set_pllon(true)); while !RCC.cr().read().pllrdy() {} - (pll_clocks.main_freq, Sw::PLL) + (pll_clocks.main_freq, Sw::PLL1_P) } }; // RM0033 Figure 9. Clock tree suggests max SYSCLK/HCLK is 168 MHz, but datasheet specifies PLL diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 3a314009..9dcd50df 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -214,7 +214,7 @@ pub(crate) unsafe fn init(config: Config) { // CFGR has been written before (PLL, PLL48, clock divider) don't overwrite these settings RCC.cfgr().modify(|w| { w.set_sw(match (pll_config, config.hse) { - (Some(_), _) => Sw::PLL, + (Some(_), _) => Sw::PLL1_P, (None, Some(_)) => Sw::HSE, (None, None) => Sw::HSI, }) @@ -271,7 +271,7 @@ pub(crate) unsafe fn init(config: Config) { pll_config.unwrap(); assert!((pclk2 == sysclk) || (pclk2 * 2u32 == sysclk)); - RCC.cfgr3().modify(|w| w.set_hrtim1sw(Timsw::PLL)); + RCC.cfgr3().modify(|w| w.set_hrtim1sw(Timsw::PLL1_P)); Some(sysclk * 2u32) } diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index b0585153..eb51dc89 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs @@ -328,7 +328,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_sw(if sysclk_on_pll { - Sw::PLL + Sw::PLL1_P } else if config.hse.is_some() { Sw::HSE } else { diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs index 5ed74fe9..7c6c150d 100644 --- a/embassy-stm32/src/rcc/f7.rs +++ b/embassy-stm32/src/rcc/f7.rs @@ -247,7 +247,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_sw(if sysclk_on_pll { - Sw::PLL + Sw::PLL1_P } else if config.hse.is_some() { Sw::HSE } else { diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index 333e9eea..f10c5962 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -131,7 +131,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_pllon(true)); while !RCC.cr().read().pllrdy() {} - (freq, Sw::PLL) + (freq, Sw::PLL1_P) } }; diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index d99bc45c..a10169d6 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -187,12 +187,12 @@ pub(crate) unsafe fn init(config: Config) { let sys_clk = match config.mux { ClockSrc::HSE => hse.unwrap(), - #[cfg(rcc_l5)] - ClockSrc::HSI16 => hsi16.unwrap(), - #[cfg(not(rcc_l5))] ClockSrc::HSI => hsi16.unwrap(), ClockSrc::MSI => msi.unwrap(), - ClockSrc::PLL => pll._r.unwrap(), + #[cfg(rcc_l4)] + ClockSrc::PLL1_P => pll._r.unwrap(), + #[cfg(not(rcc_l4))] + ClockSrc::PLL1_R => pll._r.unwrap(), }; #[cfg(stm32l4)] @@ -203,9 +203,6 @@ pub(crate) unsafe fn init(config: Config) { Clk48Src::HSI48 => hsi48, Clk48Src::MSI => msi, Clk48Src::PLLSAI1_Q => pllsai1._q, - #[cfg(rcc_l5)] - Clk48Src::PLL_Q => pll._q, - #[cfg(not(rcc_l5))] Clk48Src::PLL1_Q => pll._q, }; @@ -363,9 +360,6 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let pll_src = match pll.source { PLLSource::NONE => panic!("must not select PLL source as NONE"), PLLSource::HSE => input.hse, - #[cfg(rcc_l5)] - PLLSource::HSI16 => input.hsi16, - #[cfg(not(rcc_l5))] PLLSource::HSI => input.hsi16, PLLSource::MSI => input.msi, }; diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index 49ae15e6..d8a4e825 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs @@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi16 = true; config.rcc.pll = Some(Pll { source: PLLSource::HSI, diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index a1b41f84..fec0a349 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -15,7 +15,7 @@ use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hse = Some(Hertz::mhz(8)); config.rcc.pll = Some(Pll { source: PLLSource::HSE, diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 278d6543..3c9d2cfc 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -77,7 +77,7 @@ async fn main(spawner: Spawner) { // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) // 80MHz highest frequency for flash 0 wait. - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hse = Some(Hertz::mhz(8)); config.rcc.pll = Some(Pll { source: PLLSource::HSE, diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 34361d11..28247654 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.hsi48 = true; - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi16 = true; config.rcc.pll = Some(Pll { source: PLLSource::HSI, diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index e6233dbe..b57f438f 100644 --- a/examples/stm32l5/src/bin/rng.rs +++ b/examples/stm32l5/src/bin/rng.rs @@ -17,10 +17,10 @@ bind_interrupts!(struct Irqs { async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.hsi16 = true; - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 64Mhz clock (16 / 1 * 8 / 2) - source: PLLSource::HSI16, + source: PLLSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL8, divp: None, diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index baa86640..bbe44642 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -46,10 +46,10 @@ async fn net_task(stack: &'static Stack>) -> ! { async fn main(spawner: Spawner) { let mut config = Config::default(); config.rcc.hsi16 = true; - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI16, + source: PLLSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index 1ce7e3e4..44e29ee9 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -23,10 +23,10 @@ bind_interrupts!(struct Irqs { async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.hsi16 = true; - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI16, + source: PLLSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 03d277a2..612b891a 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -21,10 +21,10 @@ bind_interrupts!(struct Irqs { async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.hsi16 = true; - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI16, + source: PLLSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 52edae3a..9f1307ce 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -295,7 +295,14 @@ pub fn config() -> Config { #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::PLL; + #[cfg(feature = "stm32l4r5zi")] + { + config.rcc.mux = ClockSrc::PLL1_R; + } + #[cfg(not(feature = "stm32l4r5zi"))] + { + config.rcc.mux = ClockSrc::PLL1_P; + } config.rcc.hsi16 = true; config.rcc.pll = Some(Pll { source: PLLSource::HSI, @@ -320,10 +327,10 @@ pub fn config() -> Config { { use embassy_stm32::rcc::*; config.rcc.hsi16 = true; - config.rcc.mux = ClockSrc::PLL; + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 110Mhz clock (16 / 4 * 55 / 2) - source: PLLSource::HSI16, + source: PLLSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL55, divp: None, From 10f08445e499f733c2d32bbcb72708809a7d8dc9 Mon Sep 17 00:00:00 2001 From: Ted Feng Date: Wed, 18 Oct 2023 14:53:49 +1300 Subject: [PATCH 034/188] Update basic_application.adoc typo: change "embassy::main" to "embassy_executor::main" --- docs/modules/ROOT/pages/basic_application.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/basic_application.adoc b/docs/modules/ROOT/pages/basic_application.adoc index 3f4f16e2..73774c71 100644 --- a/docs/modules/ROOT/pages/basic_application.adoc +++ b/docs/modules/ROOT/pages/basic_application.adoc @@ -48,7 +48,7 @@ The `Spawner` is the way the main application spawns other tasks. The `Periphera include::example$basic/src/main.rs[lines="22..-1"] ---- -What happens when the `blinker` task has been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy::main]` macro. The macro does the following: +What happens when the `blinker` task has been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy_executor::main]` macro. The macro does the following: . Creates an Embassy Executor . Initializes the microcontroller HAL to get the `Peripherals` From 7ce3b1938972eaaea0304a4b312706d84b72ac25 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 18 Oct 2023 03:15:26 +0200 Subject: [PATCH 035/188] stm32/rcc: remove unused enum. --- embassy-stm32/src/rcc/h.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 86136d43..5dbcfea9 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -58,15 +58,6 @@ 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 From 361fde35cf37e5c8171ab470449e85ad44da4e52 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 18 Oct 2023 03:16:15 +0200 Subject: [PATCH 036/188] stm32/rcc: wait for mux switch. --- embassy-stm32/src/rcc/l4l5.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index a10169d6..683b47c0 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -241,6 +241,7 @@ pub(crate) unsafe fn init(config: Config) { w.set_ppre1(config.apb1_pre); w.set_ppre2(config.apb2_pre); }); + while RCC.cfgr().read().sws() != config.mux {} let ahb_freq = sys_clk / config.ahb_pre; From 67010d123c874383f48ccd5c1b2287907677e460 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 18 Oct 2023 03:16:36 +0200 Subject: [PATCH 037/188] stm32/rcc: refactor f7. --- embassy-stm32/src/rcc/f7.rs | 553 +++++++++++++------------ examples/stm32f7/src/bin/eth.rs | 22 +- examples/stm32f7/src/bin/hello.rs | 4 +- examples/stm32f7/src/bin/sdmmc.rs | 23 +- examples/stm32f7/src/bin/usb_serial.rs | 25 +- tests/stm32/src/common.rs | 18 +- 6 files changed, 358 insertions(+), 287 deletions(-) diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs index 7c6c150d..a984e4f4 100644 --- a/embassy-stm32/src/rcc/f7.rs +++ b/embassy-stm32/src/rcc/f7.rs @@ -1,5 +1,7 @@ -use crate::pac::pwr::vals::Vos; -use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw}; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp, Pllq, Pllr, Pllsrc as PllSource, + Ppre as APBPrescaler, Sw as Sysclk, +}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -7,299 +9,304 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// Clocks configuration -#[non_exhaustive] -#[derive(Default)] -pub struct Config { - pub hse: Option, - pub bypass_hse: bool, - pub hclk: Option, - pub sys_ck: Option, - pub pclk1: Option, - pub pclk2: Option, +#[derive(Clone, Copy, Eq, PartialEq)] +pub enum HseMode { + /// crystal/ceramic oscillator (HSEBYP=0) + Oscillator, + /// external analog clock (low swing) (HSEBYP=1) + Bypass, +} + +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct Hse { + /// HSE frequency. + pub freq: Hertz, + /// HSE mode. + pub mode: HseMode, +} + +#[derive(Clone, Copy)] +pub struct Pll { + /// PLL pre-divider (DIVM). + pub prediv: PllPreDiv, + + /// PLL multiplication factor. + pub mul: PllMul, + + /// PLL P division factor. If None, PLL P output is disabled. + 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, +} + +/// Configuration of the core clocks +#[non_exhaustive] +pub struct Config { + pub hsi: bool, + pub hse: Option, + pub sys: Sysclk, + + pub pll_src: PllSource, + + pub pll: Option, + pub plli2s: Option, + pub pllsai: Option, + + pub ahb_pre: AHBPrescaler, + pub apb1_pre: APBPrescaler, + pub apb2_pre: APBPrescaler, - pub pll48: bool, pub ls: super::LsConfig, } -fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option, pll48clk: bool) -> PllResults { - 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))); +impl Default for Config { + fn default() -> Self { + Self { + hsi: true, + hse: None, + sys: Sysclk::HSI, + pll_src: PllSource::HSI, + pll: None, + plli2s: None, + pllsai: None, - return PllResults { - use_pll: false, - pllsysclk: None, - pll48clk: None, - }; - } - // Input divisor from PLL source clock, must result to frequency in - // the range from 1 to 2 MHz - let pllm_min = (pllsrcclk + 1_999_999) / 2_000_000; - let pllm_max = pllsrcclk / 1_000_000; + ahb_pre: AHBPrescaler::DIV1, + apb1_pre: APBPrescaler::DIV1, + apb2_pre: APBPrescaler::DIV1, - // Sysclk output divisor must be one of 2, 4, 6 or 8 - let sysclk_div = core::cmp::min(8, (432_000_000 / sysclk) & !1); - - let target_freq = if pll48clk { 48_000_000 } else { sysclk * sysclk_div }; - - // Find the lowest pllm value that minimize the difference between - // target frequency and the real vco_out frequency. - let pllm = unwrap!((pllm_min..=pllm_max).min_by_key(|pllm| { - let vco_in = pllsrcclk / pllm; - let plln = target_freq / vco_in; - target_freq - vco_in * plln - })); - - let vco_in = pllsrcclk / pllm; - assert!((1_000_000..=2_000_000).contains(&vco_in)); - - // Main scaler, must result in >= 100MHz (>= 192MHz for F401) - // and <= 432MHz, min 50, max 432 - let plln = if pll48clk { - // try the different valid pllq according to the valid - // main scaller values, and take the best - let pllq = unwrap!((4..=9).min_by_key(|pllq| { - let plln = 48_000_000 * pllq / vco_in; - let pll48_diff = 48_000_000 - vco_in * plln / pllq; - let sysclk_diff = (sysclk as i32 - (vco_in * plln / sysclk_div) as i32).abs(); - (pll48_diff, sysclk_diff) - })); - 48_000_000 * pllq / vco_in - } else { - sysclk * sysclk_div / vco_in - }; - - let pllp = (sysclk_div / 2) - 1; - - let pllq = (vco_in * plln + 47_999_999) / 48_000_000; - let real_pll48clk = vco_in * plln / pllq; - - RCC.pllcfgr().modify(|w| { - 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::from_bits(pllq as u8)); - w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); - }); - - let real_pllsysclk = vco_in * plln / sysclk_div; - - PllResults { - use_pll: true, - pllsysclk: Some(real_pllsysclk), - pll48clk: if pll48clk { Some(real_pll48clk) } else { None }, + ls: Default::default(), + } } } -fn flash_setup(sysclk: u32) { +pub(crate) unsafe fn init(config: Config) { + // always enable overdrive for now. Make it configurable in the future. + PWR.cr1().modify(|w| w.set_oden(true)); + while !PWR.csr1().read().odrdy() {} + + PWR.cr1().modify(|w| w.set_odswen(true)); + while !PWR.csr1().read().odswrdy() {} + + // Configure HSI + let hsi = match config.hsi { + false => { + RCC.cr().modify(|w| w.set_hsion(false)); + None + } + true => { + RCC.cr().modify(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} + Some(HSI_FREQ) + } + }; + + // Configure HSE + let hse = match config.hse { + None => { + RCC.cr().modify(|w| w.set_hseon(false)); + None + } + Some(hse) => { + match hse.mode { + HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), + HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), + } + + RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); + RCC.cr().modify(|w| w.set_hseon(true)); + while !RCC.cr().read().hserdy() {} + Some(hse.freq) + } + }; + + // Configure PLLs. + let pll_input = PllInput { + hse, + hsi, + source: config.pll_src, + }; + let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); + let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); + let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); + + // Configure sysclk + let sys = match config.sys { + Sysclk::HSI => unwrap!(hsi), + Sysclk::HSE => unwrap!(hse), + Sysclk::PLL1_P => unwrap!(pll.p), + _ => unreachable!(), + }; + + let hclk = sys / config.ahb_pre; + let (pclk1, pclk1_tim) = calc_pclk(hclk, config.apb1_pre); + let (pclk2, pclk2_tim) = calc_pclk(hclk, config.apb2_pre); + + assert!(max::SYSCLK.contains(&sys)); + assert!(max::HCLK.contains(&hclk)); + assert!(max::PCLK1.contains(&pclk1)); + assert!(max::PCLK2.contains(&pclk2)); + + let rtc = config.ls.init(); + + flash_setup(hclk); + + RCC.cfgr().modify(|w| { + w.set_sw(config.sys); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); + }); + while RCC.cfgr().read().sws() != config.sys {} + + set_freqs(Clocks { + sys, + hclk1: hclk, + hclk2: hclk, + hclk3: hclk, + pclk1, + pclk2, + pclk1_tim, + pclk2_tim, + rtc, + pll1_q: pll.q, + }); +} + +struct PllInput { + source: PllSource, + hsi: Option, + hse: Option, +} + +#[derive(Default)] +#[allow(unused)] +struct PllOutput { + p: Option, + q: Option, + r: Option, +} + +#[derive(PartialEq, Eq, Clone, Copy)] +enum PllInstance { + Pll, + Plli2s, + Pllsai, +} + +fn pll_enable(instance: PllInstance, enabled: bool) { + match instance { + PllInstance::Pll => { + RCC.cr().modify(|w| w.set_pllon(enabled)); + while RCC.cr().read().pllrdy() != enabled {} + } + PllInstance::Plli2s => { + RCC.cr().modify(|w| w.set_plli2son(enabled)); + while RCC.cr().read().plli2srdy() != enabled {} + } + PllInstance::Pllsai => { + RCC.cr().modify(|w| w.set_pllsaion(enabled)); + while RCC.cr().read().pllsairdy() != enabled {} + } + } +} + +fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + pll_enable(instance, false); + + let Some(pll) = config else { return PllOutput::default() }; + + let pll_src = match input.source { + PllSource::HSE => input.hse, + PllSource::HSI => input.hsi, + }; + + let pll_src = pll_src.unwrap(); + + let in_freq = pll_src / pll.prediv; + assert!(max::PLL_IN.contains(&in_freq)); + let vco_freq = in_freq * pll.mul; + assert!(max::PLL_VCO.contains(&vco_freq)); + + let p = pll.divp.map(|div| vco_freq / div); + let q = pll.divq.map(|div| vco_freq / div); + let r = pll.divr.map(|div| vco_freq / div); + + macro_rules! write_fields { + ($w:ident) => { + $w.set_plln(pll.mul); + if let Some(divp) = pll.divp { + $w.set_pllp(divp); + } + if let Some(divq) = pll.divq { + $w.set_pllq(divq); + } + if let Some(divr) = pll.divr { + $w.set_pllr(divr); + } + }; + } + + match instance { + PllInstance::Pll => RCC.pllcfgr().write(|w| { + w.set_pllm(pll.prediv); + w.set_pllsrc(input.source); + write_fields!(w); + }), + PllInstance::Plli2s => RCC.plli2scfgr().write(|w| { + write_fields!(w); + }), + PllInstance::Pllsai => RCC.pllsaicfgr().write(|w| { + write_fields!(w); + }), + } + + // Enable PLL + pll_enable(instance, true); + + PllOutput { p, q, r } +} + +fn flash_setup(clk: Hertz) { use crate::pac::flash::vals::Latency; // Be conservative with voltage ranges const FLASH_LATENCY_STEP: u32 = 30_000_000; - critical_section::with(|_| { - FLASH - .acr() - .modify(|w| w.set_latency(Latency::from_bits(((sysclk - 1) / FLASH_LATENCY_STEP) as u8))); + let latency = (clk.0 - 1) / FLASH_LATENCY_STEP; + debug!("flash: latency={}", latency); + + let latency = Latency::from_bits(latency as u8); + FLASH.acr().write(|w| { + w.set_latency(latency); }); + while FLASH.acr().read().latency() != latency {} } -pub(crate) unsafe fn init(config: Config) { - if let Some(hse) = config.hse { - if config.bypass_hse { - assert!((max::HSE_BYPASS_MIN..=max::HSE_BYPASS_MAX).contains(&hse.0)); - } else { - assert!((max::HSE_OSC_MIN..=max::HSE_OSC_MAX).contains(&hse.0)); - } - } - - let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0); - let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); - let sysclk_on_pll = sysclk != pllsrcclk; - - assert!((max::SYSCLK_MIN..=max::SYSCLK_MAX).contains(&sysclk)); - - let plls = setup_pll( - pllsrcclk, - config.hse.is_some(), - if sysclk_on_pll { Some(sysclk) } else { None }, - config.pll48, - ); - - if config.pll48 { - let freq = unwrap!(plls.pll48clk); - - assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32); - } - - let sysclk = if sysclk_on_pll { unwrap!(plls.pllsysclk) } else { sysclk }; - - // AHB prescaler - let hclk = config.hclk.map(|h| h.0).unwrap_or(sysclk); - let (hpre_bits, hpre_div) = match (sysclk + hclk - 1) / hclk { - 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), - }; - - // Calculate real AHB clock - let hclk = sysclk / hpre_div; - - assert!(hclk <= max::HCLK_MAX); - - let pclk1 = config - .pclk1 - .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(max::PCLK1_MAX, hclk)); - - let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 { - 0 => unreachable!(), - 1 => (0b000, 1), - 2 => (0b100, 2), - 3..=5 => (0b101, 4), - 6..=11 => (0b110, 8), - _ => (0b111, 16), - }; - let timer_mul1 = if ppre1 == 1 { 1 } else { 2 }; - - // Calculate real APB1 clock - let pclk1 = hclk / ppre1; - assert!((max::PCLK1_MIN..=max::PCLK1_MAX).contains(&pclk1)); - - let pclk2 = config - .pclk2 - .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(max::PCLK2_MAX, hclk)); - let (ppre2_bits, ppre2) = match (hclk + pclk2 - 1) / pclk2 { - 0 => unreachable!(), - 1 => (0b000, 1), - 2 => (0b100, 2), - 3..=5 => (0b101, 4), - 6..=11 => (0b110, 8), - _ => (0b111, 16), - }; - let timer_mul2 = if ppre2 == 1 { 1 } else { 2 }; - - // Calculate real APB2 clock - let pclk2 = hclk / ppre2; - assert!((max::PCLK2_MIN..=max::PCLK2_MAX).contains(&pclk2)); - - flash_setup(sysclk); - - if config.hse.is_some() { - RCC.cr().modify(|w| { - w.set_hsebyp(config.bypass_hse); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - } - - if plls.use_pll { - RCC.cr().modify(|w| w.set_pllon(false)); - - // setup VOSScale - let vos_scale = if sysclk <= 144_000_000 { - 3 - } else if sysclk <= 168_000_000 { - 2 - } else { - 1 - }; - PWR.cr1().modify(|w| { - w.set_vos(match vos_scale { - 3 => Vos::SCALE3, - 2 => Vos::SCALE2, - 1 => Vos::SCALE1, - _ => panic!("Invalid VOS Scale."), - }) - }); - - RCC.cr().modify(|w| w.set_pllon(true)); - - if hclk > max::HCLK_OVERDRIVE_FREQUENCY { - PWR.cr1().modify(|w| w.set_oden(true)); - while !PWR.csr1().read().odrdy() {} - - PWR.cr1().modify(|w| w.set_odswen(true)); - while !PWR.csr1().read().odswrdy() {} - } - - while !RCC.cr().read().pllrdy() {} - } - - RCC.cfgr().modify(|w| { - w.set_ppre2(Ppre::from_bits(ppre2_bits)); - w.set_ppre1(Ppre::from_bits(ppre1_bits)); - w.set_hpre(hpre_bits); - }); - - // Wait for the new prescalers to kick in - // "The clocks are divided with the new prescaler factor from 1 to 16 AHB cycles after write" - cortex_m::asm::delay(16); - - RCC.cfgr().modify(|w| { - w.set_sw(if sysclk_on_pll { - Sw::PLL1_P - } else if config.hse.is_some() { - Sw::HSE - } else { - Sw::HSI - }) - }); - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: Hertz(sysclk), - pclk1: Hertz(pclk1), - pclk2: Hertz(pclk2), - - pclk1_tim: Hertz(pclk1 * timer_mul1), - pclk2_tim: Hertz(pclk2 * timer_mul2), - - hclk1: Hertz(hclk), - hclk2: Hertz(hclk), - hclk3: Hertz(hclk), - - pll1_q: plls.pll48clk.map(Hertz), - - rtc, - }); -} - -struct PllResults { - use_pll: bool, - pllsysclk: Option, - pll48clk: Option, +fn calc_pclk(hclk: Hertz, ppre: D) -> (Hertz, Hertz) +where + Hertz: core::ops::Div, +{ + let pclk = hclk / ppre; + let pclk_tim = if hclk == pclk { pclk } else { pclk * 2u32 }; + (pclk, pclk_tim) } mod max { - pub(crate) const HSE_OSC_MIN: u32 = 4_000_000; - pub(crate) const HSE_OSC_MAX: u32 = 26_000_000; - pub(crate) const HSE_BYPASS_MIN: u32 = 1_000_000; - pub(crate) const HSE_BYPASS_MAX: u32 = 50_000_000; + use core::ops::RangeInclusive; - pub(crate) const HCLK_MAX: u32 = 216_000_000; - pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 180_000_000; + use crate::time::Hertz; - pub(crate) const SYSCLK_MIN: u32 = 12_500_000; - pub(crate) const SYSCLK_MAX: u32 = 216_000_000; + pub(crate) const HSE_OSC: RangeInclusive = Hertz(4_000_000)..=Hertz(26_000_000); + pub(crate) const HSE_BYP: RangeInclusive = Hertz(1_000_000)..=Hertz(50_000_000); - pub(crate) const PCLK1_MIN: u32 = SYSCLK_MIN; - pub(crate) const PCLK1_MAX: u32 = SYSCLK_MAX / 4; + pub(crate) const SYSCLK: RangeInclusive = Hertz(12_500_000)..=Hertz(216_000_000); + pub(crate) const HCLK: RangeInclusive = Hertz(12_500_000)..=Hertz(216_000_000); + pub(crate) const PCLK1: RangeInclusive = Hertz(12_500_000)..=Hertz(216_000_000 / 4); + pub(crate) const PCLK2: RangeInclusive = Hertz(12_500_000)..=Hertz(216_000_000 / 2); - pub(crate) const PCLK2_MIN: u32 = SYSCLK_MIN; - pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; - - // USB specification allows +-0.25% - pub(crate) const PLL_48_CLK: u32 = 48_000_000; - pub(crate) const PLL_48_TOLERANCE: u32 = 120_000; + pub(crate) const PLL_IN: RangeInclusive = Hertz(1_000_000)..=Hertz(2_100_000); + pub(crate) const PLL_VCO: RangeInclusive = Hertz(100_000_000)..=Hertz(432_000_000); } diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index d50473b9..7c6c419a 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -10,7 +10,7 @@ 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::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::Timer; use embedded_io_async::Write; @@ -33,7 +33,25 @@ async fn net_task(stack: &'static Stack) -> ! { #[embassy_executor::main] async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); - config.rcc.sys_ck = Some(mhz(200)); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32f7/src/bin/hello.rs b/examples/stm32f7/src/bin/hello.rs index 27ee83aa..a2a28711 100644 --- a/examples/stm32f7/src/bin/hello.rs +++ b/examples/stm32f7/src/bin/hello.rs @@ -4,15 +4,13 @@ use defmt::info; use embassy_executor::Spawner; -use embassy_stm32::time::Hertz; use embassy_stm32::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) -> ! { - let mut config = Config::default(); - config.rcc.sys_ck = Some(Hertz(84_000_000)); + let config = Config::default(); let _p = embassy_stm32::init(config); loop { diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs index 9d43892a..430aa781 100644 --- a/examples/stm32f7/src/bin/sdmmc.rs +++ b/examples/stm32f7/src/bin/sdmmc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::sdmmc::Sdmmc; -use embassy_stm32::time::mhz; +use embassy_stm32::time::{mhz, Hertz}; use embassy_stm32::{bind_interrupts, peripherals, sdmmc, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -16,8 +16,25 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.sys_ck = Some(mhz(200)); - config.rcc.pll48 = true; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: Some(Pllq::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs index a2c76178..2f832c23 100644 --- a/examples/stm32f7/src/bin/usb_serial.rs +++ b/examples/stm32f7/src/bin/usb_serial.rs @@ -4,7 +4,7 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::usb_otg::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; @@ -22,10 +22,25 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.hse = Some(mhz(8)); - config.rcc.pll48 = true; - config.rcc.sys_ck = Some(mhz(200)); - + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: Some(Pllq::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 9f1307ce..7bc74141 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -233,7 +233,23 @@ pub fn config() -> Config { #[cfg(feature = "stm32f767zi")] { - config.rcc.sys_ck = Some(Hertz(200_000_000)); + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz. + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; } #[cfg(feature = "stm32h563zi")] From f20f170b1fa97a86e9d9258ac5cea248203580fb Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 18 Oct 2023 04:31:53 +0200 Subject: [PATCH 038/188] stm32/rcc: refactor and unify f4 into f7. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/f4.rs | 400 ----------------------- embassy-stm32/src/rcc/{f7.rs => f4f7.rs} | 67 ++++ embassy-stm32/src/rcc/mod.rs | 3 +- examples/stm32f4/src/bin/eth.rs | 22 +- examples/stm32f4/src/bin/hello.rs | 4 +- examples/stm32f4/src/bin/sdmmc.rs | 23 +- examples/stm32f4/src/bin/usb_ethernet.rs | 24 +- examples/stm32f4/src/bin/usb_serial.rs | 24 +- tests/stm32/src/common.rs | 22 +- 10 files changed, 168 insertions(+), 425 deletions(-) delete mode 100644 embassy-stm32/src/rcc/f4.rs rename embassy-stm32/src/rcc/{f7.rs => f4f7.rs} (71%) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index ab7b9221..3b9220bc 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-6f7449303bf8af60a63704d35df9af46006c6148" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-5b04234fbe61ea875f1a904cd5f68795daaeb526" } 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-6f7449303bf8af60a63704d35df9af46006c6148", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-5b04234fbe61ea875f1a904cd5f68795daaeb526", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs deleted file mode 100644 index eb51dc89..00000000 --- a/embassy-stm32/src/rcc/f4.rs +++ /dev/null @@ -1,400 +0,0 @@ -use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllq, Pllr, Ppre, Sw}; -use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// Clocks configuration -#[non_exhaustive] -#[derive(Default)] -pub struct Config { - pub hse: Option, - pub bypass_hse: bool, - pub hclk: Option, - pub sys_ck: Option, - pub pclk1: Option, - pub pclk2: Option, - - #[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] - pub plli2s: Option, - - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - pub pllsai: Option, - - pub pll48: bool, - pub ls: super::LsConfig, -} - -#[cfg(stm32f410)] -fn setup_i2s_pll(_vco_in: u32, _plli2s: Option) -> Option { - None -} - -// Not currently implemented, but will be in the future -#[cfg(any(stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))] -fn setup_i2s_pll(_vco_in: u32, _plli2s: Option) -> Option { - None -} - -#[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 { - Some(target) => target, - None => return None, - }; - - // We loop through the possible divider values to find the best configuration. Looping - // through all possible "N" values would result in more iterations. - let (n, outdiv, output, _error) = (min_div..=max_div) - .filter_map(|outdiv| { - let target_vco_out = match target.checked_mul(outdiv) { - Some(x) => x, - None => return None, - }; - let n = (target_vco_out + (vco_in >> 1)) / vco_in; - let vco_out = vco_in * n; - if !(100_000_000..=432_000_000).contains(&vco_out) { - return None; - } - let output = vco_out / outdiv; - let error = (output as i32 - target as i32).unsigned_abs(); - Some((n, outdiv, output, error)) - }) - .min_by_key(|(_, _, _, error)| *error)?; - - Some((n, outdiv, output)) -} - -#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] -fn setup_i2s_pll(vco_in: u32, plli2s: Option) -> Option { - let (n, outdiv, output) = calculate_sai_i2s_pll_values(vco_in, 7, plli2s)?; - - RCC.plli2scfgr().modify(|w| { - w.set_plli2sn(n as u16); - w.set_plli2sr(outdiv as u8); - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - w.set_plli2sq(outdiv as u8); //set sai divider same as i2s - }); - - Some(output) -} - -#[cfg(not(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479)))] -fn setup_sai_pll(_vco_in: u32, _pllsai: Option) -> Option { - None -} - -#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] -fn setup_sai_pll(vco_in: u32, pllsai: Option) -> Option { - let (n, outdiv, output) = calculate_sai_i2s_pll_values(vco_in, 15, pllsai)?; - - RCC.pllsaicfgr().modify(|w| { - w.set_pllsain(n as u16); - w.set_pllsaiq(outdiv as u8); - }); - - Some(output) -} - -fn setup_pll( - pllsrcclk: u32, - use_hse: bool, - pllsysclk: Option, - plli2s: Option, - pllsai: 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))); - - return PllResults { - use_pll: false, - pllsysclk: None, - pll48clk: None, - plli2sclk: None, - pllsaiclk: None, - }; - } - // Input divisor from PLL source clock, must result to frequency in - // the range from 1 to 2 MHz - let pllm_min = (pllsrcclk + 1_999_999) / 2_000_000; - let pllm_max = pllsrcclk / 1_000_000; - - // Sysclk output divisor must be one of 2, 4, 6 or 8 - let sysclk_div = core::cmp::min(8, (432_000_000 / sysclk) & !1); - - let target_freq = if pll48clk { 48_000_000 } else { sysclk * sysclk_div }; - - // Find the lowest pllm value that minimize the difference between - // target frequency and the real vco_out frequency. - let pllm = unwrap!((pllm_min..=pllm_max).min_by_key(|pllm| { - let vco_in = pllsrcclk / pllm; - let plln = target_freq / vco_in; - target_freq - vco_in * plln - })); - - let vco_in = pllsrcclk / pllm; - assert!((1_000_000..=2_000_000).contains(&vco_in)); - - // Main scaler, must result in >= 100MHz (>= 192MHz for F401) - // and <= 432MHz, min 50, max 432 - let plln = if pll48clk { - // try the different valid pllq according to the valid - // main scaller values, and take the best - let pllq = unwrap!((4..=9).min_by_key(|pllq| { - let plln = 48_000_000 * pllq / vco_in; - let pll48_diff = 48_000_000 - vco_in * plln / pllq; - let sysclk_diff = (sysclk as i32 - (vco_in * plln / sysclk_div) as i32).abs(); - (pll48_diff, sysclk_diff) - })); - 48_000_000 * pllq / vco_in - } else { - sysclk * sysclk_div / vco_in - }; - - let pllp = (sysclk_div / 2) - 1; - - let pllq = (vco_in * plln + 47_999_999) / 48_000_000; - let real_pll48clk = vco_in * plln / pllq; - - RCC.pllcfgr().modify(|w| { - 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::from_bits(pllq as u8)); - w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); - w.set_pllr(Pllr::from_bits(0)); - }); - - let real_pllsysclk = vco_in * plln / sysclk_div; - - PllResults { - use_pll: true, - pllsysclk: Some(real_pllsysclk), - pll48clk: if pll48clk { Some(real_pll48clk) } else { None }, - plli2sclk: setup_i2s_pll(vco_in, plli2s), - pllsaiclk: setup_sai_pll(vco_in, pllsai), - } -} - -fn flash_setup(sysclk: u32) { - use crate::pac::flash::vals::Latency; - - // Be conservative with voltage ranges - const FLASH_LATENCY_STEP: u32 = 30_000_000; - - critical_section::with(|_| { - FLASH - .acr() - .modify(|w| w.set_latency(Latency::from_bits(((sysclk - 1) / FLASH_LATENCY_STEP) as u8))); - }); -} - -pub(crate) unsafe fn init(config: Config) { - let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0); - let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); - let sysclk_on_pll = sysclk != pllsrcclk; - - let plls = setup_pll( - pllsrcclk, - config.hse.is_some(), - if sysclk_on_pll { Some(sysclk) } else { None }, - #[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] - config.plli2s.map(|i2s| i2s.0), - #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))] - None, - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - config.pllsai.map(|sai| sai.0), - #[cfg(not(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479)))] - None, - config.pll48, - ); - - if config.pll48 { - let freq = unwrap!(plls.pll48clk); - - assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32); - } - - let sysclk = if sysclk_on_pll { unwrap!(plls.pllsysclk) } else { sysclk }; - - // AHB prescaler - let hclk = config.hclk.map(|h| h.0).unwrap_or(sysclk); - let (hpre_bits, hpre_div) = match (sysclk + hclk - 1) / hclk { - 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), - }; - - // Calculate real AHB clock - let hclk = sysclk / hpre_div; - - let pclk1 = config - .pclk1 - .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(max::PCLK1_MAX, hclk)); - - let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 { - 0 => unreachable!(), - 1 => (0b000, 1), - 2 => (0b100, 2), - 3..=5 => (0b101, 4), - 6..=11 => (0b110, 8), - _ => (0b111, 16), - }; - let timer_mul1 = if ppre1 == 1 { 1 } else { 2 }; - - // Calculate real APB1 clock - let pclk1 = hclk / ppre1; - assert!(pclk1 <= max::PCLK1_MAX); - - let pclk2 = config - .pclk2 - .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(max::PCLK2_MAX, hclk)); - let (ppre2_bits, ppre2) = match (hclk + pclk2 - 1) / pclk2 { - 0 => unreachable!(), - 1 => (0b000, 1), - 2 => (0b100, 2), - 3..=5 => (0b101, 4), - 6..=11 => (0b110, 8), - _ => (0b111, 16), - }; - let timer_mul2 = if ppre2 == 1 { 1 } else { 2 }; - - // Calculate real APB2 clock - let pclk2 = hclk / ppre2; - assert!(pclk2 <= max::PCLK2_MAX); - - flash_setup(sysclk); - - if config.hse.is_some() { - RCC.cr().modify(|w| { - w.set_hsebyp(config.bypass_hse); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - } - - if plls.use_pll { - RCC.cr().modify(|w| w.set_pllon(true)); - - if hclk > max::HCLK_OVERDRIVE_FREQUENCY { - PWR.cr1().modify(|w| w.set_oden(true)); - while !PWR.csr1().read().odrdy() {} - - PWR.cr1().modify(|w| w.set_odswen(true)); - while !PWR.csr1().read().odswrdy() {} - } - - while !RCC.cr().read().pllrdy() {} - } - - #[cfg(not(stm32f410))] - if plls.plli2sclk.is_some() { - RCC.cr().modify(|w| w.set_plli2son(true)); - - while !RCC.cr().read().plli2srdy() {} - } - - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - if plls.pllsaiclk.is_some() { - RCC.cr().modify(|w| w.set_pllsaion(true)); - while !RCC.cr().read().pllsairdy() {} - } - - RCC.cfgr().modify(|w| { - w.set_ppre2(Ppre::from_bits(ppre2_bits)); - w.set_ppre1(Ppre::from_bits(ppre1_bits)); - w.set_hpre(hpre_bits); - }); - - // Wait for the new prescalers to kick in - // "The clocks are divided with the new prescaler factor from 1 to 16 AHB cycles after write" - cortex_m::asm::delay(16); - - RCC.cfgr().modify(|w| { - w.set_sw(if sysclk_on_pll { - Sw::PLL1_P - } else if config.hse.is_some() { - Sw::HSE - } else { - Sw::HSI - }) - }); - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: Hertz(sysclk), - pclk1: Hertz(pclk1), - pclk2: Hertz(pclk2), - - pclk1_tim: Hertz(pclk1 * timer_mul1), - pclk2_tim: Hertz(pclk2 * timer_mul2), - - hclk1: Hertz(hclk), - hclk2: Hertz(hclk), - hclk3: Hertz(hclk), - - pll1_q: plls.pll48clk.map(Hertz), - - #[cfg(not(stm32f410))] - plli2s1_q: plls.plli2sclk.map(Hertz), - #[cfg(not(stm32f410))] - plli2s1_r: None, - - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - pllsai1_q: plls.pllsaiclk.map(Hertz), - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - pllsai1_r: None, - - rtc, - }); -} - -struct PllResults { - use_pll: bool, - pllsysclk: Option, - pll48clk: Option, - #[allow(dead_code)] - plli2sclk: Option, - #[allow(dead_code)] - pllsaiclk: Option, -} - -mod max { - #[cfg(stm32f401)] - pub(crate) const SYSCLK_MAX: u32 = 84_000_000; - #[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))] - pub(crate) const SYSCLK_MAX: u32 = 168_000_000; - #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] - pub(crate) const SYSCLK_MAX: u32 = 100_000_000; - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479,))] - pub(crate) const SYSCLK_MAX: u32 = 180_000_000; - - pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 168_000_000; - - pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2; - - #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] - pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX; - #[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))] - pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; - - pub(crate) const PLL_48_CLK: u32 = 48_000_000; - pub(crate) const PLL_48_TOLERANCE: u32 = 120_000; -} diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f4f7.rs similarity index 71% rename from embassy-stm32/src/rcc/f7.rs rename to embassy-stm32/src/rcc/f4f7.rs index a984e4f4..de37eab7 100644 --- a/embassy-stm32/src/rcc/f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -6,6 +6,20 @@ use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; +// TODO: on some F4s, PLLM is shared between all PLLs. Enforce that. +// TODO: on some F4s, add support for plli2s_src +// +// plli2s plli2s_m plli2s_src pllsai pllsai_m +// f401 y shared +// f410 +// f411 y individual +// f412 y individual y +// f4[12]3 y individual y +// f446 y individual y individual +// f4[67]9 y shared y shared +// f4[23][79] y shared y shared +// f4[01][57] y shared + /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); @@ -51,7 +65,9 @@ pub struct Config { pub pll_src: PllSource, pub pll: Option, + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] pub plli2s: Option, + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] pub pllsai: Option, pub ahb_pre: AHBPrescaler, @@ -69,7 +85,9 @@ impl Default for Config { sys: Sysclk::HSI, pll_src: PllSource::HSI, pll: None, + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] plli2s: None, + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] pllsai: None, ahb_pre: AHBPrescaler::DIV1, @@ -128,7 +146,9 @@ pub(crate) unsafe fn init(config: Config) { source: config.pll_src, }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); // Configure sysclk @@ -171,6 +191,15 @@ pub(crate) unsafe fn init(config: Config) { pclk2_tim, rtc, pll1_q: pll.q, + #[cfg(all(rcc_f4, not(stm32f410)))] + plli2s1_q: _plli2s.q, + #[cfg(all(rcc_f4, not(stm32f410)))] + plli2s1_r: _plli2s.r, + + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + pllsai1_q: _pllsai.q, + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + pllsai1_r: _pllsai.r, }); } @@ -191,7 +220,9 @@ struct PllOutput { #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] Plli2s, + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] Pllsai, } @@ -201,10 +232,12 @@ fn pll_enable(instance: PllInstance, enabled: bool) { RCC.cr().modify(|w| w.set_pllon(enabled)); while RCC.cr().read().pllrdy() != enabled {} } + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] PllInstance::Plli2s => { RCC.cr().modify(|w| w.set_plli2son(enabled)); while RCC.cr().read().plli2srdy() != enabled {} } + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] PllInstance::Pllsai => { RCC.cr().modify(|w| w.set_pllsaion(enabled)); while RCC.cr().read().pllsairdy() != enabled {} @@ -255,9 +288,11 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll w.set_pllsrc(input.source); write_fields!(w); }), + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] PllInstance::Plli2s => RCC.plli2scfgr().write(|w| { write_fields!(w); }), + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] PllInstance::Pllsai => RCC.pllsaicfgr().write(|w| { write_fields!(w); }), @@ -294,6 +329,7 @@ where (pclk, pclk_tim) } +#[cfg(stm32f7)] mod max { use core::ops::RangeInclusive; @@ -310,3 +346,34 @@ mod max { pub(crate) const PLL_IN: RangeInclusive = Hertz(1_000_000)..=Hertz(2_100_000); pub(crate) const PLL_VCO: RangeInclusive = Hertz(100_000_000)..=Hertz(432_000_000); } + +#[cfg(stm32f4)] +mod max { + use core::ops::RangeInclusive; + + use crate::time::Hertz; + + pub(crate) const HSE_OSC: RangeInclusive = Hertz(4_000_000)..=Hertz(26_000_000); + pub(crate) const HSE_BYP: RangeInclusive = Hertz(1_000_000)..=Hertz(50_000_000); + + #[cfg(stm32f401)] + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(84_000_000); + #[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))] + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(168_000_000); + #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(100_000_000); + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479,))] + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(180_000_000); + + pub(crate) const HCLK: RangeInclusive = Hertz(0)..=Hertz(SYSCLK.end().0); + + pub(crate) const PCLK1: RangeInclusive = Hertz(0)..=Hertz(PCLK2.end().0 / 2); + + #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] + pub(crate) const PCLK2: RangeInclusive = Hertz(0)..=Hertz(HCLK.end().0); + #[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))] + pub(crate) const PCLK2: RangeInclusive = Hertz(0)..=Hertz(HCLK.end().0 / 2); + + pub(crate) const PLL_IN: RangeInclusive = Hertz(1_000_000)..=Hertz(2_100_000); + pub(crate) const PLL_VCO: RangeInclusive = Hertz(100_000_000)..=Hertz(432_000_000); +} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index d587a198..49174b27 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -13,8 +13,7 @@ pub use mco::*; #[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")] #[cfg_attr(rcc_f2, path = "f2.rs")] #[cfg_attr(any(rcc_f3, rcc_f3_v2), path = "f3.rs")] -#[cfg_attr(any(rcc_f4, rcc_f410), path = "f4.rs")] -#[cfg_attr(rcc_f7, path = "f7.rs")] +#[cfg_attr(any(rcc_f4, rcc_f410, rcc_f7), path = "f4f7.rs")] #[cfg_attr(rcc_c0, path = "c0.rs")] #[cfg_attr(rcc_g0, path = "g0.rs")] #[cfg_attr(rcc_g4, path = "g4.rs")] diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index ddf8596a..1747bbf4 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -10,7 +10,7 @@ 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::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::Timer; use embedded_io_async::Write; @@ -32,7 +32,25 @@ async fn net_task(stack: &'static Stack) -> ! { #[embassy_executor::main] async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); - config.rcc.sys_ck = Some(mhz(200)); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL180, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32f4/src/bin/hello.rs b/examples/stm32f4/src/bin/hello.rs index 27ee83aa..a2a28711 100644 --- a/examples/stm32f4/src/bin/hello.rs +++ b/examples/stm32f4/src/bin/hello.rs @@ -4,15 +4,13 @@ use defmt::info; use embassy_executor::Spawner; -use embassy_stm32::time::Hertz; use embassy_stm32::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) -> ! { - let mut config = Config::default(); - config.rcc.sys_ck = Some(Hertz(84_000_000)); + let config = Config::default(); let _p = embassy_stm32::init(config); loop { diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs index 6ec7d0fe..37e42384 100644 --- a/examples/stm32f4/src/bin/sdmmc.rs +++ b/examples/stm32f4/src/bin/sdmmc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::sdmmc::{DataBlock, Sdmmc}; -use embassy_stm32::time::mhz; +use embassy_stm32::time::{mhz, Hertz}; use embassy_stm32::{bind_interrupts, peripherals, sdmmc, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -20,8 +20,25 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.sys_ck = Some(mhz(48)); - config.rcc.pll48 = true; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL168, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index 763e3a9e..7c0644ae 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_net::tcp::TcpSocket; use embassy_net::{Stack, StackResources}; use embassy_stm32::rng::{self, Rng}; -use embassy_stm32::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::usb_otg::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; @@ -46,9 +46,25 @@ async fn main(spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.pll48 = true; - config.rcc.sys_ck = Some(mhz(48)); - + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL168, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index 4ff6452e..004ff038 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs @@ -4,7 +4,7 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::usb_otg::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; @@ -22,9 +22,25 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.pll48 = true; - config.rcc.sys_ck = Some(mhz(48)); - + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL168, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 7bc74141..8dde71fb 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -224,11 +224,23 @@ pub fn config() -> Config { #[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)); + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL180, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; } #[cfg(feature = "stm32f767zi")] From 3cbc6874247d7b814cab8ec8762bfe2f6f385828 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 16 Oct 2023 23:41:58 +0200 Subject: [PATCH 039/188] net/driver: remove Medium, make HardwareAddress non_exhaustive. --- cyw43/src/control.rs | 4 +- embassy-net-driver-channel/CHANGELOG.md | 10 ++--- embassy-net-driver-channel/README.md | 18 ++++----- embassy-net-driver-channel/src/lib.rs | 20 ++------- embassy-net-driver/CHANGELOG.md | 10 ++--- embassy-net-driver/src/lib.rs | 54 +++++++++---------------- embassy-net-enc28j60/src/lib.rs | 3 +- embassy-net-esp-hosted/src/control.rs | 4 +- embassy-net/CHANGELOG.md | 4 +- embassy-net/src/device.rs | 19 ++------- embassy-net/src/lib.rs | 36 ++++++++++++----- embassy-stm32-wpan/src/mac/driver.rs | 11 +---- 12 files changed, 76 insertions(+), 117 deletions(-) diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index 2585b31d..d2709304 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs @@ -1,7 +1,7 @@ use core::cmp::{max, min}; -use ch::driver::LinkState; use embassy_net_driver_channel as ch; +use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; use embassy_time::Timer; pub use crate::bus::SpiBusCyw43; @@ -133,7 +133,7 @@ impl<'a> Control<'a> { Timer::after_millis(100).await; - self.state_ch.set_ethernet_address(mac_addr); + self.state_ch.set_hardware_address(HardwareAddress::Ethernet(mac_addr)); debug!("INIT DONE"); } diff --git a/embassy-net-driver-channel/CHANGELOG.md b/embassy-net-driver-channel/CHANGELOG.md index 589996cf..b04d0a86 100644 --- a/embassy-net-driver-channel/CHANGELOG.md +++ b/embassy-net-driver-channel/CHANGELOG.md @@ -5,14 +5,12 @@ 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.2.0 - 2023-10-15 +## 0.2.0 - 2023-10-18 -- Update embassy-net-driver -- `Runner::new` now takes an `embassy_net_driver::HardwareAddress` parameter -- Added `Runner::set_ieee802154_address`, `Runner::ieee802154_address` +- Update `embassy-net-driver` to v0.2 +- `Runner::new` now takes an `embassy_net_driver::HardwareAddress` parameter. +- `Runner::set_ethernet_address` is now `set_hardware_address`. ## 0.1.0 - 2023-06-29 - First release - - diff --git a/embassy-net-driver-channel/README.md b/embassy-net-driver-channel/README.md index 8f904ce9..90a21638 100644 --- a/embassy-net-driver-channel/README.md +++ b/embassy-net-driver-channel/README.md @@ -7,7 +7,9 @@ The `embassy-net-driver` trait is polling-based. To implement it, you must write hand, and hook up the `Waker`s provided by `embassy-net` to the right interrupt handlers so that `embassy-net` knows when to poll your driver again to make more progress. -With `embassy-net-driver-channel` +With `embassy-net-driver-channel` you get a "channel-like" interface instead, where you can send/receive packets +to/from embassy-net. The intended usage is to spawn a "driver task" in the background that does this, passing +packets between the hardware and the channel. ## A note about deadlocks @@ -18,19 +20,19 @@ loop { // Wait for either.. match select( // ... the chip signaling an interrupt, indicating a packet is available to receive, or - irq_pin.wait_for_low(), + irq_pin.wait_for_low(), // ... a TX buffer becoming available, i.e. embassy-net wants to send a packet tx_chan.tx_buf(), ).await { Either::First(_) => { // a packet is ready to be received! let buf = rx_chan.rx_buf().await; // allocate a rx buf from the packet queue - let n = receive_packet_over_spi(buf).await; + let n = receive_packet_over_spi(buf).await; rx_chan.rx_done(n); } Either::Second(buf) => { // a packet is ready to be sent! - send_packet_over_spi(buf).await; + send_packet_over_spi(buf).await; tx_chan.tx_done(); } } @@ -41,7 +43,7 @@ However, this code has a latent deadlock bug. The symptom is it can hang at `rx_ The reason is that, under load, both the TX and RX queues can get full at the same time. When this happens, the `embassy-net` task stalls trying to send because the TX queue is full, therefore it stops processing packets in the RX queue. Your driver task also stalls because the RX queue is full, therefore it stops processing packets in the TX queue. -The fix is to make sure to always service the TX queue while you're waiting for space to become available in the TX queue. For example, select on either "tx_chan.tx_buf() available" or "INT is low AND rx_chan.rx_buf() available": +The fix is to make sure to always service the TX queue while you're waiting for space to become available in the RX queue. For example, select on either "tx_chan.tx_buf() available" or "INT is low AND rx_chan.rx_buf() available": ```rust,ignore loop { @@ -58,12 +60,12 @@ loop { ).await { Either::First(buf) => { // a packet is ready to be received! - let n = receive_packet_over_spi(buf).await; + let n = receive_packet_over_spi(buf).await; rx_chan.rx_done(n); } Either::Second(buf) => { // a packet is ready to be sent! - send_packet_over_spi(buf).await; + send_packet_over_spi(buf).await; tx_chan.tx_done(); } } @@ -79,12 +81,10 @@ These `embassy-net` drivers are implemented using this crate. You can look at th - [`embassy-net-wiznet`](https://github.com/embassy-rs/embassy/tree/main/embassy-net-wiznet) for Wiznet SPI Ethernet MAC+PHY chips. - [`embassy-net-esp-hosted`](https://github.com/embassy-rs/embassy/tree/main/embassy-net-esp-hosted) for using ESP32 chips with the [`esp-hosted`](https://github.com/espressif/esp-hosted) firmware as WiFi adapters for another non-ESP32 MCU. - ## Interoperability This crate can run on any executor. - ## License This work is licensed under either of diff --git a/embassy-net-driver-channel/src/lib.rs b/embassy-net-driver-channel/src/lib.rs index bf7ae521..bfb2c9c0 100644 --- a/embassy-net-driver-channel/src/lib.rs +++ b/embassy-net-driver-channel/src/lib.rs @@ -8,9 +8,8 @@ use core::cell::RefCell; use core::mem::MaybeUninit; use core::task::{Context, Poll}; -use driver::HardwareAddress; pub use embassy_net_driver as driver; -use embassy_net_driver::{Capabilities, LinkState, Medium}; +use embassy_net_driver::{Capabilities, LinkState}; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::blocking_mutex::Mutex; use embassy_sync::waitqueue::WakerRegistration; @@ -161,18 +160,10 @@ impl<'d> StateRunner<'d> { }); } - pub fn set_ethernet_address(&self, address: [u8; 6]) { + pub fn set_hardware_address(&self, address: driver::HardwareAddress) { self.shared.lock(|s| { let s = &mut *s.borrow_mut(); - s.hardware_address = driver::HardwareAddress::Ethernet(address); - s.waker.wake(); - }); - } - - pub fn set_ieee802154_address(&self, address: [u8; 8]) { - self.shared.lock(|s| { - let s = &mut *s.borrow_mut(); - s.hardware_address = driver::HardwareAddress::Ieee802154(address); + s.hardware_address = address; s.waker.wake(); }); } @@ -232,11 +223,6 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( ) -> (Runner<'d, MTU>, Device<'d, MTU>) { let mut caps = Capabilities::default(); caps.max_transmission_unit = MTU; - caps.medium = match &hardware_address { - HardwareAddress::Ethernet(_) => Medium::Ethernet, - HardwareAddress::Ieee802154(_) => Medium::Ieee802154, - HardwareAddress::Ip => Medium::Ip, - }; // safety: this is a self-referential struct, however: // - it can't move while the `'d` borrow is active. diff --git a/embassy-net-driver/CHANGELOG.md b/embassy-net-driver/CHANGELOG.md index 7be62282..165461ef 100644 --- a/embassy-net-driver/CHANGELOG.md +++ b/embassy-net-driver/CHANGELOG.md @@ -5,13 +5,13 @@ 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.2.0 - 2023-10-15 +## 0.2.0 - 2023-10-18 -- Added `Driver::ieee802154_address` -- Added `Medium::Ieee802154` +- Added support for IEEE 802.15.4 mediums. +- Added `Driver::hardware_address()`, `HardwareAddress`. +- Removed `Medium` enum. The medium is deduced out of the hardware address. +- Removed `Driver::ethernet_address()`. Replacement is `hardware_address()`. ## 0.1.0 - 2023-06-29 - First release - - diff --git a/embassy-net-driver/src/lib.rs b/embassy-net-driver/src/lib.rs index b64c1000..87f9f6ed 100644 --- a/embassy-net-driver/src/lib.rs +++ b/embassy-net-driver/src/lib.rs @@ -7,12 +7,23 @@ use core::task::Context; /// Representation of an hardware address, such as an Ethernet address or an IEEE802.15.4 address. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub enum HardwareAddress { - /// A six-octet Ethernet address + /// Ethernet medium, with a A six-octet Ethernet address. + /// + /// Devices of this type send and receive Ethernet frames, + /// and interfaces using it must do neighbor discovery via ARP or NDISC. + /// + /// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode. Ethernet([u8; 6]), - /// An eight-octet IEEE802.15.4 address + /// 6LoWPAN over IEEE802.15.4, with an eight-octet address. Ieee802154([u8; 8]), - /// Indicates that a Driver is IP-native, and has no hardware address + /// Indicates that a Driver is IP-native, and has no hardware address. + /// + /// Devices of this type send and receive IP frames, without an + /// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done. + /// + /// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode. Ip, } @@ -64,6 +75,10 @@ pub trait Driver { fn capabilities(&self) -> Capabilities; /// Get the device's hardware address. + /// + /// The returned hardware address also determines the "medium" of this driver. This indicates + /// what kind of packet the sent/received bytes are, and determines some behaviors of + /// the interface. For example, ARP/NDISC address resolution is only done for Ethernet mediums. fn hardware_address(&self) -> HardwareAddress; } @@ -124,13 +139,6 @@ pub trait TxToken { #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[non_exhaustive] pub struct Capabilities { - /// Medium of the device. - /// - /// This indicates what kind of packet the sent/received bytes are, and determines - /// some behaviors of Interface. For example, ARP/NDISC address resolution is only done - /// for Ethernet mediums. - pub medium: Medium, - /// Maximum transmission unit. /// /// The network device is unable to send or receive frames larger than the value returned @@ -161,32 +169,6 @@ pub struct Capabilities { pub checksum: ChecksumCapabilities, } -/// Type of medium of a device. -#[derive(Debug, Eq, PartialEq, Copy, Clone)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Medium { - /// Ethernet medium. Devices of this type send and receive Ethernet frames, - /// and interfaces using it must do neighbor discovery via ARP or NDISC. - /// - /// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode. - Ethernet, - - /// IP medium. Devices of this type send and receive IP frames, without an - /// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done. - /// - /// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode. - Ip, - - /// IEEE 802_15_4 medium - Ieee802154, -} - -impl Default for Medium { - fn default() -> Medium { - Medium::Ethernet - } -} - /// A description of checksum behavior for every supported protocol. #[derive(Debug, Clone, Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/embassy-net-enc28j60/src/lib.rs b/embassy-net-enc28j60/src/lib.rs index f96a6ff1..f1813492 100644 --- a/embassy-net-enc28j60/src/lib.rs +++ b/embassy-net-enc28j60/src/lib.rs @@ -19,7 +19,7 @@ mod traits; use core::cmp; use core::convert::TryInto; -use embassy_net_driver::{Capabilities, HardwareAddress, LinkState, Medium}; +use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; use embassy_time::Duration; use embedded_hal::digital::OutputPin; use embedded_hal::spi::{Operation, SpiDevice}; @@ -671,7 +671,6 @@ where fn capabilities(&self) -> Capabilities { let mut caps = Capabilities::default(); caps.max_transmission_unit = MTU; - caps.medium = Medium::Ethernet; caps } diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs index a4996b58..50030f43 100644 --- a/embassy-net-esp-hosted/src/control.rs +++ b/embassy-net-esp-hosted/src/control.rs @@ -1,5 +1,5 @@ -use ch::driver::LinkState; use embassy_net_driver_channel as ch; +use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; use heapless::String; use crate::ioctl::Shared; @@ -77,7 +77,7 @@ impl<'a> Control<'a> { let mac_addr = self.get_mac_addr().await?; debug!("mac addr: {:02x}", mac_addr); - self.state_ch.set_ethernet_address(mac_addr); + self.state_ch.set_hardware_address(HardwareAddress::Ethernet(mac_addr)); Ok(()) } diff --git a/embassy-net/CHANGELOG.md b/embassy-net/CHANGELOG.md index 3e7c2877..7b91b844 100644 --- a/embassy-net/CHANGELOG.md +++ b/embassy-net/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.2.0 - 2023-10-15 +## 0.2.0 - 2023-10-18 - Re-export `smoltcp::wire::IpEndpoint` - Add poll functions on UdpSocket @@ -27,5 +27,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.1.0 - 2023-06-29 - First release - - diff --git a/embassy-net/src/device.rs b/embassy-net/src/device.rs index 8c2b7d31..54a0c47e 100644 --- a/embassy-net/src/device.rs +++ b/embassy-net/src/device.rs @@ -1,7 +1,7 @@ use core::task::Context; -use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken}; -use smoltcp::phy; +use embassy_net_driver::{Capabilities, Checksum, Driver, RxToken, TxToken}; +use smoltcp::phy::{self, Medium}; use smoltcp::time::Instant; pub(crate) struct DriverAdapter<'d, 'c, T> @@ -11,6 +11,7 @@ where // must be Some when actually using this to rx/tx pub cx: Option<&'d mut Context<'c>>, pub inner: &'d mut T, + pub medium: Medium, } impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T> @@ -46,19 +47,7 @@ where smolcaps.max_transmission_unit = caps.max_transmission_unit; smolcaps.max_burst_size = caps.max_burst_size; - smolcaps.medium = match caps.medium { - #[cfg(feature = "medium-ethernet")] - Medium::Ethernet => phy::Medium::Ethernet, - #[cfg(feature = "medium-ip")] - Medium::Ip => phy::Medium::Ip, - #[cfg(feature = "medium-ieee802154")] - Medium::Ieee802154 => phy::Medium::Ieee802154, - #[allow(unreachable_patterns)] - _ => panic!( - "Unsupported medium {:?}. Make sure to enable it in embassy-net's Cargo features.", - caps.medium - ), - }; + smolcaps.medium = self.medium; smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4); smolcaps.checksum.tcp = convert(caps.checksum.tcp); smolcaps.checksum.udp = convert(caps.checksum.udp); diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index a0ad33c6..c41faee2 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -33,6 +33,7 @@ use heapless::Vec; pub use smoltcp::iface::MulticastError; #[allow(unused_imports)] use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage}; +use smoltcp::phy::Medium; #[cfg(feature = "dhcpv4")] use smoltcp::socket::dhcpv4::{self, RetryConfig}; #[cfg(feature = "medium-ethernet")] @@ -264,14 +265,17 @@ pub(crate) struct SocketStack { next_local_port: u16, } -fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> HardwareAddress { +fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> (HardwareAddress, Medium) { match addr { #[cfg(feature = "medium-ethernet")] - driver::HardwareAddress::Ethernet(eth) => HardwareAddress::Ethernet(EthernetAddress(eth)), + driver::HardwareAddress::Ethernet(eth) => (HardwareAddress::Ethernet(EthernetAddress(eth)), Medium::Ethernet), #[cfg(feature = "medium-ieee802154")] - driver::HardwareAddress::Ieee802154(ieee) => HardwareAddress::Ieee802154(Ieee802154Address::Extended(ieee)), + driver::HardwareAddress::Ieee802154(ieee) => ( + HardwareAddress::Ieee802154(Ieee802154Address::Extended(ieee)), + Medium::Ieee802154, + ), #[cfg(feature = "medium-ip")] - driver::HardwareAddress::Ip => HardwareAddress::Ip, + driver::HardwareAddress::Ip => (HardwareAddress::Ip, Medium::Ip), #[allow(unreachable_patterns)] _ => panic!( @@ -289,7 +293,8 @@ impl Stack { resources: &'static mut StackResources, random_seed: u64, ) -> Self { - let mut iface_cfg = smoltcp::iface::Config::new(to_smoltcp_hardware_address(device.hardware_address())); + let (hardware_addr, medium) = to_smoltcp_hardware_address(device.hardware_address()); + let mut iface_cfg = smoltcp::iface::Config::new(hardware_addr); iface_cfg.random_seed = random_seed; let iface = Interface::new( @@ -297,6 +302,7 @@ impl Stack { &mut DriverAdapter { inner: &mut device, cx: None, + medium, }, instant_to_smoltcp(Instant::now()), ); @@ -356,7 +362,7 @@ impl Stack { /// Get the hardware address of the network interface. pub fn hardware_address(&self) -> HardwareAddress { - self.with(|_s, i| to_smoltcp_hardware_address(i.device.hardware_address())) + self.with(|_s, i| to_smoltcp_hardware_address(i.device.hardware_address()).0) } /// Get whether the link is up. @@ -812,18 +818,28 @@ impl Inner { fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { s.waker.register(cx.waker()); + let (_hardware_addr, medium) = to_smoltcp_hardware_address(self.device.hardware_address()); + #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] - if self.device.capabilities().medium == embassy_net_driver::Medium::Ethernet - || self.device.capabilities().medium == embassy_net_driver::Medium::Ieee802154 { - s.iface - .set_hardware_addr(to_smoltcp_hardware_address(self.device.hardware_address())); + let do_set = match medium { + #[cfg(feature = "medium-ethernet")] + Medium::Ethernet => true, + #[cfg(feature = "medium-ieee802154")] + Medium::Ieee802154 => true, + #[allow(unreachable_patterns)] + _ => false, + }; + if do_set { + s.iface.set_hardware_addr(_hardware_addr); + } } let timestamp = instant_to_smoltcp(Instant::now()); let mut smoldev = DriverAdapter { cx: Some(cx), inner: &mut self.device, + medium, }; s.iface.poll(timestamp, &mut smoldev, &mut s.sockets); diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs index bfc4f1ee..ffba6e5e 100644 --- a/embassy-stm32-wpan/src/mac/driver.rs +++ b/embassy-stm32-wpan/src/mac/driver.rs @@ -3,7 +3,7 @@ use core::task::Context; -use embassy_net_driver::{Capabilities, HardwareAddress, LinkState, Medium}; +use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; @@ -60,24 +60,15 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> { let mut caps = Capabilities::default(); caps.max_transmission_unit = MTU; // caps.max_burst_size = Some(self.tx.len()); - - caps.medium = Medium::Ieee802154; caps } fn link_state(&mut self, _cx: &mut Context) -> LinkState { - // if self.phy.poll_link(&mut self.station_management, cx) { - // LinkState::Up - // } else { - // LinkState::Down - // } - LinkState::Down } fn hardware_address(&self) -> HardwareAddress { // self.mac_addr - HardwareAddress::Ieee802154([0; 8]) } } From 241488ef1ce365dc4582f51dee6dfa742f1fd63d Mon Sep 17 00:00:00 2001 From: eZio Pan Date: Wed, 18 Oct 2023 19:42:31 +0800 Subject: [PATCH 040/188] bypass `ODEN` if chip doesn't have it --- embassy-stm32/src/rcc/f4f7.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs index de37eab7..3f9a2be6 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -2,7 +2,7 @@ pub use crate::pac::rcc::vals::{ Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp, Pllq, Pllr, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, }; -use crate::pac::{FLASH, PWR, RCC}; +use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -101,11 +101,17 @@ impl Default for Config { pub(crate) unsafe fn init(config: Config) { // always enable overdrive for now. Make it configurable in the future. - PWR.cr1().modify(|w| w.set_oden(true)); - while !PWR.csr1().read().odrdy() {} + #[cfg(not(any( + stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f405, stm32f407, stm32f415, stm32f417 + )))] + { + use crate::pac::PWR; + PWR.cr1().modify(|w| w.set_oden(true)); + while !PWR.csr1().read().odrdy() {} - PWR.cr1().modify(|w| w.set_odswen(true)); - while !PWR.csr1().read().odswrdy() {} + PWR.cr1().modify(|w| w.set_odswen(true)); + while !PWR.csr1().read().odswrdy() {} + } // Configure HSI let hsi = match config.hsi { From c7803bb8f4e184b2f0beb88ef9adea6443d0319a Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Thu, 19 Oct 2023 09:29:20 +0200 Subject: [PATCH 041/188] docs: add linker script comments Existing comment were outdated. Provide an example configuration for using the softdevice with the nRF52 examples. --- examples/nrf52840-rtic/memory.x | 7 ++++++- examples/nrf52840/memory.x | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/nrf52840-rtic/memory.x b/examples/nrf52840-rtic/memory.x index 9b04edec..15b492bc 100644 --- a/examples/nrf52840-rtic/memory.x +++ b/examples/nrf52840-rtic/memory.x @@ -1,7 +1,12 @@ MEMORY { /* NOTE 1 K = 1 KiBi = 1024 bytes */ - /* These values correspond to the NRF52840 with Softdevices S140 7.0.1 */ FLASH : ORIGIN = 0x00000000, LENGTH = 1024K RAM : ORIGIN = 0x20000000, LENGTH = 256K + + /* These values correspond to the NRF52840 with Softdevices S140 7.3.0 */ + /* + FLASH : ORIGIN = 0x00027000, LENGTH = 868K + RAM : ORIGIN = 0x20020000, LENGTH = 128K + */ } diff --git a/examples/nrf52840/memory.x b/examples/nrf52840/memory.x index 9b04edec..15b492bc 100644 --- a/examples/nrf52840/memory.x +++ b/examples/nrf52840/memory.x @@ -1,7 +1,12 @@ MEMORY { /* NOTE 1 K = 1 KiBi = 1024 bytes */ - /* These values correspond to the NRF52840 with Softdevices S140 7.0.1 */ FLASH : ORIGIN = 0x00000000, LENGTH = 1024K RAM : ORIGIN = 0x20000000, LENGTH = 256K + + /* These values correspond to the NRF52840 with Softdevices S140 7.3.0 */ + /* + FLASH : ORIGIN = 0x00027000, LENGTH = 868K + RAM : ORIGIN = 0x20020000, LENGTH = 128K + */ } From 630443a4d64dda9d2840525307453bc358ef02d3 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 20 Oct 2023 01:29:10 +0200 Subject: [PATCH 042/188] net-wiznet: report link up/down on cable plug/unplug. --- embassy-net-wiznet/src/lib.rs | 54 ++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/embassy-net-wiznet/src/lib.rs b/embassy-net-wiznet/src/lib.rs index 48d17cac..afdb6729 100644 --- a/embassy-net-wiznet/src/lib.rs +++ b/embassy-net-wiznet/src/lib.rs @@ -1,14 +1,14 @@ -//! [`embassy-net`](https://crates.io/crates/embassy-net) driver for WIZnet ethernet chips. #![no_std] #![feature(async_fn_in_trait)] +#![doc = include_str!("../README.md")] pub mod chip; mod device; -use embassy_futures::select::{select, Either}; +use embassy_futures::select::{select3, Either3}; use embassy_net_driver_channel as ch; use embassy_net_driver_channel::driver::LinkState; -use embassy_time::Timer; +use embassy_time::{Duration, Ticker, Timer}; use embedded_hal::digital::OutputPin; use embedded_hal_async::digital::Wait; use embedded_hal_async::spi::SpiDevice; @@ -49,32 +49,34 @@ pub struct Runner<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> { impl<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, C, SPI, INT, RST> { pub async fn run(mut self) -> ! { let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); + let mut tick = Ticker::every(Duration::from_millis(500)); loop { - if self.mac.is_link_up().await { - state_chan.set_link_state(LinkState::Up); - loop { - match select( - async { - self.int.wait_for_low().await.ok(); - rx_chan.rx_buf().await - }, - tx_chan.tx_buf(), - ) - .await - { - Either::First(p) => { - if let Ok(n) = self.mac.read_frame(p).await { - rx_chan.rx_done(n); - } - } - Either::Second(p) => { - self.mac.write_frame(p).await.ok(); - tx_chan.tx_done(); - } + match select3( + async { + self.int.wait_for_low().await.ok(); + rx_chan.rx_buf().await + }, + tx_chan.tx_buf(), + tick.next(), + ) + .await + { + Either3::First(p) => { + if let Ok(n) = self.mac.read_frame(p).await { + rx_chan.rx_done(n); + } + } + Either3::Second(p) => { + self.mac.write_frame(p).await.ok(); + tx_chan.tx_done(); + } + Either3::Third(()) => { + if self.mac.is_link_up().await { + state_chan.set_link_state(LinkState::Up); + } else { + state_chan.set_link_state(LinkState::Down); } } - } else { - state_chan.set_link_state(LinkState::Down); } } } From 6f2995cd4c70a2b6c977f553a2d5efcd8216bba7 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 20 Oct 2023 10:41:39 +0200 Subject: [PATCH 043/188] Invert assert --- embassy-stm32/src/timer/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 755c2780..15eaf353 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -88,7 +88,7 @@ pub(crate) mod sealed { let timer_enabled = Self::regs().cr1().read().cen(); // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. // Changing direction is discouraged while the timer is running. - assert!(timer_enabled); + assert!(!timer_enabled); Self::regs_gp16().cr1().modify(|r| r.set_dir(dir)); Self::regs_gp16().cr1().modify(|r| r.set_cms(cms)) From 0fb677aad7ab185491ffe012c64a1f603daf04f0 Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 20 Oct 2023 20:21:53 -0500 Subject: [PATCH 044/188] stm32: update metapac --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/src/rcc/f1.rs | 9 +-------- embassy-stm32/src/rcc/l4l5.rs | 3 --- embassy-stm32/src/rcc/u5.rs | 4 ++-- embassy-stm32/src/rcc/wb.rs | 14 +++++++------- embassy-stm32/src/rcc/wba.rs | 4 ++-- embassy-stm32/src/rcc/wl.rs | 4 ++-- embassy-stm32/src/sdmmc/mod.rs | 4 ++-- tests/stm32/src/common.rs | 9 +-------- 9 files changed, 19 insertions(+), 36 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 3b9220bc..f70e75d4 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-5b04234fbe61ea875f1a904cd5f68795daaeb526" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-296dd041cce492e3b2b7fb3b8a6c05c9a34a90a1" } 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-5b04234fbe61ea875f1a904cd5f68795daaeb526", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-296dd041cce492e3b2b7fb3b8a6c05c9a34a90a1", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs index 8d315f7b..169551e4 100644 --- a/embassy-stm32/src/rcc/f1.rs +++ b/embassy-stm32/src/rcc/f1.rs @@ -169,14 +169,7 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(not(rcc_f100))] w.set_usbpre(Usbpre::from_bits(usbpre as u8)); w.set_sw(if pllmul_bits.is_some() { - #[cfg(not(rcc_f1cl))] - { - Sw::PLL1_P - } - #[cfg(rcc_f1cl)] - { - Sw::PLL - } + Sw::PLL1_P } else if config.hse.is_some() { Sw::HSE } else { diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 683b47c0..e54bfa0e 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -189,9 +189,6 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::HSE => hse.unwrap(), ClockSrc::HSI => hsi16.unwrap(), ClockSrc::MSI => msi.unwrap(), - #[cfg(rcc_l4)] - ClockSrc::PLL1_P => pll._r.unwrap(), - #[cfg(not(rcc_l4))] ClockSrc::PLL1_R => pll._r.unwrap(), }; diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index aba5ca83..62bed8be 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -92,7 +92,7 @@ impl Into for PllSrc { match self { PllSrc::MSIS(..) => Pllsrc::MSIS, PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI16, + PllSrc::HSI16 => Pllsrc::HSI, } } } @@ -102,7 +102,7 @@ impl Into for ClockSrc { match self { ClockSrc::MSI(..) => Sw::MSIS, ClockSrc::HSE(..) => Sw::HSE, - ClockSrc::HSI16 => Sw::HSI16, + ClockSrc::HSI16 => Sw::HSI, ClockSrc::PLL1R(..) => Sw::PLL1_R, } } diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index 64173fea..2d0b2711 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -59,7 +59,7 @@ pub const WPAN_DEFAULT: Config = Config { frequency: mhz(32), prediv: HsePrescaler::DIV1, }), - sys: Sysclk::PLL, + sys: Sysclk::PLL1_R, mux: Some(PllMux { source: PllSource::HSE, prediv: Pllm::DIV2, @@ -87,8 +87,8 @@ impl Default for Config { #[inline] fn default() -> Config { Config { + sys: Sysclk::HSI, hse: None, - sys: Sysclk::HSI16, mux: None, pll: None, pllsai: None, @@ -113,7 +113,7 @@ pub(crate) unsafe fn init(config: Config) { let mux_clk = config.mux.as_ref().map(|pll_mux| { (match pll_mux.source { PllSource::HSE => hse_clk.unwrap(), - PllSource::HSI16 => HSI_FREQ, + PllSource::HSI => HSI_FREQ, _ => unreachable!(), } / pll_mux.prediv) }); @@ -133,8 +133,8 @@ pub(crate) unsafe fn init(config: Config) { let sys_clk = match config.sys { Sysclk::HSE => hse_clk.unwrap(), - Sysclk::HSI16 => HSI_FREQ, - Sysclk::PLL => pll_r.unwrap(), + Sysclk::HSI => HSI_FREQ, + Sysclk::PLL1_R => pll_r.unwrap(), _ => unreachable!(), }; @@ -161,12 +161,12 @@ pub(crate) unsafe fn init(config: Config) { let rcc = crate::pac::RCC; let needs_hsi = if let Some(pll_mux) = &config.mux { - pll_mux.source == PllSource::HSI16 + pll_mux.source == PllSource::HSI } else { false }; - if needs_hsi || config.sys == Sysclk::HSI16 { + if needs_hsi || config.sys == Sysclk::HSI { rcc.cr().modify(|w| { w.set_hsion(true); }); diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index 72f65361..aabf782e 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -26,7 +26,7 @@ impl Into for PllSrc { fn into(self) -> Pllsrc { match self { PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI16, + PllSrc::HSI16 => Pllsrc::HSI, } } } @@ -35,7 +35,7 @@ impl Into for ClockSrc { fn into(self) -> Sw { match self { ClockSrc::HSE(..) => Sw::HSE, - ClockSrc::HSI16 => Sw::HSI16, + ClockSrc::HSI16 => Sw::HSI, } } } diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index c1f6a6b1..401486bb 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -42,7 +42,7 @@ impl Default for Config { shd_ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, - adc_clock_source: AdcClockSource::HSI16, + adc_clock_source: AdcClockSource::HSI, ls: Default::default(), } } @@ -50,7 +50,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::HSI16 => (HSI_FREQ, Sw::HSI, VoltageScale::RANGE2), ClockSrc::HSE => (HSE_FREQ, Sw::HSE, VoltageScale::RANGE1), ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), }; diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 11ff2464..a99a5707 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -1466,7 +1466,7 @@ cfg_if::cfg_if! { (SDMMC1) => { critical_section::with(|_| unsafe { let sdmmcsel = crate::pac::RCC.dckcfgr2().read().sdmmc1sel(); - if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { + if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYS { crate::rcc::get_freqs().sys } else { crate::rcc::get_freqs().pll1_q.expect("PLL48 is required for SDMMC") @@ -1476,7 +1476,7 @@ cfg_if::cfg_if! { (SDMMC2) => { critical_section::with(|_| unsafe { let sdmmcsel = crate::pac::RCC.dckcfgr2().read().sdmmc2sel(); - if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { + if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYS { crate::rcc::get_freqs().sys } else { crate::rcc::get_freqs().pll1_q.expect("PLL48 is required for SDMMC") diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 8dde71fb..95b5318f 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -323,14 +323,7 @@ pub fn config() -> Config { #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] { use embassy_stm32::rcc::*; - #[cfg(feature = "stm32l4r5zi")] - { - config.rcc.mux = ClockSrc::PLL1_R; - } - #[cfg(not(feature = "stm32l4r5zi"))] - { - config.rcc.mux = ClockSrc::PLL1_P; - } + config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi16 = true; config.rcc.pll = Some(Pll { source: PLLSource::HSI, From 3d03c18d4fd5c4f410e5e697d56b5152bb910232 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 21 Oct 2023 02:53:48 +0200 Subject: [PATCH 045/188] stm32/tests: add stm32h753zi, stm32h7a3zi. --- ci.sh | 2 ++ embassy-stm32/src/rcc/h.rs | 9 +++++++- tests/stm32/Cargo.toml | 2 ++ tests/stm32/src/bin/eth.rs | 2 ++ tests/stm32/src/bin/gpio.rs | 5 ++--- tests/stm32/src/bin/rng.rs | 8 ++++++- tests/stm32/src/common.rs | 45 +++++++++++++++++++++++++++++++++++-- 7 files changed, 66 insertions(+), 7 deletions(-) diff --git a/ci.sh b/ci.sh index ece76349..efe98c7a 100755 --- a/ci.sh +++ b/ci.sh @@ -192,6 +192,8 @@ cargo batch \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32g071rb --out-dir out/tests/stm32g071rb \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32c031c6 --out-dir out/tests/stm32c031c6 \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi --out-dir out/tests/stm32h755zi \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h753zi --out-dir out/tests/stm32h753zi \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7a3zi --out-dir out/tests/stm32h7a3zi \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55rg --out-dir out/tests/stm32wb55rg \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h563zi --out-dir out/tests/stm32h563zi \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585ai --out-dir out/tests/stm32u585ai \ diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 5dbcfea9..8883763e 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -389,7 +389,14 @@ pub(crate) unsafe fn init(config: Config) { VoltageScale::Scale2 => (Hertz(150_000_000), Hertz(150_000_000)), VoltageScale::Scale3 => (Hertz(100_000_000), Hertz(100_000_000)), }; - #[cfg(stm32h7)] + #[cfg(pwr_h7rm0455)] + let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale { + VoltageScale::Scale0 => (Hertz(280_000_000), Hertz(280_000_000), Hertz(140_000_000)), + VoltageScale::Scale1 => (Hertz(225_000_000), Hertz(225_000_000), Hertz(112_500_000)), + VoltageScale::Scale2 => (Hertz(160_000_000), Hertz(160_000_000), Hertz(80_000_000)), + VoltageScale::Scale3 => (Hertz(88_000_000), Hertz(88_000_000), Hertz(44_000_000)), + }; + #[cfg(all(stm32h7, not(pwr_h7rm0455)))] let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale { VoltageScale::Scale0 => (Hertz(480_000_000), Hertz(240_000_000), Hertz(120_000_000)), VoltageScale::Scale1 => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)), diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index b1b2f55c..48598ec2 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -12,6 +12,8 @@ stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma", "rng"] stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin", "rng"] +stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"] +stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"] stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng"] stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng"] diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index 6d5e05cd..75435494 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs @@ -60,6 +60,8 @@ async fn main(spawner: Spawner) { let n = 4; #[cfg(feature = "stm32f207zg")] let n = 5; + #[cfg(feature = "stm32h753zi")] + let n = 6; let mac_addr = [0x00, n, 0xDE, 0xAD, 0xBE, 0xEF]; diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs index 49d9a60f..83c96ce9 100644 --- a/tests/stm32/src/bin/gpio.rs +++ b/tests/stm32/src/bin/gpio.rs @@ -217,8 +217,7 @@ async fn main(_spawner: Spawner) { } fn delay() { - #[cfg(feature = "stm32h755zi")] - cortex_m::asm::delay(10000); - #[cfg(not(feature = "stm32h755zi"))] + #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h7a3zi"))] + cortex_m::asm::delay(9000); cortex_m::asm::delay(1000); } diff --git a/tests/stm32/src/bin/rng.rs b/tests/stm32/src/bin/rng.rs index 65da737d..b7f36137 100644 --- a/tests/stm32/src/bin/rng.rs +++ b/tests/stm32/src/bin/rng.rs @@ -11,7 +11,12 @@ use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng}; use {defmt_rtt as _, panic_probe as _}; -#[cfg(any(feature = "stm32l4a6zg", feature = "stm32h755zi", feature = "stm32f429zi"))] +#[cfg(any( + feature = "stm32l4a6zg", + feature = "stm32h755zi", + feature = "stm32h753zi", + feature = "stm32f429zi" +))] bind_interrupts!(struct Irqs { HASH_RNG => rng::InterruptHandler; }); @@ -23,6 +28,7 @@ bind_interrupts!(struct Irqs { feature = "stm32l4a6zg", feature = "stm32l073rz", feature = "stm32h755zi", + feature = "stm32h753zi", feature = "stm32f429zi" )))] bind_interrupts!(struct Irqs { diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 8dde71fb..cbf9538a 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -18,6 +18,10 @@ teleprobe_meta::target!(b"nucleo-stm32f429zi"); teleprobe_meta::target!(b"nucleo-stm32wb55rg"); #[cfg(feature = "stm32h755zi")] teleprobe_meta::target!(b"nucleo-stm32h755zi"); +#[cfg(feature = "stm32h753zi")] +teleprobe_meta::target!(b"nucleo-stm32h753zi"); +#[cfg(feature = "stm32h7a3zi")] +teleprobe_meta::target!(b"nucleo-stm32h7a3zi"); #[cfg(feature = "stm32u585ai")] teleprobe_meta::target!(b"iot-stm32u585ai"); #[cfg(feature = "stm32h563zi")] @@ -105,12 +109,18 @@ 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 = {LPUART1 => embassy_stm32::usart::InterruptHandler;}, ); -#[cfg(feature = "stm32h755zi")] +#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] define_peris!( UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler;}, ); +#[cfg(feature = "stm32h7a3zi")] +define_peris!( + UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, + @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler;}, +); #[cfg(feature = "stm32u585ai")] define_peris!( UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, @@ -289,7 +299,7 @@ pub fn config() -> Config { config.rcc.voltage_scale = VoltageScale::Scale0; } - #[cfg(feature = "stm32h755zi")] + #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] { use embassy_stm32::rcc::*; config.rcc.hsi = Some(Hsi::Mhz64); @@ -320,6 +330,37 @@ pub fn config() -> Config { config.rcc.adc_clock_source = AdcClockSource::PLL2_P; } + #[cfg(any(feature = "stm32h7a3zi"))] + { + 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: PllPreDiv::DIV4, + mul: PllMul::MUL35, + divp: Some(PllDiv::DIV2), // 280 Mhz + divq: Some(PllDiv::DIV8), // SPI1 cksel defaults to pll1_q + divr: None, + }); + config.rcc.pll2 = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL35, + divp: Some(PllDiv::DIV8), // 70 Mhz + divq: None, + divr: None, + }); + config.rcc.sys = Sysclk::Pll1P; // 280 Mhz + config.rcc.ahb_pre = AHBPrescaler::DIV1; // 280 Mhz + config.rcc.apb1_pre = APBPrescaler::DIV2; // 140 Mhz + config.rcc.apb2_pre = APBPrescaler::DIV2; // 140 Mhz + config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz + config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz + config.rcc.voltage_scale = VoltageScale::Scale0; + config.rcc.adc_clock_source = AdcClockSource::PLL2_P; + } + #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] { use embassy_stm32::rcc::*; From 7c5f963d1fd3b49064be8a75975ac5a72ba84356 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 21 Oct 2023 07:32:04 -0500 Subject: [PATCH 046/188] stm32: fix opamp bug in docs build --- embassy-stm32/src/opamp.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index e0fad26e..cb55cbe1 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -101,18 +101,22 @@ 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 - } - } + foreach_adc!( + ($adc, $common_inst:ident, $adc_clock:ident) => { + 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> - { - } + impl<'d, 'p, P: NonInvertingPin> crate::adc::AdcPin + for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> + { + } + }; + ); }; } From 412bcad2d1b989189f529f272683ce95d5107ef0 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 22 Oct 2023 22:39:55 +0200 Subject: [PATCH 047/188] stm32: rename HSI16 -> HSI --- embassy-stm32/Cargo.toml | 4 +-- embassy-stm32/src/rcc/g0.rs | 20 +++++++------- embassy-stm32/src/rcc/g4.rs | 14 +++++----- embassy-stm32/src/rcc/l0l1.rs | 20 +++++++------- embassy-stm32/src/rcc/l4l5.rs | 14 +++++----- embassy-stm32/src/rcc/u5.rs | 29 ++++++++++---------- embassy-stm32/src/rcc/wba.rs | 12 ++++---- embassy-stm32/src/rcc/wl.rs | 8 +++--- examples/stm32g4/src/bin/adc.rs | 2 +- examples/stm32g4/src/bin/pll.rs | 2 +- examples/stm32l0/src/bin/lora_cad.rs | 2 +- examples/stm32l0/src/bin/lora_lorawan.rs | 2 +- examples/stm32l0/src/bin/lora_p2p_receive.rs | 2 +- examples/stm32l0/src/bin/lora_p2p_send.rs | 2 +- examples/stm32l4/src/bin/rng.rs | 2 +- examples/stm32l4/src/bin/usb_serial.rs | 2 +- examples/stm32l5/src/bin/rng.rs | 2 +- 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 | 4 +-- tests/stm32/src/common.rs | 8 +++--- 22 files changed, 79 insertions(+), 78 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index f70e75d4..2d694267 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-296dd041cce492e3b2b7fb3b8a6c05c9a34a90a1" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ee64389697d9234af374a89788aa52bb93d59284" } 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-296dd041cce492e3b2b7fb3b8a6c05c9a34a90a1", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ee64389697d9234af374a89788aa52bb93d59284", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 85ebd32e..45d41a4e 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -1,7 +1,7 @@ use crate::pac::flash::vals::Latency; 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, + Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler, }; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -14,7 +14,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); #[derive(Clone, Copy)] pub enum ClockSrc { HSE(Hertz), - HSI16(HSI16Prescaler), + HSI(HSIPrescaler), PLL(PllConfig), LSI, } @@ -46,9 +46,9 @@ pub struct PllConfig { impl Default for PllConfig { #[inline] fn default() -> PllConfig { - // HSI16 / 1 * 8 / 2 = 64 MHz + // HSI / 1 * 8 / 2 = 64 MHz PllConfig { - source: PllSrc::HSI16, + source: PllSrc::HSI, m: Pllm::DIV1, n: Plln::MUL8, r: Pllr::DIV2, @@ -60,7 +60,7 @@ impl Default for PllConfig { #[derive(Clone, Copy, Eq, PartialEq)] pub enum PllSrc { - HSI16, + HSI, HSE(Hertz), } @@ -77,7 +77,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::HSI16(HSI16Prescaler::DIV1), + mux: ClockSrc::HSI(HSIPrescaler::DIV1), ahb_pre: AHBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1, low_power_run: false, @@ -89,7 +89,7 @@ impl Default for Config { impl PllConfig { pub(crate) fn init(self) -> Hertz { let (src, input_freq) = match self.source { - PllSrc::HSI16 => (vals::Pllsrc::HSI, HSI_FREQ), + PllSrc::HSI => (vals::Pllsrc::HSI, HSI_FREQ), PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq), }; @@ -121,7 +121,7 @@ impl PllConfig { // > 3. Change the desired parameter. // Enable whichever clock source we're using, and wait for it to become ready match self.source { - PllSrc::HSI16 => { + PllSrc::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} } @@ -167,8 +167,8 @@ impl PllConfig { pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw) = match config.mux { - ClockSrc::HSI16(div) => { - // Enable HSI16 + ClockSrc::HSI(div) => { + // Enable HSI RCC.cr().write(|w| { w.set_hsidiv(div); w.set_hsion(true) diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index ba2a5e19..b14a6197 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -18,14 +18,14 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); #[derive(Clone, Copy)] pub enum ClockSrc { HSE(Hertz), - HSI16, + HSI, PLL, } /// PLL clock input source #[derive(Clone, Copy, Debug)] pub enum PllSrc { - HSI16, + HSI, HSE(Hertz), } @@ -33,7 +33,7 @@ impl Into for PllSrc { fn into(self) -> Pllsrc { match self { PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI, + PllSrc::HSI => Pllsrc::HSI, } } } @@ -112,7 +112,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::HSI16, + mux: ClockSrc::HSI, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, @@ -135,7 +135,7 @@ pub struct PllFreq { pub(crate) unsafe fn init(config: Config) { let pll_freq = config.pll.map(|pll_config| { let src_freq = match pll_config.source { - PllSrc::HSI16 => { + PllSrc::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} @@ -196,8 +196,8 @@ pub(crate) unsafe fn init(config: Config) { }); let (sys_clk, sw) = match config.mux { - ClockSrc::HSI16 => { - // Enable HSI16 + ClockSrc::HSI => { + // Enable HSI RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index f10c5962..52e9ccb3 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -18,20 +18,20 @@ pub enum ClockSrc { MSI(MSIRange), PLL(PLLSource, PLLMul, PLLDiv), HSE(Hertz), - HSI16, + HSI, } /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { - HSI16, + HSI, HSE(Hertz), } impl From for Pllsrc { fn from(val: PLLSource) -> Pllsrc { match val { - PLLSource::HSI16 => Pllsrc::HSI, + PLLSource::HSI => Pllsrc::HSI, PLLSource::HSE(_) => Pllsrc::HSE, } } @@ -83,10 +83,10 @@ pub(crate) unsafe fn init(config: Config) { let freq = 32_768 * (1 << (range as u8 + 1)); (Hertz(freq), Sw::MSI) } - ClockSrc::HSI16 => { - // Enable HSI16 - RCC.cr().write(|w| w.set_hsi16on(true)); - while !RCC.cr().read().hsi16rdy() {} + ClockSrc::HSI => { + // Enable HSI + RCC.cr().write(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} (HSI_FREQ, Sw::HSI) } @@ -105,10 +105,10 @@ pub(crate) unsafe fn init(config: Config) { while !RCC.cr().read().hserdy() {} freq } - PLLSource::HSI16 => { + PLLSource::HSI => { // Enable HSI - RCC.cr().write(|w| w.set_hsi16on(true)); - while !RCC.cr().read().hsi16rdy() {} + RCC.cr().write(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} HSI_FREQ } }; diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index e54bfa0e..8cf284d1 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -34,7 +34,7 @@ pub struct Pll { pub struct Config { // base clock sources pub msi: Option, - pub hsi16: bool, + pub hsi: bool, pub hse: Option, #[cfg(not(any(stm32l47x, stm32l48x)))] pub hsi48: bool, @@ -63,7 +63,7 @@ impl Default for Config { fn default() -> Config { Config { hse: None, - hsi16: false, + hsi: false, msi: Some(MSIRange::RANGE4M), mux: ClockSrc::MSI, ahb_pre: AHBPrescaler::DIV1, @@ -127,7 +127,7 @@ pub(crate) unsafe fn init(config: Config) { msirange_to_hertz(range) }); - let hsi16 = config.hsi16.then(|| { + let hsi = config.hsi.then(|| { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} @@ -179,7 +179,7 @@ pub(crate) unsafe fn init(config: Config) { }), }; - let pll_input = PllInput { hse, hsi16, msi }; + let pll_input = PllInput { hse, hsi, msi }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] @@ -187,7 +187,7 @@ pub(crate) unsafe fn init(config: Config) { let sys_clk = match config.mux { ClockSrc::HSE => hse.unwrap(), - ClockSrc::HSI => hsi16.unwrap(), + ClockSrc::HSI => hsi.unwrap(), ClockSrc::MSI => msi.unwrap(), ClockSrc::PLL1_R => pll._r.unwrap(), }; @@ -315,7 +315,7 @@ fn get_equal(mut iter: impl Iterator) -> Result, ()> } struct PllInput { - hsi16: Option, + hsi: Option, hse: Option, msi: Option, } @@ -358,7 +358,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let pll_src = match pll.source { PLLSource::NONE => panic!("must not select PLL source as NONE"), PLLSource::HSE => input.hse, - PLLSource::HSI => input.hsi16, + PLLSource::HSI => input.hsi, PLLSource::MSI => input.msi, }; diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 62bed8be..7664557e 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -10,6 +10,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub use crate::pac::pwr::vals::Vos as VoltageScale; #[derive(Copy, Clone)] +#[allow(non_camel_case_types)] pub enum ClockSrc { /// Use an internal medium speed oscillator (MSIS) as the system clock. MSI(Msirange), @@ -19,9 +20,9 @@ pub enum ClockSrc { /// never exceed 50 MHz. HSE(Hertz), /// Use the 16 MHz internal high speed oscillator as the system clock. - HSI16, + HSI, /// Use PLL1 as the system clock. - PLL1R(PllConfig), + PLL1_R(PllConfig), } impl Default for ClockSrc { @@ -53,10 +54,10 @@ pub struct PllConfig { } impl PllConfig { - /// A configuration for HSI16 / 1 * 10 / 1 = 160 MHz - pub const fn hsi16_160mhz() -> Self { + /// A configuration for HSI / 1 * 10 / 1 = 160 MHz + pub const fn hsi_160mhz() -> Self { PllConfig { - source: PllSrc::HSI16, + source: PllSrc::HSI, m: Pllm::DIV1, n: Plln::MUL10, r: Plldiv::DIV1, @@ -84,7 +85,7 @@ pub enum PllSrc { /// never exceed 50 MHz. HSE(Hertz), /// Use the 16 MHz internal high speed oscillator as the PLL source. - HSI16, + HSI, } impl Into for PllSrc { @@ -92,7 +93,7 @@ impl Into for PllSrc { match self { PllSrc::MSIS(..) => Pllsrc::MSIS, PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI, + PllSrc::HSI => Pllsrc::HSI, } } } @@ -102,8 +103,8 @@ impl Into for ClockSrc { match self { ClockSrc::MSI(..) => Sw::MSIS, ClockSrc::HSE(..) => Sw::HSE, - ClockSrc::HSI16 => Sw::HSI, - ClockSrc::PLL1R(..) => Sw::PLL1_R, + ClockSrc::HSI => Sw::HSI, + ClockSrc::PLL1_R(..) => Sw::PLL1_R, } } } @@ -125,7 +126,7 @@ pub struct Config { } impl Config { - unsafe fn init_hsi16(&self) -> Hertz { + unsafe fn init_hsi(&self) -> Hertz { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} @@ -211,13 +212,13 @@ pub(crate) unsafe fn init(config: Config) { let sys_clk = match config.mux { ClockSrc::MSI(range) => config.init_msis(range), ClockSrc::HSE(freq) => config.init_hse(freq), - ClockSrc::HSI16 => config.init_hsi16(), - ClockSrc::PLL1R(pll) => { + ClockSrc::HSI => config.init_hsi(), + ClockSrc::PLL1_R(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(), + PllSrc::HSI => config.init_hsi(), }; // Calculate the reference clock, which is the source divided by m @@ -292,7 +293,7 @@ pub(crate) unsafe fn init(config: Config) { // Set the prescaler for PWR EPOD w.set_pllmboost(mboost); - // Enable PLL1R output + // Enable PLL1_R output w.set_pllren(true); }); diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index aabf782e..8925d960 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -13,20 +13,20 @@ pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; #[derive(Copy, Clone)] pub enum ClockSrc { HSE(Hertz), - HSI16, + HSI, } #[derive(Clone, Copy, Debug)] pub enum PllSrc { HSE(Hertz), - HSI16, + HSI, } impl Into for PllSrc { fn into(self) -> Pllsrc { match self { PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI, + PllSrc::HSI => Pllsrc::HSI, } } } @@ -35,7 +35,7 @@ impl Into for ClockSrc { fn into(self) -> Sw { match self { ClockSrc::HSE(..) => Sw::HSE, - ClockSrc::HSI16 => Sw::HSI, + ClockSrc::HSI => Sw::HSI, } } } @@ -52,7 +52,7 @@ pub struct Config { impl Default for Config { fn default() -> Self { Self { - mux: ClockSrc::HSI16, + mux: ClockSrc::HSI, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, @@ -70,7 +70,7 @@ pub(crate) unsafe fn init(config: Config) { freq } - ClockSrc::HSI16 => { + ClockSrc::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 401486bb..4d68b55c 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -19,7 +19,7 @@ pub const HSE_FREQ: Hertz = Hertz(32_000_000); pub enum ClockSrc { MSI(MSIRange), HSE, - HSI16, + HSI, } /// Clocks configutation @@ -50,7 +50,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::HSI, VoltageScale::RANGE2), + ClockSrc::HSI => (HSI_FREQ, Sw::HSI, VoltageScale::RANGE2), ClockSrc::HSE => (HSE_FREQ, Sw::HSE, VoltageScale::RANGE1), ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), }; @@ -97,8 +97,8 @@ pub(crate) unsafe fn init(config: Config) { while FLASH.acr().read().latency() != ws {} match config.mux { - ClockSrc::HSI16 => { - // Enable HSI16 + ClockSrc::HSI => { + // Enable HSI RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} } diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index db7f6ecb..f0573384 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.pll = Some(Pll { - source: PllSrc::HSI16, + source: PllSrc::HSI, prediv_m: PllM::DIV4, mul_n: PllN::MUL85, div_p: None, diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs index 43242647..90c3f8dc 100644 --- a/examples/stm32g4/src/bin/pll.rs +++ b/examples/stm32g4/src/bin/pll.rs @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.pll = Some(Pll { - source: PllSrc::HSI16, + source: PllSrc::HSI, prediv_m: PllM::DIV4, mul_n: PllN::MUL85, div_p: None, diff --git a/examples/stm32l0/src/bin/lora_cad.rs b/examples/stm32l0/src/bin/lora_cad.rs index 987cdba0..5c2b331c 100644 --- a/examples/stm32l0/src/bin/lora_cad.rs +++ b/examples/stm32l0/src/bin/lora_cad.rs @@ -23,7 +23,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; config.rcc.enable_hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l0/src/bin/lora_lorawan.rs b/examples/stm32l0/src/bin/lora_lorawan.rs index 7a93737e..d44d03d3 100644 --- a/examples/stm32l0/src/bin/lora_lorawan.rs +++ b/examples/stm32l0/src/bin/lora_lorawan.rs @@ -33,7 +33,7 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; config.rcc.enable_hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l0/src/bin/lora_p2p_receive.rs b/examples/stm32l0/src/bin/lora_p2p_receive.rs index 06e2744a..0478ce1e 100644 --- a/examples/stm32l0/src/bin/lora_p2p_receive.rs +++ b/examples/stm32l0/src/bin/lora_p2p_receive.rs @@ -23,7 +23,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; config.rcc.enable_hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l0/src/bin/lora_p2p_send.rs b/examples/stm32l0/src/bin/lora_p2p_send.rs index 23cc1c6f..88a836d3 100644 --- a/examples/stm32l0/src/bin/lora_p2p_send.rs +++ b/examples/stm32l0/src/bin/lora_p2p_send.rs @@ -23,7 +23,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; config.rcc.enable_hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index d8a4e825..553d11c0 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs @@ -17,7 +17,7 @@ bind_interrupts!(struct Irqs { async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.mux = ClockSrc::PLL1_R; - config.rcc.hsi16 = true; + config.rcc.hsi = true; config.rcc.pll = Some(Pll { source: PLLSource::HSI, prediv: PllPreDiv::DIV1, diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 28247654..15c6f198 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.hsi48 = true; config.rcc.mux = ClockSrc::PLL1_R; - config.rcc.hsi16 = true; + config.rcc.hsi = true; config.rcc.pll = Some(Pll { source: PLLSource::HSI, prediv: PllPreDiv::DIV1, diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index b57f438f..b9d4cd25 100644 --- a/examples/stm32l5/src/bin/rng.rs +++ b/examples/stm32l5/src/bin/rng.rs @@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.hsi16 = true; + config.rcc.hsi = true; config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 64Mhz clock (16 / 1 * 8 / 2) diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index bbe44642..f5b3ca34 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.hsi16 = true; + config.rcc.hsi = true; config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index 44e29ee9..bec3d5e4 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.hsi16 = true; + config.rcc.hsi = true; config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 612b891a..ff1154f9 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.hsi16 = true; + config.rcc.hsi = true; config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index 9b2adb0a..f59f623b 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -23,8 +23,8 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL1R(PllConfig { - source: PllSrc::HSI16, + config.rcc.mux = ClockSrc::PLL1_R(PllConfig { + source: PllSrc::HSI, m: Pllm::DIV2, n: Plln::MUL10, r: Plldiv::DIV1, diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index a0ccfe3a..693fd067 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -365,7 +365,7 @@ pub fn config() -> Config { { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::PLL1_R; - config.rcc.hsi16 = true; + config.rcc.hsi = true; config.rcc.pll = Some(Pll { source: PLLSource::HSI, prediv: PllPreDiv::DIV1, @@ -388,7 +388,7 @@ pub fn config() -> Config { #[cfg(any(feature = "stm32l552ze"))] { use embassy_stm32::rcc::*; - config.rcc.hsi16 = true; + config.rcc.hsi = true; config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 110Mhz clock (16 / 4 * 55 / 2) @@ -412,7 +412,7 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::PLL( // 32Mhz clock (16 * 4 / 2) - PLLSource::HSI16, + PLLSource::HSI, PLLMul::MUL4, PLLDiv::DIV2, ); @@ -423,7 +423,7 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::PLL( // 32Mhz clock (16 * 4 / 2) - PLLSource::HSI16, + PLLSource::HSI, PLLMul::MUL4, PLLDiv::DIV2, ); From a84ad741a48dfce29b7f764e0cfb6877eba9a027 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 22 Oct 2023 22:45:11 +0200 Subject: [PATCH 048/188] stm32/tests: add stm32wba52cg, stm32u5a9zj --- ci.sh | 7 +++++++ tests/stm32/Cargo.toml | 2 ++ tests/stm32/src/common.rs | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index efe98c7a..ffd36a45 100755 --- a/ci.sh +++ b/ci.sh @@ -197,6 +197,8 @@ cargo batch \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55rg --out-dir out/tests/stm32wb55rg \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h563zi --out-dir out/tests/stm32h563zi \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585ai --out-dir out/tests/stm32u585ai \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u5a5zj --out-dir out/tests/stm32u5a5zj \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wba52cg --out-dir out/tests/stm32wba52cg \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l073rz --out-dir out/tests/stm32l073rz \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l152re --out-dir out/tests/stm32l152re \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4a6zg --out-dir out/tests/stm32l4a6zg \ @@ -215,8 +217,13 @@ cargo batch \ rm out/tests/stm32wb55rg/wpan_mac rm out/tests/stm32wb55rg/wpan_ble + +# unstable, I think it's running out of RAM? rm out/tests/stm32f207zg/eth +# doesn't work. Wire in D0-D1 might be bad, or the special IOVDD2 PGx pins. +rm out/tests/stm32u5a5zj/{gpio,usart*} + if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests exit diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 48598ec2..c6a50e2c 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -17,6 +17,8 @@ stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"] stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng"] stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng"] +stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng"] +stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng"] stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma", "rng"] stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng"] diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 693fd067..0a70e6a7 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -24,6 +24,8 @@ teleprobe_meta::target!(b"nucleo-stm32h753zi"); teleprobe_meta::target!(b"nucleo-stm32h7a3zi"); #[cfg(feature = "stm32u585ai")] teleprobe_meta::target!(b"iot-stm32u585ai"); +#[cfg(feature = "stm32u5a5zj")] +teleprobe_meta::target!(b"nucleo-stm32u5a5zj"); #[cfg(feature = "stm32h563zi")] teleprobe_meta::target!(b"nucleo-stm32h563zi"); #[cfg(feature = "stm32c031c6")] @@ -48,6 +50,8 @@ teleprobe_meta::target!(b"nucleo-stm32f303ze"); teleprobe_meta::target!(b"nucleo-stm32l496zg"); #[cfg(feature = "stm32wl55jc")] teleprobe_meta::target!(b"nucleo-stm32wl55jc"); +#[cfg(feature = "stm32wba52cg")] +teleprobe_meta::target!(b"nucleo-stm32wba52cg"); macro_rules! define_peris { ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { @@ -127,6 +131,12 @@ define_peris!( SPI = SPI1, SPI_SCK = PE13, SPI_MOSI = PE15, SPI_MISO = PE14, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler;}, ); +#[cfg(feature = "stm32u5a5zj")] +define_peris!( + UART = LPUART1, UART_TX = PG7, UART_RX = PG8, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, + @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler;}, +); #[cfg(feature = "stm32h563zi")] define_peris!( UART = LPUART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, @@ -199,8 +209,21 @@ define_peris!( 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;}, ); +#[cfg(feature = "stm32wba52cg")] +define_peris!( + UART = LPUART1, UART_TX = PB5, UART_RX = PA10, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, + SPI = SPI1, SPI_SCK = PB4, SPI_MOSI = PA15, SPI_MISO = PB3, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, + @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler;}, +); pub fn config() -> Config { + // Setting this bit is mandatory to use PG[15:2]. + #[cfg(feature = "stm32u5a5zj")] + embassy_stm32::pac::PWR.svmcr().modify(|w| { + w.set_io2sv(true); + w.set_io2vmen(true); + }); + #[allow(unused_mut)] let mut config = Config::default(); @@ -401,12 +424,22 @@ pub fn config() -> Config { }); } - #[cfg(feature = "stm32u585ai")] + #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::MSI(Msirange::RANGE_48MHZ); } + #[cfg(feature = "stm32wba52cg")] + { + use embassy_stm32::rcc::*; + config.rcc.mux = ClockSrc::HSI; + + embassy_stm32::pac::RCC.ccipr2().write(|w| { + w.set_rngsel(embassy_stm32::pac::rcc::vals::Rngsel::HSI); + }); + } + #[cfg(feature = "stm32l073rz")] { use embassy_stm32::rcc::*; From b9e13cb5d1ca3e85a02b2a37b7ee14f73663b1bd Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 23 Oct 2023 00:28:54 +0200 Subject: [PATCH 049/188] stm32/rcc: merge wl into l4/l5. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/ipcc.rs | 5 +- embassy-stm32/src/rcc/l4l5.rs | 153 ++++++++++----- embassy-stm32/src/rcc/mod.rs | 3 +- embassy-stm32/src/rcc/u5.rs | 2 +- embassy-stm32/src/rcc/wl.rs | 184 ------------------ examples/stm32l4/src/bin/rtc.rs | 29 +-- .../src/bin/spe_adin1110_http_server.rs | 34 ++-- examples/stm32wl/src/bin/lora_lorawan.rs | 22 ++- examples/stm32wl/src/bin/random.rs | 23 ++- tests/stm32/src/common.rs | 15 +- 11 files changed, 198 insertions(+), 276 deletions(-) delete mode 100644 embassy-stm32/src/rcc/wl.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 2d694267..568a7eeb 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-ee64389697d9234af374a89788aa52bb93d59284" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4ddcb77c9d213d11eebb048f40e112bc54163cdc" } 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-ee64389697d9234af374a89788aa52bb93d59284", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4ddcb77c9d213d11eebb048f40e112bc54163cdc", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 1b1e182f..4006dee1 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -5,6 +5,7 @@ use core::task::Poll; use self::sealed::Instance; use crate::interrupt; use crate::interrupt::typelevel::Interrupt; +use crate::pac::rcc::vals::{Lptim1sel, Lptim2sel}; use crate::peripherals::IPCC; use crate::rcc::sealed::RccPeripheral; @@ -273,7 +274,7 @@ fn _configure_pwr() { // set LPTIM1 & LPTIM2 clock source rcc.ccipr().modify(|w| { - w.set_lptim1sel(0b00); // PCLK - w.set_lptim2sel(0b00); // PCLK + w.set_lptim1sel(Lptim1sel::PCLK1); + w.set_lptim2sel(Lptim2sel::PCLK1); }); } diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 8cf284d1..b5696227 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -1,8 +1,10 @@ use crate::pac::rcc::regs::Cfgr; +#[cfg(not(stm32wl))] +pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; use crate::pac::rcc::vals::Msirgsel; pub use crate::pac::rcc::vals::{ - Clk48sel as Clk48Src, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, - Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, + Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, + Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, }; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -11,6 +13,22 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); +#[derive(Clone, Copy, Eq, PartialEq)] +pub enum HseMode { + /// crystal/ceramic oscillator (HSEBYP=0) + Oscillator, + /// external analog clock (low swing) (HSEBYP=1) + Bypass, +} + +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct Hse { + /// HSE frequency. + pub freq: Hertz, + /// HSE mode. + pub mode: HseMode, +} + #[derive(Clone, Copy)] pub struct Pll { /// PLL source @@ -35,12 +53,13 @@ pub struct Config { // base clock sources pub msi: Option, pub hsi: bool, - pub hse: Option, - #[cfg(not(any(stm32l47x, stm32l48x)))] + pub hse: Option, + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] pub hsi48: bool, // pll pub pll: Option, + #[cfg(any(stm32l4, stm32l5))] pub pllsai1: Option, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pub pllsai2: Option, @@ -50,8 +69,11 @@ pub struct Config { pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, + #[cfg(stm32wl)] + pub shared_ahb_pre: AHBPrescaler, // muxes + #[cfg(not(stm32wl))] pub clk48_src: Clk48Src, // low speed LSI/LSE/RTC @@ -69,12 +91,16 @@ impl Default for Config { ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, + #[cfg(stm32wl)] + shared_ahb_pre: AHBPrescaler::DIV1, pll: None, + #[cfg(any(stm32l4, stm32l5))] pllsai1: None, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pllsai2: None, - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] hsi48: true, + #[cfg(not(stm32wl))] clk48_src: Clk48Src::HSI48, ls: Default::default(), } @@ -111,7 +137,7 @@ pub(crate) unsafe fn init(config: Config) { let msi = config.msi.map(|range| { // Enable MSI - RCC.cr().write(|w| { + RCC.cr().modify(|w| { w.set_msirange(range); w.set_msirgsel(Msirgsel::CR); w.set_msion(true); @@ -128,20 +154,26 @@ pub(crate) unsafe fn init(config: Config) { }); let hsi = config.hsi.then(|| { - RCC.cr().write(|w| w.set_hsion(true)); + RCC.cr().modify(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} HSI_FREQ }); - let hse = config.hse.map(|freq| { - RCC.cr().write(|w| w.set_hseon(true)); + let hse = config.hse.map(|hse| { + RCC.cr().modify(|w| { + #[cfg(stm32wl)] + w.set_hsebyppwr(hse.mode == HseMode::Bypass); + #[cfg(not(stm32wl))] + w.set_hsebyp(hse.mode == HseMode::Bypass); + w.set_hseon(true); + }); while !RCC.cr().read().hserdy() {} - freq + hse.freq }); - #[cfg(not(any(stm32l47x, stm32l48x)))] + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] let hsi48 = config.hsi48.then(|| { RCC.crrcr().modify(|w| w.set_hsi48on(true)); while !RCC.crrcr().read().hsi48rdy() {} @@ -153,6 +185,7 @@ pub(crate) unsafe fn init(config: Config) { let _plls = [ &config.pll, + #[cfg(any(stm32l4, stm32l5))] &config.pllsai1, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] &config.pllsai2, @@ -169,8 +202,8 @@ pub(crate) unsafe fn init(config: Config) { }), }; - // L4+ has shared PLLSRC, check it's equal in all PLLs. - #[cfg(any(rcc_l4plus))] + // L4+, WL has shared PLLSRC, check it's equal in all PLLs. + #[cfg(any(rcc_l4plus, stm32wl))] match get_equal(_plls.into_iter().flatten().map(|p| p.source)) { Err(()) => panic!("Source must be equal across all enabled PLLs."), Ok(None) => {} @@ -181,6 +214,7 @@ pub(crate) unsafe fn init(config: Config) { let pll_input = PllInput { hse, hsi, msi }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); + #[cfg(any(stm32l4, stm32l5))] let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); @@ -196,6 +230,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); #[cfg(stm32l5)] RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); + #[cfg(not(stm32wl))] let _clk48 = match config.clk48_src { Clk48Src::HSI48 => hsi48, Clk48Src::MSI => msi, @@ -208,38 +243,6 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(all(stm32l4, not(rcc_l4plus)))] assert!(sys_clk.0 <= 80_000_000); - // Set flash wait states - #[cfg(stm32l4)] - FLASH.acr().modify(|w| { - 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, - }) - }); - // VCORE Range 0 (performance), others TODO - #[cfg(stm32l5)] - FLASH.acr().modify(|w| { - w.set_latency(match sys_clk.0 { - 0..=20_000_000 => 0, - 0..=40_000_000 => 1, - 0..=60_000_000 => 2, - 0..=80_000_000 => 3, - 0..=100_000_000 => 4, - _ => 5, - }) - }); - - RCC.cfgr().modify(|w| { - w.set_sw(config.mux); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - while RCC.cfgr().read().sws() != config.mux {} - let ahb_freq = sys_clk / config.ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { @@ -258,15 +261,69 @@ pub(crate) unsafe fn init(config: Config) { } }; + #[cfg(stm32wl)] + let ahb3_freq = sys_clk / config.shared_ahb_pre; + + // Set flash wait states + #[cfg(stm32l4)] + let 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, + }; + #[cfg(stm32l5)] + let latency = match sys_clk.0 { + // VCORE Range 0 (performance), others TODO + 0..=20_000_000 => 0, + 0..=40_000_000 => 1, + 0..=60_000_000 => 2, + 0..=80_000_000 => 3, + 0..=100_000_000 => 4, + _ => 5, + }; + #[cfg(stm32wl)] + let latency = match ahb3_freq.0 { + // VOS RANGE1, others TODO. + ..=18_000_000 => 0, + ..=36_000_000 => 1, + _ => 2, + }; + + FLASH.acr().modify(|w| w.set_latency(latency)); + while FLASH.acr().read().latency() != latency {} + + RCC.cfgr().modify(|w| { + w.set_sw(config.mux); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); + }); + while RCC.cfgr().read().sws() != config.mux {} + + #[cfg(stm32wl)] + { + RCC.extcfgr().modify(|w| { + w.set_shdhpre(config.shared_ahb_pre); + }); + while !RCC.extcfgr().read().shdhpref() {} + } + set_freqs(Clocks { sys: sys_clk, hclk1: ahb_freq, hclk2: ahb_freq, + #[cfg(not(stm32wl))] hclk3: ahb_freq, pclk1: apb1_freq, pclk2: apb2_freq, pclk1_tim: apb1_tim_freq, pclk2_tim: apb2_tim_freq, + #[cfg(stm32wl)] + hclk3: ahb3_freq, + #[cfg(stm32wl)] + pclk3: ahb3_freq, #[cfg(rcc_l4)] hsi: None, #[cfg(rcc_l4)] @@ -330,6 +387,7 @@ struct PllOutput { #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, + #[cfg(any(stm32l4, stm32l5))] Pllsai1, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] Pllsai2, @@ -342,6 +400,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll RCC.cr().modify(|w| w.set_pllon(false)); while RCC.cr().read().pllrdy() {} } + #[cfg(any(stm32l4, stm32l5))] PllInstance::Pllsai1 => { RCC.cr().modify(|w| w.set_pllsai1on(false)); while RCC.cr().read().pllsai1rdy() {} @@ -356,7 +415,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let Some(pll) = config else { return PllOutput::default() }; let pll_src = match pll.source { - PLLSource::NONE => panic!("must not select PLL source as NONE"), + PLLSource::DISABLE => panic!("must not select PLL source as NONE"), PLLSource::HSE => input.hse, PLLSource::HSI => input.hsi, PLLSource::MSI => input.msi, @@ -400,6 +459,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll w.set_pllsrc(pll.source); write_fields!(w); }), + #[cfg(any(stm32l4, stm32l5))] PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { #[cfg(any(rcc_l4plus, stm32l5))] w.set_pllm(pll.prediv); @@ -423,6 +483,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll RCC.cr().modify(|w| w.set_pllon(true)); while !RCC.cr().read().pllrdy() {} } + #[cfg(any(stm32l4, stm32l5))] PllInstance::Pllsai1 => { RCC.cr().modify(|w| w.set_pllsai1on(true)); while !RCC.cr().read().pllsai1rdy() {} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 49174b27..78d54f80 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -19,11 +19,10 @@ pub use mco::*; #[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(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] -#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5), path = "l4l5.rs")] +#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle), path = "l4l5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wb, path = "wb.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] -#[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] mod _version; #[cfg(feature = "low-power")] use core::sync::atomic::{AtomicU32, Ordering}; diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 7664557e..2bbacbbd 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -170,7 +170,7 @@ impl Config { RCC.icscr1().modify(|w| { w.set_msisrange(range); - w.set_msirgsel(Msirgsel::RCC_ICSCR1); + w.set_msirgsel(Msirgsel::ICSCR1); }); RCC.cr().write(|w| { w.set_msipllen(false); diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs deleted file mode 100644 index 4d68b55c..00000000 --- a/embassy-stm32/src/rcc/wl.rs +++ /dev/null @@ -1,184 +0,0 @@ -pub use crate::pac::pwr::vals::Vos as VoltageScale; -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::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_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), - HSE, - HSI, -} - -/// Clocks configutation -pub struct Config { - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub shd_ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - pub adc_clock_source: AdcClockSource, - pub ls: super::LsConfig, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - mux: ClockSrc::MSI(MSIRange::RANGE4M), - ahb_pre: AHBPrescaler::DIV1, - shd_ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - adc_clock_source: AdcClockSource::HSI, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - let (sys_clk, sw, vos) = match config.mux { - ClockSrc::HSI => (HSI_FREQ, Sw::HSI, VoltageScale::RANGE2), - ClockSrc::HSE => (HSE_FREQ, Sw::HSE, VoltageScale::RANGE1), - ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), - }; - - 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 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) - } - }; - - // Adjust flash latency - let flash_clk_src_freq = shd_ahb_freq; - let ws = match vos { - 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.0 { - 0..=6_000_000 => 0b000, - 6_000_001..=12_000_000 => 0b001, - _ => 0b010, - }, - _ => unreachable!(), - }; - - FLASH.acr().modify(|w| { - w.set_latency(ws); - }); - - while FLASH.acr().read().latency() != ws {} - - match config.mux { - ClockSrc::HSI => { - // Enable HSI - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - } - ClockSrc::HSE => { - // Enable HSE - RCC.cr().write(|w| { - w.set_hsebyppwr(true); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - } - ClockSrc::MSI(range) => { - let cr = RCC.cr().read(); - assert!(!cr.msion() || cr.msirdy()); - RCC.cr().write(|w| { - w.set_msirgsel(true); - w.set_msirange(range); - w.set_msion(true); - - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(config.ls.lse.is_some()); - }); - while !RCC.cr().read().msirdy() {} - } - } - - RCC.extcfgr().modify(|w| { - 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); - w.set_ppre2(config.apb2_pre); - }); - - // ADC clock MUX - RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); - - // TODO: switch voltage range - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: sys_clk, - hclk1: ahb_freq, - hclk2: ahb_freq, - hclk3: shd_ahb_freq, - pclk1: apb1_freq, - pclk2: apb2_freq, - pclk3: shd_ahb_freq, - pclk1_tim: apb1_tim_freq, - pclk2_tim: apb2_tim_freq, - rtc, - }); -} - -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/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index fec0a349..69527c9a 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -5,7 +5,6 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; @@ -15,17 +14,23 @@ use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL1_R; - config.rcc.hse = Some(Hertz::mhz(8)); - config.rcc.pll = Some(Pll { - source: PLLSource::HSE, - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL20, - divp: None, - divq: None, - divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) - }); - config.rcc.ls = LsConfig::default_lse(); + { + use embassy_stm32::rcc::*; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.hse = Some(Hse { + freq: Hertz::mhz(8), + mode: HseMode::Oscillator, + }); + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) + }); + config.rcc.ls = LsConfig::default_lse(); + } let p = 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 3c9d2cfc..f76b504a 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -48,7 +48,6 @@ 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, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; use hal::spi::{Config as SPI_Config, Spi}; use hal::time::Hertz; @@ -74,20 +73,25 @@ async fn main(spawner: Spawner) { defmt::println!("Start main()"); let mut config = embassy_stm32::Config::default(); - - // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) - // 80MHz highest frequency for flash 0 wait. - config.rcc.mux = ClockSrc::PLL1_R; - config.rcc.hse = Some(Hertz::mhz(8)); - config.rcc.pll = Some(Pll { - source: PLLSource::HSE, - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL20, - divp: None, - divq: None, - divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) - }); - config.rcc.hsi48 = true; // needed for rng + { + use embassy_stm32::rcc::*; + // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) + // 80MHz highest frequency for flash 0 wait. + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.hse = Some(Hse { + freq: Hertz::mhz(8), + mode: HseMode::Oscillator, + }); + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) + }); + config.rcc.hsi48 = true; // needed for rng + } 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 8c789afb..e26c274a 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -12,7 +12,8 @@ use embassy_lora::LoraTimer; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::rng::{self, Rng}; use embassy_stm32::spi::Spi; -use embassy_stm32::{bind_interrupts, pac, peripherals}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, peripherals}; use embassy_time::Delay; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; @@ -33,11 +34,24 @@ 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::HSE; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } let p = embassy_stm32::init(config); - pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)); - let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); // Set CTRL1 and CTRL3 for high-power transmission, while CTRL2 acts as an RF switch between tx and rx diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 70676c70..2cf7ef9d 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -4,9 +4,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, MSIRange}; use embassy_stm32::rng::{self, Rng}; -use embassy_stm32::{bind_interrupts, pac, peripherals}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, peripherals}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs{ @@ -16,11 +16,24 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = ClockSrc::MSI(MSIRange::RANGE32M); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } let p = embassy_stm32::init(config); - pac::RCC.ccipr().modify(|w| w.set_rngsel(0b11)); // msi - info!("Hello World!"); let mut rng = Rng::new(p.RNG, Irqs); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 0a70e6a7..cb173815 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -402,9 +402,18 @@ pub fn config() -> Config { #[cfg(feature = "stm32wl55jc")] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::MSI(MSIRange::RANGE32M); - embassy_stm32::pac::RCC.ccipr().modify(|w| { - w.set_rngsel(0b11); // msi + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) }); } From 18c9bcd44aa6fdb63d7fdf8b82fbb167a1b63e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20G=C3=B3rski?= Date: Mon, 23 Oct 2023 10:56:55 +0200 Subject: [PATCH 050/188] net: Reset DHCP socket when the link up is detected Previously, because DHCP DISCOVER is sent before the link is established, socket has to timeout first. Which takes extra 10 s. Now if the state of the link changed to up, socket is explicitly reset so the DISCOVER is repeated much earlier and DHCP configuration is acquired much faster. --- embassy-net/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index c41faee2..79896287 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -860,6 +860,9 @@ impl Inner { let socket = s.sockets.get_mut::(dhcp_handle); if self.link_up { + if old_link_up != self.link_up { + socket.reset(); + } match socket.poll() { None => {} Some(dhcpv4::Event::Deconfigured) => { From 0ef1cb29f70c71d3c85f5b8b4ad3c7ce60babba8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 23 Oct 2023 01:09:36 +0200 Subject: [PATCH 051/188] stm32/rcc: merge wb into l4/l5. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/l4l5.rs | 101 ++++++-- embassy-stm32/src/rcc/mod.rs | 3 +- embassy-stm32/src/rcc/wb.rs | 258 ------------------- examples/stm32wl/src/bin/lora_lorawan.rs | 1 + examples/stm32wl/src/bin/lora_p2p_receive.rs | 19 +- examples/stm32wl/src/bin/lora_p2p_send.rs | 19 +- examples/stm32wl/src/bin/random.rs | 1 + examples/stm32wl/src/bin/rtc.rs | 26 +- tests/stm32/src/common.rs | 6 + 10 files changed, 146 insertions(+), 292 deletions(-) delete mode 100644 embassy-stm32/src/rcc/wb.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 568a7eeb..99288340 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-4ddcb77c9d213d11eebb048f40e112bc54163cdc" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9" } 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-4ddcb77c9d213d11eebb048f40e112bc54163cdc", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index b5696227..50128d38 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -1,7 +1,8 @@ use crate::pac::rcc::regs::Cfgr; -#[cfg(not(stm32wl))] +#[cfg(any(stm32l4, stm32l5, stm32wb))] pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; -use crate::pac::rcc::vals::Msirgsel; +#[cfg(any(stm32wb, stm32wl))] +pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; 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, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, @@ -27,6 +28,9 @@ pub struct Hse { pub freq: Hertz, /// HSE mode. pub mode: HseMode, + /// HSE prescaler + #[cfg(any(stm32wb, stm32wl))] + pub prescaler: HsePrescaler, } #[derive(Clone, Copy)] @@ -54,12 +58,12 @@ pub struct Config { pub msi: Option, pub hsi: bool, pub hse: Option, - #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] pub hsi48: bool, // pll pub pll: Option, - #[cfg(any(stm32l4, stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] pub pllsai1: Option, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pub pllsai2: Option, @@ -69,11 +73,13 @@ pub struct Config { pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, - #[cfg(stm32wl)] + #[cfg(any(stm32wl5x, stm32wb))] + pub core2_ahb_pre: AHBPrescaler, + #[cfg(any(stm32wl, stm32wb))] pub shared_ahb_pre: AHBPrescaler, // muxes - #[cfg(not(stm32wl))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] pub clk48_src: Clk48Src, // low speed LSI/LSE/RTC @@ -91,28 +97,63 @@ impl Default for Config { ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, - #[cfg(stm32wl)] + #[cfg(any(stm32wl5x, stm32wb))] + core2_ahb_pre: AHBPrescaler::DIV1, + #[cfg(any(stm32wl, stm32wb))] shared_ahb_pre: AHBPrescaler::DIV1, pll: None, - #[cfg(any(stm32l4, stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] pllsai1: None, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pllsai2: None, - #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] hsi48: true, - #[cfg(not(stm32wl))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] clk48_src: Clk48Src::HSI48, ls: Default::default(), } } } +#[cfg(stm32wb)] +pub const WPAN_DEFAULT: Config = Config { + hse: Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Oscillator, + prescaler: HsePrescaler::DIV1, + }), + mux: ClockSrc::PLL1_R, + hsi48: true, + msi: None, + hsi: false, + clk48_src: Clk48Src::PLL1_Q, + + ls: super::LsConfig::default_lse(), + + pll: Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL12, + divp: Some(PllPDiv::DIV3), // 32 / 2 * 12 / 3 = 64Mhz + divq: Some(PllQDiv::DIV4), // 32 / 2 * 12 / 4 = 48Mhz + divr: Some(PllRDiv::DIV3), // 32 / 2 * 12 / 3 = 64Mhz + }), + pllsai1: None, + + ahb_pre: AHBPrescaler::DIV1, + core2_ahb_pre: AHBPrescaler::DIV2, + shared_ahb_pre: AHBPrescaler::DIV1, + apb1_pre: APBPrescaler::DIV1, + apb2_pre: APBPrescaler::DIV1, +}; + 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(Msirgsel::CR); + #[cfg(not(stm32wb))] + w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); w.set_msirange(MSIRange::RANGE4M); w.set_msipllen(false); w.set_msion(true) @@ -138,8 +179,9 @@ pub(crate) unsafe fn init(config: Config) { let msi = config.msi.map(|range| { // Enable MSI RCC.cr().modify(|w| { + #[cfg(not(stm32wb))] + w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); w.set_msirange(range); - w.set_msirgsel(Msirgsel::CR); w.set_msion(true); // If LSE is enabled, enable calibration of MSI @@ -173,7 +215,7 @@ pub(crate) unsafe fn init(config: Config) { hse.freq }); - #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] let hsi48 = config.hsi48.then(|| { RCC.crrcr().modify(|w| w.set_hsi48on(true)); while !RCC.crrcr().read().hsi48rdy() {} @@ -185,7 +227,7 @@ pub(crate) unsafe fn init(config: Config) { let _plls = [ &config.pll, - #[cfg(any(stm32l4, stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] &config.pllsai1, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] &config.pllsai2, @@ -214,7 +256,7 @@ pub(crate) unsafe fn init(config: Config) { let pll_input = PllInput { hse, hsi, msi }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); - #[cfg(any(stm32l4, stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); @@ -230,7 +272,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); #[cfg(stm32l5)] RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); - #[cfg(not(stm32wl))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] let _clk48 = match config.clk48_src { Clk48Src::HSI48 => hsi48, Clk48Src::MSI => msi, @@ -261,7 +303,9 @@ pub(crate) unsafe fn init(config: Config) { } }; - #[cfg(stm32wl)] + #[cfg(any(stm32wl5x, stm32wb))] + let _ahb2_freq = sys_clk / config.core2_ahb_pre; + #[cfg(any(stm32wl, stm32wb))] let ahb3_freq = sys_clk / config.shared_ahb_pre; // Set flash wait states @@ -290,6 +334,15 @@ pub(crate) unsafe fn init(config: Config) { ..=36_000_000 => 1, _ => 2, }; + #[cfg(stm32wb)] + let latency = match ahb3_freq.0 { + // VOS RANGE1, others TODO. + ..=18_000_000 => 0, + ..=36_000_000 => 1, + ..=54_000_000 => 2, + ..=64_000_000 => 3, + _ => 4, + }; FLASH.acr().modify(|w| w.set_latency(latency)); while FLASH.acr().read().latency() != latency {} @@ -302,12 +355,16 @@ pub(crate) unsafe fn init(config: Config) { }); while RCC.cfgr().read().sws() != config.mux {} - #[cfg(stm32wl)] + #[cfg(any(stm32wl, stm32wb))] { RCC.extcfgr().modify(|w| { w.set_shdhpre(config.shared_ahb_pre); + #[cfg(any(stm32wl5x, stm32wb))] + w.set_c2hpre(config.core2_ahb_pre); }); while !RCC.extcfgr().read().shdhpref() {} + #[cfg(any(stm32wl5x, stm32wb))] + while !RCC.extcfgr().read().c2hpref() {} } set_freqs(Clocks { @@ -387,7 +444,7 @@ struct PllOutput { #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, - #[cfg(any(stm32l4, stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] Pllsai1, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] Pllsai2, @@ -400,7 +457,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll RCC.cr().modify(|w| w.set_pllon(false)); while RCC.cr().read().pllrdy() {} } - #[cfg(any(stm32l4, stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] PllInstance::Pllsai1 => { RCC.cr().modify(|w| w.set_pllsai1on(false)); while RCC.cr().read().pllsai1rdy() {} @@ -459,7 +516,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll w.set_pllsrc(pll.source); write_fields!(w); }), - #[cfg(any(stm32l4, stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { #[cfg(any(rcc_l4plus, stm32l5))] w.set_pllm(pll.prediv); @@ -483,7 +540,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll RCC.cr().modify(|w| w.set_pllon(true)); while !RCC.cr().read().pllrdy() {} } - #[cfg(any(stm32l4, stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb))] PllInstance::Pllsai1 => { RCC.cr().modify(|w| w.set_pllsai1on(true)); while !RCC.cr().read().pllsai1rdy() {} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 78d54f80..4f3d5b98 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -19,9 +19,8 @@ pub use mco::*; #[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(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] -#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle), path = "l4l5.rs")] +#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle, rcc_wb), path = "l4l5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] -#[cfg_attr(rcc_wb, path = "wb.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] mod _version; #[cfg(feature = "low-power")] diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs deleted file mode 100644 index 2d0b2711..00000000 --- a/embassy-stm32/src/rcc/wb.rs +++ /dev/null @@ -1,258 +0,0 @@ -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::{set_freqs, Clocks}; -use crate::time::{mhz, Hertz}; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -pub struct Hse { - pub prediv: HsePrescaler, - - pub frequency: Hertz, -} - -pub struct PllMux { - /// Source clock selection. - pub source: PllSource, - - /// PLL pre-divider (DIVM). Must be between 1 and 63. - pub prediv: Pllm, -} - -pub struct Pll { - /// PLL multiplication factor. Must be between 4 and 512. - 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, - /// 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, -} - -/// Clocks configutation -pub struct Config { - pub hse: Option, - pub sys: Sysclk, - pub mux: Option, - pub hsi48: bool, - - pub pll: Option, - pub pllsai: Option, - - pub ahb1_pre: AHBPrescaler, - pub ahb2_pre: AHBPrescaler, - pub ahb3_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - - pub ls: super::LsConfig, -} - -pub const WPAN_DEFAULT: Config = Config { - hse: Some(Hse { - frequency: mhz(32), - prediv: HsePrescaler::DIV1, - }), - sys: Sysclk::PLL1_R, - mux: Some(PllMux { - source: PllSource::HSE, - prediv: Pllm::DIV2, - }), - hsi48: true, - - ls: super::LsConfig::default_lse(), - - pll: Some(Pll { - mul: Plln::MUL12, - divp: Some(Pllp::DIV3), - divq: Some(Pllq::DIV4), - divr: Some(Pllr::DIV3), - }), - pllsai: None, - - ahb1_pre: AHBPrescaler::DIV1, - ahb2_pre: AHBPrescaler::DIV2, - ahb3_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, -}; - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - sys: Sysclk::HSI, - hse: None, - mux: None, - pll: None, - pllsai: None, - hsi48: true, - - ls: Default::default(), - - ahb1_pre: AHBPrescaler::DIV1, - ahb2_pre: AHBPrescaler::DIV1, - ahb3_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - } - } -} - -#[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| { - (match pll_mux.source { - PllSource::HSE => hse_clk.unwrap(), - PllSource::HSI => HSI_FREQ, - _ => unreachable!(), - } / pll_mux.prediv) - }); - - let (pll_r, _pll_q, _pll_p) = match &config.pll { - Some(pll) => { - let pll_vco = mux_clk.unwrap() * pll.mul as u32; - - ( - pll.divr.map(|divr| pll_vco / divr), - pll.divq.map(|divq| pll_vco / divq), - pll.divp.map(|divp| pll_vco / divp), - ) - } - None => (None, None, None), - }; - - let sys_clk = match config.sys { - Sysclk::HSE => hse_clk.unwrap(), - Sysclk::HSI => HSI_FREQ, - Sysclk::PLL1_R => pll_r.unwrap(), - _ => unreachable!(), - }; - - 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 freq = ahb1_clk / pre; - (freq, freq * 2u32) - } - }; - - let (apb2_clk, apb2_tim_clk) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), - pre => { - let freq = ahb1_clk / pre; - (freq, freq * 2u32) - } - }; - - let rcc = crate::pac::RCC; - - let needs_hsi = if let Some(pll_mux) = &config.mux { - pll_mux.source == PllSource::HSI - } else { - false - }; - - if needs_hsi || config.sys == Sysclk::HSI { - rcc.cr().modify(|w| { - w.set_hsion(true); - }); - - while !rcc.cr().read().hsirdy() {} - } - - rcc.cfgr().modify(|w| w.set_stopwuck(true)); - - let rtc = config.ls.init(); - - match &config.hse { - Some(hse) => { - rcc.cr().modify(|w| { - w.set_hsepre(hse.prediv); - w.set_hseon(true); - }); - - while !rcc.cr().read().hserdy() {} - } - _ => {} - } - - match &config.mux { - Some(pll_mux) => { - rcc.pllcfgr().modify(|w| { - w.set_pllm(pll_mux.prediv); - w.set_pllsrc(pll_mux.source.into()); - }); - } - _ => {} - }; - - match &config.pll { - Some(pll) => { - rcc.pllcfgr().modify(|w| { - w.set_plln(pll.mul); - pll.divp.map(|divp| { - w.set_pllpen(true); - w.set_pllp(divp) - }); - pll.divq.map(|divq| { - w.set_pllqen(true); - w.set_pllq(divq) - }); - pll.divr.map(|divr| { - w.set_pllren(true); - w.set_pllr(divr); - }); - }); - - rcc.cr().modify(|w| w.set_pllon(true)); - - while !rcc.cr().read().pllrdy() {} - } - _ => {} - } - - let _hsi48 = config.hsi48.then(|| { - rcc.crrcr().modify(|w| w.set_hsi48on(true)); - while !rcc.crrcr().read().hsi48rdy() {} - - Hertz(48_000_000) - }); - - rcc.cfgr().modify(|w| { - w.set_sw(config.sys.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); - w.set_shdhpre(config.ahb3_pre); - }); - - set_freqs(Clocks { - sys: sys_clk, - hclk1: ahb1_clk, - hclk2: ahb2_clk, - hclk3: ahb3_clk, - pclk1: apb1_clk, - pclk2: apb2_clk, - pclk1_tim: apb1_tim_clk, - pclk2_tim: apb2_tim_clk, - rtc, - }) -} diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index e26c274a..35a6a842 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -39,6 +39,7 @@ async fn main(_spawner: Spawner) { config.rcc.hse = Some(Hse { freq: Hertz(32_000_000), mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { diff --git a/examples/stm32wl/src/bin/lora_p2p_receive.rs b/examples/stm32wl/src/bin/lora_p2p_receive.rs index be33f39c..1c485d73 100644 --- a/examples/stm32wl/src/bin/lora_p2p_receive.rs +++ b/examples/stm32wl/src/bin/lora_p2p_receive.rs @@ -11,6 +11,7 @@ use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant}; use embassy_stm32::bind_interrupts; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::spi::Spi; +use embassy_stm32::time::Hertz; use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; @@ -26,7 +27,23 @@ 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::HSE; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } 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 85f6a84b..3afa78ac 100644 --- a/examples/stm32wl/src/bin/lora_p2p_send.rs +++ b/examples/stm32wl/src/bin/lora_p2p_send.rs @@ -11,6 +11,7 @@ use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant}; use embassy_stm32::bind_interrupts; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::spi::Spi; +use embassy_stm32::time::Hertz; use embassy_time::Delay; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; @@ -26,7 +27,23 @@ 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::HSE; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } 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 2cf7ef9d..1a8822b4 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -21,6 +21,7 @@ async fn main(_spawner: Spawner) { config.rcc.hse = Some(Hse { freq: Hertz(32_000_000), mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index 9ebb05f2..b3b7f9c5 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs @@ -5,20 +5,34 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, LsConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig}; +use embassy_stm32::time::Hertz; use embassy_stm32::Config; use embassy_time::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.mux = ClockSrc::HSE; + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; config.rcc.ls = LsConfig::default_lse(); - embassy_stm32::init(config) - }; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } + let p = embassy_stm32::init(config); info!("Hello World!"); let now = NaiveDate::from_ymd_opt(2020, 5, 15) diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index cb173815..4f51e4f6 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -227,6 +227,11 @@ pub fn config() -> Config { #[allow(unused_mut)] let mut config = Config::default(); + #[cfg(feature = "stm32wb55rg")] + { + config.rcc = embassy_stm32::rcc::WPAN_DEFAULT; + } + #[cfg(feature = "stm32f207zg")] { use embassy_stm32::rcc::*; @@ -405,6 +410,7 @@ pub fn config() -> Config { config.rcc.hse = Some(Hse { freq: Hertz(32_000_000), mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { From a39ae12edcf23935df82d547fb2d997ca6b7c8d5 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 23 Oct 2023 01:48:09 +0200 Subject: [PATCH 052/188] stm32/rcc: misc cleanups. --- embassy-stm32/src/rcc/f4f7.rs | 13 +- embassy-stm32/src/rcc/h.rs | 110 +++++----------- embassy-stm32/src/rcc/l0l1.rs | 30 ++--- embassy-stm32/src/rcc/l4l5.rs | 123 +++++++----------- embassy-stm32/src/rcc/mod.rs | 30 +++++ examples/stm32h5/src/bin/eth.rs | 4 +- examples/stm32h5/src/bin/usb_serial.rs | 4 +- examples/stm32h7/src/bin/adc.rs | 7 +- examples/stm32h7/src/bin/camera.rs | 6 +- examples/stm32h7/src/bin/dac.rs | 7 +- examples/stm32h7/src/bin/dac_dma.rs | 7 +- examples/stm32h7/src/bin/eth.rs | 6 +- examples/stm32h7/src/bin/eth_client.rs | 6 +- examples/stm32h7/src/bin/fmc.rs | 6 +- .../stm32h7/src/bin/low_level_timer_api.rs | 6 +- examples/stm32h7/src/bin/pwm.rs | 6 +- examples/stm32h7/src/bin/sdmmc.rs | 6 +- examples/stm32h7/src/bin/spi.rs | 6 +- examples/stm32h7/src/bin/spi_dma.rs | 6 +- examples/stm32h7/src/bin/usb_serial.rs | 6 +- tests/stm32/src/common.rs | 18 +-- 21 files changed, 175 insertions(+), 238 deletions(-) diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs index 3f9a2be6..2e4f9572 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -166,8 +166,8 @@ pub(crate) unsafe fn init(config: Config) { }; let hclk = sys / config.ahb_pre; - let (pclk1, pclk1_tim) = calc_pclk(hclk, config.apb1_pre); - let (pclk2, pclk2_tim) = calc_pclk(hclk, config.apb2_pre); + let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); + let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre); assert!(max::SYSCLK.contains(&sys)); assert!(max::HCLK.contains(&hclk)); @@ -326,15 +326,6 @@ fn flash_setup(clk: Hertz) { while FLASH.acr().read().latency() != latency {} } -fn calc_pclk(hclk: Hertz, ppre: D) -> (Hertz, Hertz) -where - Hertz: core::ops::Div, -{ - let pclk = hclk / ppre; - let pclk_tim = if hclk == pclk { pclk } else { pclk * 2u32 }; - (pclk, pclk_tim) -} - #[cfg(stm32f7)] mod max { use core::ops::RangeInclusive; diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 8883763e..7e924f0a 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -6,8 +6,11 @@ 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; -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}; +pub use crate::pac::rcc::vals::{ + Ckpersel as PerClockSource, Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, + Pllsrc as PllSource, Sw as Sysclk, +}; +use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -58,41 +61,9 @@ pub struct Hse { pub mode: HseMode, } -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum Hsi { - /// 64Mhz - Mhz64, - /// 32Mhz (divided by 2) - Mhz32, - /// 16Mhz (divided by 4) - Mhz16, - /// 8Mhz (divided by 8) - Mhz8, -} - -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum Sysclk { - /// HSI selected as sysclk - HSI, - /// HSE selected as sysclk - HSE, - /// CSI selected as sysclk - CSI, - /// PLL1_P selected as sysclk - Pll1P, -} - -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum PllSource { - Hsi, - Csi, - Hse, -} - #[derive(Clone, Copy)] pub struct Pll { /// Source clock selection. - #[cfg(stm32h5)] pub source: PllSource, /// PLL pre-divider (DIVM). @@ -152,15 +123,12 @@ impl From for Timpre { /// Configuration of the core clocks #[non_exhaustive] pub struct Config { - pub hsi: Option, + pub hsi: Option, pub hse: Option, pub csi: bool, pub hsi48: bool, pub sys: Sysclk, - #[cfg(stm32h7)] - pub pll_src: PllSource, - pub pll1: Option, pub pll2: Option, #[cfg(any(rcc_h5, stm32h7))] @@ -184,13 +152,11 @@ pub struct Config { impl Default for Config { fn default() -> Self { Self { - hsi: Some(Hsi::Mhz64), + hsi: Some(HSIPrescaler::DIV1), hse: None, csi: false, hsi48: false, sys: Sysclk::HSI, - #[cfg(stm32h7)] - pll_src: PllSource::Hsi, pll1: None, pll2: None, #[cfg(any(rcc_h5, stm32h7))] @@ -303,19 +269,13 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_hsion(false)); None } - Some(hsi) => { - let (freq, hsidiv) = match hsi { - Hsi::Mhz64 => (HSI_FREQ / 1u32, Hsidiv::DIV1), - Hsi::Mhz32 => (HSI_FREQ / 2u32, Hsidiv::DIV2), - Hsi::Mhz16 => (HSI_FREQ / 4u32, Hsidiv::DIV4), - Hsi::Mhz8 => (HSI_FREQ / 8u32, Hsidiv::DIV8), - }; + Some(hsidiv) => { RCC.cr().modify(|w| { w.set_hsidiv(hsidiv); w.set_hsion(true); }); while !RCC.cr().read().hsirdy() {} - Some(freq) + Some(HSI_FREQ / hsidiv) } }; @@ -360,25 +320,29 @@ pub(crate) unsafe fn init(config: Config) { } }; + // H7 has shared PLLSRC, check it's equal in all PLLs. + #[cfg(stm32h7)] + { + let plls = [&config.pll1, &config.pll2, &config.pll3]; + if !super::util::all_equal(plls.into_iter().flatten().map(|p| p.source)) { + panic!("Source must be equal across all enabled PLLs.") + }; + } + // Configure PLLs. - let pll_input = PllInput { - csi, - hse, - hsi, - #[cfg(stm32h7)] - source: config.pll_src, - }; + let pll_input = PllInput { csi, hse, hsi }; 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); // Configure sysclk - let (sys, sw) = match config.sys { - Sysclk::HSI => (unwrap!(hsi), Sw::HSI), - Sysclk::HSE => (unwrap!(hse), Sw::HSE), - Sysclk::CSI => (unwrap!(csi), Sw::CSI), - Sysclk::Pll1P => (unwrap!(pll1.p), Sw::PLL1_P), + let sys = match config.sys { + Sysclk::HSI => unwrap!(hsi), + Sysclk::HSE => unwrap!(hse), + Sysclk::CSI => unwrap!(csi), + Sysclk::PLL1_P => unwrap!(pll1.p), + _ => unreachable!(), }; // Check limits. @@ -502,8 +466,8 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| w.set_timpre(config.timer_prescaler.into())); - RCC.cfgr().modify(|w| w.set_sw(sw)); - while RCC.cfgr().read().sws() != sw {} + RCC.cfgr().modify(|w| w.set_sw(config.sys)); + while RCC.cfgr().read().sws() != config.sys {} // IO compensation cell - Requires CSI clock and SYSCFG #[cfg(stm32h7)] // TODO h5 @@ -588,8 +552,6 @@ struct PllInput { hsi: Option, hse: Option, csi: Option, - #[cfg(stm32h7)] - source: PllSource, } struct PllOutput { @@ -619,15 +581,11 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { }; }; - #[cfg(stm32h5)] - let source = config.source; - #[cfg(stm32h7)] - let source = input.source; - - let (in_clk, src) = match source { - PllSource::Hsi => (unwrap!(input.hsi), Pllsrc::HSI), - PllSource::Hse => (unwrap!(input.hse), Pllsrc::HSE), - PllSource::Csi => (unwrap!(input.csi), Pllsrc::CSI), + let in_clk = match config.source { + PllSource::DISABLE => panic!("must not set PllSource::Disable"), + PllSource::HSI => unwrap!(input.hsi), + PllSource::HSE => unwrap!(input.hse), + PllSource::CSI => unwrap!(input.csi), }; let ref_clk = in_clk / config.prediv as u32; @@ -667,7 +625,7 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { #[cfg(stm32h5)] RCC.pllcfgr(num).write(|w| { - w.set_pllsrc(src); + w.set_pllsrc(config.source); w.set_divm(config.prediv); w.set_pllvcosel(vco_range); w.set_pllrge(ref_range); @@ -681,7 +639,7 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { { RCC.pllckselr().modify(|w| { w.set_divm(num, config.prediv); - w.set_pllsrc(src); + w.set_pllsrc(config.source); }); RCC.pllcfgr().modify(|w| { w.set_pllvcosel(num, vco_range); diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index 52e9ccb3..9fb2062d 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -156,23 +156,9 @@ pub(crate) unsafe fn init(config: Config) { 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) - } - }; + let hclk1 = sys_clk / config.ahb_pre; + let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); + let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); #[cfg(crs)] if config.enable_hsi48 { @@ -209,11 +195,11 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - hclk1: ahb_freq, - pclk1: apb1_freq, - pclk2: apb2_freq, - pclk1_tim: apb1_tim_freq, - pclk2_tim: apb2_tim_freq, + hclk1, + pclk1, + pclk2, + pclk1_tim, + pclk2_tim, rtc, }); } diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 50128d38..2f89f682 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -235,7 +235,7 @@ pub(crate) unsafe fn init(config: Config) { // L4 has shared PLLSRC, PLLM, check it's equal in all PLLs. #[cfg(all(stm32l4, not(rcc_l4plus)))] - match get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) { + match super::util::get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) { Err(()) => panic!("Source must be equal across all enabled PLLs."), Ok(None) => {} Ok(Some((source, prediv))) => RCC.pllcfgr().write(|w| { @@ -246,7 +246,7 @@ pub(crate) unsafe fn init(config: Config) { // L4+, WL has shared PLLSRC, check it's equal in all PLLs. #[cfg(any(rcc_l4plus, stm32wl))] - match get_equal(_plls.into_iter().flatten().map(|p| p.source)) { + match super::util::get_equal(_plls.into_iter().flatten().map(|p| p.source)) { Err(()) => panic!("Source must be equal across all enabled PLLs."), Ok(None) => {} Ok(Some(source)) => RCC.pllcfgr().write(|w| { @@ -265,7 +265,7 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::HSE => hse.unwrap(), ClockSrc::HSI => hsi.unwrap(), ClockSrc::MSI => msi.unwrap(), - ClockSrc::PLL1_R => pll._r.unwrap(), + ClockSrc::PLL1_R => pll.r.unwrap(), }; #[cfg(stm32l4)] @@ -276,8 +276,8 @@ pub(crate) unsafe fn init(config: Config) { let _clk48 = match config.clk48_src { Clk48Src::HSI48 => hsi48, Clk48Src::MSI => msi, - Clk48Src::PLLSAI1_Q => pllsai1._q, - Clk48Src::PLL1_Q => pll._q, + Clk48Src::PLLSAI1_Q => pllsai1.q, + Clk48Src::PLL1_Q => pll.q, }; #[cfg(rcc_l4plus)] @@ -285,32 +285,21 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(all(stm32l4, not(rcc_l4plus)))] assert!(sys_clk.0 <= 80_000_000); - 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) - } - }; - + let hclk1 = sys_clk / config.ahb_pre; + let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); + let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); + #[cfg(not(any(stm32wl5x, stm32wb)))] + let hclk2 = hclk1; #[cfg(any(stm32wl5x, stm32wb))] - let _ahb2_freq = sys_clk / config.core2_ahb_pre; + let hclk2 = sys_clk / config.core2_ahb_pre; + #[cfg(not(any(stm32wl, stm32wb)))] + let hclk3 = hclk1; #[cfg(any(stm32wl, stm32wb))] - let ahb3_freq = sys_clk / config.shared_ahb_pre; + let hclk3 = sys_clk / config.shared_ahb_pre; // Set flash wait states #[cfg(stm32l4)] - let latency = match sys_clk.0 { + let latency = match hclk1.0 { 0..=16_000_000 => 0, 0..=32_000_000 => 1, 0..=48_000_000 => 2, @@ -318,7 +307,7 @@ pub(crate) unsafe fn init(config: Config) { _ => 4, }; #[cfg(stm32l5)] - let latency = match sys_clk.0 { + let latency = match hclk1.0 { // VCORE Range 0 (performance), others TODO 0..=20_000_000 => 0, 0..=40_000_000 => 1, @@ -328,14 +317,14 @@ pub(crate) unsafe fn init(config: Config) { _ => 5, }; #[cfg(stm32wl)] - let latency = match ahb3_freq.0 { + let latency = match hclk3.0 { // VOS RANGE1, others TODO. ..=18_000_000 => 0, ..=36_000_000 => 1, _ => 2, }; #[cfg(stm32wb)] - let latency = match ahb3_freq.0 { + let latency = match hclk3.0 { // VOS RANGE1, others TODO. ..=18_000_000 => 0, ..=36_000_000 => 1, @@ -369,18 +358,15 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - hclk1: ahb_freq, - hclk2: ahb_freq, - #[cfg(not(stm32wl))] - hclk3: ahb_freq, - pclk1: apb1_freq, - pclk2: apb2_freq, - pclk1_tim: apb1_tim_freq, - pclk2_tim: apb2_tim_freq, + hclk1, + hclk2, + hclk3, + pclk1, + pclk2, + pclk1_tim, + pclk2_tim, #[cfg(stm32wl)] - hclk3: ahb3_freq, - #[cfg(stm32wl)] - pclk3: ahb3_freq, + pclk3: hclk3, #[cfg(rcc_l4)] hsi: None, #[cfg(rcc_l4)] @@ -419,26 +405,18 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz { } } -#[allow(unused)] -fn get_equal(mut iter: impl Iterator) -> Result, ()> { - let Some(x) = iter.next() else { return Ok(None) }; - if !iter.all(|y| y == x) { - return Err(()); - } - return Ok(Some(x)); -} - struct PllInput { hsi: Option, hse: Option, msi: Option, } +#[allow(unused)] #[derive(Default)] struct PllOutput { - _p: Option, - _q: Option, - _r: Option, + p: Option, + q: Option, + r: Option, } #[derive(PartialEq, Eq, Clone, Copy)] @@ -450,29 +428,33 @@ enum PllInstance { Pllsai2, } -fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { - // Disable PLL +fn pll_enable(instance: PllInstance, enabled: bool) { match instance { PllInstance::Pll => { - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} + RCC.cr().modify(|w| w.set_pllon(enabled)); + while RCC.cr().read().pllrdy() != enabled {} } #[cfg(any(stm32l4, stm32l5, stm32wb))] PllInstance::Pllsai1 => { - RCC.cr().modify(|w| w.set_pllsai1on(false)); - while RCC.cr().read().pllsai1rdy() {} + RCC.cr().modify(|w| w.set_pllsai1on(enabled)); + while RCC.cr().read().pllsai1rdy() != enabled {} } #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] PllInstance::Pllsai2 => { - RCC.cr().modify(|w| w.set_pllsai2on(false)); - while RCC.cr().read().pllsai2rdy() {} + RCC.cr().modify(|w| w.set_pllsai2on(enabled)); + while RCC.cr().read().pllsai2rdy() != enabled {} } } +} + +fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + pll_enable(instance, false); let Some(pll) = config else { return PllOutput::default() }; let pll_src = match pll.source { - PLLSource::DISABLE => panic!("must not select PLL source as NONE"), + PLLSource::DISABLE => panic!("must not select PLL source as DISABLE"), PLLSource::HSE => input.hse, PLLSource::HSI => input.hsi, PLLSource::MSI => input.msi, @@ -535,22 +517,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll } // Enable PLL - match instance { - PllInstance::Pll => { - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - } - #[cfg(any(stm32l4, stm32l5, stm32wb))] - PllInstance::Pllsai1 => { - RCC.cr().modify(|w| w.set_pllsai1on(true)); - while !RCC.cr().read().pllsai1rdy() {} - } - #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] - PllInstance::Pllsai2 => { - RCC.cr().modify(|w| w.set_pllsai2on(true)); - while !RCC.cr().read().pllsai2rdy() {} - } - } + pll_enable(instance, true); - PllOutput { _p: p, _q: q, _r: r } + PllOutput { p, q, r } } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 4f3d5b98..8cf2d6ab 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -246,3 +246,33 @@ pub(crate) mod sealed { } pub trait RccPeripheral: sealed::RccPeripheral + 'static {} + +#[allow(unused)] +mod util { + use crate::time::Hertz; + + pub fn calc_pclk(hclk: Hertz, ppre: D) -> (Hertz, Hertz) + where + Hertz: core::ops::Div, + { + let pclk = hclk / ppre; + let pclk_tim = if hclk == pclk { pclk } else { pclk * 2u32 }; + (pclk, pclk_tim) + } + + pub fn all_equal(mut iter: impl Iterator) -> bool { + let Some(x) = iter.next() else { return true }; + if !iter.all(|y| y == x) { + return false; + } + true + } + + pub fn get_equal(mut iter: impl Iterator) -> Result, ()> { + let Some(x) = iter.next() else { return Ok(None) }; + if !iter.all(|y| y == x) { + return Err(()); + } + Ok(Some(x)) + } +} diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 6e40f0ac..5bec9d44 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -43,7 +43,7 @@ async fn main(spawner: Spawner) -> ! { mode: HseMode::BypassDigital, }); config.rcc.pll1 = Some(Pll { - source: PllSource::Hse, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL125, divp: Some(PllDiv::DIV2), @@ -54,7 +54,7 @@ async fn main(spawner: Spawner) -> ! { 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.sys = Sysclk::PLL1_P; config.rcc.voltage_scale = VoltageScale::Scale0; let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index 3b3c38e1..735826a6 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs @@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) { mode: HseMode::BypassDigital, }); config.rcc.pll1 = Some(Pll { - source: PllSource::Hse, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL125, divp: Some(PllDiv::DIV2), // 250mhz @@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) { config.rcc.apb1_pre = APBPrescaler::DIV4; config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.apb3_pre = APBPrescaler::DIV4; - config.rcc.sys = Sysclk::Pll1P; + config.rcc.sys = Sysclk::PLL1_P; config.rcc.voltage_scale = VoltageScale::Scale0; let p = embassy_stm32::init(config); diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs index 4a358a35..e367827e 100644 --- a/examples/stm32h7/src/bin/adc.rs +++ b/examples/stm32h7/src/bin/adc.rs @@ -14,10 +14,10 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), @@ -25,13 +25,14 @@ async fn main(_spawner: Spawner) { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index 8195430b..23ece1c3 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs @@ -28,17 +28,17 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index 82122189..35fd6550 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs @@ -16,10 +16,10 @@ fn main() -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), @@ -27,13 +27,14 @@ fn main() -> ! { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 334986a0..e141fc48 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -24,10 +24,10 @@ async fn main(spawner: Spawner) { let mut config = embassy_stm32::Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), @@ -35,13 +35,14 @@ async fn main(spawner: Spawner) { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 81d9c734..e37d8797 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -34,18 +34,18 @@ async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 33813706..88df53f0 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -35,18 +35,18 @@ async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs index cffd4709..54e2c362 100644 --- a/examples/stm32h7/src/bin/fmc.rs +++ b/examples/stm32h7/src/bin/fmc.rs @@ -14,17 +14,17 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index 0355ac07..e4bac8a5 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -17,18 +17,18 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs index 973a10cd..c55d780a 100644 --- a/examples/stm32h7/src/bin/pwm.rs +++ b/examples/stm32h7/src/bin/pwm.rs @@ -17,17 +17,17 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs index ecb8d654..be968ff7 100644 --- a/examples/stm32h7/src/bin/sdmmc.rs +++ b/examples/stm32h7/src/bin/sdmmc.rs @@ -18,17 +18,17 @@ async fn main(_spawner: Spawner) -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, 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 + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index f128d4a5..a8db0ff7 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs @@ -40,17 +40,17 @@ fn main() -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, 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 + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index d4c0bcdb..561052e4 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs @@ -36,17 +36,17 @@ fn main() -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, 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 + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index c1e5144b..19d77183 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs @@ -23,18 +23,18 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for USB - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 4f51e4f6..ff808281 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -312,7 +312,7 @@ pub fn config() -> Config { mode: HseMode::BypassDigital, }); config.rcc.pll1 = Some(Pll { - source: PllSource::Hse, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL125, divp: Some(PllDiv::DIV2), @@ -323,18 +323,18 @@ pub fn config() -> Config { 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.sys = Sysclk::PLL1_P; config.rcc.voltage_scale = VoltageScale::Scale0; } #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), @@ -342,13 +342,14 @@ pub fn config() -> Config { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -361,11 +362,11 @@ pub fn config() -> Config { #[cfg(any(feature = "stm32h7a3zi"))] { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL35, divp: Some(PllDiv::DIV2), // 280 Mhz @@ -373,13 +374,14 @@ pub fn config() -> Config { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL35, divp: Some(PllDiv::DIV8), // 70 Mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 280 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 280 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV1; // 280 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 140 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 140 Mhz From 82593bd404066c4cd1366ed03209d1845a91315f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 23 Oct 2023 18:12:31 +0200 Subject: [PATCH 053/188] stm32/gpio: make port G work on U5. --- ci.sh | 4 ++-- embassy-stm32/src/gpio.rs | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ci.sh b/ci.sh index ffd36a45..eac4d371 100755 --- a/ci.sh +++ b/ci.sh @@ -221,8 +221,8 @@ rm out/tests/stm32wb55rg/wpan_ble # unstable, I think it's running out of RAM? rm out/tests/stm32f207zg/eth -# doesn't work. Wire in D0-D1 might be bad, or the special IOVDD2 PGx pins. -rm out/tests/stm32u5a5zj/{gpio,usart*} +# doesn't work, gives "noise error", no idea why. usart_dma does pass. +rm out/tests/stm32u5a5zj/usart if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index e1702b00..011f4c07 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -763,6 +763,13 @@ pub(crate) unsafe fn init(_cs: CriticalSection) { ::enable_and_reset_with_cs(_cs); crate::_generated::init_gpio(); + + // Setting this bit is mandatory to use PG[15:2]. + #[cfg(stm32u5)] + crate::pac::PWR.svmcr().modify(|w| { + w.set_io2sv(true); + w.set_io2vmen(true); + }); } mod eh02 { From 591612db7e5f8f8dd5120b12a55c00da38a510a8 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Mon, 23 Oct 2023 22:39:24 +0300 Subject: [PATCH 054/188] stm32 uart: return error if rx and tx not enabled --- embassy-stm32/src/usart/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 880ca416..09d5a59d 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -108,6 +108,7 @@ pub enum StopBits { pub enum ConfigError { BaudrateTooLow, BaudrateTooHigh, + RxOrTxNotEnabled, } #[non_exhaustive] @@ -866,7 +867,7 @@ fn configure( enable_tx: bool, ) -> Result<(), ConfigError> { if !enable_rx && !enable_tx { - panic!("USART: At least one of RX or TX should be enabled"); + return Err(ConfigError::RxOrTxNotEnabled); } #[cfg(not(usart_v4))] From 188ee59ba656d5fd47f5a13f978cd064752d3b75 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Mon, 23 Oct 2023 22:40:24 +0300 Subject: [PATCH 055/188] stm32: fix setting uart databits --- embassy-stm32/src/usart/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 09d5a59d..8c4df375 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -910,6 +910,11 @@ fn configure( brr + rounding } + // UART must be disabled during configuration. + r.cr1().modify(|w| { + w.set_ue(false); + }); + #[cfg(not(usart_v1))] let mut over8 = false; let mut found_brr = None; @@ -977,10 +982,9 @@ fn configure( // enable receiver w.set_re(enable_rx); // configure word size - w.set_m0(if config.parity != Parity::ParityNone { - vals::M0::BIT9 - } else { - vals::M0::BIT8 + w.set_m0(match config.data_bits { + DataBits::DataBits8 => vals::M0::BIT8, + DataBits::DataBits9 => vals::M0::BIT9, }); // configure parity w.set_pce(config.parity != Parity::ParityNone); From df4aa0fe253252734dacd555364f5613044f7ecf Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 23 Oct 2023 16:26:34 -0500 Subject: [PATCH 056/188] stm32: fix low-power test --- embassy-stm32/src/rcc/f4f7.rs | 23 +++++++++++++++++------ embassy-stm32/src/rtc/mod.rs | 6 +++++- tests/stm32/src/bin/stop.rs | 4 +++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs index 3f9a2be6..7cc076ef 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -152,9 +152,9 @@ pub(crate) unsafe fn init(config: Config) { source: config.pll_src, }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(all(stm32f4, not(any(stm32f410, stm32f429))), stm32f7))] let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); - #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] + #[cfg(all(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7), not(stm32f429)))] let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); // Configure sysclk @@ -197,15 +197,25 @@ pub(crate) unsafe fn init(config: Config) { pclk2_tim, rtc, pll1_q: pll.q, - #[cfg(all(rcc_f4, not(stm32f410)))] + #[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))] plli2s1_q: _plli2s.q, - #[cfg(all(rcc_f4, not(stm32f410)))] + #[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))] plli2s1_r: _plli2s.r, - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + #[cfg(stm32f429)] + plli2s1_q: None, + #[cfg(stm32f429)] + plli2s1_r: None, + + #[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pllsai1_q: _pllsai.q, - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + #[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pllsai1_r: _pllsai.r, + + #[cfg(stm32f429)] + pllsai1_q: None, + #[cfg(stm32f429)] + pllsai1_r: None, }); } @@ -223,6 +233,7 @@ struct PllOutput { r: Option, } +#[allow(dead_code)] #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 552dcc76..d77443a9 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -184,7 +184,11 @@ 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_and_reset(); + critical_section::with(|cs| { + ::enable_and_reset_with_cs(cs); + #[cfg(feature = "low-power")] + crate::rcc::clock_refcount_sub(cs); + }); let mut this = Self { #[cfg(feature = "low-power")] diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index f38924c9..4f62ecae 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs @@ -11,7 +11,7 @@ use common::*; use cortex_m_rt::entry; use embassy_executor::Spawner; use embassy_stm32::low_power::{stop_with_rtc, Executor}; -use embassy_stm32::rcc::LsConfig; +use embassy_stm32::rcc::{low_power_ready, LsConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; use embassy_time::Timer; @@ -28,6 +28,7 @@ fn main() -> ! { async fn task_1() { for _ in 0..9 { info!("task 1: waiting for 500ms..."); + defmt::assert!(low_power_ready()); Timer::after_millis(500).await; } } @@ -36,6 +37,7 @@ async fn task_1() { async fn task_2() { for _ in 0..5 { info!("task 2: waiting for 1000ms..."); + defmt::assert!(low_power_ready()); Timer::after_millis(1000).await; } From 9e230b64a409379b3e24ed4ad7195c06ea212e1f Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 23 Oct 2023 18:19:42 -0500 Subject: [PATCH 057/188] stm32/build: deterministically generate data --- embassy-stm32/build.rs | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index f8908756..938e44b1 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::fmt::Write as _; use std::path::PathBuf; use std::{env, fs}; @@ -352,7 +352,7 @@ fn main() { // ======== // Generate DMA IRQs. - let mut dma_irqs: HashMap<&str, Vec<(&str, &str, &str)>> = HashMap::new(); + let mut dma_irqs: BTreeMap<&str, Vec<(&str, &str, &str)>> = BTreeMap::new(); for p in METADATA.peripherals { if let Some(r) = &p.registers { @@ -371,22 +371,27 @@ fn main() { } } - for (irq, channels) in dma_irqs { - let irq = format_ident!("{}", irq); + let dma_irqs: TokenStream = dma_irqs + .iter() + .map(|(irq, channels)| { + let irq = format_ident!("{}", irq); - let xdma = format_ident!("{}", channels[0].0); - let channels = channels.iter().map(|(_, dma, ch)| format_ident!("{}_{}", dma, ch)); + let xdma = format_ident!("{}", channels[0].0); + let channels = channels.iter().map(|(_, dma, ch)| format_ident!("{}_{}", dma, ch)); - g.extend(quote! { - #[cfg(feature = "rt")] - #[crate::interrupt] - unsafe fn #irq () { - #( - ::on_irq(); - )* + quote! { + #[cfg(feature = "rt")] + #[crate::interrupt] + unsafe fn #irq () { + #( + ::on_irq(); + )* + } } - }); - } + }) + .collect(); + + g.extend(dma_irqs); // ======== // Extract the rcc registers @@ -433,7 +438,7 @@ fn main() { // Generate RccPeripheral impls let refcounted_peripherals = HashSet::from(["usart", "adc"]); - let mut refcount_statics = HashSet::new(); + let mut refcount_statics = BTreeSet::new(); for p in METADATA.peripherals { if !singletons.contains(&p.name.to_string()) { From e8c162ac03b4825fb174666703d9a4fd3c378869 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Tue, 24 Oct 2023 07:44:04 +0200 Subject: [PATCH 058/188] stm32: Remove unneeded unsafe --- embassy-stm32/src/flash/f4.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 81deaa17..3e5959dd 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -465,7 +465,7 @@ pub(crate) fn assert_not_corrupted_read(end_address: u32) { feature = "stm32f439vg", feature = "stm32f439zg", ))] - if second_bank_read && unsafe { pac::DBGMCU.idcode().read().rev_id() < REVISION_3 && !pa12_is_output_pull_low() } { + if second_bank_read && pac::DBGMCU.idcode().read().rev_id() < REVISION_3 && !pa12_is_output_pull_low() { panic!("Read corruption for stm32f42xxG and stm32f43xxG in dual bank mode when PA12 is in use for chips below revision 3, see errata 2.2.11"); } } From 7f72dbdaf2dc43872c647086d7199769a88b5289 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Mon, 23 Oct 2023 22:43:15 +0300 Subject: [PATCH 059/188] stm32: fix set_config for buffered uart In reconfigure() cr1 register is initialised with write (not modify) which means rxneie and idleneie are disabled after reconfiguration. --- embassy-stm32/src/usart/buffered.rs | 38 ++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index cbc13a34..1c0a6d69 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -233,7 +233,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { configure(r, &config, T::frequency(), T::KIND, true, true)?; r.cr1().modify(|w| { - #[cfg(lpuart_v2)] + #[cfg(usart_v4)] w.set_fifoen(true); w.set_rxneie(true); @@ -254,7 +254,17 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + #[cfg(usart_v4)] + w.set_fifoen(true); + + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } @@ -334,7 +344,17 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + #[cfg(usart_v4)] + w.set_fifoen(true); + + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } @@ -408,7 +428,17 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + #[cfg(usart_v4)] + w.set_fifoen(true); + + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } From 1e362c750baca264e1ab199adb0f18f2098fa236 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Tue, 24 Oct 2023 09:54:17 +0300 Subject: [PATCH 060/188] stm32 uart: use ConfigError instead of () as error --- embassy-stm32/src/usart/buffered.rs | 18 +++++++++--------- embassy-stm32/src/usart/mod.rs | 20 ++++++++++---------- embassy-stm32/src/usart/ringbuffered.rs | 6 +++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 1c0a6d69..0e314c1d 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -116,28 +116,28 @@ pub struct BufferedUartRx<'d, T: BasicInstance> { impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 8c4df375..60b504da 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -182,11 +182,11 @@ pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> { impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.tx.set_config(config).map_err(|_| ())?; - self.rx.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.tx.set_config(config)?; + self.rx.set_config(config) } } @@ -197,10 +197,10 @@ pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> { impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } @@ -214,10 +214,10 @@ pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { impl<'d, T: BasicInstance, RxDma> SetConfig for UartRx<'d, T, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 55489f2e..eceabbe9 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -18,10 +18,10 @@ pub struct RingBufferedUartRx<'d, T: BasicInstance, RxDma: super::RxDma> { impl<'d, T: BasicInstance, RxDma: super::RxDma> SetConfig for RingBufferedUartRx<'d, T, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } From 25c2a9baaa863a42780e70791d6ab9df89f2dd3b Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Tue, 24 Oct 2023 10:11:54 +0300 Subject: [PATCH 061/188] stm32 uart: remove redundant set_fifoen(true) --- embassy-stm32/src/usart/buffered.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 0e314c1d..4daddfe9 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -233,9 +233,6 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { configure(r, &config, T::frequency(), T::KIND, true, true)?; r.cr1().modify(|w| { - #[cfg(usart_v4)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); @@ -257,9 +254,6 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { reconfigure::(config)?; T::regs().cr1().modify(|w| { - #[cfg(usart_v4)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); @@ -347,9 +341,6 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { reconfigure::(config)?; T::regs().cr1().modify(|w| { - #[cfg(usart_v4)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); @@ -431,9 +422,6 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { reconfigure::(config)?; T::regs().cr1().modify(|w| { - #[cfg(usart_v4)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); From bda99e59ec0f2d31e4f29b8d03fbd44d8e917fdd Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Tue, 24 Oct 2023 15:57:03 +0300 Subject: [PATCH 062/188] stm32: fix uart parity, add comment why it is so --- embassy-stm32/src/usart/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 60b504da..ea127e7f 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -974,6 +974,12 @@ fn configure( #[cfg(any(usart_v3, usart_v4))] w.set_swap(config.swap_rx_tx); }); + + #[cfg(not(usart_v1))] + r.cr3().modify(|w| { + w.set_onebit(config.assume_noise_free); + }); + r.cr1().write(|w| { // enable uart w.set_ue(true); @@ -982,9 +988,11 @@ fn configure( // enable receiver w.set_re(enable_rx); // configure word size - w.set_m0(match config.data_bits { - DataBits::DataBits8 => vals::M0::BIT8, - DataBits::DataBits9 => vals::M0::BIT9, + // if using odd or even parity it must be configured to 9bits + w.set_m0(if config.parity != Parity::ParityNone { + vals::M0::BIT9 + } else { + vals::M0::BIT8 }); // configure parity w.set_pce(config.parity != Parity::ParityNone); @@ -999,11 +1007,6 @@ fn configure( w.set_fifoen(true); }); - #[cfg(not(usart_v1))] - r.cr3().modify(|w| { - w.set_onebit(config.assume_noise_free); - }); - Ok(()) } From ceb0d0bf08ba0cf0cccd4760d446a40b5bb7f322 Mon Sep 17 00:00:00 2001 From: Gabriel Smith Date: Tue, 24 Oct 2023 15:20:59 -0400 Subject: [PATCH 063/188] time: Add tick rates in multiples of 10 kHz --- embassy-time/CHANGELOG.md | 4 +++ embassy-time/Cargo.toml | 19 +++++++++++++ embassy-time/gen_tick.py | 2 ++ embassy-time/src/tick.rs | 57 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/embassy-time/CHANGELOG.md b/embassy-time/CHANGELOG.md index 6e79addf..1421d76a 100644 --- a/embassy-time/CHANGELOG.md +++ b/embassy-time/CHANGELOG.md @@ -5,6 +5,10 @@ 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.6 - ??? + +- Added tick rates in multiples of 10 kHz + ## 0.1.5 - 2023-10-16 - Added `links` key to Cargo.toml, to prevent multiple copies of this crate in the same binary. diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 87b57d1e..62404863 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -126,6 +126,25 @@ tick-hz-65_536_000 = [] tick-hz-131_072_000 = [] tick-hz-262_144_000 = [] tick-hz-524_288_000 = [] +tick-hz-20_000 = [] +tick-hz-40_000 = [] +tick-hz-80_000 = [] +tick-hz-160_000 = [] +tick-hz-320_000 = [] +tick-hz-640_000 = [] +tick-hz-1_280_000 = [] +tick-hz-2_560_000 = [] +tick-hz-5_120_000 = [] +tick-hz-10_240_000 = [] +tick-hz-20_480_000 = [] +tick-hz-40_960_000 = [] +tick-hz-81_920_000 = [] +tick-hz-163_840_000 = [] +tick-hz-327_680_000 = [] +tick-hz-655_360_000 = [] +tick-hz-1_310_720_000 = [] +tick-hz-2_621_440_000 = [] +tick-hz-5_242_880_000 = [] tick-hz-2_000_000 = [] tick-hz-3_000_000 = [] tick-hz-4_000_000 = [] diff --git a/embassy-time/gen_tick.py b/embassy-time/gen_tick.py index 67a4c79c..d4a17591 100644 --- a/embassy-time/gen_tick.py +++ b/embassy-time/gen_tick.py @@ -13,6 +13,8 @@ for i in range(1, 25): ticks.append(2**i) for i in range(1, 20): ticks.append(2**i * 1000) +for i in range(1, 20): + ticks.append(2**i * 10000) for i in range(1, 10): ticks.append(2**i * 1000000) ticks.append(2**i * 9 // 8 * 1000000) diff --git a/embassy-time/src/tick.rs b/embassy-time/src/tick.rs index be544181..834e7c09 100644 --- a/embassy-time/src/tick.rs +++ b/embassy-time/src/tick.rs @@ -106,6 +106,44 @@ pub const TICK_HZ: u64 = 131_072_000; pub const TICK_HZ: u64 = 262_144_000; #[cfg(feature = "tick-hz-524_288_000")] pub const TICK_HZ: u64 = 524_288_000; +#[cfg(feature = "tick-hz-20_000")] +pub const TICK_HZ: u64 = 20_000; +#[cfg(feature = "tick-hz-40_000")] +pub const TICK_HZ: u64 = 40_000; +#[cfg(feature = "tick-hz-80_000")] +pub const TICK_HZ: u64 = 80_000; +#[cfg(feature = "tick-hz-160_000")] +pub const TICK_HZ: u64 = 160_000; +#[cfg(feature = "tick-hz-320_000")] +pub const TICK_HZ: u64 = 320_000; +#[cfg(feature = "tick-hz-640_000")] +pub const TICK_HZ: u64 = 640_000; +#[cfg(feature = "tick-hz-1_280_000")] +pub const TICK_HZ: u64 = 1_280_000; +#[cfg(feature = "tick-hz-2_560_000")] +pub const TICK_HZ: u64 = 2_560_000; +#[cfg(feature = "tick-hz-5_120_000")] +pub const TICK_HZ: u64 = 5_120_000; +#[cfg(feature = "tick-hz-10_240_000")] +pub const TICK_HZ: u64 = 10_240_000; +#[cfg(feature = "tick-hz-20_480_000")] +pub const TICK_HZ: u64 = 20_480_000; +#[cfg(feature = "tick-hz-40_960_000")] +pub const TICK_HZ: u64 = 40_960_000; +#[cfg(feature = "tick-hz-81_920_000")] +pub const TICK_HZ: u64 = 81_920_000; +#[cfg(feature = "tick-hz-163_840_000")] +pub const TICK_HZ: u64 = 163_840_000; +#[cfg(feature = "tick-hz-327_680_000")] +pub const TICK_HZ: u64 = 327_680_000; +#[cfg(feature = "tick-hz-655_360_000")] +pub const TICK_HZ: u64 = 655_360_000; +#[cfg(feature = "tick-hz-1_310_720_000")] +pub const TICK_HZ: u64 = 1_310_720_000; +#[cfg(feature = "tick-hz-2_621_440_000")] +pub const TICK_HZ: u64 = 2_621_440_000; +#[cfg(feature = "tick-hz-5_242_880_000")] +pub const TICK_HZ: u64 = 5_242_880_000; #[cfg(feature = "tick-hz-2_000_000")] pub const TICK_HZ: u64 = 2_000_000; #[cfg(feature = "tick-hz-3_000_000")] @@ -334,6 +372,25 @@ pub const TICK_HZ: u64 = 980_000_000; feature = "tick-hz-131_072_000", feature = "tick-hz-262_144_000", feature = "tick-hz-524_288_000", + feature = "tick-hz-20_000", + feature = "tick-hz-40_000", + feature = "tick-hz-80_000", + feature = "tick-hz-160_000", + feature = "tick-hz-320_000", + feature = "tick-hz-640_000", + feature = "tick-hz-1_280_000", + feature = "tick-hz-2_560_000", + feature = "tick-hz-5_120_000", + feature = "tick-hz-10_240_000", + feature = "tick-hz-20_480_000", + feature = "tick-hz-40_960_000", + feature = "tick-hz-81_920_000", + feature = "tick-hz-163_840_000", + feature = "tick-hz-327_680_000", + feature = "tick-hz-655_360_000", + feature = "tick-hz-1_310_720_000", + feature = "tick-hz-2_621_440_000", + feature = "tick-hz-5_242_880_000", feature = "tick-hz-2_000_000", feature = "tick-hz-3_000_000", feature = "tick-hz-4_000_000", From 6b19c0abd15afa03546f08bc54164c19886e56bc Mon Sep 17 00:00:00 2001 From: Aleksandr Krotov Date: Wed, 25 Oct 2023 11:01:35 +0300 Subject: [PATCH 064/188] Fix #2100 - function address comparison --- embassy-executor/src/raw/waker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-executor/src/raw/waker.rs b/embassy-executor/src/raw/waker.rs index 400b37fa..522853e3 100644 --- a/embassy-executor/src/raw/waker.rs +++ b/embassy-executor/src/raw/waker.rs @@ -3,7 +3,7 @@ use core::task::{RawWaker, RawWakerVTable, Waker}; use super::{wake_task, TaskHeader, TaskRef}; -const VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop); +static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop); unsafe fn clone(p: *const ()) -> RawWaker { RawWaker::new(p, &VTABLE) From e8a3cfaed6b3e0ee9e77e16caf51d4479c89090f Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 25 Oct 2023 19:07:31 -0500 Subject: [PATCH 065/188] stm32/low-power: refactor refcount --- embassy-stm32/build.rs | 4 ++-- embassy-stm32/src/lib.rs | 6 +++--- embassy-stm32/src/low_power.rs | 18 ++++++++++++++++-- embassy-stm32/src/rcc/mod.rs | 24 +----------------------- embassy-stm32/src/rtc/mod.rs | 4 +++- tests/stm32/src/bin/stop.rs | 8 ++++---- 6 files changed, 29 insertions(+), 35 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 938e44b1..3400529c 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -564,7 +564,7 @@ fn main() { fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { #before_enable #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_add(_cs); + unsafe { crate::rcc::REFCOUNT_STOP2 += 1 }; crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); #after_enable #rst @@ -573,7 +573,7 @@ fn main() { #before_disable crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_sub(_cs); + unsafe { crate::rcc::REFCOUNT_STOP2 -= 1 }; } } diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 372246f8..5c7067d2 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -226,9 +226,9 @@ pub fn init(config: Config) -> Peripherals { time_driver::init(cs); #[cfg(feature = "low-power")] - while !crate::rcc::low_power_ready() { - crate::rcc::clock_refcount_sub(cs); - } + { + crate::rcc::REFCOUNT_STOP2 = 0 + }; } p diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 861a59d7..d5846f53 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -6,7 +6,6 @@ use cortex_m::peripheral::SCB; use embassy_executor::*; use crate::interrupt; -use crate::rcc::low_power_ready; use crate::time_driver::{get_driver, RtcDriver}; const THREAD_PENDER: usize = usize::MAX; @@ -33,6 +32,15 @@ pub fn stop_with_rtc(rtc: &'static Rtc) { unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc) } +pub fn stop_ready(stop_mode: StopMode) -> bool { + unsafe { EXECUTOR.as_mut().unwrap() }.stop_ready(stop_mode) +} + +#[non_exhaustive] +pub enum StopMode { + Stop2, +} + /// Thread mode executor, using WFE/SEV. /// /// This is the simplest and most common kind of executor. It runs on @@ -80,12 +88,18 @@ impl Executor { trace!("low power: stop with rtc configured"); } + fn stop_ready(&self, stop_mode: StopMode) -> bool { + match stop_mode { + StopMode::Stop2 => unsafe { crate::rcc::REFCOUNT_STOP2 == 0 }, + } + } + fn configure_pwr(&mut self) { self.scb.clear_sleepdeep(); compiler_fence(Ordering::SeqCst); - if !low_power_ready() { + if !self.stop_ready(StopMode::Stop2) { trace!("low power: not ready to stop"); } else if self.time_driver.pause_time().is_err() { trace!("low power: failed to pause time"); diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 8cf2d6ab..3b19e4b9 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -23,8 +23,6 @@ pub use mco::*; #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] mod _version; -#[cfg(feature = "low-power")] -use core::sync::atomic::{AtomicU32, Ordering}; pub use _version::*; @@ -183,27 +181,7 @@ pub struct Clocks { } #[cfg(feature = "low-power")] -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)); - CLOCK_REFCOUNT.load(Ordering::SeqCst) == 0 -} - -#[cfg(feature = "low-power")] -pub(crate) fn clock_refcount_add(_cs: critical_section::CriticalSection) { - // We don't check for overflow because constructing more than u32 peripherals is unlikely - let n = CLOCK_REFCOUNT.load(Ordering::Relaxed); - CLOCK_REFCOUNT.store(n + 1, Ordering::Relaxed); -} - -#[cfg(feature = "low-power")] -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); -} +pub(crate) static mut REFCOUNT_STOP2: u32 = 0; /// Frozen clock frequencies /// diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index d77443a9..3334262f 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -187,7 +187,9 @@ impl Rtc { critical_section::with(|cs| { ::enable_and_reset_with_cs(cs); #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_sub(cs); + unsafe { + crate::rcc::REFCOUNT_STOP2 -= 1 + }; }); let mut this = Self { diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 4f62ecae..b9810673 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs @@ -10,8 +10,8 @@ use chrono::NaiveDate; use common::*; use cortex_m_rt::entry; use embassy_executor::Spawner; -use embassy_stm32::low_power::{stop_with_rtc, Executor}; -use embassy_stm32::rcc::{low_power_ready, LsConfig}; +use embassy_stm32::low_power::{stop_ready, stop_with_rtc, Executor, StopMode}; +use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; use embassy_time::Timer; @@ -28,7 +28,7 @@ fn main() -> ! { async fn task_1() { for _ in 0..9 { info!("task 1: waiting for 500ms..."); - defmt::assert!(low_power_ready()); + defmt::assert!(stop_ready(StopMode::Stop2)); Timer::after_millis(500).await; } } @@ -37,7 +37,7 @@ async fn task_1() { async fn task_2() { for _ in 0..5 { info!("task 2: waiting for 1000ms..."); - defmt::assert!(low_power_ready()); + defmt::assert!(stop_ready(StopMode::Stop2)); Timer::after_millis(1000).await; } From 0beb84768e4ce42c1dedbcbb7b76d5309fce1171 Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 25 Oct 2023 19:50:30 -0500 Subject: [PATCH 066/188] stm32/rtc: more rtc cleanup --- embassy-stm32/src/rtc/datetime.rs | 191 ++++++++++++++++++++---------- embassy-stm32/src/rtc/mod.rs | 89 +++++++------- embassy-stm32/src/rtc/v2.rs | 13 +- 3 files changed, 173 insertions(+), 120 deletions(-) diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs index 3efe9be5..a1943cf3 100644 --- a/embassy-stm32/src/rtc/datetime.rs +++ b/embassy-stm32/src/rtc/datetime.rs @@ -4,8 +4,60 @@ use core::convert::From; #[cfg(feature = "chrono")] use chrono::{self, Datelike, NaiveDate, Timelike, Weekday}; -use super::byte_to_bcd2; -use crate::pac::rtc::Rtc; +#[cfg(any(feature = "defmt", feature = "time"))] +use crate::peripherals::RTC; +#[cfg(any(feature = "defmt", feature = "time"))] +use crate::rtc::sealed::Instance; + +/// Represents an instant in time that can be substracted to compute a duration +pub struct RtcInstant { + /// 0..59 + pub second: u8, + /// 0..256 + pub subsecond: u16, +} + +impl RtcInstant { + #[allow(dead_code)] + pub(super) fn from(second: u8, subsecond: u16) -> Result { + Ok(Self { second, subsecond }) + } +} + +#[cfg(feature = "defmt")] +impl defmt::Format for RtcInstant { + fn format(&self, fmt: defmt::Formatter) { + defmt::write!( + fmt, + "{}:{}", + self.second, + RTC::regs().prer().read().prediv_s() - self.subsecond, + ) + } +} + +#[cfg(feature = "time")] +impl core::ops::Sub for RtcInstant { + type Output = embassy_time::Duration; + + fn sub(self, rhs: Self) -> Self::Output { + use embassy_time::{Duration, TICK_HZ}; + + let second = if self.second < rhs.second { + self.second + 60 + } else { + self.second + }; + + let psc = RTC::regs().prer().read().prediv_s() as u32; + + let self_ticks = second as u32 * (psc + 1) + (psc - self.subsecond as u32); + let other_ticks = rhs.second as u32 * (psc + 1) + (psc - rhs.subsecond as u32); + let rtc_ticks = self_ticks - other_ticks; + + Duration::from_ticks(((rtc_ticks * TICK_HZ as u32) / (psc + 1)) as u64) + } +} /// Errors regarding the [`DateTime`] struct. #[derive(Clone, Debug, PartialEq, Eq)] @@ -32,19 +84,85 @@ pub enum Error { /// Structure containing date and time information pub struct DateTime { /// 0..4095 - pub year: u16, + year: u16, /// 1..12, 1 is January - pub month: u8, + month: u8, /// 1..28,29,30,31 depending on month - pub day: u8, + day: u8, /// - pub day_of_week: DayOfWeek, + day_of_week: DayOfWeek, /// 0..23 - pub hour: u8, + hour: u8, /// 0..59 - pub minute: u8, + minute: u8, /// 0..59 - pub second: u8, + second: u8, +} + +impl DateTime { + pub const fn year(&self) -> u16 { + self.year + } + + pub const fn month(&self) -> u8 { + self.month + } + + pub const fn day(&self) -> u8 { + self.day + } + + pub const fn day_of_week(&self) -> DayOfWeek { + self.day_of_week + } + + pub const fn hour(&self) -> u8 { + self.hour + } + + pub const fn minute(&self) -> u8 { + self.minute + } + + pub const fn second(&self) -> u8 { + self.second + } + + pub fn from( + year: u16, + month: u8, + day: u8, + day_of_week: u8, + hour: u8, + minute: u8, + second: u8, + ) -> Result { + let day_of_week = day_of_week_from_u8(day_of_week)?; + + if year > 4095 { + Err(Error::InvalidYear) + } else if month < 1 || month > 12 { + Err(Error::InvalidMonth) + } else if day < 1 || day > 31 { + Err(Error::InvalidDay) + } else if hour > 23 { + Err(Error::InvalidHour) + } else if minute > 59 { + Err(Error::InvalidMinute) + } else if second > 59 { + Err(Error::InvalidSecond) + } else { + Ok(Self { + year, + month, + day, + day_of_week, + hour, + minute, + second, + }) + } + } } #[cfg(feature = "chrono")] @@ -142,58 +260,3 @@ pub(super) fn validate_datetime(dt: &DateTime) -> Result<(), Error> { Ok(()) } } - -pub(super) fn write_date_time(rtc: &Rtc, t: DateTime) { - let (ht, hu) = byte_to_bcd2(t.hour as u8); - let (mnt, mnu) = byte_to_bcd2(t.minute as u8); - let (st, su) = byte_to_bcd2(t.second as u8); - - let (dt, du) = byte_to_bcd2(t.day as u8); - let (mt, mu) = byte_to_bcd2(t.month as u8); - let yr = t.year as u16; - let yr_offset = (yr - 1970_u16) as u8; - let (yt, yu) = byte_to_bcd2(yr_offset); - - use crate::pac::rtc::vals::Ampm; - - rtc.tr().write(|w| { - w.set_ht(ht); - w.set_hu(hu); - w.set_mnt(mnt); - w.set_mnu(mnu); - w.set_st(st); - w.set_su(su); - w.set_pm(Ampm::AM); - }); - - rtc.dr().write(|w| { - w.set_dt(dt); - w.set_du(du); - w.set_mt(mt > 0); - w.set_mu(mu); - w.set_yt(yt); - w.set_yu(yu); - w.set_wdu(day_of_week_to_u8(t.day_of_week)); - }); -} - -pub(super) fn datetime( - year: u16, - month: u8, - day: u8, - day_of_week: u8, - hour: u8, - minute: u8, - second: u8, -) -> Result { - let day_of_week = day_of_week_from_u8(day_of_week)?; - Ok(DateTime { - year, - month, - day, - day_of_week, - hour, - minute, - second, - }) -} diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index d77443a9..da79c392 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -9,7 +9,8 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; #[cfg(feature = "low-power")] use embassy_sync::blocking_mutex::Mutex; -pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; +pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError, RtcInstant}; +use crate::rtc::datetime::day_of_week_to_u8; use crate::time::Hertz; /// refer to AN4759 to compare features of RTC2 and RTC3 @@ -39,48 +40,6 @@ pub enum RtcError { NotRunning, } -#[cfg(feature = "low-power")] -/// Represents an instant in time that can be substracted to compute a duration -struct RtcInstant { - second: u8, - subsecond: u16, -} - -#[cfg(all(feature = "low-power", feature = "defmt"))] -impl defmt::Format for RtcInstant { - fn format(&self, fmt: defmt::Formatter) { - defmt::write!( - fmt, - "{}:{}", - self.second, - RTC::regs().prer().read().prediv_s() - self.subsecond, - ) - } -} - -#[cfg(feature = "low-power")] -impl core::ops::Sub for RtcInstant { - type Output = embassy_time::Duration; - - fn sub(self, rhs: Self) -> Self::Output { - use embassy_time::{Duration, TICK_HZ}; - - let second = if self.second < rhs.second { - self.second + 60 - } else { - self.second - }; - - let psc = RTC::regs().prer().read().prediv_s() as u32; - - let self_ticks = second as u32 * (psc + 1) + (psc - self.subsecond as u32); - let other_ticks = rhs.second as u32 * (psc + 1) + (psc - rhs.subsecond as u32); - let rtc_ticks = self_ticks - other_ticks; - - Duration::from_ticks(((rtc_ticks * TICK_HZ as u32) / (psc + 1)) as u64) - } -} - pub struct RtcTimeProvider { _private: (), } @@ -113,7 +72,7 @@ impl RtcTimeProvider { 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) + return DateTime::from(year, month, day, weekday, hour, minute, second) .map_err(RtcError::InvalidDateTime); } } @@ -134,7 +93,7 @@ impl RtcTimeProvider { 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) + DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) } } } @@ -223,14 +182,46 @@ impl Rtc { /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> { self::datetime::validate_datetime(&t).map_err(RtcError::InvalidDateTime)?; - self.write(true, |rtc| self::datetime::write_date_time(rtc, t)); + self.write(true, |rtc| { + let (ht, hu) = byte_to_bcd2(t.hour() as u8); + let (mnt, mnu) = byte_to_bcd2(t.minute() as u8); + let (st, su) = byte_to_bcd2(t.second() as u8); + + let (dt, du) = byte_to_bcd2(t.day() as u8); + let (mt, mu) = byte_to_bcd2(t.month() as u8); + let yr = t.year() as u16; + let yr_offset = (yr - 1970_u16) as u8; + let (yt, yu) = byte_to_bcd2(yr_offset); + + use crate::pac::rtc::vals::Ampm; + + rtc.tr().write(|w| { + w.set_ht(ht); + w.set_hu(hu); + w.set_mnt(mnt); + w.set_mnu(mnu); + w.set_st(st); + w.set_su(su); + w.set_pm(Ampm::AM); + }); + + rtc.dr().write(|w| { + w.set_dt(dt); + w.set_du(du); + w.set_mt(mt > 0); + w.set_mu(mu); + w.set_yt(yt); + w.set_yu(yu); + w.set_wdu(day_of_week_to_u8(t.day_of_week())); + }); + }); Ok(()) } - #[cfg(feature = "low-power")] + #[cfg(not(rtc_v2f2))] /// Return the current instant. - fn instant(&self) -> RtcInstant { + pub fn instant(&self) -> Result { let r = RTC::regs(); let tr = r.tr().read(); let subsecond = r.ssr().read().ss(); @@ -239,7 +230,7 @@ impl Rtc { // Unlock the registers r.dr().read(); - RtcInstant { second, subsecond } + RtcInstant::from(second, subsecond.try_into().unwrap()) } /// Return the current datetime. diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index eeb23e1f..b6ab9b20 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs @@ -95,15 +95,16 @@ impl super::Rtc { regs.cr().modify(|w| w.set_wutie(true)); }); + let instant = self.instant().unwrap(); trace!( "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}", Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(), prescaler as u32, rtc_ticks, - self.instant(), + instant, ); - assert!(self.stop_time.borrow(cs).replace(Some(self.instant())).is_none()) + assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none()) } #[cfg(feature = "low-power")] @@ -112,8 +113,9 @@ impl super::Rtc { pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option { use crate::interrupt::typelevel::Interrupt; + let instant = self.instant().unwrap(); if RTC::regs().cr().read().wute() { - trace!("rtc: stop wakeup alarm at {}", self.instant()); + trace!("rtc: stop wakeup alarm at {}", instant); self.write(false, |regs| { regs.cr().modify(|w| w.set_wutie(false)); @@ -128,10 +130,7 @@ impl super::Rtc { }); } - self.stop_time - .borrow(cs) - .take() - .map(|stop_time| self.instant() - stop_time) + self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time) } #[cfg(feature = "low-power")] From b1e5b6ffe1587362d4a58f5da831338dfa41a1bc Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Sat, 28 Oct 2023 13:50:02 +0200 Subject: [PATCH 067/188] Add raw fmc access implementation --- embassy-stm32/src/fmc.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs index d6e25996..dd0d2721 100644 --- a/embassy-stm32/src/fmc.rs +++ b/embassy-stm32/src/fmc.rs @@ -12,6 +12,37 @@ pub struct Fmc<'d, T: Instance> { unsafe impl<'d, T> Send for Fmc<'d, T> where T: Instance {} +impl<'d, T> Fmc<'d, T> +where + T: Instance, +{ + /// Create a raw FMC instance. + /// + /// **Note:** This is currently used to provide access to some basic FMC functions + /// for manual configuration for memory types that stm32-fmc does not support. + pub fn new_raw(_instance: impl Peripheral

+ 'd) -> Self { + Self { peri: PhantomData } + } + + /// Enable the FMC peripheral and reset it. + pub fn enable(&mut self) { + T::enable_and_reset(); + } + + /// Enable the memory controller on applicable chips. + pub fn memory_controller_enable(&mut self) { + // fmc v1 and v2 does not have the fmcen bit + // fsmc v1, v2 and v3 does not have the fmcen bit + // This is a "not" because it is expected that all future versions have this bit + #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1)))] + T::REGS.bcr1().modify(|r| r.set_fmcen(true)); + } + + pub fn source_clock_hz(&self) -> u32 { + ::frequency().0 + } +} + unsafe impl<'d, T> stm32_fmc::FmcPeripheral for Fmc<'d, T> where T: Instance, From 0d6094c8b10da141d048ec23133df4525befbd44 Mon Sep 17 00:00:00 2001 From: "Andres O. Vela" Date: Sun, 29 Oct 2023 19:49:52 +0100 Subject: [PATCH 068/188] time: add MockDriver for testing purposes --- embassy-time/Cargo.toml | 3 ++ embassy-time/src/driver_mock.rs | 73 +++++++++++++++++++++++++++++++++ embassy-time/src/lib.rs | 6 +++ 3 files changed, 82 insertions(+) create mode 100644 embassy-time/src/driver_mock.rs diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 62404863..8b5d31ee 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -59,6 +59,9 @@ generic-queue-32 = ["generic-queue"] generic-queue-64 = ["generic-queue"] generic-queue-128 = ["generic-queue"] +# Create a `MockDriver` that can be manually advanced for testing purposes. +mock-driver = ["tick-hz-1_000_000"] + # Set the `embassy_time` tick rate. # # At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used. diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs new file mode 100644 index 00000000..4ae5a2d9 --- /dev/null +++ b/embassy-time/src/driver_mock.rs @@ -0,0 +1,73 @@ +use core::cell::Cell; + +use critical_section::Mutex as CsMutex; + +use crate::driver::{AlarmHandle, Driver}; +use crate::{Duration, Instant}; + +/// A mock driver that can be manually advanced. +/// This is useful for testing code that works with [`Instant`] and [`Duration`]. +/// +/// This driver cannot currently be used to test runtime functionality, such as +/// timers, delays, etc. +/// +/// # Example +/// +/// ```ignore +/// fn has_a_second_passed(reference: Instant) -> bool { +/// Instant::now().duration_since(reference) > Duration::from_secs(1) +/// } +/// +/// fn test_second_passed() { +/// let driver = embassy_time::MockDriver::get(); +/// let reference = Instant::now(); +/// assert_eq!(false, has_a_second_passed(reference)); +/// driver.advance(Duration::from_secs(1)); +/// assert_eq!(true, has_a_second_passed(reference)); +/// } +/// ``` +pub struct MockDriver { + now: CsMutex>, +} + +crate::time_driver_impl!(static DRIVER: MockDriver = MockDriver { + now: CsMutex::new(Cell::new(Instant::from_ticks(0))), +}); + +impl MockDriver { + /// Gets a reference to the global mock driver. + pub fn get() -> &'static MockDriver { + &DRIVER + } + + /// Sets the current time of the mock driver. + pub fn set_current_time(&self, now: Instant) { + critical_section::with(|cs| self.now.borrow(cs).set(now)) + } + + /// Advances the time by the specified [`Duration`]. + pub fn advance(&self, duration: Duration) { + critical_section::with(|cs| { + let now = self.now.borrow(cs).get().as_ticks(); + self.now.borrow(cs).set(Instant::from_ticks(now + duration.as_ticks())); + }); + } +} + +impl Driver for MockDriver { + fn now(&self) -> u64 { + critical_section::with(|cs| self.now.borrow(cs).get().as_micros() as u64) + } + + unsafe fn allocate_alarm(&self) -> Option { + unimplemented!("MockDriver does not support runtime features that require an executor"); + } + + fn set_alarm_callback(&self, _alarm: AlarmHandle, _callback: fn(*mut ()), _ctx: *mut ()) { + unimplemented!("MockDriver does not support runtime features that require an executor"); + } + + fn set_alarm(&self, _alarm: AlarmHandle, _timestamp: u64) -> bool { + unimplemented!("MockDriver does not support runtime features that require an executor"); + } +} diff --git a/embassy-time/src/lib.rs b/embassy-time/src/lib.rs index 8f57eabc..45c1e882 100644 --- a/embassy-time/src/lib.rs +++ b/embassy-time/src/lib.rs @@ -15,6 +15,12 @@ pub mod queue; mod tick; mod timer; +#[cfg(feature = "mock-driver")] +mod driver_mock; + +#[cfg(feature = "mock-driver")] +pub use driver_mock::MockDriver; + #[cfg(feature = "std")] mod driver_std; #[cfg(feature = "wasm")] From f4a78e00a7a6a1e5046c8e6af2cc5c08df9d7bc1 Mon Sep 17 00:00:00 2001 From: "Andres O. Vela" Date: Sun, 29 Oct 2023 19:52:35 +0100 Subject: [PATCH 069/188] Remove set_current_time API --- embassy-time/src/driver_mock.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs index 4ae5a2d9..c7cab342 100644 --- a/embassy-time/src/driver_mock.rs +++ b/embassy-time/src/driver_mock.rs @@ -40,11 +40,6 @@ impl MockDriver { &DRIVER } - /// Sets the current time of the mock driver. - pub fn set_current_time(&self, now: Instant) { - critical_section::with(|cs| self.now.borrow(cs).set(now)) - } - /// Advances the time by the specified [`Duration`]. pub fn advance(&self, duration: Duration) { critical_section::with(|cs| { From 573734008a8a0659e6cfe832db382b9206e3f4f1 Mon Sep 17 00:00:00 2001 From: "Andres O. Vela" Date: Sun, 29 Oct 2023 20:03:11 +0100 Subject: [PATCH 070/188] Fix test --- embassy-time/src/driver_mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs index c7cab342..becb6bfd 100644 --- a/embassy-time/src/driver_mock.rs +++ b/embassy-time/src/driver_mock.rs @@ -15,7 +15,7 @@ use crate::{Duration, Instant}; /// /// ```ignore /// fn has_a_second_passed(reference: Instant) -> bool { -/// Instant::now().duration_since(reference) > Duration::from_secs(1) +/// Instant::now().duration_since(reference) >= Duration::from_secs(1) /// } /// /// fn test_second_passed() { From ad07ea02909f7c10b5c2bd2bb40c81aea414db4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 30 Oct 2023 19:06:08 +0100 Subject: [PATCH 071/188] Re-add impl_trait_projections --- embassy-embedded-hal/src/lib.rs | 3 ++- embassy-lora/src/lib.rs | 3 ++- embassy-net/src/lib.rs | 3 ++- embassy-nrf/src/lib.rs | 3 ++- embassy-rp/src/lib.rs | 3 ++- embassy-stm32/src/lib.rs | 3 ++- embassy-sync/src/lib.rs | 3 ++- examples/std/src/bin/net_ppp.rs | 3 ++- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/embassy-embedded-hal/src/lib.rs b/embassy-embedded-hal/src/lib.rs index ee964e40..f836d9f7 100644 --- a/embassy-embedded-hal/src/lib.rs +++ b/embassy-embedded-hal/src/lib.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, try_blocks))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections, try_blocks))] +#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))] #![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 5637802b..653c9825 100644 --- a/embassy-lora/src/lib.rs +++ b/embassy-lora/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] -#![feature(async_fn_in_trait)] +#![feature(async_fn_in_trait, impl_trait_projections)] +#![allow(stable_features, unknown_lints, 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 79896287..b9315079 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, 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 2cc83d74..71528111 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, 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 2728395b..c9fe89b8 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, 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 5c7067d2..23d42bae 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(test), no_std)] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, 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 aca6ff38..c40fa3b6 100644 --- a/embassy-sync/src/lib.rs +++ b/embassy-sync/src/lib.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] -#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] +#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] +#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, 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 9ea07b29..6ac31f2f 100644 --- a/examples/std/src/bin/net_ppp.rs +++ b/examples/std/src/bin/net_ppp.rs @@ -8,7 +8,8 @@ //! nc 192.168.7.10 1234 #![feature(type_alias_impl_trait)] -#![feature(async_fn_in_trait)] +#![feature(async_fn_in_trait, impl_trait_projections)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] #[path = "../serial_port.rs"] mod serial_port; From aa97fe7cbd9e6b7dbb83b61133a38d436fb3efc0 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Mon, 30 Oct 2023 13:36:52 -0400 Subject: [PATCH 072/188] stm32: Add some documentation to `low_power` This begins to explain the operation of the low-power executor. --- embassy-stm32/src/low_power.rs | 47 ++++++++++++++++++++++++++++++++ embassy-stm32/src/time_driver.rs | 6 +++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index d5846f53..385795bc 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -1,3 +1,50 @@ +/// The STM32 line of microcontrollers support various deep-sleep modes which exploit clock-gating +/// to reduce power consumption. `embassy-stm32` provides a low-power executor, [`Executor`] which +/// can use knowledge of which peripherals are currently blocked upon to transparently and safely +/// enter such low-power modes (currently, only `STOP2`) when idle. +/// +/// The executor determines which peripherals are active by their RCC state; consequently, +/// low-power states can only be entered if all peripherals have been `drop`'d. There are a few +/// exceptions to this rule: +/// +/// * `GPIO` +/// * `RCC` +/// +/// Since entering and leaving low-power modes typically incurs a significant latency, the +/// low-power executor will only attempt to enter when the next timer event is at least +/// [`time_driver::MIN_STOP_PAUSE`] in the future. +/// +/// Currently there is no macro analogous to `embassy_executor::main` for this executor; +/// consequently one must define their entrypoint manually. Moveover, you must relinquish control +/// of the `RTC` peripheral to the executor. This will typically look like +/// +/// ```rust,no_run +/// use embassy_executor::Spawner; +/// use embassy_stm32::low_power::Executor; +/// use embassy_stm32::rtc::{Rtc, RtcConfig}; +/// use static_cell::make_static; +/// +/// #[cortex_m_rt::entry] +/// fn main() -> ! { +/// Executor::take().run(|spawner| { +/// unwrap!(spawner.spawn(async_main(spawner))); +/// }); +/// } +/// +/// #[embassy_executor::task] +/// async fn async_main(spawner: Spawner) { +/// // initialize the platform... +/// let mut config = embassy_stm32::Config::default(); +/// let p = embassy_stm32::init(config); +/// +/// // give the RTC to the executor... +/// let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); +/// let rtc = make_static!(rtc); +/// embassy_stm32::low_power::stop_with_rtc(rtc); +/// +/// // your application here... +/// } +/// ``` use core::arch::asm; use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index add8be83..564c9d08 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -345,6 +345,10 @@ impl RtcDriver { }); } + #[cfg(feature = "low-power")] + /// The minimum pause time beyond which the executor will enter a low-power state. + pub(crate) const MIN_STOP_PAUSE: embassy_time::Duration = embassy_time::Duration::from_millis(250); + #[cfg(feature = "low-power")] /// Pause the timer if ready; return err if not pub(crate) fn pause_time(&self) -> Result<(), ()> { @@ -357,7 +361,7 @@ impl RtcDriver { self.stop_wakeup_alarm(cs); let time_until_next_alarm = self.time_until_next_alarm(cs); - if time_until_next_alarm < embassy_time::Duration::from_millis(250) { + if time_until_next_alarm < Self::MIN_STOP_PAUSE { Err(()) } else { self.rtc From c9b50e46a531985328b29246b168db924b910704 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Mon, 30 Oct 2023 20:50:37 +0100 Subject: [PATCH 073/188] rp: Add PIO stepper motor driver example --- examples/rp/src/bin/pio_stepper.rs | 169 +++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 examples/rp/src/bin/pio_stepper.rs diff --git a/examples/rp/src/bin/pio_stepper.rs b/examples/rp/src/bin/pio_stepper.rs new file mode 100644 index 00000000..02fb2069 --- /dev/null +++ b/examples/rp/src/bin/pio_stepper.rs @@ -0,0 +1,169 @@ +//! This example shows how to use the PIO module in the RP2040 to implement a stepper motor driver +//! for a 5-wire stepper such as the 28BYJ-48. You can halt an ongoing rotation by dropping the future. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] +use core::mem::{self, MaybeUninit}; + +use defmt::info; +use embassy_executor::Spawner; +use embassy_rp::bind_interrupts; +use embassy_rp::peripherals::PIO0; +use embassy_rp::pio::{Common, Config, Direction, Instance, InterruptHandler, Irq, Pio, PioPin, StateMachine}; +use embassy_time::{with_timeout, Duration, Timer}; +use fixed::traits::ToFixed; +use fixed::types::extra::U8; +use fixed::FixedU32; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + PIO0_IRQ_0 => InterruptHandler; +}); + +pub struct PioStepper<'d, T: Instance, const SM: usize> { + irq: Irq<'d, T, SM>, + sm: StateMachine<'d, T, SM>, +} + +impl<'d, T: Instance, const SM: usize> PioStepper<'d, T, SM> { + pub fn new( + pio: &mut Common<'d, T>, + mut sm: StateMachine<'d, T, SM>, + irq: Irq<'d, T, SM>, + pin0: impl PioPin, + pin1: impl PioPin, + pin2: impl PioPin, + pin3: impl PioPin, + ) -> Self { + let prg = pio_proc::pio_asm!( + "pull block", + "mov x, osr", + "pull block", + "mov y, osr", + "jmp !x end", + "loop:", + "jmp !osre step", + "mov osr, y", + "step:", + "out pins, 4 [31]" + "jmp x-- loop", + "end:", + "irq 0 rel" + ); + let pin0 = pio.make_pio_pin(pin0); + let pin1 = pio.make_pio_pin(pin1); + let pin2 = pio.make_pio_pin(pin2); + let pin3 = pio.make_pio_pin(pin3); + sm.set_pin_dirs(Direction::Out, &[&pin0, &pin1, &pin2, &pin3]); + let mut cfg = Config::default(); + cfg.set_out_pins(&[&pin0, &pin1, &pin2, &pin3]); + cfg.clock_divider = (125_000_000 / (100 * 136)).to_fixed(); + cfg.use_program(&pio.load_program(&prg.program), &[]); + sm.set_config(&cfg); + sm.set_enable(true); + Self { irq, sm } + } + + // Set pulse frequency + pub fn set_frequency(&mut self, freq: u32) { + let clock_divider: FixedU32 = (125_000_000 / (freq * 136)).to_fixed(); + assert!(clock_divider <= 65536, "clkdiv must be <= 65536"); + assert!(clock_divider >= 1, "clkdiv must be >= 1"); + T::PIO.sm(SM).clkdiv().write(|w| w.0 = clock_divider.to_bits() << 8); + self.sm.clkdiv_restart(); + } + + // Full step, one phase + pub async fn step(&mut self, steps: i32) { + if steps > 0 { + self.run(steps, 0b1000_0100_0010_0001_1000_0100_0010_0001).await + } else { + self.run(-steps, 0b0001_0010_0100_1000_0001_0010_0100_1000).await + } + } + + // Full step, two phase + pub async fn step2(&mut self, steps: i32) { + if steps > 0 { + self.run(steps, 0b1001_1100_0110_0011_1001_1100_0110_0011).await + } else { + self.run(-steps, 0b0011_0110_1100_1001_0011_0110_1100_1001).await + } + } + + // Half step + pub async fn step_half(&mut self, steps: i32) { + if steps > 0 { + self.run(steps, 0b1001_1000_1100_0100_0110_0010_0011_0001).await + } else { + self.run(-steps, 0b0001_0011_0010_0110_0100_1100_1000_1001).await + } + } + + async fn run(&mut self, steps: i32, pattern: u32) { + self.sm.tx().wait_push(steps as u32).await; + self.sm.tx().wait_push(pattern).await; + let drop = OnDrop::new(|| { + self.sm.clear_fifos(); + unsafe { + self.sm.exec_instr( + pio::InstructionOperands::JMP { + address: 0, + condition: pio::JmpCondition::Always, + } + .encode(), + ); + } + }); + self.irq.wait().await; + drop.defuse(); + } +} + +struct OnDrop { + f: MaybeUninit, +} + +impl OnDrop { + pub fn new(f: F) -> Self { + Self { f: MaybeUninit::new(f) } + } + + pub fn defuse(self) { + mem::forget(self) + } +} + +impl Drop for OnDrop { + fn drop(&mut self) { + unsafe { self.f.as_ptr().read()() } + } +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + let Pio { + mut common, irq0, sm0, .. + } = Pio::new(p.PIO0, Irqs); + + let mut stepper = PioStepper::new(&mut common, sm0, irq0, p.PIN_4, p.PIN_5, p.PIN_6, p.PIN_7); + stepper.set_frequency(120); + loop { + info!("CW full steps"); + stepper.step(1000).await; + + info!("CCW full steps, drop after 1 sec"); + if let Err(_) = with_timeout(Duration::from_secs(1), stepper.step(i32::MIN)).await { + info!("Time's up!"); + Timer::after(Duration::from_secs(1)).await; + } + + info!("CW half steps"); + stepper.step_half(1000).await; + + info!("CCW half steps"); + stepper.step_half(-1000).await; + } +} From 3912f5d67b5096e8753b0ef0c980083e79d38e00 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Mon, 30 Oct 2023 20:26:08 +0000 Subject: [PATCH 074/188] Fix dow range off-by-one error --- embassy-stm32/src/rtc/datetime.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs index a1943cf3..d897843d 100644 --- a/embassy-stm32/src/rtc/datetime.rs +++ b/embassy-stm32/src/rtc/datetime.rs @@ -195,13 +195,13 @@ impl From for chrono::NaiveDateTime { #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)] #[allow(missing_docs)] pub enum DayOfWeek { - Monday = 0, - Tuesday = 1, - Wednesday = 2, - Thursday = 3, - Friday = 4, - Saturday = 5, - Sunday = 6, + Monday = 1, + Tuesday = 2, + Wednesday = 3, + Thursday = 4, + Friday = 5, + Saturday = 6, + Sunday = 7, } #[cfg(feature = "chrono")] @@ -228,13 +228,13 @@ impl From for chrono::Weekday { fn day_of_week_from_u8(v: u8) -> Result { Ok(match v { - 0 => DayOfWeek::Monday, - 1 => DayOfWeek::Tuesday, - 2 => DayOfWeek::Wednesday, - 3 => DayOfWeek::Thursday, - 4 => DayOfWeek::Friday, - 5 => DayOfWeek::Saturday, - 6 => DayOfWeek::Sunday, + 1 => DayOfWeek::Monday, + 2 => DayOfWeek::Tuesday, + 3 => DayOfWeek::Wednesday, + 4 => DayOfWeek::Thursday, + 5 => DayOfWeek::Friday, + 6 => DayOfWeek::Saturday, + 7 => DayOfWeek::Sunday, x => return Err(Error::InvalidDayOfWeek(x)), }) } From 57edf289eaa2de10da35b34a2710fa255f2746d8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 31 Oct 2023 00:04:15 +0100 Subject: [PATCH 075/188] stm32/tests: disable stop test. --- ci.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci.sh b/ci.sh index eac4d371..5c69d3a2 100755 --- a/ci.sh +++ b/ci.sh @@ -218,6 +218,9 @@ cargo batch \ rm out/tests/stm32wb55rg/wpan_mac rm out/tests/stm32wb55rg/wpan_ble +# unstable +rm out/tests/stm32f429zi/stop + # unstable, I think it's running out of RAM? rm out/tests/stm32f207zg/eth From d94188206616d341d6646f55181d2cbd636e056b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 31 Oct 2023 09:18:00 +0100 Subject: [PATCH 076/188] Prepare embassy-net 0.2.1 and embassy-sync 0.4.0 --- cyw43/Cargo.toml | 2 +- embassy-boot/boot/Cargo.toml | 2 +- embassy-boot/nrf/Cargo.toml | 2 +- embassy-boot/rp/Cargo.toml | 2 +- embassy-boot/stm32/Cargo.toml | 2 +- embassy-embedded-hal/Cargo.toml | 2 +- embassy-lora/Cargo.toml | 2 +- embassy-net-driver-channel/Cargo.toml | 2 +- embassy-net-esp-hosted/Cargo.toml | 2 +- embassy-net-ppp/Cargo.toml | 2 +- embassy-net/CHANGELOG.md | 5 +++++ embassy-net/Cargo.toml | 4 ++-- embassy-nrf/Cargo.toml | 2 +- embassy-rp/Cargo.toml | 2 +- embassy-stm32-wpan/Cargo.toml | 2 +- embassy-stm32/Cargo.toml | 2 +- embassy-sync/CHANGELOG.md | 7 ++++++- embassy-sync/Cargo.toml | 2 +- embassy-usb-logger/Cargo.toml | 2 +- embassy-usb/Cargo.toml | 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/boot/bootloader/nrf/Cargo.toml | 2 +- examples/boot/bootloader/rp/Cargo.toml | 2 +- examples/boot/bootloader/stm32/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/stm32f334/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/riscv32/Cargo.toml | 2 +- tests/rp/Cargo.toml | 2 +- tests/stm32/Cargo.toml | 2 +- 63 files changed, 73 insertions(+), 63 deletions(-) diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index b19cabfe..789e3ab0 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml @@ -12,7 +12,7 @@ firmware-logs = [] [dependencies] embassy-time = { version = "0.1.5", path = "../embassy-time"} -embassy-sync = { version = "0.3.0", path = "../embassy-sync"} +embassy-sync = { version = "0.4.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} diff --git a/embassy-boot/boot/Cargo.toml b/embassy-boot/boot/Cargo.toml index 6a334f01..8e11db57 100644 --- a/embassy-boot/boot/Cargo.toml +++ b/embassy-boot/boot/Cargo.toml @@ -28,7 +28,7 @@ digest = "0.10" log = { version = "0.4", optional = true } ed25519-dalek = { version = "1.0.1", default_features = false, features = ["u32_backend"], optional = true } embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } -embassy-sync = { version = "0.3.0", path = "../../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } embedded-storage = "0.3.0" embedded-storage-async = { version = "0.4.0", optional = true } salty = { git = "https://github.com/ycrypto/salty.git", rev = "a9f17911a5024698406b75c0fac56ab5ccf6a8c7", optional = true } diff --git a/embassy-boot/nrf/Cargo.toml b/embassy-boot/nrf/Cargo.toml index 8186a995..72c27efa 100644 --- a/embassy-boot/nrf/Cargo.toml +++ b/embassy-boot/nrf/Cargo.toml @@ -16,7 +16,7 @@ target = "thumbv7em-none-eabi" [dependencies] defmt = { version = "0.3", optional = true } -embassy-sync = { path = "../../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } embassy-nrf = { path = "../../embassy-nrf" } embassy-boot = { path = "../boot", default-features = false } cortex-m = { version = "0.7.6" } diff --git a/embassy-boot/rp/Cargo.toml b/embassy-boot/rp/Cargo.toml index 5147392c..efa0ef8a 100644 --- a/embassy-boot/rp/Cargo.toml +++ b/embassy-boot/rp/Cargo.toml @@ -17,7 +17,7 @@ defmt = { version = "0.3", optional = true } defmt-rtt = { version = "0.4", optional = true } log = { version = "0.4", optional = true } -embassy-sync = { path = "../../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } embassy-rp = { path = "../../embassy-rp", default-features = false } embassy-boot = { path = "../boot", default-features = false } embassy-time = { path = "../../embassy-time" } diff --git a/embassy-boot/stm32/Cargo.toml b/embassy-boot/stm32/Cargo.toml index 99a6b8e0..da310277 100644 --- a/embassy-boot/stm32/Cargo.toml +++ b/embassy-boot/stm32/Cargo.toml @@ -18,7 +18,7 @@ defmt = { version = "0.3", optional = true } defmt-rtt = { version = "0.4", optional = true } log = { version = "0.4", optional = true } -embassy-sync = { path = "../../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } embassy-stm32 = { path = "../../embassy-stm32", default-features = false } embassy-boot = { path = "../boot", default-features = false } cortex-m = { version = "0.7.6" } diff --git a/embassy-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml index 55ef734e..11e47acb 100644 --- a/embassy-embedded-hal/Cargo.toml +++ b/embassy-embedded-hal/Cargo.toml @@ -20,7 +20,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-sync = { version = "0.4.0", path = "../embassy-sync" } embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [ "unproven", diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml index 846c3919..f2ba379b 100644 --- a/embassy-lora/Cargo.toml +++ b/embassy-lora/Cargo.toml @@ -21,7 +21,7 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.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" } embedded-hal = { version = "0.2", features = ["unproven"] } diff --git a/embassy-net-driver-channel/Cargo.toml b/embassy-net-driver-channel/Cargo.toml index 2fd26a7c..100c3ebc 100644 --- a/embassy-net-driver-channel/Cargo.toml +++ b/embassy-net-driver-channel/Cargo.toml @@ -24,6 +24,6 @@ features = ["defmt"] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../embassy-sync" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index 5f901bb9..eba54249 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml @@ -8,7 +8,7 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } embassy-time = { version = "0.1.5", path = "../embassy-time" } -embassy-sync = { version = "0.3.0", path = "../embassy-sync"} +embassy-sync = { version = "0.4.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml index bd992de0..273dccbc 100644 --- a/embassy-net-ppp/Cargo.toml +++ b/embassy-net-ppp/Cargo.toml @@ -19,7 +19,7 @@ embedded-io-async = { version = "0.6.0" } embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } ppproto = { version = "0.1.2"} -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../embassy-sync" } [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-ppp-v$VERSION/embassy-net-ppp/src/" diff --git a/embassy-net/CHANGELOG.md b/embassy-net/CHANGELOG.md index 7b91b844..4030e050 100644 --- a/embassy-net/CHANGELOG.md +++ b/embassy-net/CHANGELOG.md @@ -5,6 +5,11 @@ 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.2.1 - 2023-10-31 + +- Re-add impl_trait_projections +- Fix: Reset DHCP socket when the link up is detected + ## 0.2.0 - 2023-10-18 - Re-export `smoltcp::wire::IpEndpoint` diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 573d20fb..918c5bd3 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-net" -version = "0.2.0" +version = "0.2.1" edition = "2021" license = "MIT OR Apache-2.0" description = "Async TCP/IP network stack for embedded systems" @@ -53,7 +53,7 @@ smoltcp = { version = "0.10.0", default-features = false, features = [ embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-time = { version = "0.1.5", path = "../embassy-time" } -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../embassy-sync" } embedded-io-async = { version = "0.6.0", optional = true } managed = { version = "0.8.0", default-features = false, features = [ "map" ] } diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 360f77c1..1052a52a 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -95,7 +95,7 @@ _nrf52832_anomaly_109 = [] [dependencies] embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.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" } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true } diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 903dc25a..5760d10d 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -59,7 +59,7 @@ nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "em unstable-traits = ["embedded-hal-1", "embedded-hal-nb"] [dependencies] -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../embassy-sync" } embassy-time = { version = "0.1.5", 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"] } diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 52ecf15d..bee03901 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -12,7 +12,7 @@ features = ["stm32wb55rg"] [dependencies] embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../embassy-sync" } embassy-time = { version = "0.1.5", 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" } diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 99288340..143cb735 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -32,7 +32,7 @@ flavors = [ ] [dependencies] -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../embassy-sync" } embassy-time = { version = "0.1.5", 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"] } diff --git a/embassy-sync/CHANGELOG.md b/embassy-sync/CHANGELOG.md index 2c53dd0f..9340d734 100644 --- a/embassy-sync/CHANGELOG.md +++ b/embassy-sync/CHANGELOG.md @@ -5,9 +5,14 @@ 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.4.0 - 2023-10-31 + +- Re-add impl_trait_projections +- switch to `embedded-io 0.6` + ## 0.3.0 - 2023-09-14 -- switch to embedded-io 0.5 +- switch to `embedded-io 0.5` - add api for polling channels with context - standardise fn names on channels - add zero-copy channel diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index 7d3d2c58..81aeafae 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-sync" -version = "0.3.0" +version = "0.4.0" edition = "2021" description = "no-std, no-alloc synchronization primitives with async support" repository = "https://github.com/embassy-rs/embassy" diff --git a/embassy-usb-logger/Cargo.toml b/embassy-usb-logger/Cargo.toml index 944a48a5..29a8e421 100644 --- a/embassy-usb-logger/Cargo.toml +++ b/embassy-usb-logger/Cargo.toml @@ -10,7 +10,7 @@ target = "thumbv7em-none-eabi" [dependencies] embassy-usb = { version = "0.1.0", path = "../embassy-usb" } -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../embassy-sync" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } futures = { version = "0.3", default-features = false } static_cell = "1" diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 9ae14499..d820a2d0 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -41,7 +41,7 @@ max-handler-count-8 = [] [dependencies] embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } -embassy-sync = { version = "0.3.0", path = "../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../embassy-sync" } embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } defmt = { version = "0.3", optional = true } diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 275367ff..e35952a6 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", path = "../../../../embassy-time", features = ["nightly"] } embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly"] } diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index da89f15d..43e74dd0 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", path = "../../../../embassy-time", features = ["nightly"] } embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", "unstable-traits", "nightly"] } diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index 147a5bcf..b4fe2a24 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index 3fa136ae..237e359d 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index 7ca767bd..0ae6aaf3 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index 3e3cbbd8..b59ea5e8 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 5e77b7d5..502aceae 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index aa5c5cf9..112fefea 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index 87b8a116..2b97a8b6 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/boot/bootloader/nrf/Cargo.toml b/examples/boot/bootloader/nrf/Cargo.toml index 42391778..db0ffaec 100644 --- a/examples/boot/bootloader/nrf/Cargo.toml +++ b/examples/boot/bootloader/nrf/Cargo.toml @@ -12,7 +12,7 @@ defmt-rtt = { version = "0.4", optional = true } embassy-nrf = { path = "../../../../embassy-nrf", features = ["nightly"] } embassy-boot-nrf = { path = "../../../../embassy-boot/nrf" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } -embassy-sync = { path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } cortex-m-rt = { version = "0.7" } cfg-if = "1.0.0" diff --git a/examples/boot/bootloader/rp/Cargo.toml b/examples/boot/bootloader/rp/Cargo.toml index c1dc99ee..b139a4b5 100644 --- a/examples/boot/bootloader/rp/Cargo.toml +++ b/examples/boot/bootloader/rp/Cargo.toml @@ -11,7 +11,7 @@ defmt-rtt = { version = "0.4", optional = true } embassy-rp = { path = "../../../../embassy-rp", features = ["nightly"] } embassy-boot-rp = { path = "../../../../embassy-boot/rp" } -embassy-sync = { path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } embassy-time = { path = "../../../../embassy-time", features = ["nightly"] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } diff --git a/examples/boot/bootloader/stm32/Cargo.toml b/examples/boot/bootloader/stm32/Cargo.toml index 9175768d..4816e62e 100644 --- a/examples/boot/bootloader/stm32/Cargo.toml +++ b/examples/boot/bootloader/stm32/Cargo.toml @@ -12,7 +12,7 @@ defmt-rtt = { version = "0.4", optional = true } embassy-stm32 = { path = "../../../../embassy-stm32", features = ["nightly"] } embassy-boot-stm32 = { path = "../../../../embassy-boot/stm32" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } -embassy-sync = { path = "../../../../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } cortex-m-rt = { version = "0.7" } embedded-storage = "0.3.0" embedded-storage-async = "0.4.0" diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index e5820f26..f49f56b4 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -16,7 +16,7 @@ log = [ ] [dependencies] -embassy-sync = { version = "0.3.0", path = "../../embassy-sync" } +embassy-sync = { version = "0.4.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.5", path = "../../embassy-time" } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index a81d43a2..5bb8dc8a 100644 --- a/examples/nrf52840-rtic/Cargo.toml +++ b/examples/nrf52840-rtic/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" 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-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 75373350..76b6dbce 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -29,7 +29,7 @@ nightly = [ [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 24972a4f..4b4cccae 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = [ +embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = [ "defmt", ] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 7386eeea..e3460023 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] 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-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index a5f4c871..a6fa4281 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["log"] } +embassy-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["log", "std", "nightly"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index b80ccd30..ba3f47fe 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32c031c6 to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 47a95ec1..deb113d9 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -14,7 +14,7 @@ cortex-m-rt = "0.7.0" defmt = "0.3" defmt-rtt = "0.4" panic-probe = "0.3" -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } static_cell = { version = "1.1", features = ["nightly"]} diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 34319fbd..290819a6 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f103c8 to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index fbf50836..7808dbf2 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f207zg to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index b3b2b123..919d681b 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f303ze to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml index 239c58b3..1b89021a 100644 --- a/examples/stm32f334/Cargo.toml +++ b/examples/stm32f334/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.4.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.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] } diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 9b10e975..08642d6b 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f429zi to your chip name, if necessary. 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-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 5cbaca46..98540862 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32f767zi to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index d0b7d85f..967c99b2 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32g071rb to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 908c6d19..4fb08dde 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32g491re to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index f5980d87..02d0a315 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32h563zi to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 0855bdfc..0f9770f5 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -7,7 +7,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", "chrono"] } -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index 03b6d600..6c709dfb 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -12,7 +12,7 @@ nightly = ["embassy-stm32/nightly", "embassy-time/nightly", "embassy-time/unstab [dependencies] # Change stm32l072cz to your chip name, if necessary. 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-sync = { version = "0.4.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.5", 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 } diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index 70058d49..6c77cfc5 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index b420ad56..0781aa37 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32l4s5vi to your chip name, if necessary. 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-sync = { version = "0.4.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.5", 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" } diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index ecf88d7e..21c7e35f 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32l552ze to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index de60b3b1..a746909b 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32u585ai to your chip name, if necessary. 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index fa2cc63f..eca8ef44 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32wb55rg to your chip name in both dependencies, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 68ab5a46..712bbb4c 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] 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-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 6a338af4..d072f9ac 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32wl55jc-cm4 to your chip name, if necessary. 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-sync = { version = "0.4.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.5", 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" } diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index 29339295..b5bf2b83 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" crate-type = ["cdylib"] [dependencies] -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["log"] } +embassy-sync = { version = "0.4.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.5", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 96a5871e..aa45fd9a 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" 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-sync = { version = "0.4.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.5", 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"] } diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index 3bb46d37..da2a8d55 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] critical-section = { version = "1.1.1", features = ["restore-state-bool"] } -embassy-sync = { version = "0.3.0", path = "../../embassy-sync" } +embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] } embassy-time = { version = "0.1.5", path = "../../embassy-time" } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 1fb73857..689ca9fa 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] teleprobe-meta = "1.1" -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.4.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.5", 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"] } diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index c6a50e2c..afd97e20 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -45,7 +45,7 @@ dac-adc-pin = [] [dependencies] teleprobe-meta = "1" -embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-sync = { version = "0.4.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.5", 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"] } From aed3e5674f780135a87db8e178ae78042361975e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 31 Oct 2023 10:13:27 +0100 Subject: [PATCH 077/188] Drop futures dependency in embassy-nrf --- embassy-nrf/Cargo.toml | 1 - embassy-nrf/src/pdm.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 360f77c1..c30b319c 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -110,7 +110,6 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } cortex-m-rt = ">=0.6.15,<0.8" cortex-m = "0.7.6" -futures = { version = "0.3.17", default-features = false } critical-section = "1.1" rand_core = "0.6.3" fixed = "1.10.0" diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs index 01f41e9f..24fa29a4 100644 --- a/embassy-nrf/src/pdm.rs +++ b/embassy-nrf/src/pdm.rs @@ -2,6 +2,7 @@ #![macro_use] +use core::future::poll_fn; use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; @@ -9,7 +10,6 @@ use core::task::Poll; use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::{into_ref, PeripheralRef}; use fixed::types::I7F1; -use futures::future::poll_fn; use crate::chip::EASY_DMA_SIZE; use crate::gpio::sealed::Pin; From 5f9602d28bdac06f5f2fbfa2c49cd98d689f4c37 Mon Sep 17 00:00:00 2001 From: "Andres O. Vela" Date: Tue, 31 Oct 2023 22:48:52 +0100 Subject: [PATCH 078/188] time: fix MockDriver::now() --- embassy-time/src/driver_mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs index becb6bfd..c255615c 100644 --- a/embassy-time/src/driver_mock.rs +++ b/embassy-time/src/driver_mock.rs @@ -51,7 +51,7 @@ impl MockDriver { impl Driver for MockDriver { fn now(&self) -> u64 { - critical_section::with(|cs| self.now.borrow(cs).get().as_micros() as u64) + critical_section::with(|cs| self.now.borrow(cs).get().as_ticks() as u64) } unsafe fn allocate_alarm(&self) -> Option { From dd6a29adb2b503520f7db28e50563f41cf1f4730 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 1 Nov 2023 00:17:44 +0100 Subject: [PATCH 079/188] Release embassy-executor v0.3.1 --- embassy-executor/CHANGELOG.md | 4 ++++ embassy-executor/Cargo.toml | 2 +- embassy-rp/Cargo.toml | 2 +- embassy-stm32/Cargo.toml | 2 +- embassy-time/Cargo.toml | 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/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/stm32f334/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/riscv32/Cargo.toml | 2 +- tests/rp/Cargo.toml | 2 +- tests/stm32/Cargo.toml | 2 +- 44 files changed, 47 insertions(+), 43 deletions(-) diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index ccbca1eb..cade48f0 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/CHANGELOG.md @@ -5,6 +5,10 @@ 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.3.1 - 2023-11-01 + +- Fix spurious "Found waker not created by the Embassy executor" error in recent nightlies. + ## 0.3.0 - 2023-08-25 - Replaced Pender. Implementations now must define an extern function called `__pender`. diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index a793a198..d8cc3e8a 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-executor" -version = "0.3.0" +version = "0.3.1" edition = "2021" license = "MIT OR Apache-2.0" description = "async/await executor designed for embedded usage" diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 5760d10d..5dc15c73 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -94,5 +94,5 @@ pio = {version= "0.2.1" } rp2040-boot2 = "0.3" [dev-dependencies] -embassy-executor = { version = "0.3.0", path = "../embassy-executor", features = ["nightly", "arch-std", "executor-thread"] } +embassy-executor = { version = "0.3.1", path = "../embassy-executor", features = ["nightly", "arch-std", "executor-thread"] } static_cell = "1.1" diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 143cb735..ffb70934 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -39,7 +39,7 @@ embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", fea embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } -embassy-executor = { version = "0.3.0", path = "../embassy-executor", optional = true } +embassy-executor = { version = "0.3.1", path = "../embassy-executor", optional = true } 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} diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 8b5d31ee..76008f0a 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -258,4 +258,4 @@ wasm-timer = { version = "0.2.5", optional = true } [dev-dependencies] serial_test = "0.9" critical-section = { version = "1.1", features = ["std"] } -embassy-executor = { version = "0.3.0", path = "../embassy-executor", features = ["nightly"] } +embassy-executor = { version = "0.3.1", path = "../embassy-executor", features = ["nightly"] } diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index e35952a6..98c15b1a 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 43e74dd0..061e7b86 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index b4fe2a24..f15467b0 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index 237e359d..80ff485d 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index 0ae6aaf3..29b5e202 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index b59ea5e8..8d4ec07b 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 502aceae..4a937999 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index 112fefea..1c8b15f8 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index 2b97a8b6..eaa17de2 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index f49f56b4..e1bb00b1 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -17,7 +17,7 @@ log = [ [dependencies] embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time" } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 76b6dbce..0554b7e0 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -30,7 +30,7 @@ nightly = [ [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 4b4cccae..9c62508c 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -9,7 +9,7 @@ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = [ "defmt", ] } -embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", +embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "defmt", "integrated-timers", diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index e3460023..d020a0f5 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] } embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index a6fa4281..12ec40fa 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["log", "std", "nightly"] } embassy-net = { version = "0.2.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" } diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index ba3f47fe..39470f37 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32c031c6 to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index deb113d9..953fa584 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -15,7 +15,7 @@ defmt = "0.3" defmt-rtt = "0.4" panic-probe = "0.3" embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } static_cell = { version = "1.1", features = ["nightly"]} diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 290819a6..1fe460dd 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f103c8 to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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 7808dbf2..bfb8f514 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f207zg to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 919d681b..548191ca 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f303ze to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml index 1b89021a..b42cc996 100644 --- a/examples/stm32f334/Cargo.toml +++ b/examples/stm32f334/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 08642d6b..916d0490 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f429zi to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 98540862..35757e62 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f767zi to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } embedded-io-async = { version = "0.6.0" } diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 967c99b2..fb7f780f 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32g071rb to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 4fb08dde..3ca6ff2f 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32g491re to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index 02d0a315..c4f41d1c 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32h563zi to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } embedded-io-async = { version = "0.6.0" } diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 0f9770f5..d6b14a60 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # 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", "chrono"] } embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } embedded-io-async = { version = "0.6.0" } diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index 6c709dfb..edd1d026 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -13,7 +13,7 @@ nightly = ["embassy-stm32/nightly", "embassy-time/nightly", "embassy-time/unstab # Change stm32l072cz to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] } embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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 } diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index 6c77cfc5..cc27dfc6 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 0781aa37..2fbba463 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32l4s5vi to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 21c7e35f..2457b40d 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32l552ze to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index a746909b..27c25ebc 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32u585ai to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index eca8ef44..5864906d 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 712bbb4c..12e0e5ab 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] } embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index d072f9ac..9e8ffa16 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32wl55jc-cm4 to your chip name, if necessary. 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.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index b5bf2b83..a7250cb7 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } wasm-logger = "0.2.0" diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index aa45fd9a..6441d5c3 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -9,7 +9,7 @@ teleprobe-meta = "1" embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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" } diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index da2a8d55..56db42dd 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] critical-section = { version = "1.1.1", features = ["restore-state-bool"] } embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } -embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] } +embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] } embassy-time = { version = "0.1.5", path = "../../embassy-time" } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 689ca9fa..d947568b 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" teleprobe-meta = "1.1" embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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" } diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index afd97e20..1ca14ee8 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -46,7 +46,7 @@ dac-adc-pin = [] teleprobe-meta = "1" embassy-sync = { version = "0.4.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-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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" } From e519e002657e992c47bebc356b044902334d32bc Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 1 Nov 2023 04:56:56 +0100 Subject: [PATCH 080/188] Update Rust nightly. --- cyw43-pio/src/lib.rs | 2 +- cyw43/src/control.rs | 1 - cyw43/src/lib.rs | 2 +- embassy-boot/boot/src/lib.rs | 1 + embassy-executor/src/lib.rs | 1 + embassy-net-adin1110/src/lib.rs | 1 + embassy-net-wiznet/src/lib.rs | 1 + embassy-stm32-wpan/src/lib.rs | 4 ++++ embassy-stm32-wpan/src/mac/driver.rs | 1 - embassy-time/src/lib.rs | 1 + embassy-usb-driver/src/lib.rs | 1 + examples/rp/src/bin/pio_uart.rs | 1 + examples/rp/src/bin/wifi_ap_tcp_server.rs | 2 +- examples/rp/src/bin/wifi_scan.rs | 2 +- examples/rp/src/bin/wifi_tcp_server.rs | 2 +- examples/stm32wl/src/bin/lora_lorawan.rs | 1 + examples/stm32wl/src/bin/lora_p2p_receive.rs | 1 + examples/stm32wl/src/bin/lora_p2p_send.rs | 1 + rust-toolchain.toml | 2 +- 19 files changed, 20 insertions(+), 8 deletions(-) diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs index 830a5b44..de89ed58 100644 --- a/cyw43-pio/src/lib.rs +++ b/cyw43-pio/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] -#![allow(incomplete_features)] #![feature(async_fn_in_trait)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] use core::slice; diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index d2709304..ffcf2d9b 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs @@ -4,7 +4,6 @@ use embassy_net_driver_channel as ch; use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; use embassy_time::Timer; -pub use crate::bus::SpiBusCyw43; use crate::consts::*; use crate::events::{Event, EventSubscriber, Events}; use crate::fmt::Bytes; diff --git a/cyw43/src/lib.rs b/cyw43/src/lib.rs index 6b124cf7..e60f87d0 100644 --- a/cyw43/src/lib.rs +++ b/cyw43/src/lib.rs @@ -1,7 +1,7 @@ #![no_std] #![no_main] -#![allow(incomplete_features)] #![feature(async_fn_in_trait, type_alias_impl_trait, concat_bytes)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] #![deny(unused_must_use)] // This mod MUST go first, so that the others see its macros. diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs index 47f7c179..9f035637 100644 --- a/embassy-boot/boot/src/lib.rs +++ b/embassy-boot/boot/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] +#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))] #![no_std] #![warn(missing_docs)] #![doc = include_str!("../README.md")] diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 3ce687eb..020f9095 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -33,6 +33,7 @@ check_at_most_one!("arch-cortex-m", "arch-riscv32", "arch-xtensa", "arch-std", " mod arch; #[cfg(feature = "_arch")] +#[allow(unused_imports)] // don't warn if the module is empty. pub use arch::*; pub mod raw; diff --git a/embassy-net-adin1110/src/lib.rs b/embassy-net-adin1110/src/lib.rs index edee3438..331c596d 100644 --- a/embassy-net-adin1110/src/lib.rs +++ b/embassy-net-adin1110/src/lib.rs @@ -1,5 +1,6 @@ #![deny(clippy::pedantic)] #![feature(async_fn_in_trait)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] #![cfg_attr(not(any(test, feature = "std")), no_std)] #![allow(clippy::module_name_repetitions)] #![allow(clippy::missing_errors_doc)] diff --git a/embassy-net-wiznet/src/lib.rs b/embassy-net-wiznet/src/lib.rs index afdb6729..21d5f46d 100644 --- a/embassy-net-wiznet/src/lib.rs +++ b/embassy-net-wiznet/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] #![feature(async_fn_in_trait)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] #![doc = include_str!("../README.md")] pub mod chip; diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs index 2a8ab725..69a3d082 100644 --- a/embassy-stm32-wpan/src/lib.rs +++ b/embassy-stm32-wpan/src/lib.rs @@ -1,5 +1,9 @@ #![no_std] #![cfg_attr(any(feature = "ble", feature = "mac"), feature(async_fn_in_trait))] +#![cfg_attr( + any(feature = "ble", feature = "mac"), + allow(stable_features, unknown_lints, async_fn_in_trait) +)] #![cfg_attr(feature = "mac", feature(type_alias_impl_trait, concat_bytes))] // This must go FIRST so that all the other modules see its macros. diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs index ffba6e5e..5b9d5daf 100644 --- a/embassy-stm32-wpan/src/mac/driver.rs +++ b/embassy-stm32-wpan/src/mac/driver.rs @@ -1,4 +1,3 @@ -#![allow(incomplete_features)] #![deny(unused_must_use)] use core::task::Context; diff --git a/embassy-time/src/lib.rs b/embassy-time/src/lib.rs index 45c1e882..a90368d5 100644 --- a/embassy-time/src/lib.rs +++ b/embassy-time/src/lib.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(any(feature = "std", feature = "wasm", test)), no_std)] #![cfg_attr(feature = "nightly", feature(async_fn_in_trait))] +#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))] #![doc = include_str!("../README.md")] #![allow(clippy::new_without_default)] #![warn(missing_docs)] diff --git a/embassy-usb-driver/src/lib.rs b/embassy-usb-driver/src/lib.rs index 86e37595..9c2dddda 100644 --- a/embassy-usb-driver/src/lib.rs +++ b/embassy-usb-driver/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] #![feature(async_fn_in_trait)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] #![doc = include_str!("../README.md")] #![warn(missing_docs)] diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs index aa9e52cb..45416c56 100644 --- a/examples/rp/src/bin/pio_uart.rs +++ b/examples/rp/src/bin/pio_uart.rs @@ -10,6 +10,7 @@ #![no_main] #![feature(type_alias_impl_trait)] #![feature(async_fn_in_trait)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] use defmt::{info, panic, trace}; use embassy_executor::Spawner; diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs index 98cae53f..b5344c18 100644 --- a/examples/rp/src/bin/wifi_ap_tcp_server.rs +++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs @@ -5,7 +5,7 @@ #![no_main] #![feature(type_alias_impl_trait)] #![feature(async_fn_in_trait)] -#![allow(incomplete_features)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] use core::str::from_utf8; diff --git a/examples/rp/src/bin/wifi_scan.rs b/examples/rp/src/bin/wifi_scan.rs index dbbbf6c8..f2acaf3e 100644 --- a/examples/rp/src/bin/wifi_scan.rs +++ b/examples/rp/src/bin/wifi_scan.rs @@ -5,7 +5,7 @@ #![no_main] #![feature(type_alias_impl_trait)] #![feature(async_fn_in_trait)] -#![allow(incomplete_features)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] use core::str; diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index c00fff21..4e74ad11 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs @@ -5,7 +5,7 @@ #![no_main] #![feature(type_alias_impl_trait)] #![feature(async_fn_in_trait)] -#![allow(incomplete_features)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] use core::str::from_utf8; diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 35a6a842..226e6786 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -4,6 +4,7 @@ #![no_main] #![macro_use] #![feature(type_alias_impl_trait, async_fn_in_trait)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] use defmt::info; use embassy_executor::Spawner; diff --git a/examples/stm32wl/src/bin/lora_p2p_receive.rs b/examples/stm32wl/src/bin/lora_p2p_receive.rs index 1c485d73..a3bb0c0f 100644 --- a/examples/stm32wl/src/bin/lora_p2p_receive.rs +++ b/examples/stm32wl/src/bin/lora_p2p_receive.rs @@ -4,6 +4,7 @@ #![no_main] #![macro_use] #![feature(type_alias_impl_trait, async_fn_in_trait)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] use defmt::info; use embassy_executor::Spawner; diff --git a/examples/stm32wl/src/bin/lora_p2p_send.rs b/examples/stm32wl/src/bin/lora_p2p_send.rs index 3afa78ac..08dd0845 100644 --- a/examples/stm32wl/src/bin/lora_p2p_send.rs +++ b/examples/stm32wl/src/bin/lora_p2p_send.rs @@ -4,6 +4,7 @@ #![no_main] #![macro_use] #![feature(type_alias_impl_trait, async_fn_in_trait)] +#![allow(stable_features, unknown_lints, async_fn_in_trait)] use defmt::info; use embassy_executor::Spawner; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 755a9207..419c3108 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ # Before upgrading check that everything is available on all tier1 targets here: # https://rust-lang.github.io/rustup-components-history [toolchain] -channel = "nightly-2023-10-02" +channel = "nightly-2023-11-01" components = [ "rust-src", "rustfmt", "llvm-tools" ] targets = [ "thumbv7em-none-eabi", From e78a6db15138fd2befea5e15cab4e57fab3d0431 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Wed, 1 Nov 2023 03:36:54 +0000 Subject: [PATCH 081/188] stm32: Don't try handle EXTI inputs above 16 --- embassy-stm32/src/exti.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 538791a5..07c63a2e 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -47,6 +47,9 @@ pub unsafe fn on_irq() { #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] let bits = EXTI.rpr(0).read().0 | EXTI.fpr(0).read().0; + // We don't handle or change any EXTI lines above 16. + let bits = bits & 0x0000FFFF; + // Mask all the channels that fired. cpu_regs().imr(0).modify(|w| w.0 &= !bits); From d0d8585e4cdb73373ead13289a28b7d155377963 Mon Sep 17 00:00:00 2001 From: shakencodes Date: Wed, 1 Nov 2023 11:46:17 -0700 Subject: [PATCH 082/188] Reinstate rcc::Config adc_clock_source field --- embassy-stm32/src/rcc/l4l5.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 2f89f682..a7c136a3 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -4,8 +4,8 @@ pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; #[cfg(any(stm32wb, stm32wl))] pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; 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, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, + Adcsel, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, + Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, }; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -52,7 +52,30 @@ pub struct Pll { pub divr: Option, } -/// Clocks configutation +#[derive(Clone, Copy)] +pub enum AdcClockSource { + HSI16, + PLLPCLK, + SYSCLK, +} + +impl AdcClockSource { + pub fn adcsel(&self) -> Adcsel { + match self { + AdcClockSource::HSI16 => Adcsel::HSI, + AdcClockSource::PLLPCLK => Adcsel::PLL1_P, + AdcClockSource::SYSCLK => Adcsel::SYS, + } + } +} + +impl Default for AdcClockSource { + fn default() -> Self { + Self::HSI16 + } +} + +/// Clocks configuration pub struct Config { // base clock sources pub msi: Option, @@ -84,6 +107,8 @@ pub struct Config { // low speed LSI/LSE/RTC pub ls: super::LsConfig, + + pub adc_clock_source: AdcClockSource, } impl Default for Config { @@ -111,6 +136,7 @@ impl Default for Config { #[cfg(any(stm32l4, stm32l5, stm32wb))] clk48_src: Clk48Src::HSI48, ls: Default::default(), + adc_clock_source: AdcClockSource::default(), } } } @@ -344,6 +370,8 @@ pub(crate) unsafe fn init(config: Config) { }); while RCC.cfgr().read().sws() != config.mux {} + RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source.adcsel())); + #[cfg(any(stm32wl, stm32wb))] { RCC.extcfgr().modify(|w| { From e2688dda22a813fdcf7938ef7ca003be4c94c0c2 Mon Sep 17 00:00:00 2001 From: shakencodes Date: Wed, 1 Nov 2023 12:06:19 -0700 Subject: [PATCH 083/188] Eliminates redefinition of AdcClockSource --- embassy-stm32/src/rcc/l4l5.rs | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index a7c136a3..78b8e060 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -4,8 +4,8 @@ pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; #[cfg(any(stm32wb, stm32wl))] pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; pub use crate::pac::rcc::vals::{ - Adcsel, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, - Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, + Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, + Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, }; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -52,29 +52,6 @@ pub struct Pll { pub divr: Option, } -#[derive(Clone, Copy)] -pub enum AdcClockSource { - HSI16, - PLLPCLK, - SYSCLK, -} - -impl AdcClockSource { - pub fn adcsel(&self) -> Adcsel { - match self { - AdcClockSource::HSI16 => Adcsel::HSI, - AdcClockSource::PLLPCLK => Adcsel::PLL1_P, - AdcClockSource::SYSCLK => Adcsel::SYS, - } - } -} - -impl Default for AdcClockSource { - fn default() -> Self { - Self::HSI16 - } -} - /// Clocks configuration pub struct Config { // base clock sources @@ -136,7 +113,7 @@ impl Default for Config { #[cfg(any(stm32l4, stm32l5, stm32wb))] clk48_src: Clk48Src::HSI48, ls: Default::default(), - adc_clock_source: AdcClockSource::default(), + adc_clock_source: AdcClockSource::HSI, } } } @@ -370,7 +347,7 @@ pub(crate) unsafe fn init(config: Config) { }); while RCC.cfgr().read().sws() != config.mux {} - RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source.adcsel())); + RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); #[cfg(any(stm32wl, stm32wb))] { From b4a82b7ed44cfbb9929d4c1a6357aaf6ec177ac2 Mon Sep 17 00:00:00 2001 From: shakencodes Date: Wed, 1 Nov 2023 12:48:08 -0700 Subject: [PATCH 084/188] =?UTF-8?q?Correct=20adc=5Fclock=5Fsource=20for=20?= =?UTF-8?q?all=20=C2=B5procs=20in=20l4l5.rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/src/rcc/l4l5.rs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index ffb70934..bc79ab7a 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-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73b8c37ae74fc28b247188c989fd99400611bd6b" } 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-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73b8c37ae74fc28b247188c989fd99400611bd6b", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 78b8e060..d855d477 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -113,7 +113,7 @@ impl Default for Config { #[cfg(any(stm32l4, stm32l5, stm32wb))] clk48_src: Clk48Src::HSI48, ls: Default::default(), - adc_clock_source: AdcClockSource::HSI, + adc_clock_source: AdcClockSource::SYS, } } } @@ -347,6 +347,9 @@ pub(crate) unsafe fn init(config: Config) { }); while RCC.cfgr().read().sws() != config.mux {} + #[cfg(stm32l5)] + RCC.ccipr1().modify(|w| w.set_adcsel(config.adc_clock_source)); + #[cfg(not(stm32l5))] RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); #[cfg(any(stm32wl, stm32wb))] From bc07539133937c254930bbdafe1b01bb0f5912e3 Mon Sep 17 00:00:00 2001 From: shakencodes Date: Wed, 1 Nov 2023 13:30:04 -0700 Subject: [PATCH 085/188] Fix missed field in cfg'd code --- embassy-stm32/src/rcc/l4l5.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index d855d477..0d052713 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -148,6 +148,7 @@ pub const WPAN_DEFAULT: Config = Config { shared_ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, + adc_clock_source: AdcClockSource::SYS, }; pub(crate) unsafe fn init(config: Config) { From bab61f96650751d1133538431f3bfccdfda29bf7 Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 1 Nov 2023 17:17:14 -0500 Subject: [PATCH 086/188] stm32/rtc: misc. cleanup and move to bps by default --- embassy-stm32/src/low_power.rs | 4 +- embassy-stm32/src/rtc/datetime.rs | 32 +++------- embassy-stm32/src/rtc/mod.rs | 102 ++++++++++++++++-------------- embassy-stm32/src/rtc/v2.rs | 4 +- embassy-stm32/src/rtc/v3.rs | 1 + 5 files changed, 70 insertions(+), 73 deletions(-) diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index d5846f53..0d853fda 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -61,7 +61,7 @@ pub struct Executor { impl Executor { /// Create a new Executor. pub fn take() -> &'static mut Self { - unsafe { + critical_section::with(|_| unsafe { assert!(EXECUTOR.is_none()); EXECUTOR = Some(Self { @@ -72,7 +72,7 @@ impl Executor { }); EXECUTOR.as_mut().unwrap() - } + }) } unsafe fn on_wakeup_irq(&mut self) { diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs index d897843d..f3428108 100644 --- a/embassy-stm32/src/rtc/datetime.rs +++ b/embassy-stm32/src/rtc/datetime.rs @@ -18,9 +18,13 @@ pub struct RtcInstant { } impl RtcInstant { - #[allow(dead_code)] - pub(super) fn from(second: u8, subsecond: u16) -> Result { - Ok(Self { second, subsecond }) + #[cfg(not(rtc_v2f2))] + pub(super) const fn from(second: u8, subsecond: u16) -> Result { + if second > 59 { + Err(Error::InvalidSecond) + } else { + Ok(Self { second, subsecond }) + } } } @@ -226,7 +230,7 @@ impl From for chrono::Weekday { } } -fn day_of_week_from_u8(v: u8) -> Result { +pub(super) const fn day_of_week_from_u8(v: u8) -> Result { Ok(match v { 1 => DayOfWeek::Monday, 2 => DayOfWeek::Tuesday, @@ -239,24 +243,6 @@ fn day_of_week_from_u8(v: u8) -> Result { }) } -pub(super) fn day_of_week_to_u8(dotw: DayOfWeek) -> u8 { +pub(super) const fn day_of_week_to_u8(dotw: DayOfWeek) -> u8 { dotw as u8 } - -pub(super) fn validate_datetime(dt: &DateTime) -> Result<(), Error> { - if dt.year > 4095 { - Err(Error::InvalidYear) - } else if dt.month < 1 || dt.month > 12 { - Err(Error::InvalidMonth) - } else if dt.day < 1 || dt.day > 31 { - Err(Error::InvalidDay) - } else if dt.hour > 23 { - Err(Error::InvalidHour) - } else if dt.minute > 59 { - Err(Error::InvalidMinute) - } else if dt.second > 59 { - Err(Error::InvalidSecond) - } else { - Ok(()) - } -} diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index c8990c30..e527fdfe 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -9,8 +9,11 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; #[cfg(feature = "low-power")] use embassy_sync::blocking_mutex::Mutex; -pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError, RtcInstant}; -use crate::rtc::datetime::day_of_week_to_u8; +use self::datetime::day_of_week_to_u8; +#[cfg(not(rtc_v2f2))] +use self::datetime::RtcInstant; +pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; +use crate::pac::rtc::regs::{Dr, Tr}; use crate::time::Hertz; /// refer to AN4759 to compare features of RTC2 and RTC3 @@ -31,11 +34,15 @@ use crate::peripherals::RTC; use crate::rtc::sealed::Instance; /// Errors that can occur on methods on [RtcClock] +#[non_exhaustive] #[derive(Clone, Debug, PartialEq, Eq)] pub enum RtcError { /// An invalid DateTime was given or stored on the hardware. InvalidDateTime(DateTimeError), + /// The current time could not be read + ReadFailure, + /// The RTC clock is not running NotRunning, } @@ -45,48 +52,25 @@ pub struct RtcTimeProvider { } impl RtcTimeProvider { + #[cfg(not(rtc_v2f2))] + pub(crate) fn instant(&self) -> Result { + self.read(|_, tr, ss| { + let second = bcd2_to_byte((tr.st(), tr.su())); + + RtcInstant::from(second, ss).map_err(RtcError::InvalidDateTime) + }) + } + /// Return the current datetime. /// /// # Errors /// /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. pub fn now(&self) -> Result { - // 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(); - - // 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())); - - 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 DateTime::from(year, month, day, weekday, hour, minute, second) - .map_err(RtcError::InvalidDateTime); - } - } - - #[cfg(not(rcc_h7rm0433))] - { - let r = RTC::regs(); - let tr = r.tr().read(); + self.read(|dr, tr, _| { 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())); @@ -94,7 +78,33 @@ impl RtcTimeProvider { let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) + }) + } + + fn read(&self, mut f: impl FnMut(Dr, Tr, u16) -> Result) -> Result { + let r = RTC::regs(); + + #[cfg(not(rtc_v2f2))] + let read_ss = || r.ssr().read().ss(); + #[cfg(rtc_v2f2)] + let read_ss = || 0; + + let mut ss = read_ss(); + for _ in 0..5 { + let tr = r.tr().read(); + let dr = r.dr().read(); + let ss_after = read_ss(); + + // 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) + if ss == ss_after { + return f(dr, tr, ss.try_into().unwrap()); + } else { + ss = ss_after + } } + + return Err(RtcError::ReadFailure); } } @@ -145,6 +155,7 @@ impl Rtc { #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] critical_section::with(|cs| { ::enable_and_reset_with_cs(cs); + #[cfg(feature = "low-power")] unsafe { crate::rcc::REFCOUNT_STOP2 -= 1 @@ -164,6 +175,14 @@ impl Rtc { this.configure(async_psc, sync_psc); + // Wait for the clock to update after initialization + #[cfg(not(rtc_v2f2))] + { + let now = this.instant().unwrap(); + + while this.instant().unwrap().subsecond == now.subsecond {} + } + this } @@ -183,7 +202,6 @@ impl Rtc { /// /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> { - self::datetime::validate_datetime(&t).map_err(RtcError::InvalidDateTime)?; self.write(true, |rtc| { let (ht, hu) = byte_to_bcd2(t.hour() as u8); let (mnt, mnu) = byte_to_bcd2(t.minute() as u8); @@ -223,16 +241,8 @@ impl Rtc { #[cfg(not(rtc_v2f2))] /// Return the current instant. - pub fn instant(&self) -> Result { - let r = RTC::regs(); - let tr = r.tr().read(); - let subsecond = r.ssr().read().ss(); - let second = bcd2_to_byte((tr.st(), tr.su())); - - // Unlock the registers - r.dr().read(); - - RtcInstant::from(second, subsecond.try_into().unwrap()) + fn instant(&self) -> Result { + self.time_provider().instant() } /// Return the current datetime. diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index b6ab9b20..006fd63f 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs @@ -150,14 +150,14 @@ impl super::Rtc { pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) { self.write(true, |rtc| { rtc.cr().modify(|w| { + #[cfg(not(rtc_v2f2))] + w.set_bypshad(true); #[cfg(rtc_v2f2)] w.set_fmt(false); #[cfg(not(rtc_v2f2))] 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/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index a6b2655d..7bf757e7 100644 --- a/embassy-stm32/src/rtc/v3.rs +++ b/embassy-stm32/src/rtc/v3.rs @@ -11,6 +11,7 @@ impl super::Rtc { pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) { self.write(true, |rtc| { rtc.cr().modify(|w| { + w.set_bypshad(true); w.set_fmt(Fmt::TWENTYFOURHOUR); w.set_osel(Osel::DISABLED); w.set_pol(Pol::HIGH); From a9045385550d3b72d61e9387acd6336c1bab6984 Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 1 Nov 2023 17:27:33 -0500 Subject: [PATCH 087/188] stm32/rcc: revert part of #2106 --- embassy-stm32/src/rcc/f4f7.rs | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs index 3102600a..2e4f9572 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -152,9 +152,9 @@ pub(crate) unsafe fn init(config: Config) { source: config.pll_src, }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); - #[cfg(any(all(stm32f4, not(any(stm32f410, stm32f429))), stm32f7))] + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); - #[cfg(all(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7), not(stm32f429)))] + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); // Configure sysclk @@ -197,25 +197,15 @@ pub(crate) unsafe fn init(config: Config) { pclk2_tim, rtc, pll1_q: pll.q, - #[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))] + #[cfg(all(rcc_f4, not(stm32f410)))] plli2s1_q: _plli2s.q, - #[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))] + #[cfg(all(rcc_f4, not(stm32f410)))] plli2s1_r: _plli2s.r, - #[cfg(stm32f429)] - plli2s1_q: None, - #[cfg(stm32f429)] - plli2s1_r: None, - - #[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pllsai1_q: _pllsai.q, - #[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] pllsai1_r: _pllsai.r, - - #[cfg(stm32f429)] - pllsai1_q: None, - #[cfg(stm32f429)] - pllsai1_r: None, }); } @@ -233,7 +223,6 @@ struct PllOutput { r: Option, } -#[allow(dead_code)] #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, From dcce8945afbf67658b34eb488d57adaa1adecac2 Mon Sep 17 00:00:00 2001 From: Alex Martens Date: Wed, 1 Nov 2023 16:44:31 -0700 Subject: [PATCH 088/188] embedded-hal-mock: git -> 0.10.0-rc.1 --- embassy-net-adin1110/Cargo.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/embassy-net-adin1110/Cargo.toml b/embassy-net-adin1110/Cargo.toml index a781f3bd..08c6aabd 100644 --- a/embassy-net-adin1110/Cargo.toml +++ b/embassy-net-adin1110/Cargo.toml @@ -22,9 +22,7 @@ embassy-futures = { version = "0.1.0", path = "../embassy-futures" } bitfield = "0.14.0" [dev-dependencies] -# reenable when https://github.com/dbrgn/embedded-hal-mock/pull/86 is merged. -#embedded-hal-mock = { git = "https://github.com/dbrgn/embedded-hal-mock", branch = "1-alpha", features = ["embedded-hal-async", "eh1"] }] } -embedded-hal-mock = { git = "https://github.com/newAM/embedded-hal-mock", branch = "eh1-rc.1", features = ["embedded-hal-async", "eh1"] } +embedded-hal-mock = { version = "=0.10.0-rc.1", features = ["embedded-hal-async", "eh1"] } crc = "3.0.1" env_logger = "0.10" critical-section = { version = "1.1.2", features = ["std"] } From 1f51367eb92830c4c2c36406444d255fddb6b283 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 2 Nov 2023 21:52:07 +0100 Subject: [PATCH 089/188] Upgrade static-cell to v2.0 --- embassy-executor/Cargo.toml | 1 - embassy-executor/src/lib.rs | 1 - embassy-macros/src/macros/main.rs | 3 +-- embassy-rp/Cargo.toml | 2 +- embassy-sync/Cargo.toml | 2 +- embassy-usb-logger/Cargo.toml | 2 +- examples/nrf52840/Cargo.toml | 2 +- examples/nrf5340/Cargo.toml | 2 +- examples/rp/Cargo.toml | 3 ++- examples/std/Cargo.toml | 2 +- examples/stm32f0/Cargo.toml | 3 ++- examples/stm32f3/Cargo.toml | 2 +- examples/stm32f334/Cargo.toml | 2 +- examples/stm32f4/Cargo.toml | 2 +- examples/stm32f7/Cargo.toml | 2 +- examples/stm32g0/Cargo.toml | 1 + examples/stm32h5/Cargo.toml | 2 +- examples/stm32h7/Cargo.toml | 2 +- examples/stm32l0/Cargo.toml | 3 ++- examples/stm32l4/Cargo.toml | 2 +- examples/stm32l5/Cargo.toml | 2 +- examples/stm32wb/Cargo.toml | 2 +- examples/stm32wba/Cargo.toml | 2 +- tests/nrf/Cargo.toml | 2 +- tests/rp/Cargo.toml | 3 ++- tests/rp/src/bin/gpio_multicore.rs | 2 +- tests/rp/src/bin/i2c.rs | 2 +- tests/rp/src/bin/multicore.rs | 2 +- tests/stm32/Cargo.toml | 11 +++++++---- 29 files changed, 37 insertions(+), 32 deletions(-) diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index d8cc3e8a..8e36637a 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -62,7 +62,6 @@ embassy-macros = { version = "0.2.1", path = "../embassy-macros" } embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true} atomic-polyfill = "1.0.1" critical-section = "1.1" -static_cell = "1.1" # arch-cortex-m dependencies cortex-m = { version = "0.7.6", optional = true } diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 020f9095..f2c86d8e 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -47,7 +47,6 @@ pub use spawner::*; pub mod _export { #[cfg(feature = "rtos-trace")] pub use rtos_trace::trace; - pub use static_cell::StaticCell; /// Expands the given block of code when `embassy-executor` is compiled with /// the `rtos-trace-interrupt` feature. diff --git a/embassy-macros/src/macros/main.rs b/embassy-macros/src/macros/main.rs index 7c4d5516..3c0d5856 100644 --- a/embassy-macros/src/macros/main.rs +++ b/embassy-macros/src/macros/main.rs @@ -53,8 +53,7 @@ pub fn wasm() -> TokenStream { quote! { #[wasm_bindgen::prelude::wasm_bindgen(start)] pub fn main() -> Result<(), wasm_bindgen::JsValue> { - static EXECUTOR: ::embassy_executor::_export::StaticCell<::embassy_executor::Executor> = ::embassy_executor::_export::StaticCell::new(); - let executor = EXECUTOR.init(::embassy_executor::Executor::new()); + let executor = ::std::boxed::Box::leak(::std::boxed::Box::new(::embassy_executor::Executor::new())); executor.start(|spawner| { spawner.spawn(__embassy_main(spawner)).unwrap(); diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 5dc15c73..6be9f4bb 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -95,4 +95,4 @@ rp2040-boot2 = "0.3" [dev-dependencies] embassy-executor = { version = "0.3.1", path = "../embassy-executor", features = ["nightly", "arch-std", "executor-thread"] } -static_cell = "1.1" +static_cell = { version = "2" } diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index 81aeafae..9a47fa21 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml @@ -45,4 +45,4 @@ futures-util = { version = "0.3.17", features = [ "channel" ] } # Enable critical-section implementation for std, for tests critical-section = { version = "1.1", features = ["std"] } -static_cell = "1.1" +static_cell = { version = "2" } diff --git a/embassy-usb-logger/Cargo.toml b/embassy-usb-logger/Cargo.toml index 29a8e421..48b8bbcc 100644 --- a/embassy-usb-logger/Cargo.toml +++ b/embassy-usb-logger/Cargo.toml @@ -13,6 +13,6 @@ embassy-usb = { version = "0.1.0", path = "../embassy-usb" } embassy-sync = { version = "0.4.0", path = "../embassy-sync" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } futures = { version = "0.3", default-features = false } -static_cell = "1" +static_cell = { version = "2" } usbd-hid = "0.6.0" log = "0.4" diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 0554b7e0..f803adb0 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -48,7 +48,7 @@ defmt = "0.3" defmt-rtt = "0.4" fixed = "1.10.0" -static_cell = "1.1" +static_cell = { version = "2" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 9c62508c..4196d61a 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -42,7 +42,7 @@ embedded-io-async = { version = "0.6.0" } defmt = "0.3" defmt-rtt = "0.4" -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index d020a0f5..fbe7acae 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -47,7 +47,8 @@ embedded-hal-async = "1.0.0-rc.1" embedded-hal-bus = { version = "0.1.0-rc.1", features = ["async"] } embedded-io-async = { version = "0.6.0", features = ["defmt-03"] } embedded-storage = { version = "0.3" } -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} +portable-atomic = { version = "1.5", features = ["critical-section"] } log = "0.4" pio-proc = "0.2" pio = "0.2.1" diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 12ec40fa..99511292 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -24,7 +24,7 @@ nix = "0.26.2" clap = { version = "3.0.0-beta.5", features = ["derive"] } rand_core = { version = "0.6.3", features = ["std"] } heapless = { version = "0.7.5", default-features = false } -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} [profile.release] debug = 2 diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 953fa584..3f781d76 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -17,7 +17,8 @@ panic-probe = "0.3" embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} +portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } [profile.release] debug = 2 diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 548191ca..0ab25c4c 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -24,7 +24,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa heapless = { version = "0.7.5", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} [profile.release] debug = 2 diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml index b42cc996..b3bfde44 100644 --- a/examples/stm32f334/Cargo.toml +++ b/examples/stm32f334/Cargo.toml @@ -23,4 +23,4 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa heapless = { version = "0.7.5", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 916d0490..fca18203 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -27,7 +27,7 @@ heapless = { version = "0.7.5", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" micromath = "2.0.0" -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} chrono = { version = "^0.4", default-features = false} [profile.release] diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 35757e62..0a567d04 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -27,7 +27,7 @@ nb = "1.0.0" rand_core = "0.6.3" critical-section = "1.1" embedded-storage = "0.3.0" -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} [profile.release] debug = 2 diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index fb7f780f..42d7d328 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -20,6 +20,7 @@ embedded-hal = "0.2.6" 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 } +portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } [profile.release] debug = 2 diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index c4f41d1c..db56b685 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -31,7 +31,7 @@ critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.3.0" embedded-storage = "0.3.0" -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} # cargo build/run [profile.dev] diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index d6b14a60..c300c864 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -31,7 +31,7 @@ critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.3.0" embedded-storage = "0.3.0" -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} chrono = { version = "^0.4", default-features = false } # cargo build/run diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index edd1d026..e294d042 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -33,7 +33,8 @@ 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 } embedded-hal = "0.2.6" -static_cell = "1.1" +static_cell = { version = "2" } +portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } [profile.release] debug = 2 diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 2fbba463..5d79cf1e 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -32,7 +32,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa heapless = { version = "0.7.5", default-features = false } chrono = { version = "^0.4", default-features = false } rand = { version = "0.8.5", default-features = false } -static_cell = {version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} micromath = "2.0.0" diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 2457b40d..1cd32892 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -26,7 +26,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa heapless = { version = "0.7.5", default-features = false } rand_core = { version = "0.6.3", default-features = false } embedded-io-async = { version = "0.6.0" } -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} [profile.release] debug = 2 diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 5864906d..daacc11c 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -22,7 +22,7 @@ embedded-hal = "0.2.6" 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 } -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} [features] default = ["ble", "mac"] diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 12e0e5ab..c5284850 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -20,7 +20,7 @@ embedded-hal = "0.2.6" 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 } -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} [profile.release] debug = 2 diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 6441d5c3..f7a10409 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -18,7 +18,7 @@ embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-host embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } embedded-hal-async = { version = "1.0.0-rc.1" } embedded-hal-bus = { version = "0.1.0-rc.1", features = ["async"] } -static_cell = { version = "1.1", features = [ "nightly" ] } +static_cell = { version = "2", features = [ "nightly" ] } perf-client = { path = "../perf-client" } defmt = "0.3" diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index d947568b..1bf149c9 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -31,7 +31,8 @@ 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.6.0" } embedded-storage = { version = "0.3" } -static_cell = { version = "1.1", features = ["nightly"]} +static_cell = { version = "2", features = ["nightly"]} +portable-atomic = { version = "1.5", features = ["critical-section"] } pio = "0.2" pio-proc = "0.2" rand = { version = "0.8.5", default-features = false } diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs index 6ab7f671..a4923b6b 100644 --- a/tests/rp/src/bin/gpio_multicore.rs +++ b/tests/rp/src/bin/gpio_multicore.rs @@ -5,12 +5,12 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::{info, unwrap}; use embassy_executor::Executor; -use embassy_executor::_export::StaticCell; use embassy_rp::gpio::{Input, Level, Output, Pull}; use embassy_rp::multicore::{spawn_core1, Stack}; use embassy_rp::peripherals::{PIN_0, PIN_1}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; static mut CORE1_STACK: Stack<1024> = Stack::new(); diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs index 425f2d08..7ddb71c7 100644 --- a/tests/rp/src/bin/i2c.rs +++ b/tests/rp/src/bin/i2c.rs @@ -5,12 +5,12 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, info, panic, unwrap}; use embassy_executor::Executor; -use embassy_executor::_export::StaticCell; use embassy_rp::multicore::{spawn_core1, Stack}; use embassy_rp::peripherals::{I2C0, I2C1}; use embassy_rp::{bind_interrupts, i2c, i2c_slave}; use embedded_hal_1::i2c::Operation; use embedded_hal_async::i2c::I2c; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; static mut CORE1_STACK: Stack<1024> = Stack::new(); diff --git a/tests/rp/src/bin/multicore.rs b/tests/rp/src/bin/multicore.rs index f4188135..6560b6c8 100644 --- a/tests/rp/src/bin/multicore.rs +++ b/tests/rp/src/bin/multicore.rs @@ -5,10 +5,10 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::{info, unwrap}; use embassy_executor::Executor; -use embassy_executor::_export::StaticCell; use embassy_rp::multicore::{spawn_core1, Stack}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; static mut CORE1_STACK: Stack<1024> = Stack::new(); diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 1ca14ee8..14f27678 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -8,8 +8,8 @@ autobins = false [features] stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin", "rng"] -stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] -stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] +stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac-adc-pin"] +stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"] stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma", "rng"] stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin", "rng"] stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"] @@ -19,7 +19,7 @@ stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng"] stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng"] stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng"] stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng"] -stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma", "rng"] +stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng"] stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] @@ -42,6 +42,8 @@ embassy-stm32-wpan = [] not-gpdma = [] dac-adc-pin = [] +cm0 = ["portable-atomic/unsafe-assume-single-core"] + [dependencies] teleprobe-meta = "1" @@ -66,7 +68,8 @@ micromath = "2.0.0" panic-probe = { version = "0.3.0", features = ["print-defmt"] } rand_core = { version = "0.6", default-features = false } rand_chacha = { version = "0.3", default-features = false } -static_cell = {version = "1.1", features = ["nightly"] } +static_cell = { version = "2", features = ["nightly"] } +portable-atomic = { version = "1.5", features = [] } chrono = { version = "^0.4", default-features = false, optional = true} From 44486c5b397e8f8f14a1b79825c9b4e611d1528f Mon Sep 17 00:00:00 2001 From: kalkyl Date: Thu, 2 Nov 2023 21:54:20 +0100 Subject: [PATCH 090/188] rp: Add PIO rotary encoder example --- examples/rp/src/bin/pio_rotary_encoder.rs | 91 +++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 examples/rp/src/bin/pio_rotary_encoder.rs diff --git a/examples/rp/src/bin/pio_rotary_encoder.rs b/examples/rp/src/bin/pio_rotary_encoder.rs new file mode 100644 index 00000000..589f38a7 --- /dev/null +++ b/examples/rp/src/bin/pio_rotary_encoder.rs @@ -0,0 +1,91 @@ +//! This example shows how to use the PIO module in the RP2040 to read a quadrature rotary encoder. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_rp::gpio::Pull; +use embassy_rp::peripherals::PIO0; +use embassy_rp::{bind_interrupts, pio}; +use fixed::traits::ToFixed; +use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + PIO0_IRQ_0 => InterruptHandler; +}); + +pub struct PioEncoder<'d, T: Instance, const SM: usize> { + sm: StateMachine<'d, T, SM>, +} + +impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> { + pub fn new( + pio: &mut Common<'d, T>, + mut sm: StateMachine<'d, T, SM>, + pin_a: impl PioPin, + pin_b: impl PioPin, + ) -> Self { + let mut pin_a = pio.make_pio_pin(pin_a); + let mut pin_b = pio.make_pio_pin(pin_b); + pin_a.set_pull(Pull::Up); + pin_b.set_pull(Pull::Up); + sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]); + + let prg = pio_proc::pio_asm!( + r#" + wait 1 pin 1 + .wrap_target + wait 0 pin 1 + in pins, 2 + push + wait 1 pin 1 + .wrap + "# + ); + + let mut cfg = Config::default(); + cfg.set_in_pins(&[&pin_a, &pin_b]); + cfg.fifo_join = FifoJoin::RxOnly; + cfg.use_program(&pio.load_program(&prg.program), &[]); + cfg.shift_in.direction = ShiftDirection::Left; + cfg.clock_divider = 10_000.to_fixed(); + sm.set_config(&cfg); + sm.set_enable(true); + Self { sm } + } + + pub async fn read(&mut self) -> Direction { + loop { + match self.sm.rx().wait_pull().await { + 0 => return Direction::CounterClockwise, + 1 => return Direction::Clockwise, + _ => {} + } + } + } +} + +pub enum Direction { + Clockwise, + CounterClockwise, +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs); + + let mut encoder = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5); + + let mut count = 0; + loop { + info!("Count: {}", count); + count += match encoder.read().await { + Direction::Clockwise => 1, + Direction::CounterClockwise => -1, + }; + } +} From ec744558b200aebbb05e4d0db89197fea86a25f4 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Thu, 2 Nov 2023 22:37:03 +0100 Subject: [PATCH 091/188] Cleanup --- examples/rp/src/bin/pio_rotary_encoder.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/examples/rp/src/bin/pio_rotary_encoder.rs b/examples/rp/src/bin/pio_rotary_encoder.rs index 589f38a7..6d9d59df 100644 --- a/examples/rp/src/bin/pio_rotary_encoder.rs +++ b/examples/rp/src/bin/pio_rotary_encoder.rs @@ -34,24 +34,14 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> { pin_b.set_pull(Pull::Up); sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]); - let prg = pio_proc::pio_asm!( - r#" - wait 1 pin 1 - .wrap_target - wait 0 pin 1 - in pins, 2 - push - wait 1 pin 1 - .wrap - "# - ); + let prg = pio_proc::pio_asm!("wait 1 pin 1", "wait 0 pin 1", "in pins, 2", "push",); let mut cfg = Config::default(); cfg.set_in_pins(&[&pin_a, &pin_b]); cfg.fifo_join = FifoJoin::RxOnly; - cfg.use_program(&pio.load_program(&prg.program), &[]); cfg.shift_in.direction = ShiftDirection::Left; cfg.clock_divider = 10_000.to_fixed(); + cfg.use_program(&pio.load_program(&prg.program), &[]); sm.set_config(&cfg); sm.set_enable(true); Self { sm } From 413b394d317a87e7664d83bce83e832588d7448c Mon Sep 17 00:00:00 2001 From: kalkyl Date: Fri, 3 Nov 2023 00:37:58 +0100 Subject: [PATCH 092/188] rp: Add PWM input example --- examples/rp/src/bin/pwm_input.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 examples/rp/src/bin/pwm_input.rs diff --git a/examples/rp/src/bin/pwm_input.rs b/examples/rp/src/bin/pwm_input.rs new file mode 100644 index 00000000..794b28af --- /dev/null +++ b/examples/rp/src/bin/pwm_input.rs @@ -0,0 +1,26 @@ +//! This example shows how to use the PWM module to measure the frequency of an input signal. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_rp::pwm::{Config, InputMode, Pwm}; +use embassy_time::{Duration, Ticker}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + + let mut cfg: Config = Default::default(); + let mut pwm = Pwm::new_input(p.PWM_CH2, p.PIN_5, InputMode::RisingEdge, cfg); + + let mut ticker = Ticker::every(Duration::from_secs(1)); + loop { + info!("Input frequency: {} Hz", pwm.counter()); + pwm.set_counter(0); + ticker.next().await; + } +} From 649f1a122ad16cbd05aa1b5f0afd65cf959e2b47 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Fri, 3 Nov 2023 00:41:16 +0100 Subject: [PATCH 093/188] Cleanup --- examples/rp/src/bin/pwm_input.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/rp/src/bin/pwm_input.rs b/examples/rp/src/bin/pwm_input.rs index 794b28af..0fc2e40c 100644 --- a/examples/rp/src/bin/pwm_input.rs +++ b/examples/rp/src/bin/pwm_input.rs @@ -14,8 +14,8 @@ use {defmt_rtt as _, panic_probe as _}; async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); - let mut cfg: Config = Default::default(); - let mut pwm = Pwm::new_input(p.PWM_CH2, p.PIN_5, InputMode::RisingEdge, cfg); + let cfg: Config = Default::default(); + let pwm = Pwm::new_input(p.PWM_CH2, p.PIN_5, InputMode::RisingEdge, cfg); let mut ticker = Ticker::every(Duration::from_secs(1)); loop { From dc467e89a0f093c1656eaf63955c28dd3b08be6c Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 4 Nov 2023 13:49:54 -0500 Subject: [PATCH 094/188] stm32: compute stop mode and workaround rtt test bug --- ci.sh | 2 -- embassy-stm32/Cargo.toml | 1 + embassy-stm32/build.rs | 32 ++++++++++++++++++++++++++++---- embassy-stm32/src/lib.rs | 5 +++-- embassy-stm32/src/low_power.rs | 34 ++++++++++++++++++++++++++++------ embassy-stm32/src/rcc/mod.rs | 9 +++++++++ embassy-stm32/src/rtc/mod.rs | 8 +------- tests/stm32/Cargo.toml | 2 +- 8 files changed, 71 insertions(+), 22 deletions(-) diff --git a/ci.sh b/ci.sh index 5c69d3a2..2e6bbae8 100755 --- a/ci.sh +++ b/ci.sh @@ -218,8 +218,6 @@ cargo batch \ rm out/tests/stm32wb55rg/wpan_mac rm out/tests/stm32wb55rg/wpan_ble -# unstable -rm out/tests/stm32f429zi/stop # unstable, I think it's running out of RAM? rm out/tests/stm32f207zg/eth diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index bc79ab7a..2a2df5c5 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -90,6 +90,7 @@ defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-emb exti = [] low-power = [ "dep:embassy-executor", "embassy-executor/arch-cortex-m" ] +low-power-debug-with-sleep = [] embassy-executor = [] ## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 3400529c..276c1d63 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -556,6 +556,32 @@ fn main() { }, }; + /* + If LP and non-LP peripherals share the same RCC enable bit, then a refcount leak will result. + + This should be checked in stm32-data-gen. + */ + let stop_refcount = if p.name.starts_with("LP") { + quote! { REFCOUNT_STOP2 } + } else { + quote! { REFCOUNT_STOP1 } + }; + + let (incr_stop_refcount, decr_stop_refcount) = if p.name != "RTC" { + ( + quote! { + #[cfg(feature = "low-power")] + unsafe { crate::rcc::#stop_refcount += 1 }; + }, + quote! { + #[cfg(feature = "low-power")] + unsafe { crate::rcc::#stop_refcount -= 1 }; + }, + ) + } else { + (quote! {}, quote! {}) + }; + g.extend(quote! { impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { fn frequency() -> crate::time::Hertz { @@ -563,8 +589,7 @@ fn main() { } fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { #before_enable - #[cfg(feature = "low-power")] - unsafe { crate::rcc::REFCOUNT_STOP2 += 1 }; + #incr_stop_refcount crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); #after_enable #rst @@ -572,8 +597,7 @@ fn main() { 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")] - unsafe { crate::rcc::REFCOUNT_STOP2 -= 1 }; + #decr_stop_refcount } } diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 23d42bae..511da917 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -228,8 +228,9 @@ pub fn init(config: Config) -> Peripherals { #[cfg(feature = "low-power")] { - crate::rcc::REFCOUNT_STOP2 = 0 - }; + crate::rcc::REFCOUNT_STOP2 = 0; + crate::rcc::REFCOUNT_STOP1 = 0; + } } p diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index d5846f53..8e75f641 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -33,11 +33,17 @@ pub fn stop_with_rtc(rtc: &'static Rtc) { } pub fn stop_ready(stop_mode: StopMode) -> bool { - unsafe { EXECUTOR.as_mut().unwrap() }.stop_ready(stop_mode) + match unsafe { EXECUTOR.as_mut().unwrap() }.stop_mode() { + Some(StopMode::Stop2) => true, + Some(StopMode::Stop1) => stop_mode == StopMode::Stop1, + None => false, + } } #[non_exhaustive] +#[derive(PartialEq)] pub enum StopMode { + Stop1, Stop2, } @@ -88,23 +94,39 @@ impl Executor { trace!("low power: stop with rtc configured"); } - fn stop_ready(&self, stop_mode: StopMode) -> bool { - match stop_mode { - StopMode::Stop2 => unsafe { crate::rcc::REFCOUNT_STOP2 == 0 }, + fn stop_mode(&self) -> Option { + if unsafe { crate::rcc::REFCOUNT_STOP2 == 0 } && unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } { + Some(StopMode::Stop2) + } else if unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } { + Some(StopMode::Stop1) + } else { + None } } + fn configure_stop(&mut self, _stop_mode: StopMode) { + // TODO: configure chip-specific settings for stop + } + fn configure_pwr(&mut self) { self.scb.clear_sleepdeep(); compiler_fence(Ordering::SeqCst); - if !self.stop_ready(StopMode::Stop2) { + let stop_mode = self.stop_mode(); + if stop_mode.is_none() { 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"); + let stop_mode = stop_mode.unwrap(); + match stop_mode { + StopMode::Stop1 => trace!("low power: stop 1"), + StopMode::Stop2 => trace!("low power: stop 2"), + } + self.configure_stop(stop_mode); + + #[cfg(not(feature = "low-power-debug-with-sleep"))] self.scb.set_sleepdeep(); } } diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 3b19e4b9..c11a9cc6 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -181,6 +181,15 @@ pub struct Clocks { } #[cfg(feature = "low-power")] +/// Must be written within a critical section +/// +/// May be read without a critical section +pub(crate) static mut REFCOUNT_STOP1: u32 = 0; + +#[cfg(feature = "low-power")] +/// Must be written within a critical section +/// +/// May be read without a critical section pub(crate) static mut REFCOUNT_STOP2: u32 = 0; /// Frozen clock frequencies diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index c8990c30..68836be0 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -143,13 +143,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)))] - critical_section::with(|cs| { - ::enable_and_reset_with_cs(cs); - #[cfg(feature = "low-power")] - unsafe { - crate::rcc::REFCOUNT_STOP2 -= 1 - }; - }); + ::enable_and_reset(); let mut this = Self { #[cfg(feature = "low-power")] diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 1ca14ee8..db265daa 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -33,7 +33,7 @@ stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] eth = [] rng = [] sdmmc = [] -stop = ["embassy-stm32/low-power"] +stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] chrono = ["embassy-stm32/chrono", "dep:chrono"] can = [] ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"] From 8911a4d8558cd41244af2be2bce2b0969a4ffbea Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 5 Nov 2023 03:06:13 +0100 Subject: [PATCH 095/188] stm32/rcc: switch to modern api for l0, l1. --- embassy-stm32/src/rcc/l0l1.rs | 197 ++++++++++--------- embassy-stm32/src/rcc/l4l5.rs | 3 - examples/stm32l0/src/bin/button_exti.rs | 2 +- examples/stm32l0/src/bin/lora_cad.rs | 2 +- examples/stm32l0/src/bin/lora_lorawan.rs | 2 +- examples/stm32l0/src/bin/lora_p2p_receive.rs | 2 +- examples/stm32l0/src/bin/lora_p2p_send.rs | 2 +- tests/stm32/src/common.rs | 26 +-- 8 files changed, 124 insertions(+), 112 deletions(-) diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index 9fb2062d..3af27959 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -1,8 +1,8 @@ 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, + Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Plldiv as PllDiv, Pllmul as PLLMul, Pllmul as PllMul, + Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, }; -use crate::pac::rcc::vals::{Pllsrc, Sw}; #[cfg(crs)] use crate::pac::{crs, CRS, SYSCFG}; use crate::pac::{FLASH, PWR, RCC}; @@ -12,39 +12,50 @@ use crate::time::Hertz; /// HSI speed pub const HSI_FREQ: Hertz = Hertz(16_000_000); -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - MSI(MSIRange), - PLL(PLLSource, PLLMul, PLLDiv), - HSE(Hertz), - HSI, +#[derive(Clone, Copy, Eq, PartialEq)] +pub enum HseMode { + /// crystal/ceramic oscillator (HSEBYP=0) + Oscillator, + /// external analog clock (low swing) (HSEBYP=1) + Bypass, } -/// PLL clock input source -#[derive(Clone, Copy)] -pub enum PLLSource { - HSI, - HSE(Hertz), +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct Hse { + /// HSE frequency. + pub freq: Hertz, + /// HSE mode. + pub mode: HseMode, } -impl From for Pllsrc { - fn from(val: PLLSource) -> Pllsrc { - match val { - PLLSource::HSI => Pllsrc::HSI, - PLLSource::HSE(_) => Pllsrc::HSE, - } - } +#[derive(Clone, Copy)] +pub struct Pll { + /// PLL source + pub source: PLLSource, + + /// PLL multiplication factor. + pub mul: PllMul, + + /// PLL main output division factor. + pub div: PllDiv, } /// Clocks configutation pub struct Config { + // base clock sources + pub msi: Option, + pub hsi: bool, + pub hse: Option, + #[cfg(crs)] + pub hsi48: bool, + + pub pll: Option, + pub mux: ClockSrc, pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, - #[cfg(crs)] - pub enable_hsi48: bool, + pub ls: super::LsConfig, pub voltage_scale: VoltageScale, } @@ -53,12 +64,18 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::MSI(MSIRange::RANGE5), + msi: Some(MSIRange::RANGE5), + hse: None, + hsi: false, + #[cfg(crs)] + hsi48: false, + + pll: None, + + mux: ClockSrc::MSI, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, - #[cfg(crs)] - enable_hsi48: false, voltage_scale: VoltageScale::RANGE1, ls: Default::default(), } @@ -71,72 +88,68 @@ pub(crate) unsafe fn init(config: Config) { PWR.cr().write(|w| w.set_vos(config.voltage_scale)); while PWR.csr().read().vosf() {} - 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::PLL1_P) - } - }; - let rtc = config.ls.init(); + let msi = config.msi.map(|range| { + RCC.icscr().modify(|w| w.set_msirange(range)); + + RCC.cr().modify(|w| w.set_msion(true)); + while !RCC.cr().read().msirdy() {} + + Hertz(32_768 * (1 << (range as u8 + 1))) + }); + + let hsi = config.hsi.then(|| { + RCC.cr().modify(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} + + HSI_FREQ + }); + + let hse = config.hse.map(|hse| { + RCC.cr().modify(|w| { + w.set_hsebyp(hse.mode == HseMode::Bypass); + w.set_hseon(true); + }); + while !RCC.cr().read().hserdy() {} + + hse.freq + }); + + let pll = config.pll.map(|pll| { + let freq = match pll.source { + PLLSource::HSE => hse.unwrap(), + PLLSource::HSI => hsi.unwrap(), + }; + + // Disable PLL + RCC.cr().modify(|w| w.set_pllon(false)); + while RCC.cr().read().pllrdy() {} + + let freq = freq * pll.mul / pll.div; + + assert!(freq <= Hertz(32_000_000)); + + RCC.cfgr().write(move |w| { + w.set_pllmul(pll.mul); + w.set_plldiv(pll.div); + w.set_pllsrc(pll.source); + }); + + // Enable PLL + RCC.cr().modify(|w| w.set_pllon(true)); + while !RCC.cr().read().pllrdy() {} + + freq + }); + + let sys_clk = match config.mux { + ClockSrc::HSE => hse.unwrap(), + ClockSrc::HSI => hsi.unwrap(), + ClockSrc::MSI => msi.unwrap(), + ClockSrc::PLL1_P => pll.unwrap(), + }; + let wait_states = match (config.voltage_scale, sys_clk.0) { (VoltageScale::RANGE1, ..=16_000_000) => 0, (VoltageScale::RANGE2, ..=8_000_000) => 0, @@ -150,7 +163,7 @@ pub(crate) unsafe fn init(config: Config) { FLASH.acr().modify(|w| w.set_latency(wait_states != 0)); RCC.cfgr().modify(|w| { - w.set_sw(sw); + w.set_sw(config.mux); w.set_hpre(config.ahb_pre); w.set_ppre1(config.apb1_pre); w.set_ppre2(config.apb2_pre); @@ -161,7 +174,7 @@ pub(crate) unsafe fn init(config: Config) { let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); #[cfg(crs)] - if config.enable_hsi48 { + if config.hsi48 { // Reset CRS peripheral RCC.apb1rstr().modify(|w| w.set_crsrst(true)); RCC.apb1rstr().modify(|w| w.set_crsrst(false)); diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 0d052713..44748620 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -193,9 +193,6 @@ 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 range == MSIRange::RANGE48M {} - msirange_to_hertz(range) }); diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs index af82b995..441b00c6 100644 --- a/examples/stm32l0/src/bin/button_exti.rs +++ b/examples/stm32l0/src/bin/button_exti.rs @@ -12,7 +12,7 @@ use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.enable_hsi48 = true; + config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let button = Input::new(p.PB2, Pull::Up); diff --git a/examples/stm32l0/src/bin/lora_cad.rs b/examples/stm32l0/src/bin/lora_cad.rs index 5c2b331c..61024ef7 100644 --- a/examples/stm32l0/src/bin/lora_cad.rs +++ b/examples/stm32l0/src/bin/lora_cad.rs @@ -24,7 +24,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; - config.rcc.enable_hsi48 = true; + config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let mut spi_config = spi::Config::default(); diff --git a/examples/stm32l0/src/bin/lora_lorawan.rs b/examples/stm32l0/src/bin/lora_lorawan.rs index d44d03d3..9c4f3291 100644 --- a/examples/stm32l0/src/bin/lora_lorawan.rs +++ b/examples/stm32l0/src/bin/lora_lorawan.rs @@ -34,7 +34,7 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; - config.rcc.enable_hsi48 = true; + config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let mut spi_config = spi::Config::default(); diff --git a/examples/stm32l0/src/bin/lora_p2p_receive.rs b/examples/stm32l0/src/bin/lora_p2p_receive.rs index 0478ce1e..4a50182c 100644 --- a/examples/stm32l0/src/bin/lora_p2p_receive.rs +++ b/examples/stm32l0/src/bin/lora_p2p_receive.rs @@ -24,7 +24,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; - config.rcc.enable_hsi48 = true; + config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let mut spi_config = spi::Config::default(); diff --git a/examples/stm32l0/src/bin/lora_p2p_send.rs b/examples/stm32l0/src/bin/lora_p2p_send.rs index 88a836d3..f6de6a5c 100644 --- a/examples/stm32l0/src/bin/lora_p2p_send.rs +++ b/examples/stm32l0/src/bin/lora_p2p_send.rs @@ -24,7 +24,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; - config.rcc.enable_hsi48 = true; + config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let mut spi_config = spi::Config::default(); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index ff808281..54e23e43 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -460,23 +460,25 @@ pub fn config() -> Config { #[cfg(feature = "stm32l073rz")] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::PLL( - // 32Mhz clock (16 * 4 / 2) - PLLSource::HSI, - PLLMul::MUL4, - PLLDiv::DIV2, - ); + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PLLSource::HSI, + mul: PLLMul::MUL4, + div: PLLDiv::DIV2, // 32Mhz clock (16 * 4 / 2) + }); + config.rcc.mux = ClockSrc::PLL1_P; } #[cfg(any(feature = "stm32l152re"))] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::PLL( - // 32Mhz clock (16 * 4 / 2) - PLLSource::HSI, - PLLMul::MUL4, - PLLDiv::DIV2, - ); + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PLLSource::HSI, + mul: PLLMul::MUL4, + div: PLLDiv::DIV2, // 32Mhz clock (16 * 4 / 2) + }); + config.rcc.mux = ClockSrc::PLL1_P; } config From fa45dcd0348379e7b9714f9b845fa3eb75671890 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 5 Nov 2023 15:41:31 +0000 Subject: [PATCH 096/188] Add raw USB example using control transfers --- examples/stm32f4/src/bin/usb_raw.rs | 201 ++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 examples/stm32f4/src/bin/usb_raw.rs diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs new file mode 100644 index 00000000..8d4e6c7d --- /dev/null +++ b/examples/stm32f4/src/bin/usb_raw.rs @@ -0,0 +1,201 @@ +//! Example of using USB without a pre-defined class, but instead responding to +//! raw USB control requests. +//! +//! The host computer can either: +//! * send a command, with a 16-bit request ID, a 16-bit value, and an optional data buffer +//! * request some data, with a 16-bit request ID, a 16-bit value, and a length of data to receive +//! +//! For higher throughput data, you can add some bulk endpoints after creating the alternate, +//! but for low rate command/response, plain control transfers can be very simple and effective. +//! +//! Example code to send/receive data using `nusb`: +//! +//! ```ignore +//! use futures_lite::future::block_on; +//! use nusb::transfer::{ControlIn, ControlOut, ControlType, Recipient}; +//! +//! fn main() { +//! let di = nusb::list_devices() +//! .unwrap() +//! .find(|d| d.vendor_id() == 0xc0de && d.product_id() == 0xcafe) +//! .expect("no device found"); +//! let device = di.open().expect("error opening device"); +//! let interface = device.claim_interface(0).expect("error claiming interface"); +//! +//! // Send "hello world" to device +//! let result = block_on(interface.control_out(ControlOut { +//! control_type: ControlType::Vendor, +//! recipient: Recipient::Interface, +//! request: 100, +//! value: 200, +//! index: 0, +//! data: b"hello world", +//! })); +//! println!("{result:?}"); +//! +//! // Receive "hello" from device +//! let result = block_on(interface.control_in(ControlIn { +//! control_type: ControlType::Vendor, +//! recipient: Recipient::Interface, +//! request: 101, +//! value: 201, +//! index: 0, +//! length: 5, +//! })); +//! println!("{result:?}"); +//! } +//! ``` + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::time::Hertz; +use embassy_stm32::usb_otg::Driver; +use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; +use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; +use embassy_usb::types::InterfaceNumber; +use embassy_usb::{Builder, Handler}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + OTG_FS => usb_otg::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Hello World!"); + + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL168, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } + let p = embassy_stm32::init(config); + + // Create the driver, from the HAL. + let mut ep_out_buffer = [0u8; 256]; + let mut config = embassy_stm32::usb_otg::Config::default(); + config.vbus_detection = true; + let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); + + // Create embassy-usb Config + let mut config = embassy_usb::Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Embassy"); + config.product = Some("USB-raw example"); + config.serial_number = Some("12345678"); + + // 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 handler = ControlHandler { + if_num: InterfaceNumber(0), + }; + + let mut builder = Builder::new( + driver, + config, + &mut device_descriptor, + &mut config_descriptor, + &mut bos_descriptor, + &mut control_buf, + ); + + // Add a vendor-specific function (class 0xFF), and corresponding interface, + // that uses our custom handler. + let mut function = builder.function(0xFF, 0, 0); + let mut interface = function.interface(); + let _alternate = interface.alt_setting(0xFF, 0, 0, None); + handler.if_num = interface.interface_number(); + drop(function); + builder.handler(&mut handler); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + usb.run().await; +} + +/// Handle CONTROL endpoint requests and responses. For many simple requests and responses +/// you can get away with only using the control endpoint. +struct ControlHandler { + if_num: InterfaceNumber, +} + +impl Handler for ControlHandler { + /// Respond to HostToDevice control messages, where the host sends us a command and + /// optionally some data, and we can only acknowledge or reject it. + fn control_out<'a>(&'a mut self, req: Request, buf: &'a [u8]) -> Option { + // Log the request before filtering to help with debugging. + info!("Got control_out, request={}, buf={:a}", req, buf); + + // Only handle Vendor request types to an Interface. + if req.request_type != RequestType::Vendor || req.recipient != Recipient::Interface { + return None; + } + + // Ignore requests to other interfaces. + if req.index != self.if_num.0 as u16 { + return None; + } + + // Accept request 100, value 200, reject others. + if req.request == 100 && req.value == 200 { + Some(OutResponse::Accepted) + } else { + Some(OutResponse::Rejected) + } + } + + /// Respond to DeviceToHost control messages, where the host requests some data from us. + fn control_in<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> Option> { + info!("Got control_in, request={}", req); + + // Only handle Vendor request types to an Interface. + if req.request_type != RequestType::Vendor || req.recipient != Recipient::Interface { + return None; + } + + // Ignore requests to other interfaces. + if req.index != self.if_num.0 as u16 { + return None; + } + + // Respond "hello" to request 101, value 201, when asked for 5 bytes, otherwise reject. + if req.request == 101 && req.value == 201 && req.length == 5 { + buf[..5].copy_from_slice(b"hello"); + Some(InResponse::Accepted(&buf[..5])) + } else { + Some(InResponse::Rejected) + } + } +} From 0272deb158c4cc821e8f587283817a0fe5f82cf8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 5 Nov 2023 23:35:01 +0100 Subject: [PATCH 097/188] stm32/rcc: add shared code for hsi48 with crs support. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/g4.rs | 50 ++------------- embassy-stm32/src/rcc/h.rs | 16 +---- embassy-stm32/src/rcc/hsi48.rs | 62 +++++++++++++++++++ embassy-stm32/src/rcc/l0l1.rs | 38 ++---------- embassy-stm32/src/rcc/l4l5.rs | 26 ++++---- embassy-stm32/src/rcc/mod.rs | 5 ++ embassy-stm32/src/rcc/u5.rs | 9 +-- examples/stm32g4/src/bin/usb_serial.rs | 6 +- examples/stm32h5/src/bin/eth.rs | 2 +- examples/stm32h5/src/bin/usb_serial.rs | 46 +++++++------- examples/stm32h7/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth_client.rs | 2 +- .../stm32h7/src/bin/low_level_timer_api.rs | 1 - examples/stm32h7/src/bin/rng.rs | 2 +- examples/stm32h7/src/bin/usb_serial.rs | 2 +- examples/stm32l0/src/bin/button_exti.rs | 3 +- examples/stm32l0/src/bin/lora_cad.rs | 2 +- examples/stm32l0/src/bin/lora_lorawan.rs | 2 +- examples/stm32l0/src/bin/lora_p2p_receive.rs | 2 +- examples/stm32l0/src/bin/lora_p2p_send.rs | 2 +- .../src/bin/spe_adin1110_http_server.rs | 2 +- examples/stm32l4/src/bin/usb_serial.rs | 2 +- examples/stm32u5/src/bin/usb_serial.rs | 3 +- tests/stm32/src/common.rs | 6 +- 25 files changed, 136 insertions(+), 161 deletions(-) create mode 100644 embassy-stm32/src/rcc/hsi48.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 2a2df5c5..7e11e263 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-73b8c37ae74fc28b247188c989fd99400611bd6b" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8381654ade324de3945c3c755d359686e957e99b" } 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-73b8c37ae74fc28b247188c989fd99400611bd6b", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8381654ade324de3945c3c755d359686e957e99b", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index b14a6197..13eb0c48 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -7,7 +7,6 @@ pub use crate::pac::rcc::vals::{ Pllr as PllR, Ppre as APBPrescaler, }; use crate::pac::{PWR, RCC}; -use crate::rcc::sealed::RccPeripheral; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -67,23 +66,13 @@ pub struct Pll { pub enum Clock48MhzSrc { /// Use the High Speed Internal Oscillator. For USB usage, the CRS must be used to calibrate the /// oscillator to comply with the USB specification for oscillator tolerance. - Hsi48(Option), + Hsi48(super::Hsi48Config), /// Use the PLLQ output. The PLL must be configured to output a 48MHz clock. For USB usage the /// PLL needs to be using the HSE source to comply with the USB specification for oscillator /// tolerance. PllQ, } -/// Sets the sync source for the Clock Recovery System (CRS). -pub enum CrsSyncSource { - /// Use an external GPIO to sync the CRS. - Gpio, - /// Use the Low Speed External oscillator to sync the CRS. - Lse, - /// Use the USB SOF to sync the CRS. - Usb, -} - /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -102,12 +91,6 @@ pub struct Config { pub ls: super::LsConfig, } -/// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator. -pub struct CrsConfig { - /// Sync source for the CRS. - pub sync_src: CrsSyncSource, -} - impl Default for Config { #[inline] fn default() -> Config { @@ -118,7 +101,7 @@ impl Default for Config { apb2_pre: APBPrescaler::DIV1, low_power_run: false, pll: None, - clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(None)), + clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(Default::default())), adc12_clock_source: Adcsel::DISABLE, adc345_clock_source: Adcsel::DISABLE, ls: Default::default(), @@ -288,33 +271,8 @@ pub(crate) unsafe fn init(config: Config) { crate::pac::rcc::vals::Clk48sel::PLL1_Q } - Clock48MhzSrc::Hsi48(crs_config) => { - // Enable HSI48 - RCC.crrcr().modify(|w| w.set_hsi48on(true)); - // Wait for HSI48 to turn on - while RCC.crrcr().read().hsi48rdy() == false {} - - // Enable and setup CRS if needed - if let Some(crs_config) = crs_config { - crate::peripherals::CRS::enable_and_reset(); - - let sync_src = match crs_config.sync_src { - CrsSyncSource::Gpio => crate::pac::crs::vals::Syncsrc::GPIO, - CrsSyncSource::Lse => crate::pac::crs::vals::Syncsrc::LSE, - CrsSyncSource::Usb => crate::pac::crs::vals::Syncsrc::USB, - }; - - crate::pac::CRS.cfgr().modify(|w| { - w.set_syncsrc(sync_src); - }); - - // These are the correct settings for standard USB operation. If other settings - // are needed there will need to be additional config options for the CRS. - crate::pac::CRS.cr().modify(|w| { - w.set_autotrimen(true); - w.set_cen(true); - }); - } + Clock48MhzSrc::Hsi48(config) => { + super::init_hsi48(config); crate::pac::rcc::vals::Clk48sel::HSI48 } }; diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 7e924f0a..4407d9e9 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -21,9 +21,6 @@ pub const HSI_FREQ: Hertz = Hertz(64_000_000); /// CSI speed pub const CSI_FREQ: Hertz = Hertz(4_000_000); -/// HSI48 speed -pub const HSI48_FREQ: Hertz = Hertz(48_000_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); @@ -126,7 +123,7 @@ pub struct Config { pub hsi: Option, pub hse: Option, pub csi: bool, - pub hsi48: bool, + pub hsi48: Option, pub sys: Sysclk, pub pll1: Option, @@ -155,7 +152,7 @@ impl Default for Config { hsi: Some(HSIPrescaler::DIV1), hse: None, csi: false, - hsi48: false, + hsi48: Some(Default::default()), sys: Sysclk::HSI, pll1: None, pll2: None, @@ -301,14 +298,7 @@ pub(crate) unsafe fn init(config: Config) { }; // Configure HSI48. - RCC.cr().modify(|w| w.set_hsi48on(config.hsi48)); - let _hsi48 = match config.hsi48 { - false => None, - true => { - while !RCC.cr().read().hsi48rdy() {} - Some(CSI_FREQ) - } - }; + let _hsi48 = config.hsi48.map(super::init_hsi48); // Configure CSI. RCC.cr().modify(|w| w.set_csion(config.csi)); diff --git a/embassy-stm32/src/rcc/hsi48.rs b/embassy-stm32/src/rcc/hsi48.rs new file mode 100644 index 00000000..19a8c8cb --- /dev/null +++ b/embassy-stm32/src/rcc/hsi48.rs @@ -0,0 +1,62 @@ +#![allow(unused)] + +use crate::pac::crs::vals::Syncsrc; +use crate::pac::{CRS, RCC}; +use crate::rcc::sealed::RccPeripheral; +use crate::time::Hertz; + +/// HSI48 speed +pub const HSI48_FREQ: Hertz = Hertz(48_000_000); + +/// Configuration for the HSI48 clock +#[derive(Clone, Copy, Debug)] +pub struct Hsi48Config { + /// Enable CRS Sync from USB Start Of Frame (SOF) events. + /// Required if HSI48 is going to be used as USB clock. + /// + /// Other use cases of CRS are not supported yet. + pub sync_from_usb: bool, +} + +impl Default for Hsi48Config { + fn default() -> Self { + Self { sync_from_usb: false } + } +} + +pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz { + // Enable VREFINT reference for HSI48 oscillator + #[cfg(stm32l0)] + crate::pac::SYSCFG.cfgr3().modify(|w| { + w.set_enref_hsi48(true); + w.set_en_vrefint(true); + }); + + // Enable HSI48 + #[cfg(not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba, stm32f0)))] + let r = RCC.crrcr(); + #[cfg(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32u5, stm32wba))] + let r = RCC.cr(); + #[cfg(any(stm32f0))] + let r = RCC.cr2(); + + r.modify(|w| w.set_hsi48on(true)); + while r.read().hsi48rdy() == false {} + + if config.sync_from_usb { + crate::peripherals::CRS::enable_and_reset(); + + CRS.cfgr().modify(|w| { + w.set_syncsrc(Syncsrc::USB); + }); + + // These are the correct settings for standard USB operation. If other settings + // are needed there will need to be additional config options for the CRS. + crate::pac::CRS.cr().modify(|w| { + w.set_autotrimen(true); + w.set_cen(true); + }); + } + + HSI48_FREQ +} diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index 3af27959..25a7762a 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -3,8 +3,6 @@ pub use crate::pac::rcc::vals::{ Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Plldiv as PllDiv, Pllmul as PLLMul, Pllmul as PllMul, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, }; -#[cfg(crs)] -use crate::pac::{crs, CRS, SYSCFG}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -47,7 +45,7 @@ pub struct Config { pub hsi: bool, pub hse: Option, #[cfg(crs)] - pub hsi48: bool, + pub hsi48: Option, pub pll: Option, @@ -68,7 +66,7 @@ impl Default for Config { hse: None, hsi: false, #[cfg(crs)] - hsi48: false, + hsi48: Some(Default::default()), pll: None, @@ -174,37 +172,11 @@ pub(crate) unsafe fn init(config: Config) { let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); #[cfg(crs)] - if config.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); - }); - + let _hsi48 = config.hsi48.map(|config| { // 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() {} - } + super::init_hsi48(config) + }); set_freqs(Clocks { sys: sys_clk, diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 44748620..c4483910 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -58,8 +58,8 @@ pub struct Config { pub msi: Option, pub hsi: bool, pub hse: Option, - #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] - pub hsi48: bool, + #[cfg(crs)] + pub hsi48: Option, // pll pub pll: Option, @@ -108,8 +108,8 @@ impl Default for Config { pllsai1: None, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pllsai2: None, - #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] - hsi48: true, + #[cfg(crs)] + hsi48: Some(Default::default()), #[cfg(any(stm32l4, stm32l5, stm32wb))] clk48_src: Clk48Src::HSI48, ls: Default::default(), @@ -126,7 +126,8 @@ pub const WPAN_DEFAULT: Config = Config { prescaler: HsePrescaler::DIV1, }), mux: ClockSrc::PLL1_R, - hsi48: true, + #[cfg(crs)] + hsi48: Some(super::Hsi48Config { sync_from_usb: false }), msi: None, hsi: false, clk48_src: Clk48Src::PLL1_Q, @@ -216,15 +217,10 @@ pub(crate) unsafe fn init(config: Config) { hse.freq }); - #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] - let hsi48 = config.hsi48.then(|| { - RCC.crrcr().modify(|w| w.set_hsi48on(true)); - while !RCC.crrcr().read().hsi48rdy() {} - - Hertz(48_000_000) - }); - #[cfg(any(stm32l47x, stm32l48x))] - let hsi48 = None; + #[cfg(crs)] + let _hsi48 = config.hsi48.map(super::init_hsi48); + #[cfg(not(crs))] + let _hsi48: Option = None; let _plls = [ &config.pll, @@ -275,7 +271,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); #[cfg(any(stm32l4, stm32l5, stm32wb))] let _clk48 = match config.clk48_src { - Clk48Src::HSI48 => hsi48, + Clk48Src::HSI48 => _hsi48, Clk48Src::MSI => msi, Clk48Src::PLLSAI1_Q => pllsai1.q, Clk48Src::PLL1_Q => pll.q, diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index c11a9cc6..e15f4fe4 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -9,6 +9,11 @@ mod mco; pub use bd::*; pub use mco::*; +#[cfg(crs)] +mod hsi48; +#[cfg(crs)] +pub use hsi48::*; + #[cfg_attr(rcc_f0, path = "f0.rs")] #[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")] #[cfg_attr(rcc_f2, path = "f2.rs")] diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 2bbacbbd..c111362b 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -115,7 +115,7 @@ pub struct Config { pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, pub apb3_pre: APBPrescaler, - pub hsi48: bool, + pub hsi48: Option, /// 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`. @@ -189,7 +189,7 @@ impl Default for Config { apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, apb3_pre: APBPrescaler::DIV1, - hsi48: true, + hsi48: Some(Default::default()), voltage_range: VoltageScale::RANGE3, ls: Default::default(), } @@ -322,10 +322,7 @@ pub(crate) unsafe fn init(config: Config) { } }; - if config.hsi48 { - RCC.cr().modify(|w| w.set_hsi48on(true)); - while !RCC.cr().read().hsi48rdy() {} - } + let _hsi48 = config.hsi48.map(super::init_hsi48); // The clock source is ready // Calculate and set the flash wait states diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index 9099b609..188988b1 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs @@ -4,7 +4,7 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, CrsConfig, CrsSyncSource, Pll, PllM, PllN, PllQ, PllR, PllSrc}; +use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSrc}; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{self, Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, Config}; @@ -41,9 +41,7 @@ async fn main(_spawner: Spawner) { if USE_HSI48 { // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator. - config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Some(CrsConfig { - sync_src: CrsSyncSource::Usb, - }))); + config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true })); } else { config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ); } diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 5bec9d44..b2758cba 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -37,7 +37,7 @@ async fn net_task(stack: &'static Stack) -> ! { async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); config.rcc.hsi = None; - config.rcc.hsi48 = true; // needed for rng + config.rcc.hsi48 = Some(Default::default()); // needed for RNG config.rcc.hse = Some(Hse { freq: Hertz(8_000_000), mode: HseMode::BypassDigital, diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index 735826a6..13b218d0 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs @@ -4,9 +4,6 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -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}; @@ -23,26 +20,29 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.hsi = None; - config.rcc.hsi48 = true; // needed for usb - config.rcc.hse = Some(Hse { - freq: Hertz(8_000_000), - mode: HseMode::BypassDigital, - }); - config.rcc.pll1 = Some(Pll { - source: PllSource::HSE, - prediv: PllPreDiv::DIV2, - mul: PllMul::MUL125, - divp: Some(PllDiv::DIV2), // 250mhz - divq: None, - divr: None, - }); - config.rcc.ahb_pre = AHBPrescaler::DIV2; - config.rcc.apb1_pre = APBPrescaler::DIV4; - config.rcc.apb2_pre = APBPrescaler::DIV2; - config.rcc.apb3_pre = APBPrescaler::DIV4; - config.rcc.sys = Sysclk::PLL1_P; - config.rcc.voltage_scale = VoltageScale::Scale0; + { + use embassy_stm32::rcc::*; + config.rcc.hsi = None; + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::BypassDigital, + }); + config.rcc.pll1 = Some(Pll { + source: PllSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL125, + divp: Some(PllDiv::DIV2), // 250mhz + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV2; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.apb3_pre = APBPrescaler::DIV4; + config.rcc.sys = Sysclk::PLL1_P; + config.rcc.voltage_scale = VoltageScale::Scale0; + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index e37d8797..b7a07737 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -36,7 +36,7 @@ async fn main(spawner: Spawner) -> ! { use embassy_stm32::rcc::*; config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.hsi48 = true; // needed for RNG + config.rcc.hsi48 = Some(Default::default()); // needed for RNG config.rcc.pll1 = Some(Pll { source: PllSource::HSI, prediv: PllPreDiv::DIV4, diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 88df53f0..f0f28ec9 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -37,7 +37,7 @@ async fn main(spawner: Spawner) -> ! { use embassy_stm32::rcc::*; config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.hsi48 = true; // needed for RNG + config.rcc.hsi48 = Some(Default::default()); // needed for RNG config.rcc.pll1 = Some(Pll { source: PllSource::HSI, prediv: PllPreDiv::DIV4, diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index e4bac8a5..e0be495d 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -19,7 +19,6 @@ async fn main(_spawner: Spawner) { use embassy_stm32::rcc::*; config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.hsi48 = true; // needed for RNG config.rcc.pll1 = Some(Pll { source: PllSource::HSI, prediv: PllPreDiv::DIV4, diff --git a/examples/stm32h7/src/bin/rng.rs b/examples/stm32h7/src/bin/rng.rs index af1d6ebb..1fb4cfec 100644 --- a/examples/stm32h7/src/bin/rng.rs +++ b/examples/stm32h7/src/bin/rng.rs @@ -15,7 +15,7 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.hsi48 = true; // needed for RNG. + config.rcc.hsi48 = Some(Default::default()); // needed for RNG let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index 19d77183..648ff6ee 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs @@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) { use embassy_stm32::rcc::*; config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.hsi48 = true; // needed for USB + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB config.rcc.pll1 = Some(Pll { source: PllSource::HSI, prediv: PllPreDiv::DIV4, diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs index 441b00c6..ffede253 100644 --- a/examples/stm32l0/src/bin/button_exti.rs +++ b/examples/stm32l0/src/bin/button_exti.rs @@ -11,8 +11,7 @@ use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let mut config = Config::default(); - config.rcc.hsi48 = true; + let config = Config::default(); let p = embassy_stm32::init(config); let button = Input::new(p.PB2, Pull::Up); diff --git a/examples/stm32l0/src/bin/lora_cad.rs b/examples/stm32l0/src/bin/lora_cad.rs index 61024ef7..8ca9e8b2 100644 --- a/examples/stm32l0/src/bin/lora_cad.rs +++ b/examples/stm32l0/src/bin/lora_cad.rs @@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); + config.rcc.hsi = true; config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; - config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let mut spi_config = spi::Config::default(); diff --git a/examples/stm32l0/src/bin/lora_lorawan.rs b/examples/stm32l0/src/bin/lora_lorawan.rs index 9c4f3291..4365c4cf 100644 --- a/examples/stm32l0/src/bin/lora_lorawan.rs +++ b/examples/stm32l0/src/bin/lora_lorawan.rs @@ -33,8 +33,8 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); + config.rcc.hsi = true; config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; - config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let mut spi_config = spi::Config::default(); diff --git a/examples/stm32l0/src/bin/lora_p2p_receive.rs b/examples/stm32l0/src/bin/lora_p2p_receive.rs index 4a50182c..0627ac08 100644 --- a/examples/stm32l0/src/bin/lora_p2p_receive.rs +++ b/examples/stm32l0/src/bin/lora_p2p_receive.rs @@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); + config.rcc.hsi = true; config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; - config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let mut spi_config = spi::Config::default(); diff --git a/examples/stm32l0/src/bin/lora_p2p_send.rs b/examples/stm32l0/src/bin/lora_p2p_send.rs index f6de6a5c..4f12cadc 100644 --- a/examples/stm32l0/src/bin/lora_p2p_send.rs +++ b/examples/stm32l0/src/bin/lora_p2p_send.rs @@ -23,8 +23,8 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); + config.rcc.hsi = true; config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; - config.rcc.hsi48 = true; let p = embassy_stm32::init(config); let mut spi_config = spi::Config::default(); diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index f76b504a..62caeea5 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -90,7 +90,7 @@ async fn main(spawner: Spawner) { divq: None, divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) }); - config.rcc.hsi48 = true; // needed for rng + config.rcc.hsi48 = Some(Default::default()); // needed for RNG } let dp = embassy_stm32::init(config); diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 15c6f198..d459245d 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.hsi48 = true; + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi = true; config.rcc.pll = Some(Pll { diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index f59f623b..eaa1c291 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -29,8 +29,7 @@ async fn main(_spawner: Spawner) { n: Plln::MUL10, r: Plldiv::DIV1, }); - //config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz); - config.rcc.hsi48 = true; + config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB let p = embassy_stm32::init(config); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 54e23e43..3668e18c 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -306,7 +306,7 @@ pub fn config() -> Config { { use embassy_stm32::rcc::*; config.rcc.hsi = None; - config.rcc.hsi48 = true; // needed for rng + config.rcc.hsi48 = Some(Default::default()); // needed for RNG config.rcc.hse = Some(Hse { freq: Hertz(8_000_000), mode: HseMode::BypassDigital, @@ -332,7 +332,7 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.hsi48 = true; // needed for RNG + config.rcc.hsi48 = Some(Default::default()); // needed for RNG config.rcc.pll1 = Some(Pll { source: PllSource::HSI, prediv: PllPreDiv::DIV4, @@ -364,7 +364,7 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.hsi48 = true; // needed for RNG + config.rcc.hsi48 = Some(Default::default()); // needed for RNG config.rcc.pll1 = Some(Pll { source: PllSource::HSI, prediv: PllPreDiv::DIV4, From 28eb4cd8173063b5e61f371c9642edb5a9289a2b Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 5 Nov 2023 03:37:22 +0000 Subject: [PATCH 098/188] stm32: support internal output on g4 opamps --- embassy-stm32/build.rs | 28 ++-- embassy-stm32/src/opamp.rs | 217 ++++++++++++++++++++++++---- examples/stm32f334/src/bin/opamp.rs | 2 +- 3 files changed, 211 insertions(+), 36 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 276c1d63..35c3f23b 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -944,17 +944,25 @@ fn main() { } if regs.kind == "opamp" { - if !pin.signal.starts_with("VP") { - continue; + println!("{}", pin.signal); + + if pin.signal.starts_with("VP") { + // Impl NonInvertingPin for the VP* signals (VP0, VP1, VP2, etc) + 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_vp_pin!( #peri, #pin_name, #ch); + }) + } else if pin.signal == "VOUT" { + // Impl OutputPin for the VOUT pin + let peri = format_ident!("{}", p.name); + let pin_name = format_ident!("{}", pin.pin); + g.extend(quote! { + impl_opamp_vout_pin!( #peri, #pin_name ); + }) } - - 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 diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index cb55cbe1..89db6d14 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -13,21 +13,50 @@ pub enum OpAmpGain { Mul16, } -pub struct OpAmpOutput<'d, 'p, T: Instance, P: NonInvertingPin> { - _inner: &'d OpAmp<'d, T>, - _input: &'p mut P, +#[derive(Clone, Copy)] +pub enum OpAmpSpeed { + Normal, + HighSpeed, } +#[cfg(opamp_g4)] +impl From for crate::pac::opamp::vals::OpampCsrOpahsm { + fn from(v: OpAmpSpeed) -> Self { + match v { + OpAmpSpeed::Normal => crate::pac::opamp::vals::OpampCsrOpahsm::NORMAL, + OpAmpSpeed::HighSpeed => crate::pac::opamp::vals::OpampCsrOpahsm::HIGHSPEED, + } + } +} + +/// OpAmp external outputs, wired to a GPIO pad. +/// +/// The GPIO output pad is held by this struct to ensure it cannot be used elsewhere. +/// +/// This struct can also be used as an ADC input. +pub struct OpAmpOutput<'d, 'p, T: Instance, P: OutputPin> { + _inner: &'d OpAmp<'d, T>, + _output: &'p mut P, +} + +/// OpAmp internal outputs, wired directly to ADC inputs. +/// +/// This struct can be used as an ADC input. +pub struct OpAmpInternalOutput<'d, T: Instance> { + _inner: &'d OpAmp<'d, T>, +} + +/// OpAmp driver. 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 { + /// Create a new driver instance. + /// + /// Enables the OpAmp and configures the speed, but + /// does not set any other configuration. + pub fn new(opamp: impl Peripheral

+ 'd, #[cfg(opamp_g4)] speed: OpAmpSpeed) -> Self { into_ref!(opamp); #[cfg(opamp_f3)] @@ -38,15 +67,34 @@ impl<'d, T: Instance> OpAmp<'d, T> { #[cfg(opamp_g4)] T::regs().opamp_csr().modify(|w| { w.set_opaen(true); + w.set_opahsm(speed.into()); }); Self { _inner: opamp } } - pub fn buffer_for<'a, 'b, P>(&'a mut self, pin: &'b mut P, gain: OpAmpGain) -> OpAmpOutput<'a, 'b, T, P> + /// Configure the OpAmp as a buffer for the provided input pin, + /// outputting to the provided output pin. + /// + /// The input pin is configured for analogue mode but not consumed, + /// so it may subsequently be used for ADC or comparator inputs. + /// + /// The output pin is held within the returned [`OpAmpOutput`] struct, + /// preventing it being used elsewhere. The `OpAmpOutput` can then be + /// directly used as an ADC input. + pub fn buffer_ext<'a, 'b, IP, OP>( + &'a mut self, + in_pin: &IP, + out_pin: &'b mut OP, + gain: OpAmpGain, + ) -> OpAmpOutput<'a, 'b, T, OP> where - P: NonInvertingPin, + IP: NonInvertingPin + crate::gpio::sealed::Pin, + OP: OutputPin + crate::gpio::sealed::Pin, { + in_pin.set_as_analog(); + out_pin.set_as_analog(); + let (vm_sel, pga_gain) = match gain { OpAmpGain::Mul1 => (0b11, 0b00), OpAmpGain::Mul2 => (0b10, 0b00), @@ -57,25 +105,76 @@ impl<'d, T: Instance> OpAmp<'d, T> { #[cfg(opamp_f3)] T::regs().opampcsr().modify(|w| { - w.set_vp_sel(pin.channel()); + w.set_vp_sel(in_pin.channel()); w.set_vm_sel(vm_sel); w.set_pga_gain(pga_gain); + w.set_opampen(true); }); #[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_vp_sel(OpampCsrVpSel::from_bits(in_pin.channel())); w.set_vm_sel(OpampCsrVmSel::from_bits(vm_sel)); w.set_pga_gain(OpampCsrPgaGain::from_bits(pga_gain)); + w.set_opaintoen(OpampCsrOpaintoen::OUTPUTPIN); + w.set_opaen(true); }); OpAmpOutput { _inner: self, - _input: pin, + _output: out_pin, } } + + /// Configure the OpAmp as a buffer for the provided input pin, + /// with the output only used internally. + /// + /// The input pin is configured for analogue mode but not consumed, + /// so it may be subsequently used for ADC or comparator inputs. + /// + /// The returned `OpAmpInternalOutput` struct may be used as an ADC input. + #[cfg(opamp_g4)] + pub fn buffer_int<'a, P>(&'a mut self, pin: &P, gain: OpAmpGain) -> OpAmpInternalOutput<'a, T> + where + P: NonInvertingPin + crate::gpio::sealed::Pin, + { + pin.set_as_analog(); + + 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), + }; + + 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)); + w.set_opaintoen(OpampCsrOpaintoen::ADCCHANNEL); + w.set_opaen(true); + }); + + OpAmpInternalOutput { _inner: self } + } +} + +impl<'d, T: Instance> Drop for OpAmp<'d, T> { + fn drop(&mut self) { + #[cfg(opamp_f3)] + T::regs().opampcsr().modify(|w| { + w.set_opampen(false); + }); + + #[cfg(opamp_g4)] + T::regs().opamp_csr().modify(|w| { + w.set_opaen(false); + }); + } } pub trait Instance: sealed::Instance + 'static {} @@ -92,18 +191,19 @@ pub(crate) mod sealed { pub trait InvertingPin { fn channel(&self) -> u8; } + + pub trait OutputPin {} } pub trait NonInvertingPin: sealed::NonInvertingPin {} - pub trait InvertingPin: sealed::InvertingPin {} +pub trait OutputPin: sealed::OutputPin {} -#[cfg(opamp_f3)] -macro_rules! impl_opamp_output { +macro_rules! impl_opamp_external_output { ($inst:ident, $adc:ident, $ch:expr) => { foreach_adc!( ($adc, $common_inst:ident, $adc_clock:ident) => { - impl<'d, 'p, P: NonInvertingPin> crate::adc::sealed::AdcPin + impl<'d, 'p, P: OutputPin> crate::adc::sealed::AdcPin for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> { fn channel(&self) -> u8 { @@ -111,7 +211,7 @@ macro_rules! impl_opamp_output { } } - impl<'d, 'p, P: NonInvertingPin> crate::adc::AdcPin + impl<'d, 'p, P: OutputPin> crate::adc::AdcPin for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> { } @@ -120,19 +220,79 @@ macro_rules! impl_opamp_output { }; } -#[cfg(opamp_f3)] foreach_peripheral!( (opamp, OPAMP1) => { - impl_opamp_output!(OPAMP1, ADC1, 3); + impl_opamp_external_output!(OPAMP1, ADC1, 3); }; (opamp, OPAMP2) => { - impl_opamp_output!(OPAMP2, ADC2, 3); + impl_opamp_external_output!(OPAMP2, ADC2, 3); }; (opamp, OPAMP3) => { - impl_opamp_output!(OPAMP3, ADC3, 1); + impl_opamp_external_output!(OPAMP3, ADC3, 1); }; + // OPAMP4 only in STM32G4 Cat 3 devices (opamp, OPAMP4) => { - impl_opamp_output!(OPAMP4, ADC4, 3); + impl_opamp_external_output!(OPAMP4, ADC4, 3); + }; + // OPAMP5 only in STM32G4 Cat 3 devices + (opamp, OPAMP5) => { + impl_opamp_external_output!(OPAMP5, ADC5, 1); + }; + // OPAMP6 only in STM32G4 Cat 3/4 devices + (opamp, OPAMP6) => { + impl_opamp_external_output!(OPAMP6, ADC1, 14); + }; +); + +#[cfg(opamp_g4)] +macro_rules! impl_opamp_internal_output { + ($inst:ident, $adc:ident, $ch:expr) => { + foreach_adc!( + ($adc, $common_inst:ident, $adc_clock:ident) => { + impl<'d> crate::adc::sealed::AdcPin + for OpAmpInternalOutput<'d, crate::peripherals::$inst> + { + fn channel(&self) -> u8 { + $ch + } + } + + impl<'d> crate::adc::AdcPin + for OpAmpInternalOutput<'d, crate::peripherals::$inst> + { + } + }; + ); + }; +} + +#[cfg(opamp_g4)] +foreach_peripheral!( + (opamp, OPAMP1) => { + impl_opamp_internal_output!(OPAMP1, ADC1, 13); + }; + (opamp, OPAMP2) => { + impl_opamp_internal_output!(OPAMP2, ADC2, 16); + }; + (opamp, OPAMP3) => { + impl_opamp_internal_output!(OPAMP3, ADC2, 18); + // Only in Cat 3/4 devices + impl_opamp_internal_output!(OPAMP3, ADC3, 13); + }; + // OPAMP4 only in Cat 3 devices + (opamp, OPAMP4) => { + impl_opamp_internal_output!(OPAMP4, ADC5, 5); + }; + // OPAMP5 only in Cat 3 devices + (opamp, OPAMP5) => { + impl_opamp_internal_output!(OPAMP5, ADC5, 3); + }; + // OPAMP6 only in Cat 3/4 devices + (opamp, OPAMP6) => { + // Only in Cat 3 devices + impl_opamp_internal_output!(OPAMP6, ADC4, 17); + // Only in Cat 4 devices + impl_opamp_internal_output!(OPAMP6, ADC3, 17); }; ); @@ -145,13 +305,12 @@ foreach_peripheral! { } impl Instance for crate::peripherals::$inst { - } }; } #[allow(unused_macros)] -macro_rules! impl_opamp_pin { +macro_rules! impl_opamp_vp_pin { ($inst:ident, $pin:ident, $ch:expr) => { impl crate::opamp::NonInvertingPin for crate::peripherals::$pin {} impl crate::opamp::sealed::NonInvertingPin for crate::peripherals::$pin { @@ -161,3 +320,11 @@ macro_rules! impl_opamp_pin { } }; } + +#[allow(unused_macros)] +macro_rules! impl_opamp_vout_pin { + ($inst:ident, $pin:ident) => { + impl crate::opamp::OutputPin for crate::peripherals::$pin {} + impl crate::opamp::sealed::OutputPin for crate::peripherals::$pin {} + }; +} diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index 128001bf..137fc9e6 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs @@ -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, OpAmpGain::Mul1); + let mut buffer = opamp.buffer_ext(&p.PA7, &mut p.PA6, OpAmpGain::Mul1); loop { let vref = adc.read(&mut vrefint).await; From d464d1a841191b79bae6dd7bf9366e7fd076de41 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Mon, 6 Nov 2023 01:11:57 +0000 Subject: [PATCH 099/188] Remove accidentally leftover println --- embassy-stm32/build.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 35c3f23b..965fe4e8 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -944,8 +944,6 @@ fn main() { } if regs.kind == "opamp" { - println!("{}", pin.signal); - if pin.signal.starts_with("VP") { // Impl NonInvertingPin for the VP* signals (VP0, VP1, VP2, etc) let peri = format_ident!("{}", p.name); From 239ad5ebea8fb67e8ff2446675343c97687ef81e Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 5 Nov 2023 20:09:33 -0600 Subject: [PATCH 100/188] stm32: update metapac and use stop data --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/build.rs | 23 +++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 7e11e263..01a9d482 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-8381654ade324de3945c3c755d359686e957e99b" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1374ed622714ef4702826699ca21cc1f741f4133" } 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-8381654ade324de3945c3c755d359686e957e99b", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1374ed622714ef4702826699ca21cc1f741f4133", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 1307656a..6b41cd39 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -6,7 +6,7 @@ use std::{env, fs}; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; use stm32_metapac::metadata::ir::{BlockItemInner, Enum, FieldSet}; -use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA}; +use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, StopMode, METADATA}; fn main() { let target = env::var("TARGET").unwrap(); @@ -557,18 +557,18 @@ fn main() { }; /* - If LP and non-LP peripherals share the same RCC enable bit, then a refcount leak will result. + A refcount leak can result if the same field is shared by peripherals with different stop modes - This should be checked in stm32-data-gen. + This condition should be checked in stm32-data */ - let stop_refcount = if p.name.starts_with("LP") { - quote! { REFCOUNT_STOP2 } - } else { - quote! { REFCOUNT_STOP1 } + let stop_refcount = match rcc.stop_mode { + StopMode::Standby => None, + StopMode::Stop2 => Some(quote! { REFCOUNT_STOP2 }), + StopMode::Stop1 => Some(quote! { REFCOUNT_STOP1 }), }; - let (incr_stop_refcount, decr_stop_refcount) = if p.name != "RTC" { - ( + let (incr_stop_refcount, decr_stop_refcount) = match stop_refcount { + Some(stop_refcount) => ( quote! { #[cfg(feature = "low-power")] unsafe { crate::rcc::#stop_refcount += 1 }; @@ -577,9 +577,8 @@ fn main() { #[cfg(feature = "low-power")] unsafe { crate::rcc::#stop_refcount -= 1 }; }, - ) - } else { - (quote! {}, quote! {}) + ), + None => (TokenStream::new(), TokenStream::new()), }; g.extend(quote! { From d9b00c01e09deea8d1255a89ce40174960aad793 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 03:26:00 +0100 Subject: [PATCH 101/188] usb: reject instead of panic on CONTROL OUT longer than the buf. --- embassy-usb/src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 88d88cad..9fc1e332 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -406,6 +406,16 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { let max_packet_size = self.control.max_packet_size(); let mut total = 0; + if req_length > self.control_buf.len() { + warn!( + "got CONTROL OUT with length {} higher than the control_buf len {}, rejecting.", + req_length, + self.control_buf.len() + ); + self.control.reject().await; + return; + } + let chunks = self.control_buf[..req_length].chunks_mut(max_packet_size); for (first, last, chunk) in first_last(chunks) { let size = match self.control.data_out(chunk, first, last).await { From b8679c0cc85e5eb65bd996ee18deac4a952b1b10 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 03:37:39 +0100 Subject: [PATCH 102/188] stm32/rcc: set highest VOS on some F4s with no overdrive. --- embassy-stm32/src/rcc/f4f7.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs index 2e4f9572..d507a6fd 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -113,6 +113,14 @@ pub(crate) unsafe fn init(config: Config) { while !PWR.csr1().read().odswrdy() {} } + #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423))] + { + use crate::pac::pwr::vals::Vos; + use crate::pac::PWR; + + PWR.cr1().modify(|w| w.set_vos(Vos::SCALE1)); + } + // Configure HSI let hsi = match config.hsi { false => { From 70a700e430b5258b77c678ba66dfb33977f3e7a8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 03:38:13 +0100 Subject: [PATCH 103/188] stm32/otg: log TRDT --- embassy-stm32/src/usb_otg/usb.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index e45e4ac4..26a14ff0 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs @@ -911,11 +911,9 @@ impl<'d, T: Instance> embassy_usb_driver::Bus for Bus<'d, T> { trace!("enumdne"); let speed = r.dsts().read().enumspd(); - trace!(" speed={}", speed.to_bits()); - - r.gusbcfg().modify(|w| { - w.set_trdt(calculate_trdt(speed, T::frequency())); - }); + let trdt = calculate_trdt(speed, T::frequency()); + trace!(" speed={} trdt={}", speed.to_bits(), trdt); + r.gusbcfg().modify(|w| w.set_trdt(trdt)); r.gintsts().write(|w| w.set_enumdne(true)); // clear Self::restore_irqs(); From b4eef6b1ee5d1b92263ada437692fb7c9c3fe569 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 03:38:42 +0100 Subject: [PATCH 104/188] stm32/otg: fix CONTROL OUT transfers on F4. --- embassy-stm32/src/usb_otg/usb.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index 26a14ff0..d90f8343 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs @@ -40,6 +40,7 @@ impl interrupt::typelevel::Handler for InterruptHandl // Handle RX while r.gintsts().read().rxflvl() { let status = r.grxstsp().read(); + trace!("=== status {:08x}", status.0); let ep_num = status.epnum() as usize; let len = status.bcnt() as usize; @@ -51,6 +52,15 @@ impl interrupt::typelevel::Handler for InterruptHandl assert!(len == 8, "invalid SETUP packet length={}", len); assert!(ep_num == 0, "invalid SETUP packet endpoint={}", ep_num); + // flushing TX if something stuck in control endpoint + if r.dieptsiz(ep_num).read().pktcnt() != 0 { + r.grstctl().modify(|w| { + w.set_txfnum(ep_num as _); + w.set_txfflsh(true); + }); + while r.grstctl().read().txfflsh() {} + } + if state.ep0_setup_ready.load(Ordering::Relaxed) == false { // SAFETY: exclusive access ensured by atomic bool let data = unsafe { &mut *state.ep0_setup_data.get() }; @@ -96,6 +106,11 @@ impl interrupt::typelevel::Handler for InterruptHandl } vals::Pktstsd::SETUP_DATA_DONE => { trace!("SETUP_DATA_DONE ep={}", ep_num); + + // Clear NAK to indicate we are ready to receive more data + T::regs().doepctl(ep_num).modify(|w| { + w.set_cnak(true); + }); } x => trace!("unknown PKTSTS: {}", x.to_bits()), } @@ -1312,11 +1327,6 @@ impl<'d, T: Instance> embassy_usb_driver::ControlPipe for ControlPipe<'d, T> { w.set_rxdpid_stupcnt(1); }); - // Clear NAK to indicate we are ready to receive more data - T::regs().doepctl(self.ep_out.info.addr.index()).modify(|w| { - w.set_cnak(true); - }); - trace!("SETUP received: {:?}", data); Poll::Ready(data) } else { From 7084570478cafd86e392202598da1550e5cafcaf Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 6 Nov 2023 04:13:06 +0100 Subject: [PATCH 105/188] stm32/otg: fix enumeration on non-f4 chips. Fixes regression from #2148 --- embassy-stm32/src/usb_otg/usb.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index d90f8343..ba77bfb1 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs @@ -107,10 +107,10 @@ impl interrupt::typelevel::Handler for InterruptHandl vals::Pktstsd::SETUP_DATA_DONE => { trace!("SETUP_DATA_DONE ep={}", ep_num); - // Clear NAK to indicate we are ready to receive more data - T::regs().doepctl(ep_num).modify(|w| { - w.set_cnak(true); - }); + if quirk_setup_late_cnak(r) { + // Clear NAK to indicate we are ready to receive more data + r.doepctl(ep_num).modify(|w| w.set_cnak(true)); + } } x => trace!("unknown PKTSTS: {}", x.to_bits()), } @@ -1317,16 +1317,23 @@ impl<'d, T: Instance> embassy_usb_driver::ControlPipe for ControlPipe<'d, T> { state.ep_out_wakers[0].register(cx.waker()); + let r = T::regs(); + if state.ep0_setup_ready.load(Ordering::Relaxed) { let data = unsafe { *state.ep0_setup_data.get() }; state.ep0_setup_ready.store(false, Ordering::Release); // EP0 should not be controlled by `Bus` so this RMW does not need a critical section // Receive 1 SETUP packet - T::regs().doeptsiz(self.ep_out.info.addr.index()).modify(|w| { + r.doeptsiz(self.ep_out.info.addr.index()).modify(|w| { w.set_rxdpid_stupcnt(1); }); + // Clear NAK to indicate we are ready to receive more data + if !quirk_setup_late_cnak(r) { + r.doepctl(self.ep_out.info.addr.index()).modify(|w| w.set_cnak(true)); + } + trace!("SETUP received: {:?}", data); Poll::Ready(data) } else { @@ -1461,3 +1468,7 @@ fn calculate_trdt(speed: vals::Dspd, ahb_freq: Hertz) -> u8 { _ => unimplemented!(), } } + +fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool { + r.cid().read().0 & 0xf000 == 0x1000 +} From 15660cfc68f88b18f4e2fa7a2d776da4ec8b422a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 6 Nov 2023 08:52:11 +0100 Subject: [PATCH 106/188] Ensure TcpIo not blocking when reading into empty slice --- embassy-net/CHANGELOG.md | 4 ++++ embassy-net/src/tcp.rs | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/embassy-net/CHANGELOG.md b/embassy-net/CHANGELOG.md index 4030e050..ada34cb7 100644 --- a/embassy-net/CHANGELOG.md +++ b/embassy-net/CHANGELOG.md @@ -5,6 +5,10 @@ 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). +## Unreleased + +- Avoid never resolving `TcpIo::read` when the output buffer is empty. + ## 0.2.1 - 2023-10-31 - Re-add impl_trait_projections diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index b5615cb6..bcd5bb61 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -390,6 +390,13 @@ impl<'d> TcpIo<'d> { // CAUTION: smoltcp semantics around EOF are different to what you'd expect // from posix-like IO, so we have to tweak things here. self.with_mut(|s, _| match s.recv_slice(buf) { + // Reading into empty buffer + Ok(0) if buf.is_empty() => { + // embedded_io_async::Read's contract is to not block if buf is empty. While + // this function is not a direct implementor of the trait method, we still don't + // want our future to never resolve. + Poll::Ready(Ok(0)) + } // No data ready Ok(0) => { s.register_recv_waker(cx.waker()); From 8f543062aa8bd44526e864e16deb9765618f191c Mon Sep 17 00:00:00 2001 From: eZio Pan Date: Mon, 6 Nov 2023 18:30:59 +0800 Subject: [PATCH 107/188] check PLL settings before set VOS --- embassy-stm32/src/rcc/f4f7.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs index d507a6fd..9e8c639d 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -1,8 +1,9 @@ +use crate::pac::pwr::vals::Vos; pub use crate::pac::rcc::vals::{ Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp, Pllq, Pllr, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, }; -use crate::pac::{FLASH, RCC}; +use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -100,12 +101,17 @@ impl Default for Config { } pub(crate) unsafe fn init(config: Config) { + // set VOS to SCALE1, if use PLL + // TODO: check real clock speed before set VOS + if config.pll.is_some() { + PWR.cr1().modify(|w| w.set_vos(Vos::SCALE1)); + } + // always enable overdrive for now. Make it configurable in the future. #[cfg(not(any( stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f405, stm32f407, stm32f415, stm32f417 )))] { - use crate::pac::PWR; PWR.cr1().modify(|w| w.set_oden(true)); while !PWR.csr1().read().odrdy() {} @@ -113,14 +119,6 @@ pub(crate) unsafe fn init(config: Config) { while !PWR.csr1().read().odswrdy() {} } - #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423))] - { - use crate::pac::pwr::vals::Vos; - use crate::pac::PWR; - - PWR.cr1().modify(|w| w.set_vos(Vos::SCALE1)); - } - // Configure HSI let hsi = match config.hsi { false => { From 8d8d50cc7a97fa65976e9dc1a82a58de29e7eb64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 6 Nov 2023 15:21:53 +0100 Subject: [PATCH 108/188] Yeet core::sync::atomic, remove futures-util dep --- embassy-executor/CHANGELOG.md | 4 ++++ embassy-executor/Cargo.toml | 1 - embassy-executor/src/arch/riscv32.rs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index cade48f0..ad3e2e95 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/CHANGELOG.md @@ -5,6 +5,10 @@ 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.3.2 + +- Use `atomic-polyfill` for `riscv32` + ## 0.3.1 - 2023-11-01 - Fix spurious "Found waker not created by the Embassy executor" error in recent nightlies. diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 8e36637a..f59d0f97 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -57,7 +57,6 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } 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.5", path = "../embassy-time", optional = true} atomic-polyfill = "1.0.1" diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs index 40c6877e..e5c0ff2e 100644 --- a/embassy-executor/src/arch/riscv32.rs +++ b/embassy-executor/src/arch/riscv32.rs @@ -6,8 +6,8 @@ pub use thread::*; #[cfg(feature = "executor-thread")] mod thread { use core::marker::PhantomData; - use core::sync::atomic::{AtomicBool, Ordering}; + use atomic_polyfill::{AtomicBool, Ordering}; #[cfg(feature = "nightly")] pub use embassy_macros::main_riscv as main; From b8f9341edc721d19e999a76ab4b01c1420200b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 6 Nov 2023 21:50:40 +0100 Subject: [PATCH 109/188] Prepare embassy-executor 0.3.2 --- embassy-executor/CHANGELOG.md | 3 ++- embassy-executor/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index ad3e2e95..e7914cbc 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/CHANGELOG.md @@ -5,9 +5,10 @@ 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.3.2 +## 0.3.2 - 2023-11-06 - Use `atomic-polyfill` for `riscv32` +- Removed unused dependencies (static_cell, futures-util) ## 0.3.1 - 2023-11-01 diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index f59d0f97..a85c5dff 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-executor" -version = "0.3.1" +version = "0.3.2" edition = "2021" license = "MIT OR Apache-2.0" description = "async/await executor designed for embedded usage" From 326bc98bd225a8ec65093e5881e29c57e66fb1cd Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Tue, 7 Nov 2023 02:34:14 +0000 Subject: [PATCH 110/188] Update stm32 usb_raw example to use MSOS descriptors for WinUSB --- examples/stm32f4/Cargo.toml | 2 +- examples/stm32f4/src/bin/usb_ethernet.rs | 1 + examples/stm32f4/src/bin/usb_raw.rs | 21 +++++++++++++++++++++ examples/stm32f4/src/bin/usb_serial.rs | 1 + 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index fca18203..bcf37371 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -10,7 +10,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "msos-descriptor"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } defmt = "0.3" diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index 7c0644ae..45dcf56a 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -94,6 +94,7 @@ async fn main(spawner: Spawner) { &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], + &mut [], &mut make_static!([0; 128])[..], ); diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs index 8d4e6c7d..689aea4f 100644 --- a/examples/stm32f4/src/bin/usb_raw.rs +++ b/examples/stm32f4/src/bin/usb_raw.rs @@ -56,10 +56,16 @@ use embassy_stm32::time::Hertz; use embassy_stm32::usb_otg::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; +use embassy_usb::msos::{self, windows_version}; use embassy_usb::types::InterfaceNumber; use embassy_usb::{Builder, Handler}; use {defmt_rtt as _, panic_probe as _}; +// Randomly generated UUID because Windows requires you provide one to use WinUSB. +// In principle WinUSB-using software could find this device (or a specific interface +// on it) by its GUID instead of using the VID/PID, but in practice that seems unhelpful. +const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"]; + bind_interrupts!(struct Irqs { OTG_FS => usb_otg::InterruptHandler; }); @@ -114,6 +120,7 @@ async fn main(_spawner: Spawner) { let mut device_descriptor = [0; 256]; let mut config_descriptor = [0; 256]; let mut bos_descriptor = [0; 256]; + let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; let mut handler = ControlHandler { @@ -126,9 +133,23 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut msos_descriptor, &mut control_buf, ); + // Add the Microsoft OS Descriptor (MSOS/MOD) descriptor. + // We tell Windows that this entire device is compatible with the "WINUSB" feature, + // which causes it to use the built-in WinUSB driver automatically, which in turn + // can be used by libusb/rusb software without needing a custom driver or INF file. + // In principle you might want to call msos_feature() just on a specific function, + // if your device also has other functions that still use standard class drivers. + builder.msos_descriptor(windows_version::WIN8_1, 0); + builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + // Add a vendor-specific function (class 0xFF), and corresponding interface, // that uses our custom handler. let mut function = builder.function(0xFF, 0, 0); diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index 004ff038..3ab9a6c5 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs @@ -77,6 +77,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], &mut control_buf, ); From db4cd73894f13cf63114c42db6b82f0904070ffb Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 7 Nov 2023 09:05:10 +0100 Subject: [PATCH 111/188] rp: Add USB raw example + msos descriptor to examples and usb-logger --- embassy-usb-logger/Cargo.toml | 3 + embassy-usb-logger/src/lib.rs | 6 + examples/rp/Cargo.toml | 4 +- examples/rp/src/bin/usb_ethernet.rs | 1 + examples/rp/src/bin/usb_hid_keyboard.rs | 4 +- examples/rp/src/bin/usb_midi.rs | 1 + examples/rp/src/bin/usb_raw.rs | 149 ++++++++++++++++++++++++ examples/rp/src/bin/usb_serial.rs | 1 + 8 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 examples/rp/src/bin/usb_raw.rs diff --git a/embassy-usb-logger/Cargo.toml b/embassy-usb-logger/Cargo.toml index 48b8bbcc..02d0ed8e 100644 --- a/embassy-usb-logger/Cargo.toml +++ b/embassy-usb-logger/Cargo.toml @@ -8,6 +8,9 @@ src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-logger-v$VERS src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-logger/src/" target = "thumbv7em-none-eabi" +[features] +msos-descriptor = ["embassy-usb/msos-descriptor"] + [dependencies] embassy-usb = { version = "0.1.0", path = "../embassy-usb" } embassy-sync = { version = "0.4.0", path = "../embassy-sync" } diff --git a/embassy-usb-logger/src/lib.rs b/embassy-usb-logger/src/lib.rs index 9178dd6d..95fc0a7e 100644 --- a/embassy-usb-logger/src/lib.rs +++ b/embassy-usb-logger/src/lib.rs @@ -19,6 +19,8 @@ pub struct LoggerState<'d> { device_descriptor: [u8; 32], config_descriptor: [u8; 128], bos_descriptor: [u8; 16], + #[cfg(feature = "msos-descriptor")] + msos_descriptor: [u8; 256], control_buf: [u8; 64], } @@ -30,6 +32,8 @@ impl<'d> LoggerState<'d> { device_descriptor: [0; 32], config_descriptor: [0; 128], bos_descriptor: [0; 16], + #[cfg(feature = "msos-descriptor")] + msos_descriptor: [0; 256], control_buf: [0; 64], } } @@ -73,6 +77,8 @@ impl UsbLogger { &mut state.device_descriptor, &mut state.config_descriptor, &mut state.bos_descriptor, + #[cfg(feature = "msos-descriptor")] + &mut state.msos_descriptor, &mut state.control_buf, ); diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index fbe7acae..5ff505e8 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -11,11 +11,11 @@ embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "msos-descriptor"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } +embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger", features = ["msos-descriptor"]} embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["time", "defmt"] } lora-phy = { version = "2" } lorawan-device = { version = "0.11.0", default-features = false, features = ["async", "external-lora-phy"] } diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index 6c2f27ac..aea9e648 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs @@ -71,6 +71,7 @@ async fn main(spawner: Spawner) { &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], + &mut make_static!([0; 0])[..], &mut make_static!([0; 128])[..], ); diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs index cc2090d2..569c9b12 100644 --- a/examples/rp/src/bin/usb_hid_keyboard.rs +++ b/examples/rp/src/bin/usb_hid_keyboard.rs @@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) { let mut config_descriptor = [0; 256]; let mut bos_descriptor = [0; 256]; // You can also add a Microsoft OS descriptor. - // let mut msos_descriptor = [0; 256]; + let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; let request_handler = MyRequestHandler {}; let mut device_handler = MyDeviceHandler::new(); @@ -54,7 +54,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, - // &mut msos_descriptor, + &mut msos_descriptor, &mut control_buf, ); diff --git a/examples/rp/src/bin/usb_midi.rs b/examples/rp/src/bin/usb_midi.rs index f0b03c81..3ba34c80 100644 --- a/examples/rp/src/bin/usb_midi.rs +++ b/examples/rp/src/bin/usb_midi.rs @@ -58,6 +58,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], &mut control_buf, ); diff --git a/examples/rp/src/bin/usb_raw.rs b/examples/rp/src/bin/usb_raw.rs new file mode 100644 index 00000000..e0e5daa5 --- /dev/null +++ b/examples/rp/src/bin/usb_raw.rs @@ -0,0 +1,149 @@ +//! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip. +//! +//! This creates a USB serial port that echos. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_rp::bind_interrupts; +use embassy_rp::peripherals::USB; +use embassy_rp::usb::{Driver, InterruptHandler}; +use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; +use embassy_usb::msos::{self, windows_version}; +use embassy_usb::types::InterfaceNumber; +use embassy_usb::{Builder, Config, Handler}; +use {defmt_rtt as _, panic_probe as _}; + +// This is a randomly generated GUID to allow clients on Windows to find our device +const DEVICE_INTERFACE_GUIDS: &[&str] = &["{AFB9A6FB-30BA-44BC-9232-806CFC875321}"]; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Hello there!"); + + 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 raw 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 msos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + + let mut handler = ControlHandler { + if_num: InterfaceNumber(0), + }; + + let mut builder = Builder::new( + driver, + config, + &mut device_descriptor, + &mut config_descriptor, + &mut bos_descriptor, + &mut msos_descriptor, + &mut control_buf, + ); + + builder.msos_descriptor(windows_version::WIN8_1, 0); + builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + + // Add a vendor-specific function (class 0xFF), and corresponding interface, + // that uses our custom handler. + let mut function = builder.function(0xFF, 0, 0); + let mut interface = function.interface(); + let _alt = interface.alt_setting(0xFF, 0, 0, None); + handler.if_num = interface.interface_number(); + drop(function); + builder.handler(&mut handler); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + usb.run().await; +} + +/// Handle CONTROL endpoint requests and responses. For many simple requests and responses +/// you can get away with only using the control endpoint. +struct ControlHandler { + if_num: InterfaceNumber, +} + +impl Handler for ControlHandler { + /// Respond to HostToDevice control messages, where the host sends us a command and + /// optionally some data, and we can only acknowledge or reject it. + fn control_out<'a>(&'a mut self, req: Request, buf: &'a [u8]) -> Option { + // Log the request before filtering to help with debugging. + info!("Got control_out, request={}, buf={:a}", req, buf); + + // Only handle Vendor request types to an Interface. + if req.request_type != RequestType::Vendor || req.recipient != Recipient::Interface { + return None; + } + + // Ignore requests to other interfaces. + if req.index != self.if_num.0 as u16 { + return None; + } + + // Accept request 100, value 200, reject others. + if req.request == 100 && req.value == 200 { + Some(OutResponse::Accepted) + } else { + Some(OutResponse::Rejected) + } + } + + /// Respond to DeviceToHost control messages, where the host requests some data from us. + fn control_in<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> Option> { + info!("Got control_in, request={}", req); + + // Only handle Vendor request types to an Interface. + if req.request_type != RequestType::Vendor || req.recipient != Recipient::Interface { + return None; + } + + // Ignore requests to other interfaces. + if req.index != self.if_num.0 as u16 { + return None; + } + + // Respond "hello" to request 101, value 201, when asked for 5 bytes, otherwise reject. + if req.request == 101 && req.value == 201 && req.length == 5 { + buf[..5].copy_from_slice(b"hello"); + Some(InResponse::Accepted(&buf[..5])) + } else { + Some(InResponse::Rejected) + } + } +} diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index 164e2052..0d0317cd 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs @@ -60,6 +60,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], &mut control_buf, ); From 50139752bc671c86521e11e0b3872cd64109c65c Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 7 Nov 2023 09:10:18 +0100 Subject: [PATCH 112/188] Add comments --- examples/rp/src/bin/usb_raw.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/rp/src/bin/usb_raw.rs b/examples/rp/src/bin/usb_raw.rs index e0e5daa5..044e728a 100644 --- a/examples/rp/src/bin/usb_raw.rs +++ b/examples/rp/src/bin/usb_raw.rs @@ -70,6 +70,12 @@ async fn main(_spawner: Spawner) { &mut control_buf, ); + // Add the Microsoft OS Descriptor (MSOS/MOD) descriptor. + // We tell Windows that this entire device is compatible with the "WINUSB" feature, + // which causes it to use the built-in WinUSB driver automatically, which in turn + // can be used by libusb/rusb software without needing a custom driver or INF file. + // In principle you might want to call msos_feature() just on a specific function, + // if your device also has other functions that still use standard class drivers. builder.msos_descriptor(windows_version::WIN8_1, 0); builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( From 38bfa6916f61f1e633955b311e70da8ecfb81972 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 7 Nov 2023 09:15:21 +0100 Subject: [PATCH 113/188] Update pio-uart example --- examples/rp/src/bin/pio_uart.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs index 45416c56..dca28d77 100644 --- a/examples/rp/src/bin/pio_uart.rs +++ b/examples/rp/src/bin/pio_uart.rs @@ -75,6 +75,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], &mut control_buf, ); From e3fe13e9052e6502b9618b94a64ed69688bbf5b6 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 7 Nov 2023 10:58:35 +0100 Subject: [PATCH 114/188] Add docs --- examples/rp/src/bin/usb_raw.rs | 48 ++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/examples/rp/src/bin/usb_raw.rs b/examples/rp/src/bin/usb_raw.rs index 044e728a..f59262e5 100644 --- a/examples/rp/src/bin/usb_raw.rs +++ b/examples/rp/src/bin/usb_raw.rs @@ -1,6 +1,50 @@ -//! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip. +//! Example of using USB without a pre-defined class, but instead responding to +//! raw USB control requests. //! -//! This creates a USB serial port that echos. +//! The host computer can either: +//! * send a command, with a 16-bit request ID, a 16-bit value, and an optional data buffer +//! * request some data, with a 16-bit request ID, a 16-bit value, and a length of data to receive +//! +//! For higher throughput data, you can add some bulk endpoints after creating the alternate, +//! but for low rate command/response, plain control transfers can be very simple and effective. +//! +//! Example code to send/receive data using `nusb`: +//! +//! ```ignore +//! use futures_lite::future::block_on; +//! use nusb::transfer::{ControlIn, ControlOut, ControlType, Recipient}; +//! +//! fn main() { +//! let di = nusb::list_devices() +//! .unwrap() +//! .find(|d| d.vendor_id() == 0xc0de && d.product_id() == 0xcafe) +//! .expect("no device found"); +//! let device = di.open().expect("error opening device"); +//! let interface = device.claim_interface(0).expect("error claiming interface"); +//! +//! // Send "hello world" to device +//! let result = block_on(interface.control_out(ControlOut { +//! control_type: ControlType::Vendor, +//! recipient: Recipient::Interface, +//! request: 100, +//! value: 200, +//! index: 0, +//! data: b"hello world", +//! })); +//! println!("{result:?}"); +//! +//! // Receive "hello" from device +//! let result = block_on(interface.control_in(ControlIn { +//! control_type: ControlType::Vendor, +//! recipient: Recipient::Interface, +//! request: 101, +//! value: 201, +//! index: 0, +//! length: 5, +//! })); +//! println!("{result:?}"); +//! } +//! ``` #![no_std] #![no_main] From d1adc936141b06cb2d8acd2f8a15279307ef06a6 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 7 Nov 2023 19:57:05 +0100 Subject: [PATCH 115/188] rp: Add USB raw bulk example --- examples/rp/Cargo.toml | 1 + examples/rp/src/bin/usb_raw_bulk.rs | 150 ++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 examples/rp/src/bin/usb_raw_bulk.rs diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 5ff505e8..c5351044 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -12,6 +12,7 @@ embassy-executor = { version = "0.3.1", path = "../../embassy-executor", feature embassy-time = { version = "0.1.5", 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", "msos-descriptor"] } +embassy-usb-driver = { version = "0.1.0", path = "../../embassy-usb-driver" } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/rp/src/bin/usb_raw_bulk.rs b/examples/rp/src/bin/usb_raw_bulk.rs new file mode 100644 index 00000000..e8618c48 --- /dev/null +++ b/examples/rp/src/bin/usb_raw_bulk.rs @@ -0,0 +1,150 @@ +//! Example of using USB without a pre-defined class, but instead using raw USB bulk transfers. +//! +//! Example code to send/receive data using `nusb`: +//! +//! ```ignore +//! use futures_lite::future::block_on; +//! use nusb::transfer::RequestBuffer; +//! +//! const BULK_OUT_EP: u8 = 0x01; +//! const BULK_IN_EP: u8 = 0x81; +//! +//! fn main() { +//! let di = nusb::list_devices() +//! .unwrap() +//! .find(|d| d.vendor_id() == 0xc0de && d.product_id() == 0xcafe) +//! .expect("no device found"); +//! let device = di.open().expect("error opening device"); +//! let interface = device.claim_interface(0).expect("error claiming interface"); +//! +//! let result = block_on(interface.bulk_out(BULK_OUT_EP, b"hello world".into())); +//! println!("{result:?}"); +//! let result = block_on(interface.bulk_in(BULK_IN_EP, RequestBuffer::new(64))); +//! println!("{result:?}"); +//! } +//! ``` + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_rp::bind_interrupts; +use embassy_rp::peripherals::USB; +use embassy_rp::usb::{Driver, InterruptHandler}; +use embassy_usb::msos::{self, windows_version}; +use embassy_usb::{Builder, Config, Handler}; +use embassy_usb_driver::{Endpoint, EndpointIn, EndpointOut}; +use {defmt_rtt as _, panic_probe as _}; + +// This is a randomly generated GUID to allow clients on Windows to find our device +const DEVICE_INTERFACE_GUIDS: &[&str] = &["{AFB9A6FB-30BA-44BC-9232-806CFC875321}"]; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Hello there!"); + + 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 raw 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 msos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + + let mut handler = ControlHandler; + + let mut builder = Builder::new( + driver, + config, + &mut device_descriptor, + &mut config_descriptor, + &mut bos_descriptor, + &mut msos_descriptor, + &mut control_buf, + ); + + // Add the Microsoft OS Descriptor (MSOS/MOD) descriptor. + // We tell Windows that this entire device is compatible with the "WINUSB" feature, + // which causes it to use the built-in WinUSB driver automatically, which in turn + // can be used by libusb/rusb software without needing a custom driver or INF file. + // In principle you might want to call msos_feature() just on a specific function, + // if your device also has other functions that still use standard class drivers. + builder.msos_descriptor(windows_version::WIN8_1, 0); + builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + + // Add a vendor-specific function (class 0xFF), and corresponding interface, + // that uses our custom handler. + let mut function = builder.function(0xFF, 0, 0); + let mut interface = function.interface(); + let mut alt = interface.alt_setting(0xFF, 0, 0, None); + let mut read_ep = alt.endpoint_bulk_out(64); + let mut write_ep = alt.endpoint_bulk_in(64); + + drop(function); + builder.handler(&mut handler); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + + // Do stuff with the class! + let echo_fut = async { + loop { + read_ep.wait_enabled().await; + info!("Connected"); + loop { + let mut data = [0; 64]; + match read_ep.read(&mut data).await { + Ok(n) => { + info!("Got bulk: {:a}", data[..n]); + // Echo back to the host: + write_ep.write(&data[..n]).await.ok(); + } + Err(_) => break, + } + } + info!("Disconnected"); + } + }; + + // Run everything concurrently. + // If we had made everything `'static` above instead, we could do this using separate tasks instead. + join(usb_fut, echo_fut).await; +} + +/// Handle CONTROL endpoint requests and responses. +struct ControlHandler; +impl Handler for ControlHandler {} From 37a773c037223573f5bfb3c81c347240af4fa171 Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 7 Nov 2023 20:17:19 +0100 Subject: [PATCH 116/188] Use driver reexport --- examples/rp/Cargo.toml | 1 - examples/rp/src/bin/usb_raw_bulk.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index c5351044..5ff505e8 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -12,7 +12,6 @@ embassy-executor = { version = "0.3.1", path = "../../embassy-executor", feature embassy-time = { version = "0.1.5", 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", "msos-descriptor"] } -embassy-usb-driver = { version = "0.1.0", path = "../../embassy-usb-driver" } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/rp/src/bin/usb_raw_bulk.rs b/examples/rp/src/bin/usb_raw_bulk.rs index e8618c48..b2274e6c 100644 --- a/examples/rp/src/bin/usb_raw_bulk.rs +++ b/examples/rp/src/bin/usb_raw_bulk.rs @@ -36,7 +36,7 @@ use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver, InterruptHandler}; use embassy_usb::msos::{self, windows_version}; use embassy_usb::{Builder, Config, Handler}; -use embassy_usb_driver::{Endpoint, EndpointIn, EndpointOut}; +use embassy_usb::driver::{Endpoint, EndpointIn, EndpointOut}; use {defmt_rtt as _, panic_probe as _}; // This is a randomly generated GUID to allow clients on Windows to find our device From d44383e9a7cfaaa5e5cdbd4b3ade32f5f753616f Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 7 Nov 2023 20:19:56 +0100 Subject: [PATCH 117/188] fmt --- examples/rp/src/bin/usb_raw_bulk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rp/src/bin/usb_raw_bulk.rs b/examples/rp/src/bin/usb_raw_bulk.rs index b2274e6c..ad31045f 100644 --- a/examples/rp/src/bin/usb_raw_bulk.rs +++ b/examples/rp/src/bin/usb_raw_bulk.rs @@ -34,9 +34,9 @@ use embassy_futures::join::join; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver, InterruptHandler}; +use embassy_usb::driver::{Endpoint, EndpointIn, EndpointOut}; use embassy_usb::msos::{self, windows_version}; use embassy_usb::{Builder, Config, Handler}; -use embassy_usb::driver::{Endpoint, EndpointIn, EndpointOut}; use {defmt_rtt as _, panic_probe as _}; // This is a randomly generated GUID to allow clients on Windows to find our device From 8effff338302d82b08e2a8f0d97a2d69d9a7b96a Mon Sep 17 00:00:00 2001 From: kalkyl Date: Tue, 7 Nov 2023 20:45:01 +0100 Subject: [PATCH 118/188] rp: Remove control handler from USB raw bulk example --- examples/rp/src/bin/usb_raw_bulk.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/examples/rp/src/bin/usb_raw_bulk.rs b/examples/rp/src/bin/usb_raw_bulk.rs index ad31045f..288be5a4 100644 --- a/examples/rp/src/bin/usb_raw_bulk.rs +++ b/examples/rp/src/bin/usb_raw_bulk.rs @@ -36,7 +36,7 @@ use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver, InterruptHandler}; use embassy_usb::driver::{Endpoint, EndpointIn, EndpointOut}; use embassy_usb::msos::{self, windows_version}; -use embassy_usb::{Builder, Config, Handler}; +use embassy_usb::{Builder, Config}; use {defmt_rtt as _, panic_probe as _}; // This is a randomly generated GUID to allow clients on Windows to find our device @@ -78,8 +78,6 @@ async fn main(_spawner: Spawner) { let mut msos_descriptor = [0; 256]; let mut control_buf = [0; 64]; - let mut handler = ControlHandler; - let mut builder = Builder::new( driver, config, @@ -110,9 +108,7 @@ async fn main(_spawner: Spawner) { let mut alt = interface.alt_setting(0xFF, 0, 0, None); let mut read_ep = alt.endpoint_bulk_out(64); let mut write_ep = alt.endpoint_bulk_in(64); - drop(function); - builder.handler(&mut handler); // Build the builder. let mut usb = builder.build(); @@ -144,7 +140,3 @@ async fn main(_spawner: Spawner) { // If we had made everything `'static` above instead, we could do this using separate tasks instead. join(usb_fut, echo_fut).await; } - -/// Handle CONTROL endpoint requests and responses. -struct ControlHandler; -impl Handler for ControlHandler {} From 553f0158c0a8abaa293ada3b3f214194418a767e Mon Sep 17 00:00:00 2001 From: xoviat Date: Tue, 7 Nov 2023 15:39:06 -0600 Subject: [PATCH 119/188] stm32: resolve eth/v2 security bug fixes #2129 --- embassy-stm32/src/eth/v2/descriptors.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/embassy-stm32/src/eth/v2/descriptors.rs b/embassy-stm32/src/eth/v2/descriptors.rs index e9799adf..01ea8e57 100644 --- a/embassy-stm32/src/eth/v2/descriptors.rs +++ b/embassy-stm32/src/eth/v2/descriptors.rs @@ -119,13 +119,11 @@ impl<'a> TDesRing<'a> { // "Preceding reads and writes cannot be moved past subsequent writes." fence(Ordering::Release); - self.index = self.index + 1; - if self.index == self.descriptors.len() { - self.index = 0; - } - // signal DMA it can try again. - ETH.ethernet_dma().dmactx_dtpr().write(|w| w.0 = 0) + // See issue #2129 + ETH.ethernet_dma().dmactx_dtpr().write(|w| w.0 = &td as *const _ as u32); + + self.index = (self.index + 1) % self.descriptors.len(); } } @@ -237,21 +235,19 @@ impl<'a> RDesRing<'a> { /// Pop the packet previously returned by `available`. pub(crate) fn pop_packet(&mut self) { - let descriptor = &mut self.descriptors[self.index]; - assert!(descriptor.available()); + let rd = &mut self.descriptors[self.index]; + assert!(rd.available()); - self.descriptors[self.index].set_ready(self.buffers[self.index].0.as_mut_ptr()); + rd.set_ready(self.buffers[self.index].0.as_mut_ptr()); // "Preceding reads and writes cannot be moved past subsequent writes." fence(Ordering::Release); // signal DMA it can try again. - ETH.ethernet_dma().dmacrx_dtpr().write(|w| w.0 = 0); + // See issue #2129 + ETH.ethernet_dma().dmacrx_dtpr().write(|w| w.0 = &rd as *const _ as u32); // Increment index. - self.index += 1; - if self.index == self.descriptors.len() { - self.index = 0 - } + self.index = (self.index + 1) % self.descriptors.len(); } } From a3e200d0115d35c710abe28e69addc8ee68a0d2c Mon Sep 17 00:00:00 2001 From: Nigecat Date: Wed, 8 Nov 2023 09:28:33 +1100 Subject: [PATCH 120/188] Fix typo in embassy-net docs --- embassy-net/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-net/README.md b/embassy-net/README.md index 7bb2283c..52d048e6 100644 --- a/embassy-net/README.md +++ b/embassy-net/README.md @@ -4,7 +4,7 @@ It builds on [`smoltcp`](https://github.com/smoltcp-rs/smoltcp). It provides a higher-level and more opinionated API. It glues together the components provided by `smoltcp`, handling the low-level details with defaults and -memory management designed to work well for embedded systems, aiiming for a more "Just Works" experience. +memory management designed to work well for embedded systems, aiming for a more "Just Works" experience. ## Features From 79acb560ecb9089e31efdea29c6046225971fee3 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 8 Nov 2023 23:05:00 +0100 Subject: [PATCH 121/188] Pin noproto git rev. --- embassy-net-esp-hosted/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index eba54249..2a8c2857 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml @@ -15,7 +15,7 @@ embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver- embedded-hal = { version = "1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } -noproto = { git="https://github.com/embassy-rs/noproto", default-features = false, features = ["derive"] } +noproto = { git="https://github.com/embassy-rs/noproto", rev = "c90f3a78d7b5642415e0a07af401320b84d8ab6f", default-features = false, features = ["derive"] } #noproto = { version = "0.1", path = "/home/dirbaio/noproto", default-features = false, features = ["derive"] } heapless = "0.7.16" From 0b015bd727547d1eade5cd12c8b6a1b77483e6db Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 8 Nov 2023 23:08:50 +0100 Subject: [PATCH 122/188] usb: remove msos-descriptor feature. --- embassy-usb-logger/Cargo.toml | 3 --- embassy-usb-logger/src/lib.rs | 3 --- embassy-usb/Cargo.toml | 1 - embassy-usb/src/builder.rs | 18 ++---------------- embassy-usb/src/lib.rs | 23 ++++++----------------- embassy-usb/src/msos.rs | 2 -- examples/nrf52840/Cargo.toml | 2 +- examples/rp/Cargo.toml | 4 ++-- examples/rp/src/bin/pio_uart.rs | 2 +- examples/rp/src/bin/usb_ethernet.rs | 2 +- examples/rp/src/bin/usb_midi.rs | 2 +- examples/rp/src/bin/usb_serial.rs | 2 +- examples/stm32f1/src/bin/usb_serial.rs | 1 + examples/stm32f3/src/bin/usb_serial.rs | 1 + examples/stm32f4/Cargo.toml | 2 +- examples/stm32f4/src/bin/usb_ethernet.rs | 2 +- examples/stm32f4/src/bin/usb_serial.rs | 2 +- examples/stm32f7/src/bin/usb_serial.rs | 1 + examples/stm32g4/src/bin/usb_serial.rs | 1 + examples/stm32h5/src/bin/usb_serial.rs | 1 + examples/stm32h7/src/bin/usb_serial.rs | 1 + examples/stm32l4/src/bin/usb_serial.rs | 1 + examples/stm32l5/src/bin/usb_ethernet.rs | 1 + examples/stm32l5/src/bin/usb_hid_mouse.rs | 1 + examples/stm32l5/src/bin/usb_serial.rs | 1 + examples/stm32u5/src/bin/usb_serial.rs | 1 + 26 files changed, 29 insertions(+), 52 deletions(-) diff --git a/embassy-usb-logger/Cargo.toml b/embassy-usb-logger/Cargo.toml index 02d0ed8e..48b8bbcc 100644 --- a/embassy-usb-logger/Cargo.toml +++ b/embassy-usb-logger/Cargo.toml @@ -8,9 +8,6 @@ src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-logger-v$VERS src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb-logger/src/" target = "thumbv7em-none-eabi" -[features] -msos-descriptor = ["embassy-usb/msos-descriptor"] - [dependencies] embassy-usb = { version = "0.1.0", path = "../embassy-usb" } embassy-sync = { version = "0.4.0", path = "../embassy-sync" } diff --git a/embassy-usb-logger/src/lib.rs b/embassy-usb-logger/src/lib.rs index 95fc0a7e..45d780bf 100644 --- a/embassy-usb-logger/src/lib.rs +++ b/embassy-usb-logger/src/lib.rs @@ -19,7 +19,6 @@ pub struct LoggerState<'d> { device_descriptor: [u8; 32], config_descriptor: [u8; 128], bos_descriptor: [u8; 16], - #[cfg(feature = "msos-descriptor")] msos_descriptor: [u8; 256], control_buf: [u8; 64], } @@ -32,7 +31,6 @@ impl<'d> LoggerState<'d> { device_descriptor: [0; 32], config_descriptor: [0; 128], bos_descriptor: [0; 16], - #[cfg(feature = "msos-descriptor")] msos_descriptor: [0; 256], control_buf: [0; 64], } @@ -77,7 +75,6 @@ impl UsbLogger { &mut state.device_descriptor, &mut state.config_descriptor, &mut state.bos_descriptor, - #[cfg(feature = "msos-descriptor")] &mut state.msos_descriptor, &mut state.control_buf, ); diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index d820a2d0..5f64b721 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -13,7 +13,6 @@ target = "thumbv7em-none-eabi" [features] defmt = ["dep:defmt", "embassy-usb-driver/defmt"] usbd-hid = ["dep:usbd-hid", "dep:ssmarshal"] -msos-descriptor = [] default = ["usbd-hid"] # BEGIN AUTOGENERATED CONFIG FEATURES diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index b4ddccd7..c4705d04 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs @@ -3,7 +3,6 @@ use heapless::Vec; use crate::config::MAX_HANDLER_COUNT; use crate::descriptor::{BosWriter, DescriptorWriter}; use crate::driver::{Driver, Endpoint, EndpointType}; -#[cfg(feature = "msos-descriptor")] use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter}; use crate::types::{InterfaceNumber, StringIndex}; use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START}; @@ -133,7 +132,6 @@ pub struct Builder<'d, D: Driver<'d>> { config_descriptor: DescriptorWriter<'d>, bos_descriptor: BosWriter<'d>, - #[cfg(feature = "msos-descriptor")] msos_descriptor: MsOsDescriptorWriter<'d>, } @@ -149,7 +147,7 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { device_descriptor_buf: &'d mut [u8], config_descriptor_buf: &'d mut [u8], bos_descriptor_buf: &'d mut [u8], - #[cfg(feature = "msos-descriptor")] msos_descriptor_buf: &'d mut [u8], + msos_descriptor_buf: &'d mut [u8], control_buf: &'d mut [u8], ) -> Self { // Magic values specified in USB-IF ECN on IADs. @@ -189,14 +187,12 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { config_descriptor, bos_descriptor, - #[cfg(feature = "msos-descriptor")] msos_descriptor: MsOsDescriptorWriter::new(msos_descriptor_buf), } } /// Creates the [`UsbDevice`] instance with the configuration in this builder. pub fn build(mut self) -> UsbDevice<'d, D> { - #[cfg(feature = "msos-descriptor")] let msos_descriptor = self.msos_descriptor.build(&mut self.bos_descriptor); self.config_descriptor.end_configuration(); @@ -206,7 +202,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { info!("USB: device_descriptor used: {}", self.device_descriptor.position()); info!("USB: config_descriptor used: {}", self.config_descriptor.position()); info!("USB: bos_descriptor used: {}", self.bos_descriptor.writer.position()); - #[cfg(feature = "msos-descriptor")] info!("USB: msos_descriptor used: {}", msos_descriptor.len()); info!("USB: control_buf size: {}", self.control_buf.len()); @@ -217,10 +212,9 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { self.device_descriptor.into_buf(), self.config_descriptor.into_buf(), self.bos_descriptor.writer.into_buf(), + msos_descriptor, self.interfaces, self.control_buf, - #[cfg(feature = "msos-descriptor")] - msos_descriptor, ) } @@ -251,7 +245,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { builder: self, iface_count_index, - #[cfg(feature = "msos-descriptor")] first_interface, } } @@ -275,7 +268,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { StringIndex::new(index) } - #[cfg(feature = "msos-descriptor")] /// Add an MS OS 2.0 Descriptor Set. /// /// Panics if called more than once. @@ -283,13 +275,11 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { self.msos_descriptor.header(windows_version, vendor_code); } - #[cfg(feature = "msos-descriptor")] /// Add an MS OS 2.0 Device Level Feature Descriptor. pub fn msos_feature(&mut self, desc: T) { self.msos_descriptor.device_feature(desc); } - #[cfg(feature = "msos-descriptor")] /// Gets the underlying [`MsOsDescriptorWriter`] to allow adding subsets and features for classes that /// do not add their own. pub fn msos_writer(&mut self) -> &mut MsOsDescriptorWriter<'d> { @@ -306,13 +296,11 @@ pub struct FunctionBuilder<'a, 'd, D: Driver<'d>> { builder: &'a mut Builder<'d, D>, iface_count_index: Option, - #[cfg(feature = "msos-descriptor")] first_interface: InterfaceNumber, } impl<'a, 'd, D: Driver<'d>> Drop for FunctionBuilder<'a, 'd, D> { fn drop(&mut self) { - #[cfg(feature = "msos-descriptor")] self.builder.msos_descriptor.end_function(); } } @@ -344,7 +332,6 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> { } } - #[cfg(feature = "msos-descriptor")] /// Add an MS OS 2.0 Function Level Feature Descriptor. pub fn msos_feature(&mut self, desc: T) { if !self.builder.msos_descriptor.is_in_config_subset() { @@ -355,7 +342,6 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> { self.builder.msos_descriptor.function(self.first_interface); } - #[cfg(feature = "msos-descriptor")] self.builder.msos_descriptor.function_feature(desc); } } diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 9fc1e332..241e33a7 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -175,10 +175,7 @@ pub struct UsbBufferReport { /// Number of bos descriptor bytes used pub bos_descriptor_used: usize, /// Number of msos descriptor bytes used - /// - /// Will be `None` if the "msos-descriptor" feature is not active. - /// Otherwise will return Some(bytes). - pub msos_descriptor_used: Option, + pub msos_descriptor_used: usize, /// Size of the control buffer pub control_buffer_size: usize, } @@ -197,6 +194,7 @@ struct Inner<'d, D: Driver<'d>> { device_descriptor: &'d [u8], config_descriptor: &'d [u8], bos_descriptor: &'d [u8], + msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, device_state: UsbDeviceState, suspended: bool, @@ -212,9 +210,6 @@ struct Inner<'d, D: Driver<'d>> { interfaces: Vec, handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>, - - #[cfg(feature = "msos-descriptor")] - msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, } impl<'d, D: Driver<'d>> UsbDevice<'d, D> { @@ -225,9 +220,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { device_descriptor: &'d [u8], config_descriptor: &'d [u8], bos_descriptor: &'d [u8], + msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, interfaces: Vec, control_buf: &'d mut [u8], - #[cfg(feature = "msos-descriptor")] msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, ) -> UsbDevice<'d, D> { // Start the USB bus. // This prevent further allocation by consuming the driver. @@ -242,6 +237,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { device_descriptor, config_descriptor, bos_descriptor, + msos_descriptor, device_state: UsbDeviceState::Unpowered, suspended: false, @@ -251,8 +247,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { set_address_pending: false, interfaces, handlers, - #[cfg(feature = "msos-descriptor")] - msos_descriptor, }, } } @@ -261,16 +255,11 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { /// /// Useful for tuning buffer sizes for actual usage pub fn buffer_usage(&self) -> UsbBufferReport { - #[cfg(not(feature = "msos-descriptor"))] - let mdu = None; - #[cfg(feature = "msos-descriptor")] - let mdu = Some(self.inner.msos_descriptor.len()); - UsbBufferReport { device_descriptor_used: self.inner.device_descriptor.len(), config_descriptor_used: self.inner.config_descriptor.len(), bos_descriptor_used: self.inner.bos_descriptor.len(), - msos_descriptor_used: mdu, + msos_descriptor_used: self.inner.msos_descriptor.len(), control_buffer_size: self.control_buf.len(), } } @@ -684,7 +673,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { } _ => InResponse::Rejected, }, - #[cfg(feature = "msos-descriptor")] + (RequestType::Vendor, Recipient::Device) => { if !self.msos_descriptor.is_empty() && req.request == self.msos_descriptor.vendor_code() diff --git a/embassy-usb/src/msos.rs b/embassy-usb/src/msos.rs index 13d5d7c4..3858c0f5 100644 --- a/embassy-usb/src/msos.rs +++ b/embassy-usb/src/msos.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "msos-descriptor")] - //! Microsoft OS Descriptors //! //! diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index f803adb0..7bf904ee 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -34,7 +34,7 @@ embassy-executor = { version = "0.3.1", path = "../../embassy-executor", feature embassy-time = { version = "0.1.5", 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.2.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 } +embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true } 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 } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 5ff505e8..fbe7acae 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -11,11 +11,11 @@ embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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", "msos-descriptor"] } +embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger", features = ["msos-descriptor"]} +embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["time", "defmt"] } lora-phy = { version = "2" } lorawan-device = { version = "0.11.0", default-features = false, features = ["async", "external-lora-phy"] } diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs index dca28d77..fb9d423e 100644 --- a/examples/rp/src/bin/pio_uart.rs +++ b/examples/rp/src/bin/pio_uart.rs @@ -75,7 +75,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, - &mut [], + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index aea9e648..cc63029f 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs @@ -71,7 +71,7 @@ async fn main(spawner: Spawner) { &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], - &mut make_static!([0; 0])[..], + &mut [], // no msos descriptors &mut make_static!([0; 128])[..], ); diff --git a/examples/rp/src/bin/usb_midi.rs b/examples/rp/src/bin/usb_midi.rs index 3ba34c80..d5cdae31 100644 --- a/examples/rp/src/bin/usb_midi.rs +++ b/examples/rp/src/bin/usb_midi.rs @@ -58,7 +58,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, - &mut [], + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index 0d0317cd..30347d92 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs @@ -60,7 +60,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, - &mut [], + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs index 60eb5d0e..31519555 100644 --- a/examples/stm32f1/src/bin/usb_serial.rs +++ b/examples/stm32f1/src/bin/usb_serial.rs @@ -60,6 +60,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32f3/src/bin/usb_serial.rs b/examples/stm32f3/src/bin/usb_serial.rs index a9537c77..d5d068d6 100644 --- a/examples/stm32f3/src/bin/usb_serial.rs +++ b/examples/stm32f3/src/bin/usb_serial.rs @@ -57,6 +57,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index bcf37371..f8182190 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -10,7 +10,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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", "msos-descriptor"] } +embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt" ] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } defmt = "0.3" diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index 45dcf56a..34407b95 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -94,7 +94,7 @@ async fn main(spawner: Spawner) { &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], - &mut [], + &mut [], // no msos descriptors &mut make_static!([0; 128])[..], ); diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index 3ab9a6c5..3e05b0ef 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs @@ -77,7 +77,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, - &mut [], + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs index 2f832c23..6aca732b 100644 --- a/examples/stm32f7/src/bin/usb_serial.rs +++ b/examples/stm32f7/src/bin/usb_serial.rs @@ -77,6 +77,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index 188988b1..378e7b98 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs @@ -75,6 +75,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index 13b218d0..7d45818a 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs @@ -82,6 +82,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index 648ff6ee..f80cf63e 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs @@ -78,6 +78,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index d459245d..d977398f 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -72,6 +72,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index f5b3ca34..923193ab 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -82,6 +82,7 @@ async fn main(spawner: Spawner) { &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], &mut make_static!([0; 256])[..], + &mut [], // no msos descriptors &mut make_static!([0; 128])[..], ); diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index bec3d5e4..f64d0f34 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -62,6 +62,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index ff1154f9..58a8898a 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -57,6 +57,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index eaa1c291..a218d5df 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -67,6 +67,7 @@ async fn main(_spawner: Spawner) { &mut device_descriptor, &mut config_descriptor, &mut bos_descriptor, + &mut [], // no msos descriptors &mut control_buf, ); From 4b4c28d8752aab0a96fc244f9eaabe256e7dbeb2 Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 8 Nov 2023 19:04:20 -0600 Subject: [PATCH 123/188] stm32: add low power for g4 --- embassy-stm32/Cargo.toml | 2 +- embassy-stm32/src/rtc/mod.rs | 162 +++++++++++++++++++++++++++++++++++ embassy-stm32/src/rtc/v2.rs | 138 ----------------------------- embassy-stm32/src/rtc/v3.rs | 8 +- tests/stm32/Cargo.toml | 2 +- 5 files changed, 171 insertions(+), 141 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 01a9d482..7b3a6c2b 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -18,7 +18,7 @@ flavors = [ { regex_feature = "stm32f7.*", target = "thumbv7em-none-eabi" }, { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" }, { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" }, - { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi" }, + { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] }, { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf" }, { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" }, { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] }, diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index e94a5857..3f03d83a 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -33,6 +33,60 @@ use embassy_hal_internal::Peripheral; use crate::peripherals::RTC; use crate::rtc::sealed::Instance; +#[repr(u8)] +#[derive(Clone, Copy, Debug)] +pub(crate) enum WakeupPrescaler { + Div2 = 2, + Div4 = 4, + Div8 = 8, + Div16 = 16, +} + +#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4))] +impl From for crate::pac::rtc::vals::Wucksel { + fn from(val: WakeupPrescaler) -> Self { + use crate::pac::rtc::vals::Wucksel; + + match val { + WakeupPrescaler::Div2 => Wucksel::DIV2, + WakeupPrescaler::Div4 => Wucksel::DIV4, + WakeupPrescaler::Div8 => Wucksel::DIV8, + WakeupPrescaler::Div16 => Wucksel::DIV16, + } + } +} + +#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4))] +impl From for WakeupPrescaler { + fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { + use crate::pac::rtc::vals::Wucksel; + + match val { + Wucksel::DIV2 => WakeupPrescaler::Div2, + Wucksel::DIV4 => WakeupPrescaler::Div4, + Wucksel::DIV8 => WakeupPrescaler::Div8, + Wucksel::DIV16 => WakeupPrescaler::Div16, + _ => unreachable!(), + } + } +} + +#[cfg(feature = "low-power")] +impl WakeupPrescaler { + pub fn compute_min(val: u32) -> Self { + *[ + WakeupPrescaler::Div2, + WakeupPrescaler::Div4, + WakeupPrescaler::Div8, + WakeupPrescaler::Div16, + ] + .iter() + .skip_while(|psc| **psc as u32 <= val) + .next() + .unwrap_or(&WakeupPrescaler::Div16) + } +} + /// Errors that can occur on methods on [RtcClock] #[non_exhaustive] #[derive(Clone, Debug, PartialEq, Eq)] @@ -277,6 +331,114 @@ impl Rtc { pub fn write_backup_register(&self, register: usize, value: u32) { RTC::write_backup_register(&RTC::regs(), register, value) } + + #[cfg(feature = "low-power")] + /// start the wakeup alarm and wtih a duration that is as close to but less than + /// the requested duration, and record the instant the wakeup alarm was started + pub(crate) fn start_wakeup_alarm( + &self, + requested_duration: embassy_time::Duration, + cs: critical_section::CriticalSection, + ) { + use embassy_time::{Duration, TICK_HZ}; + + #[cfg(any(rtc_v3, rtc_v3u5))] + use crate::pac::rtc::vals::Calrf; + + // Panic if the rcc mod knows we're not using low-power rtc + #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] + unsafe { crate::rcc::get_freqs() }.rtc.unwrap(); + + let requested_duration = requested_duration.as_ticks().clamp(0, u32::MAX as u64); + let rtc_hz = Self::frequency().0 as u64; + let rtc_ticks = requested_duration * rtc_hz / TICK_HZ; + let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32); + + // adjust the rtc ticks to the prescaler and subtract one rtc tick + let rtc_ticks = rtc_ticks / prescaler as u64; + let rtc_ticks = rtc_ticks.clamp(0, (u16::MAX - 1) as u64).saturating_sub(1) as u16; + + self.write(false, |regs| { + regs.cr().modify(|w| w.set_wute(false)); + + #[cfg(any( + rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb + ))] + { + regs.isr().modify(|w| w.set_wutf(false)); + while !regs.isr().read().wutwf() {} + } + + #[cfg(any(rtc_v3, rtc_v3u5))] + { + regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR)); + while !regs.icsr().read().wutwf() {} + } + + regs.cr().modify(|w| w.set_wucksel(prescaler.into())); + regs.wutr().write(|w| w.set_wut(rtc_ticks)); + regs.cr().modify(|w| w.set_wute(true)); + regs.cr().modify(|w| w.set_wutie(true)); + }); + + let instant = self.instant().unwrap(); + trace!( + "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}", + Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(), + prescaler as u32, + rtc_ticks, + instant, + ); + + assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none()) + } + + #[cfg(feature = "low-power")] + /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm` + /// was called, otherwise none + pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option { + use crate::interrupt::typelevel::Interrupt; + #[cfg(any(rtc_v3, rtc_v3u5))] + use crate::pac::rtc::vals::Calrf; + + let instant = self.instant().unwrap(); + if RTC::regs().cr().read().wute() { + trace!("rtc: stop wakeup alarm at {}", instant); + + self.write(false, |regs| { + regs.cr().modify(|w| w.set_wutie(false)); + regs.cr().modify(|w| w.set_wute(false)); + + #[cfg(any( + rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb + ))] + regs.isr().modify(|w| w.set_wutf(false)); + + #[cfg(any(rtc_v3, rtc_v3u5))] + regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR)); + + crate::pac::EXTI + .pr(0) + .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); + + ::WakeupInterrupt::unpend(); + }); + } + + self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time) + } + + #[cfg(feature = "low-power")] + pub(crate) fn enable_wakeup_line(&self) { + use crate::interrupt::typelevel::Interrupt; + use crate::pac::EXTI; + + ::WakeupInterrupt::unpend(); + unsafe { ::WakeupInterrupt::enable() }; + + EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); + EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); + } } pub(crate) fn byte_to_bcd2(byte: u8) -> (u8, u8) { diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 006fd63f..91f08fae 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs @@ -6,145 +6,7 @@ use crate::peripherals::RTC; use crate::rtc::sealed::Instance; #[allow(dead_code)] -#[repr(u8)] -#[derive(Clone, Copy, Debug)] -pub(crate) enum WakeupPrescaler { - Div2 = 2, - Div4 = 4, - Div8 = 8, - Div16 = 16, -} - -#[cfg(any(stm32wb, stm32f4, stm32l0))] -impl From for crate::pac::rtc::vals::Wucksel { - fn from(val: WakeupPrescaler) -> Self { - use crate::pac::rtc::vals::Wucksel; - - match val { - WakeupPrescaler::Div2 => Wucksel::DIV2, - WakeupPrescaler::Div4 => Wucksel::DIV4, - WakeupPrescaler::Div8 => Wucksel::DIV8, - WakeupPrescaler::Div16 => Wucksel::DIV16, - } - } -} - -#[cfg(any(stm32wb, stm32f4, stm32l0))] -impl From for WakeupPrescaler { - fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { - use crate::pac::rtc::vals::Wucksel; - - match val { - Wucksel::DIV2 => WakeupPrescaler::Div2, - Wucksel::DIV4 => WakeupPrescaler::Div4, - Wucksel::DIV8 => WakeupPrescaler::Div8, - Wucksel::DIV16 => WakeupPrescaler::Div16, - _ => unreachable!(), - } - } -} - -#[allow(dead_code)] -impl WakeupPrescaler { - pub fn compute_min(val: u32) -> Self { - *[ - WakeupPrescaler::Div2, - WakeupPrescaler::Div4, - WakeupPrescaler::Div8, - WakeupPrescaler::Div16, - ] - .iter() - .skip_while(|psc| **psc as u32 <= val) - .next() - .unwrap_or(&WakeupPrescaler::Div16) - } -} - impl super::Rtc { - #[cfg(feature = "low-power")] - /// start the wakeup alarm and wtih a duration that is as close to but less than - /// the requested duration, and record the instant the wakeup alarm was started - pub(crate) fn start_wakeup_alarm( - &self, - requested_duration: embassy_time::Duration, - cs: critical_section::CriticalSection, - ) { - use embassy_time::{Duration, TICK_HZ}; - - // Panic if the rcc mod knows we're not using low-power rtc - #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] - unsafe { crate::rcc::get_freqs() }.rtc.unwrap(); - - let requested_duration = requested_duration.as_ticks().clamp(0, u32::MAX as u64); - let rtc_hz = Self::frequency().0 as u64; - let rtc_ticks = requested_duration * rtc_hz / TICK_HZ; - let prescaler = WakeupPrescaler::compute_min((rtc_ticks / u16::MAX as u64) as u32); - - // adjust the rtc ticks to the prescaler and subtract one rtc tick - let rtc_ticks = rtc_ticks / prescaler as u64; - let rtc_ticks = rtc_ticks.clamp(0, (u16::MAX - 1) as u64).saturating_sub(1) as u16; - - self.write(false, |regs| { - regs.cr().modify(|w| w.set_wute(false)); - regs.isr().modify(|w| w.set_wutf(false)); - while !regs.isr().read().wutwf() {} - - regs.cr().modify(|w| w.set_wucksel(prescaler.into())); - regs.wutr().write(|w| w.set_wut(rtc_ticks)); - regs.cr().modify(|w| w.set_wute(true)); - regs.cr().modify(|w| w.set_wutie(true)); - }); - - let instant = self.instant().unwrap(); - trace!( - "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}", - Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(), - prescaler as u32, - rtc_ticks, - instant, - ); - - assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none()) - } - - #[cfg(feature = "low-power")] - /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm` - /// was called, otherwise none - pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option { - use crate::interrupt::typelevel::Interrupt; - - let instant = self.instant().unwrap(); - if RTC::regs().cr().read().wute() { - trace!("rtc: stop wakeup alarm at {}", 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)); - - crate::pac::EXTI - .pr(0) - .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); - - ::WakeupInterrupt::unpend(); - }); - } - - self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time) - } - - #[cfg(feature = "low-power")] - pub(crate) fn enable_wakeup_line(&self) { - use crate::interrupt::typelevel::Interrupt; - use crate::pac::EXTI; - - ::WakeupInterrupt::unpend(); - unsafe { ::WakeupInterrupt::enable() }; - - EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); - EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); - } - /// Applies the RTC config /// It this changes the RTC clock source the time will be reset pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) { diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index 7bf757e7..d2d0d930 100644 --- a/embassy-stm32/src/rtc/v3.rs +++ b/embassy-stm32/src/rtc/v3.rs @@ -95,7 +95,7 @@ impl super::Rtc { }) } - pub(super) fn write(&mut self, init_mode: bool, f: F) -> R + pub(super) fn write(&self, init_mode: bool, f: F) -> R where F: FnOnce(&crate::pac::rtc::Rtc) -> R, { @@ -129,6 +129,12 @@ impl super::Rtc { impl sealed::Instance for crate::peripherals::RTC { const BACKUP_REGISTER_COUNT: usize = 32; + #[cfg(all(feature = "low-power", stm32g4))] + const EXTI_WAKEUP_LINE: usize = 20; + + #[cfg(all(feature = "low-power", stm32g4))] + type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; + fn read_backup_register(_rtc: &Rtc, register: usize) -> Option { #[allow(clippy::if_same_then_else)] if register < Self::BACKUP_REGISTER_COUNT { diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 4b769b1c..9b9273a5 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -10,7 +10,7 @@ stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin", "rng"] stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac-adc-pin"] stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"] -stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma", "rng"] +stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng"] stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin", "rng"] stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"] stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"] From 05a4bb3a4acdb5a980efbb6f807696c1c702e01c Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 8 Nov 2023 19:06:29 -0600 Subject: [PATCH 124/188] rustfmt --- embassy-stm32/src/rtc/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 3f03d83a..b4315f53 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -33,6 +33,7 @@ use embassy_hal_internal::Peripheral; use crate::peripherals::RTC; use crate::rtc::sealed::Instance; +#[allow(dead_code)] #[repr(u8)] #[derive(Clone, Copy, Debug)] pub(crate) enum WakeupPrescaler { From 3b33cc46915f0b400a2a9dd87cfe51eca9f7e434 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Fri, 10 Nov 2023 15:49:31 +0200 Subject: [PATCH 125/188] i2c: expose async api without needing time This exposes I2C async API without needing "time" feature. With "time" feature additional async API with timeouts is exposed. --- embassy-stm32/src/i2c/v2.rs | 207 ++++++++++++++++++++++++++++++------ 1 file changed, 175 insertions(+), 32 deletions(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index fc6dcd6e..7049affe 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -1,21 +1,14 @@ use core::cmp; -#[cfg(feature = "time")] -use core::future::poll_fn; +use core::future::{poll_fn, Future}; 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; -#[cfg(feature = "time")] -use crate::dma::Transfer; +use crate::dma::{NoDma, Transfer}; use crate::gpio::sealed::AFType; use crate::gpio::Pull; use crate::i2c::{Error, Instance, SclPin, SdaPin}; @@ -24,6 +17,92 @@ use crate::pac::i2c; use crate::time::Hertz; use crate::{interrupt, Peripheral}; +/// # Async I2C Operations with Optional Timeouts +/// +/// This module provides compatibility for async I2C operations with timeout-based APIs, +/// even when the "time" feature is not enabled. In the absence of the "time" feature, +/// operations effectively never time out. +/// +/// ## Usage Scenario +/// This is particularly useful in scenarios such as when using RTIC, where a user might +/// have their own monotonic timer and thus choose not to enable the "time" feature. +/// In such cases, this module allows the use of async I2C APIs without actual timeout +/// handling. +/// +/// ## Functionality +/// - When the "time" feature is disabled, `Duration` and `Instant` types are provided +/// as dummy implementations, and timeout functions do not perform real timing but +/// simply mimic the required interfaces. +/// - When the "time" feature is enabled, `Duration` and `Instant` from the `embassy_time` +/// are used, and timeouts are handled as expected. +#[cfg(not(feature = "time"))] +mod dummy_time { + use core::ops::Sub; + + use super::{Error, Future}; + + #[derive(Copy, Clone)] + pub struct Duration; + + impl Duration { + pub fn dummy_duration() -> Duration { + Duration + } + } + + pub struct Instant; + + impl Instant { + pub fn now() -> Self { + Self + } + + pub fn duration_since(&self, _since: Instant) -> Duration { + Duration + } + } + + impl Sub for Duration { + type Output = Duration; + + fn sub(self, _rhs: Duration) -> Duration { + Duration + } + } + + /// Timeout that never times out. + pub fn timeout_fn(_timeout: Duration) -> impl Fn() -> Result<(), Error> { + move || Ok(()) + } + + /// This is compatible with `embassy_time::with_timeout` however it never times out. + pub async fn with_timeout(_timeout: Duration, fut: F) -> Result { + Ok(fut.await) + } +} + +#[cfg(not(feature = "time"))] +use dummy_time::{timeout_fn, with_timeout, Duration, Instant}; +#[cfg(feature = "time")] +use embassy_time::{Duration, Instant}; + +#[cfg(feature = "time")] +fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> { + let deadline = Instant::now() + timeout; + move || { + if Instant::now() > deadline { + Err(Error::Timeout) + } else { + Ok(()) + } + } +} + +#[cfg(feature = "time")] +async fn with_timeout(timeout: Duration, fut: F) -> Result { + embassy_time::with_timeout(timeout, fut).await +} + /// Interrupt handler. pub struct InterruptHandler { _phantom: PhantomData, @@ -437,7 +516,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { result } - #[cfg(feature = "time")] async fn write_dma_internal( &mut self, address: u8, @@ -528,7 +606,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } - #[cfg(feature = "time")] async fn read_dma_internal( &mut self, address: u8, @@ -616,18 +693,34 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { where TXDMA: crate::i2c::TxDma, { - self.write_timeout(address, write, self.timeout).await + self.write_timeout_internal(address, write, self.timeout).await + } + + #[cfg(not(feature = "time"))] + pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> + where + TXDMA: crate::i2c::TxDma, + { + self.write_timeout_internal(address, write, Duration::dummy_duration()) + .await } #[cfg(feature = "time")] pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> + where + TXDMA: crate::i2c::TxDma, + { + self.write_timeout_internal(address, write, timeout).await + } + + async fn write_timeout_internal(&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, timeout_fn(timeout)) } else { - embassy_time::with_timeout( + with_timeout( timeout, self.write_dma_internal(address, write, true, true, timeout_fn(timeout)), ) @@ -641,11 +734,32 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { where TXDMA: crate::i2c::TxDma, { - self.write_vectored_timeout(address, write, self.timeout).await + self.write_vectored_timeout_internal(address, write, self.timeout).await + } + + #[cfg(not(feature = "time"))] + pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> + where + TXDMA: crate::i2c::TxDma, + { + self.write_vectored_timeout_internal(address, write, Duration::dummy_duration()) + .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, + { + self.write_vectored_timeout_internal(address, write, timeout).await + } + + async fn write_vectored_timeout_internal( + &mut self, + address: u8, + write: &[&[u8]], + timeout: Duration, + ) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, { @@ -660,7 +774,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { let next = iter.next(); let is_last = next.is_none(); - embassy_time::with_timeout( + with_timeout( timeout, self.write_dma_internal(address, c, first, is_last, timeout_fn(timeout)), ) @@ -677,18 +791,34 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { where RXDMA: crate::i2c::RxDma, { - self.read_timeout(address, buffer, self.timeout).await + self.read_timeout_internal(address, buffer, self.timeout).await + } + + #[cfg(not(feature = "time"))] + pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> + where + RXDMA: crate::i2c::RxDma, + { + self.read_timeout_internal(address, buffer, Duration::dummy_duration()) + .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, + { + self.read_timeout_internal(address, buffer, timeout).await + } + + async fn read_timeout_internal(&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, timeout_fn(timeout)) } else { - embassy_time::with_timeout( + with_timeout( timeout, self.read_dma_internal(address, buffer, false, timeout_fn(timeout)), ) @@ -703,7 +833,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { TXDMA: super::TxDma, RXDMA: super::RxDma, { - self.write_read_timeout(address, write, read, self.timeout).await + self.write_read_timeout_internal(address, write, read, self.timeout) + .await + } + + #[cfg(not(feature = "time"))] + 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_internal(address, write, read, Duration::dummy_duration()) + .await } #[cfg(feature = "time")] @@ -714,6 +855,20 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { read: &mut [u8], timeout: Duration, ) -> Result<(), Error> + where + TXDMA: super::TxDma, + RXDMA: super::RxDma, + { + self.write_read_timeout_internal(address, write, read, timeout).await + } + + async fn write_read_timeout_internal( + &mut self, + address: u8, + write: &[u8], + read: &mut [u8], + timeout: Duration, + ) -> Result<(), Error> where TXDMA: super::TxDma, RXDMA: super::RxDma, @@ -723,7 +878,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if write.is_empty() { self.write_internal(address, write, false, &check_timeout)?; } else { - embassy_time::with_timeout( + with_timeout( timeout, self.write_dma_internal(address, write, true, true, &check_timeout), ) @@ -736,7 +891,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if read.is_empty() { self.read_internal(address, read, true, &check_timeout)?; } else { - embassy_time::with_timeout( + with_timeout( time_left_until_timeout, self.read_dma_internal(address, read, true, &check_timeout), ) @@ -1201,15 +1356,3 @@ impl<'d, T: Instance> SetConfig for I2c<'d, T> { Ok(()) } } - -#[cfg(feature = "time")] -fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> { - let deadline = Instant::now() + timeout; - move || { - if Instant::now() > deadline { - Err(Error::Timeout) - } else { - Ok(()) - } - } -} From 4647df14b16c95ef56bf2e6cc4303583be3b4846 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 8 Nov 2023 22:59:58 +0100 Subject: [PATCH 126/188] Update heapless to v0.8, embedded-nal-async to v0.7 --- embassy-net-adin1110/Cargo.toml | 2 +- embassy-net-esp-hosted/Cargo.toml | 4 ++-- embassy-net-esp-hosted/src/control.rs | 4 ++-- embassy-net/Cargo.toml | 6 +++--- embassy-net/src/dns.rs | 3 ++- embassy-net/src/tcp.rs | 5 +---- embassy-stm32-wpan/Cargo.toml | 2 +- embassy-sync/Cargo.toml | 2 +- embassy-time/Cargo.toml | 2 +- embassy-usb/Cargo.toml | 2 +- examples/rp/Cargo.toml | 2 +- examples/std/Cargo.toml | 3 +-- examples/stm32c0/Cargo.toml | 2 +- examples/stm32f1/Cargo.toml | 2 +- examples/stm32f2/Cargo.toml | 2 +- examples/stm32f3/Cargo.toml | 2 +- examples/stm32f334/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 | 4 ++-- examples/stm32h7/Cargo.toml | 6 +++--- 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 +- 31 files changed, 39 insertions(+), 42 deletions(-) diff --git a/embassy-net-adin1110/Cargo.toml b/embassy-net-adin1110/Cargo.toml index 08c6aabd..3f016160 100644 --- a/embassy-net-adin1110/Cargo.toml +++ b/embassy-net-adin1110/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -heapless = "0.7.16" +heapless = "0.8" defmt = { version = "0.3", optional = true } log = { version = "0.4", default-features = false, optional = true } embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index 2a8c2857..e86be445 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml @@ -15,9 +15,9 @@ embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver- embedded-hal = { version = "1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } -noproto = { git="https://github.com/embassy-rs/noproto", rev = "c90f3a78d7b5642415e0a07af401320b84d8ab6f", default-features = false, features = ["derive"] } +noproto = { git="https://github.com/embassy-rs/noproto", rev = "f5e6d1f325b6ad4e344f60452b09576e24671f62", default-features = false, features = ["derive"] } #noproto = { version = "0.1", path = "/home/dirbaio/noproto", default-features = false, features = ["derive"] } -heapless = "0.7.16" +heapless = "0.8" [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-esp-hosted-v$VERSION/embassy-net-esp-hosted/src/" diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs index 50030f43..c86891bc 100644 --- a/embassy-net-esp-hosted/src/control.rs +++ b/embassy-net-esp-hosted/src/control.rs @@ -97,8 +97,8 @@ impl<'a> Control<'a> { pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { let req = proto::CtrlMsgReqConnectAp { - ssid: String::from(ssid), - pwd: String::from(password), + ssid: unwrap!(String::try_from(ssid)), + pwd: unwrap!(String::try_from(password)), bssid: String::new(), listen_interval: 3, is_wpa3_supported: false, diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 918c5bd3..0b029bd3 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -46,7 +46,7 @@ igmp = ["smoltcp/proto-igmp"] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -smoltcp = { version = "0.10.0", default-features = false, features = [ +smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "9b791ae3057e10f7afcb70c67deb5daf714293a9", default-features = false, features = [ "socket", "async", ] } @@ -57,10 +57,10 @@ embassy-sync = { version = "0.4.0", path = "../embassy-sync" } 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 } +heapless = { version = "0.8", default-features = false } as-slice = "0.2.1" 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.6.0", optional = true } +embedded-nal-async = { version = "0.7", optional = true } diff --git a/embassy-net/src/dns.rs b/embassy-net/src/dns.rs index fdd45b31..6b804f9e 100644 --- a/embassy-net/src/dns.rs +++ b/embassy-net/src/dns.rs @@ -101,7 +101,8 @@ where async fn get_host_by_address( &self, _addr: embedded_nal_async::IpAddr, - ) -> Result, Self::Error> { + _result: &mut [u8], + ) -> Result { todo!() } } diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index bcd5bb61..90fd08e9 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs @@ -618,10 +618,7 @@ pub mod client { async fn connect<'a>( &'a self, remote: embedded_nal_async::SocketAddr, - ) -> Result, Self::Error> - where - Self: 'a, - { + ) -> Result, Self::Error> { let addr: crate::IpAddress = match remote.ip() { #[cfg(feature = "proto-ipv4")] IpAddr::V4(addr) => crate::IpAddress::Ipv4(crate::Ipv4Address::from_bytes(&addr.octets())), diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index bee03901..607cd44c 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -21,7 +21,7 @@ embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver", option defmt = { version = "0.3", optional = true } cortex-m = "0.7.6" -heapless = "0.7.16" +heapless = "0.8" aligned = "0.4.1" bit_field = "0.10.2" diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index 9a47fa21..e395389a 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml @@ -33,7 +33,7 @@ log = { version = "0.4.14", optional = true } futures-util = { version = "0.3.17", default-features = false } critical-section = "1.1" -heapless = "0.7.5" +heapless = "0.8" cfg-if = "1.0.0" embedded-io-async = { version = "0.6.0", optional = true } diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 76008f0a..37b79d0c 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -248,7 +248,7 @@ embedded-hal-async = { version = "=1.0.0-rc.1", optional = true} futures-util = { version = "0.3.17", default-features = false } critical-section = "1.1" cfg-if = "1.0.0" -heapless = "0.7" +heapless = "0.8" # WASM dependencies wasm-bindgen = { version = "0.2.81", optional = true } diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 5f64b721..ac2082dc 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -45,7 +45,7 @@ embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver- defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -heapless = "0.7.10" +heapless = "0.8" # for HID usbd-hid = { version = "0.6.0", optional = true } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index fbe7acae..b2383634 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -39,7 +39,7 @@ st7789 = "0.6.1" display-interface = "0.4.1" byte-slice-cast = { version = "1.2.0", default-features = false } smart-leds = "0.3.0" -heapless = "0.7.15" +heapless = "0.8" usbd-hid = "0.6.1" embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 99511292..ee35ef49 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -14,7 +14,6 @@ embassy-net-ppp = { version = "0.1.0", path = "../../embassy-net-ppp", features 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"] } async-io = "1.6.0" env_logger = "0.9.0" @@ -23,7 +22,7 @@ log = "0.4.14" nix = "0.26.2" clap = { version = "3.0.0-beta.5", features = ["derive"] } rand_core = { version = "0.6.3", features = ["std"] } -heapless = { version = "0.7.5", default-features = false } +heapless = { version = "0.8", default-features = false } static_cell = { version = "2", features = ["nightly"]} [profile.release] diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index 39470f37..9824aa95 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -19,7 +19,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } [profile.release] debug = 2 diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 1fe460dd..dbe09757 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -21,7 +21,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } nb = "1.0.0" [profile.dev] diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index bfb8f514..6eb883ac 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -19,7 +19,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } nb = "1.0.0" [profile.release] diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 0ab25c4c..96096f79 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -21,7 +21,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" static_cell = { version = "2", features = ["nightly"]} diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml index b3bfde44..344409ce 100644 --- a/examples/stm32f334/Cargo.toml +++ b/examples/stm32f334/Cargo.toml @@ -20,7 +20,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" static_cell = { version = "2", features = ["nightly"]} diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index f8182190..2ef044d0 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -23,7 +23,7 @@ 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 } +heapless = { version = "0.8", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" micromath = "2.0.0" diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 0a567d04..f451eb48 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -22,7 +22,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } nb = "1.0.0" rand_core = "0.6.3" critical-section = "1.1" diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 42d7d328..8c25406c 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -19,7 +19,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } [profile.release] diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 3ca6ff2f..abca22f2 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -22,7 +22,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } [profile.release] debug = 2 diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index db56b685..4d3bf0b8 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -22,10 +22,10 @@ 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.6.0" } +embedded-nal-async = { version = "0.7" } 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 } +heapless = { version = "0.8", default-features = false } rand_core = "0.6.3" critical-section = "1.1" micromath = "2.0.0" diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index c300c864..77b026d4 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -10,7 +10,7 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } -embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } @@ -22,10 +22,10 @@ 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.6.0" } +embedded-nal-async = { version = "0.7" } 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 } +heapless = { version = "0.8", default-features = false } rand_core = "0.6.3" critical-section = "1.1" micromath = "2.0.0" diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index e294d042..a5506469 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -31,7 +31,7 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.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 } +heapless = { version = "0.8", default-features = false } embedded-hal = "0.2.6" static_cell = { version = "2" } portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index cc27dfc6..b9d88884 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -18,7 +18,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } embedded-storage = "0.3.0" [profile.release] diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 5d79cf1e..66f9ce71 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/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", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } -heapless = { version = "0.7.5", default-features = false } +heapless = { version = "0.8", default-features = false } chrono = { version = "^0.4", default-features = false } rand = { version = "0.8.5", default-features = false } static_cell = { version = "2", features = ["nightly"]} diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 1cd32892..5ba95313 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -23,7 +23,7 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" futures = { version = "0.3.17", default-features = false, features = ["async-await"] } -heapless = { version = "0.7.5", default-features = false } +heapless = { version = "0.8", default-features = false } rand_core = { version = "0.6.3", default-features = false } embedded-io-async = { version = "0.6.0" } static_cell = { version = "2", features = ["nightly"]} diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 27c25ebc..07dc88d7 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -20,7 +20,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } micromath = "2.0.0" diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index daacc11c..132823a8 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -21,7 +21,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } static_cell = { version = "2", features = ["nightly"]} [features] diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index c5284850..04136f4f 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -19,7 +19,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" 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 } +heapless = { version = "0.8", default-features = false } static_cell = { version = "2", features = ["nightly"]} [profile.release] diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 9e8ffa16..bf2e7f07 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -25,7 +25,7 @@ embedded-hal = "0.2.6" embedded-storage = "0.3.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 } +heapless = { version = "0.8", default-features = false } chrono = { version = "^0.4", default-features = false } [profile.release] From 6c42885d4a072b7fa8662062ff4073063d8bd2ad Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Sat, 11 Nov 2023 14:05:58 +0200 Subject: [PATCH 127/188] stm32 i2c: remove pub _timeout api --- embassy-stm32/src/i2c/v2.rs | 156 +++--------------------------------- 1 file changed, 13 insertions(+), 143 deletions(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 7049affe..54d2fe6e 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -162,7 +162,6 @@ 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, } @@ -226,6 +225,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { rx_dma, #[cfg(feature = "time")] timeout: config.transaction_timeout, + #[cfg(not(feature = "time"))] + timeout: Duration::dummy_duration(), } } @@ -339,21 +340,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } fn flush_txdr(&self) { - //if $i2c.isr.read().txis().bit_is_set() { - //$i2c.txdr.write(|w| w.txdata().bits(0)); - //} - if T::regs().isr().read().txis() { T::regs().txdr().write(|w| w.set_txdata(0)); } if !T::regs().isr().read().txe() { T::regs().isr().modify(|w| w.set_txe(true)) } - - // If TXDR is not flagged as empty, write 1 to flush it - //if $i2c.isr.read().txe().is_not_empty() { - //$i2c.isr.write(|w| w.txe().set_bit()); - //} } fn wait_txe(&self, check_timeout: impl Fn() -> Result<(), Error>) -> Result<(), Error> { @@ -687,79 +679,23 @@ 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, - { - self.write_timeout_internal(address, write, self.timeout).await - } - - #[cfg(not(feature = "time"))] - pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma, - { - self.write_timeout_internal(address, write, Duration::dummy_duration()) - .await - } - - #[cfg(feature = "time")] - pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma, - { - self.write_timeout_internal(address, write, timeout).await - } - - async fn write_timeout_internal(&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, timeout_fn(timeout)) + self.write_internal(address, write, true, timeout_fn(self.timeout)) } else { with_timeout( - timeout, - self.write_dma_internal(address, write, true, true, timeout_fn(timeout)), + self.timeout, + self.write_dma_internal(address, write, true, true, timeout_fn(self.timeout)), ) .await .unwrap_or(Err(Error::Timeout)) } } - #[cfg(feature = "time")] pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma, - { - self.write_vectored_timeout_internal(address, write, self.timeout).await - } - - #[cfg(not(feature = "time"))] - pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> - where - TXDMA: crate::i2c::TxDma, - { - self.write_vectored_timeout_internal(address, write, Duration::dummy_duration()) - .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, - { - self.write_vectored_timeout_internal(address, write, timeout).await - } - - async fn write_vectored_timeout_internal( - &mut self, - address: u8, - write: &[&[u8]], - timeout: Duration, - ) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, { @@ -775,8 +711,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { let is_last = next.is_none(); with_timeout( - timeout, - self.write_dma_internal(address, c, first, is_last, timeout_fn(timeout)), + self.timeout, + self.write_dma_internal(address, c, first, is_last, timeout_fn(self.timeout)), ) .await .unwrap_or(Err(Error::Timeout))?; @@ -786,107 +722,41 @@ 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, - { - self.read_timeout_internal(address, buffer, self.timeout).await - } - - #[cfg(not(feature = "time"))] - pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> - where - RXDMA: crate::i2c::RxDma, - { - self.read_timeout_internal(address, buffer, Duration::dummy_duration()) - .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, - { - self.read_timeout_internal(address, buffer, timeout).await - } - - async fn read_timeout_internal(&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, timeout_fn(timeout)) + self.read_internal(address, buffer, false, timeout_fn(self.timeout)) } else { with_timeout( - timeout, - self.read_dma_internal(address, buffer, false, timeout_fn(timeout)), + self.timeout, + self.read_dma_internal(address, buffer, false, timeout_fn(self.timeout)), ) .await .unwrap_or(Err(Error::Timeout)) } } - #[cfg(feature = "time")] 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_internal(address, write, read, self.timeout) - .await - } - - #[cfg(not(feature = "time"))] - 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_internal(address, write, read, Duration::dummy_duration()) - .await - } - - #[cfg(feature = "time")] - 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.write_read_timeout_internal(address, write, read, timeout).await - } - - async fn write_read_timeout_internal( - &mut self, - address: u8, - write: &[u8], - read: &mut [u8], - timeout: Duration, - ) -> Result<(), Error> where TXDMA: super::TxDma, RXDMA: super::RxDma, { let start_instant = Instant::now(); - let check_timeout = timeout_fn(timeout); + let check_timeout = timeout_fn(self.timeout); if write.is_empty() { self.write_internal(address, write, false, &check_timeout)?; } else { with_timeout( - timeout, + self.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); + let time_left_until_timeout = self.timeout - Instant::now().duration_since(start_instant); if read.is_empty() { self.read_internal(address, read, true, &check_timeout)?; From 0f2208c0af8b89d91368c04ead9f84df664951e6 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Sat, 11 Nov 2023 14:29:24 +0200 Subject: [PATCH 128/188] stm32 i2c: remove mod dummy_time --- embassy-stm32/src/i2c/v2.rs | 167 +++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 80 deletions(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 54d2fe6e..062a6225 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -1,5 +1,5 @@ use core::cmp; -use core::future::{poll_fn, Future}; +use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; @@ -7,6 +7,8 @@ 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}; use crate::gpio::sealed::AFType; @@ -17,75 +19,6 @@ use crate::pac::i2c; use crate::time::Hertz; use crate::{interrupt, Peripheral}; -/// # Async I2C Operations with Optional Timeouts -/// -/// This module provides compatibility for async I2C operations with timeout-based APIs, -/// even when the "time" feature is not enabled. In the absence of the "time" feature, -/// operations effectively never time out. -/// -/// ## Usage Scenario -/// This is particularly useful in scenarios such as when using RTIC, where a user might -/// have their own monotonic timer and thus choose not to enable the "time" feature. -/// In such cases, this module allows the use of async I2C APIs without actual timeout -/// handling. -/// -/// ## Functionality -/// - When the "time" feature is disabled, `Duration` and `Instant` types are provided -/// as dummy implementations, and timeout functions do not perform real timing but -/// simply mimic the required interfaces. -/// - When the "time" feature is enabled, `Duration` and `Instant` from the `embassy_time` -/// are used, and timeouts are handled as expected. -#[cfg(not(feature = "time"))] -mod dummy_time { - use core::ops::Sub; - - use super::{Error, Future}; - - #[derive(Copy, Clone)] - pub struct Duration; - - impl Duration { - pub fn dummy_duration() -> Duration { - Duration - } - } - - pub struct Instant; - - impl Instant { - pub fn now() -> Self { - Self - } - - pub fn duration_since(&self, _since: Instant) -> Duration { - Duration - } - } - - impl Sub for Duration { - type Output = Duration; - - fn sub(self, _rhs: Duration) -> Duration { - Duration - } - } - - /// Timeout that never times out. - pub fn timeout_fn(_timeout: Duration) -> impl Fn() -> Result<(), Error> { - move || Ok(()) - } - - /// This is compatible with `embassy_time::with_timeout` however it never times out. - pub async fn with_timeout(_timeout: Duration, fut: F) -> Result { - Ok(fut.await) - } -} - -#[cfg(not(feature = "time"))] -use dummy_time::{timeout_fn, with_timeout, Duration, Instant}; -#[cfg(feature = "time")] -use embassy_time::{Duration, Instant}; - #[cfg(feature = "time")] fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> { let deadline = Instant::now() + timeout; @@ -98,9 +31,9 @@ fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> { } } -#[cfg(feature = "time")] -async fn with_timeout(timeout: Duration, fut: F) -> Result { - embassy_time::with_timeout(timeout, fut).await +#[cfg(not(feature = "time"))] +pub fn no_timeout_fn() -> impl Fn() -> Result<(), Error> { + move || Ok(()) } /// Interrupt handler. @@ -162,6 +95,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, } @@ -225,8 +159,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { rx_dma, #[cfg(feature = "time")] timeout: config.transaction_timeout, - #[cfg(not(feature = "time"))] - timeout: Duration::dummy_duration(), } } @@ -679,6 +611,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, @@ -686,7 +619,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if write.is_empty() { self.write_internal(address, write, true, timeout_fn(self.timeout)) } else { - with_timeout( + embassy_time::with_timeout( self.timeout, self.write_dma_internal(address, write, true, true, timeout_fn(self.timeout)), ) @@ -695,6 +628,20 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } + #[cfg(not(feature = "time"))] + pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> + where + TXDMA: crate::i2c::TxDma, + { + if write.is_empty() { + self.write_internal(address, write, true, no_timeout_fn()) + } else { + self.write_dma_internal(address, write, true, true, no_timeout_fn()) + .await + } + } + + #[cfg(feature = "time")] pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, @@ -710,7 +657,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { let next = iter.next(); let is_last = next.is_none(); - with_timeout( + embassy_time::with_timeout( self.timeout, self.write_dma_internal(address, c, first, is_last, timeout_fn(self.timeout)), ) @@ -722,6 +669,31 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } + #[cfg(not(feature = "time"))] + pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> + where + TXDMA: crate::i2c::TxDma, + { + if write.is_empty() { + return Err(Error::ZeroLengthTransfer); + } + let mut iter = write.iter(); + + let mut first = true; + let mut current = iter.next(); + while let Some(c) = current { + let next = iter.next(); + let is_last = next.is_none(); + + self.write_dma_internal(address, c, first, is_last, no_timeout_fn()) + .await?; + first = false; + current = next; + } + Ok(()) + } + + #[cfg(feature = "time")] pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> where RXDMA: crate::i2c::RxDma, @@ -729,7 +701,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if buffer.is_empty() { self.read_internal(address, buffer, false, timeout_fn(self.timeout)) } else { - with_timeout( + embassy_time::with_timeout( self.timeout, self.read_dma_internal(address, buffer, false, timeout_fn(self.timeout)), ) @@ -738,6 +710,19 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } + #[cfg(not(feature = "time"))] + pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> + where + RXDMA: crate::i2c::RxDma, + { + if buffer.is_empty() { + self.read_internal(address, buffer, false, no_timeout_fn()) + } else { + self.read_dma_internal(address, buffer, false, no_timeout_fn()).await + } + } + + #[cfg(feature = "time")] pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> where TXDMA: super::TxDma, @@ -748,7 +733,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if write.is_empty() { self.write_internal(address, write, false, &check_timeout)?; } else { - with_timeout( + embassy_time::with_timeout( self.timeout, self.write_dma_internal(address, write, true, true, &check_timeout), ) @@ -761,7 +746,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { if read.is_empty() { self.read_internal(address, read, true, &check_timeout)?; } else { - with_timeout( + embassy_time::with_timeout( time_left_until_timeout, self.read_dma_internal(address, read, true, &check_timeout), ) @@ -772,6 +757,28 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { Ok(()) } + #[cfg(not(feature = "time"))] + pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> + where + TXDMA: super::TxDma, + RXDMA: super::RxDma, + { + let no_timeout = no_timeout_fn(); + if write.is_empty() { + self.write_internal(address, write, false, &no_timeout)?; + } else { + self.write_dma_internal(address, write, true, true, &no_timeout).await?; + } + + if read.is_empty() { + self.read_internal(address, read, true, &no_timeout)?; + } else { + self.read_dma_internal(address, read, true, &no_timeout).await?; + } + + Ok(()) + } + // ========================= // Blocking public API From 4fe344ebc0f4e030ff7a03755f27e66e9ad0476f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 13 Nov 2023 00:52:01 +0100 Subject: [PATCH 129/188] stm32/rcc: consistent casing and naming for PLL enums. --- embassy-stm32/src/rcc/f2.rs | 46 +++++++++---------- embassy-stm32/src/rcc/g0.rs | 14 +++--- embassy-stm32/src/rcc/g4.rs | 14 +++--- embassy-stm32/src/rcc/l0l1.rs | 10 ++-- embassy-stm32/src/rcc/l4l5.rs | 14 +++--- embassy-stm32/src/rcc/u5.rs | 22 ++++----- embassy-stm32/src/rcc/wba.rs | 8 ++-- examples/stm32f2/src/bin/pll.rs | 14 +++--- examples/stm32g4/src/bin/adc.rs | 4 +- examples/stm32g4/src/bin/pll.rs | 4 +- examples/stm32g4/src/bin/usb_serial.rs | 8 ++-- examples/stm32l4/src/bin/rng.rs | 4 +- examples/stm32l4/src/bin/rtc.rs | 2 +- .../src/bin/spe_adin1110_http_server.rs | 4 +- examples/stm32l4/src/bin/usb_serial.rs | 2 +- examples/stm32l5/src/bin/rng.rs | 4 +- 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 | 2 +- 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 +- tests/stm32/src/common.rs | 30 ++++++------ 26 files changed, 111 insertions(+), 111 deletions(-) diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 9a66e75a..00480222 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -1,7 +1,7 @@ use crate::pac::flash::vals::Latency; 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, + Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllsrc as PllSource, Ppre as APBPrescaler, }; use crate::pac::{FLASH, RCC}; @@ -35,30 +35,30 @@ pub enum HSESrc { } #[derive(Clone, Copy)] -pub struct PLLConfig { - pub pre_div: PLLPreDiv, - pub mul: PLLMul, - pub p_div: PLLPDiv, - pub q_div: PLLQDiv, +pub struct Pll { + pub pre_div: PllPreDiv, + pub mul: PllMul, + pub divp: PllPDiv, + pub divq: PllQDiv, } -impl Default for PLLConfig { +impl Default for Pll { fn default() -> Self { - PLLConfig { - pre_div: PLLPreDiv::DIV16, - mul: PLLMul::MUL192, - p_div: PLLPDiv::DIV2, - q_div: PLLQDiv::DIV4, + Pll { + pre_div: PllPreDiv::DIV16, + mul: PllMul::MUL192, + divp: PllPDiv::DIV2, + divq: PllQDiv::DIV4, } } } -impl PLLConfig { +impl Pll { pub fn clocks(&self, src_freq: Hertz) -> PLLClocks { let in_freq = src_freq / self.pre_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; + let main_freq = vco_freq / self.divp; + let pll48_freq = vco_freq / self.divq; PLLClocks { in_freq, vco_freq, @@ -172,8 +172,8 @@ impl VoltageScale { pub struct Config { pub hse: Option, pub hsi: bool, - pub pll_mux: PLLSrc, - pub pll: PLLConfig, + pub pll_mux: PllSource, + pub pll: Pll, pub mux: ClockSrc, pub voltage: VoltageScale, pub ahb_pre: AHBPrescaler, @@ -188,8 +188,8 @@ impl Default for Config { Config { hse: None, hsi: true, - pll_mux: PLLSrc::HSI, - pll: PLLConfig::default(), + pll_mux: PllSource::HSI, + pll: Pll::default(), voltage: VoltageScale::Range3, mux: ClockSrc::HSI, ahb_pre: AHBPrescaler::DIV1, @@ -217,13 +217,13 @@ pub(crate) unsafe fn init(config: Config) { } let pll_src_freq = match config.pll_mux { - PLLSrc::HSE => { + PllSource::HSE => { let hse_config = config .hse .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input")); hse_config.frequency } - PLLSrc::HSI => HSI_FREQ, + PllSource::HSI => HSI_FREQ, }; // Reference: STM32F215xx/217xx datasheet Table 33. Main PLL characteristics @@ -238,8 +238,8 @@ pub(crate) unsafe fn init(config: Config) { 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); + w.set_pllp(config.pll.divp); + w.set_pllq(config.pll.divq); }); let (sys_clk, sw) = match config.mux { diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 45d41a4e..75613dd2 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -28,7 +28,7 @@ pub enum ClockSrc { #[derive(Clone, Copy)] pub struct PllConfig { /// The source from which the PLL receives a clock signal - pub source: PllSrc, + pub source: PllSource, /// The initial divisor of that clock signal pub m: Pllm, /// The PLL VCO multiplier, which must be in the range `8..=86`. @@ -48,7 +48,7 @@ impl Default for PllConfig { fn default() -> PllConfig { // HSI / 1 * 8 / 2 = 64 MHz PllConfig { - source: PllSrc::HSI, + source: PllSource::HSI, m: Pllm::DIV1, n: Plln::MUL8, r: Pllr::DIV2, @@ -59,7 +59,7 @@ impl Default for PllConfig { } #[derive(Clone, Copy, Eq, PartialEq)] -pub enum PllSrc { +pub enum PllSource { HSI, HSE(Hertz), } @@ -89,8 +89,8 @@ impl Default for Config { impl PllConfig { pub(crate) fn init(self) -> Hertz { let (src, input_freq) = match self.source { - PllSrc::HSI => (vals::Pllsrc::HSI, HSI_FREQ), - PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq), + PllSource::HSI => (vals::Pllsrc::HSI, HSI_FREQ), + PllSource::HSE(freq) => (vals::Pllsrc::HSE, freq), }; let m_freq = input_freq / self.m; @@ -121,11 +121,11 @@ impl PllConfig { // > 3. Change the desired parameter. // Enable whichever clock source we're using, and wait for it to become ready match self.source { - PllSrc::HSI => { + PllSource::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} } - PllSrc::HSE(_) => { + PllSource::HSE(_) => { RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} } diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 13eb0c48..48b27255 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -23,16 +23,16 @@ pub enum ClockSrc { /// PLL clock input source #[derive(Clone, Copy, Debug)] -pub enum PllSrc { +pub enum PllSource { HSI, HSE(Hertz), } -impl Into for PllSrc { +impl Into for PllSource { fn into(self) -> Pllsrc { match self { - PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI => Pllsrc::HSI, + PllSource::HSE(..) => Pllsrc::HSE, + PllSource::HSI => Pllsrc::HSI, } } } @@ -44,7 +44,7 @@ impl Into for PllSrc { /// frequency ranges for each of these settings. pub struct Pll { /// PLL Source clock selection. - pub source: PllSrc, + pub source: PllSource, /// PLL pre-divider pub prediv_m: PllM, @@ -118,13 +118,13 @@ pub struct PllFreq { pub(crate) unsafe fn init(config: Config) { let pll_freq = config.pll.map(|pll_config| { let src_freq = match pll_config.source { - PllSrc::HSI => { + PllSource::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} HSI_FREQ } - PllSrc::HSE(freq) => { + PllSource::HSE(freq) => { RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} freq diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index 25a7762a..c3d58e8e 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -1,7 +1,7 @@ pub use crate::pac::pwr::vals::Vos as VoltageScale; pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Plldiv as PllDiv, Pllmul as PLLMul, Pllmul as PllMul, - Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, + Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PllDiv, Pllmul as PllMul, Pllsrc as PllSource, + Ppre as APBPrescaler, Sw as ClockSrc, }; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -29,7 +29,7 @@ pub struct Hse { #[derive(Clone, Copy)] pub struct Pll { /// PLL source - pub source: PLLSource, + pub source: PllSource, /// PLL multiplication factor. pub mul: PllMul, @@ -116,8 +116,8 @@ pub(crate) unsafe fn init(config: Config) { let pll = config.pll.map(|pll| { let freq = match pll.source { - PLLSource::HSE => hse.unwrap(), - PLLSource::HSI => hsi.unwrap(), + PllSource::HSE => hse.unwrap(), + PllSource::HSI => hsi.unwrap(), }; // Disable PLL diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index c4483910..97f231f6 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -5,7 +5,7 @@ pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; pub use crate::pac::rcc::vals::{ Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, - Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, + Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as ClockSrc, }; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -36,7 +36,7 @@ pub struct Hse { #[derive(Clone, Copy)] pub struct Pll { /// PLL source - pub source: PLLSource, + pub source: PllSource, /// PLL pre-divider (DIVM). pub prediv: PllPreDiv, @@ -135,7 +135,7 @@ pub const WPAN_DEFAULT: Config = Config { ls: super::LsConfig::default_lse(), pll: Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL12, divp: Some(PllPDiv::DIV3), // 32 / 2 * 12 / 3 = 64Mhz @@ -456,10 +456,10 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let Some(pll) = config else { return PllOutput::default() }; let pll_src = match pll.source { - PLLSource::DISABLE => panic!("must not select PLL source as DISABLE"), - PLLSource::HSE => input.hse, - PLLSource::HSI => input.hsi, - PLLSource::MSI => input.msi, + PllSource::DISABLE => panic!("must not select PLL source as DISABLE"), + PllSource::HSE => input.hse, + PllSource::HSI => input.hsi, + PllSource::MSI => input.msi, }; let pll_src = pll_src.unwrap(); diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index c111362b..81bdec88 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -35,7 +35,7 @@ impl Default for ClockSrc { #[derive(Clone, Copy)] pub struct PllConfig { /// The clock source for the PLL. - pub source: PllSrc, + pub source: PllSource, /// The PLL prescaler. /// /// The clock speed of the `source` divided by `m` must be between 4 and 16 MHz. @@ -57,7 +57,7 @@ impl PllConfig { /// A configuration for HSI / 1 * 10 / 1 = 160 MHz pub const fn hsi_160mhz() -> Self { PllConfig { - source: PllSrc::HSI, + source: PllSource::HSI, m: Pllm::DIV1, n: Plln::MUL10, r: Plldiv::DIV1, @@ -67,7 +67,7 @@ impl PllConfig { /// A configuration for MSIS @ 48 MHz / 3 * 10 / 1 = 160 MHz pub const fn msis_160mhz() -> Self { PllConfig { - source: PllSrc::MSIS(Msirange::RANGE_48MHZ), + source: PllSource::MSIS(Msirange::RANGE_48MHZ), m: Pllm::DIV3, n: Plln::MUL10, r: Plldiv::DIV1, @@ -76,7 +76,7 @@ impl PllConfig { } #[derive(Clone, Copy)] -pub enum PllSrc { +pub enum PllSource { /// Use an internal medium speed oscillator as the PLL source. MSIS(Msirange), /// Use the external high speed clock as the system PLL source. @@ -88,12 +88,12 @@ pub enum PllSrc { HSI, } -impl Into for PllSrc { +impl Into for PllSource { fn into(self) -> Pllsrc { match self { - PllSrc::MSIS(..) => Pllsrc::MSIS, - PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI => Pllsrc::HSI, + PllSource::MSIS(..) => Pllsrc::MSIS, + PllSource::HSE(..) => Pllsrc::HSE, + PllSource::HSI => Pllsrc::HSI, } } } @@ -216,9 +216,9 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::PLL1_R(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::HSI => config.init_hsi(), + PllSource::MSIS(range) => config.init_msis(range), + PllSource::HSE(hertz) => config.init_hse(hertz), + PllSource::HSI => config.init_hsi(), }; // Calculate the reference clock, which is the source divided by m diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index 8925d960..c0cd9150 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -17,16 +17,16 @@ pub enum ClockSrc { } #[derive(Clone, Copy, Debug)] -pub enum PllSrc { +pub enum PllSource { HSE(Hertz), HSI, } -impl Into for PllSrc { +impl Into for PllSource { fn into(self) -> Pllsrc { match self { - PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI => Pllsrc::HSI, + PllSource::HSE(..) => Pllsrc::HSE, + PllSource::HSI => Pllsrc::HSI, } } } diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs index 56591b52..feec9001 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, PLLConfig, PLLMul, PLLPDiv, PLLPreDiv, PLLQDiv, PLLSrc, + APBPrescaler, ClockSrc, HSEConfig, HSESrc, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllSource, }; use embassy_stm32::time::Hertz; use embassy_stm32::Config; @@ -25,16 +25,16 @@ async fn main(_spawner: Spawner) { source: HSESrc::Bypass, }); // PLL uses HSE as the clock source - config.rcc.pll_mux = PLLSrc::HSE; - config.rcc.pll = PLLConfig { + config.rcc.pll_mux = PllSource::HSE; + config.rcc.pll = Pll { // 8 MHz clock source / 8 = 1 MHz PLL input - pre_div: unwrap!(PLLPreDiv::try_from(8)), + pre_div: unwrap!(PllPreDiv::try_from(8)), // 1 MHz PLL input * 240 = 240 MHz PLL VCO - mul: unwrap!(PLLMul::try_from(240)), + mul: unwrap!(PllMul::try_from(240)), // 240 MHz PLL VCO / 2 = 120 MHz main PLL output - p_div: PLLPDiv::DIV2, + divp: PllPDiv::DIV2, // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - q_div: PLLQDiv::DIV5, + divq: 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 f0573384..63b20c0d 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; -use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSrc}; +use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSource}; use embassy_stm32::Config; use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.pll = Some(Pll { - source: PllSrc::HSI, + source: PllSource::HSI, prediv_m: PllM::DIV4, mul_n: PllN::MUL85, div_p: None, diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs index 90c3f8dc..09ef59d4 100644 --- a/examples/stm32g4/src/bin/pll.rs +++ b/examples/stm32g4/src/bin/pll.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSrc}; +use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSource}; use embassy_stm32::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.pll = Some(Pll { - source: PllSrc::HSI, + source: PllSource::HSI, prediv_m: PllM::DIV4, mul_n: PllN::MUL85, div_p: None, diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index 378e7b98..565b25d6 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs @@ -4,7 +4,7 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSrc}; +use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSource}; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{self, Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, Config}; @@ -25,14 +25,14 @@ 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 plldivq = if USE_HSI48 { None } else { Some(PllQ::DIV6) }; config.rcc.pll = Some(Pll { - source: PllSrc::HSE(Hertz(8_000_000)), + source: PllSource::HSE(Hertz(8_000_000)), prediv_m: PllM::DIV2, mul_n: PllN::MUL72, div_p: None, - div_q: pllq_div, + div_q: plldivq, // Main system clock at 144 MHz div_r: Some(PllR::DIV2), }); diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index 553d11c0..e5ad56fb 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, PLLSource, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, PllSource}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL18, divp: None, diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index 69527c9a..d2a2aa1f 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) { mode: HseMode::Oscillator, }); config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None, diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 62caeea5..3a7e5370 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -75,7 +75,7 @@ async fn main(spawner: Spawner) { let mut config = embassy_stm32::Config::default(); { use embassy_stm32::rcc::*; - // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) + // 80Mhz clock (Source: 8 / SrcDiv: 1 * PllMul 20 / ClkDiv 2) // 80MHz highest frequency for flash 0 wait. config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hse = Some(Hse { @@ -83,7 +83,7 @@ async fn main(spawner: Spawner) { mode: HseMode::Oscillator, }); config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None, diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index d977398f..4baf5f05 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -27,7 +27,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index b9d4cd25..279f4f65 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, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, Pll, PllMul, PllPreDiv, PllRDiv, PllSource}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 64Mhz clock (16 / 1 * 8 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL8, divp: None, diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 923193ab..0b0a0e2d 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -49,7 +49,7 @@ async fn main(spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index f64d0f34..3614a8e0 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -26,7 +26,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 58a8898a..f2b894b6 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index a218d5df..839d6472 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.mux = ClockSrc::PLL1_R(PllConfig { - source: PllSrc::HSI, + source: PllSource::HSI, m: Pllm::DIV2, n: Plln::MUL10, r: Plldiv::DIV1, diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 226e6786..348e3cdc 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -44,7 +44,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/examples/stm32wl/src/bin/lora_p2p_receive.rs b/examples/stm32wl/src/bin/lora_p2p_receive.rs index a3bb0c0f..c643ddb1 100644 --- a/examples/stm32wl/src/bin/lora_p2p_receive.rs +++ b/examples/stm32wl/src/bin/lora_p2p_receive.rs @@ -37,7 +37,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/examples/stm32wl/src/bin/lora_p2p_send.rs b/examples/stm32wl/src/bin/lora_p2p_send.rs index 08dd0845..7fe8cea3 100644 --- a/examples/stm32wl/src/bin/lora_p2p_send.rs +++ b/examples/stm32wl/src/bin/lora_p2p_send.rs @@ -37,7 +37,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 1a8822b4..2fd23496 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index b3b7f9c5..4ffb0bb5 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 3668e18c..35f42d28 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -241,16 +241,16 @@ pub fn config() -> Config { source: HSESrc::Bypass, }); // PLL uses HSE as the clock source - config.rcc.pll_mux = PLLSrc::HSE; - config.rcc.pll = PLLConfig { + config.rcc.pll_mux = PllSource::HSE; + config.rcc.pll = Pll { // 8 MHz clock source / 8 = 1 MHz PLL input - pre_div: unwrap!(PLLPreDiv::try_from(8)), + pre_div: unwrap!(PllPreDiv::try_from(8)), // 1 MHz PLL input * 240 = 240 MHz PLL VCO - mul: unwrap!(PLLMul::try_from(240)), + mul: unwrap!(PllMul::try_from(240)), // 240 MHz PLL VCO / 2 = 120 MHz main PLL output - p_div: PLLPDiv::DIV2, + divp: PllPDiv::DIV2, // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - q_div: PLLQDiv::DIV5, + divq: PllQDiv::DIV5, }; // System clock comes from PLL (= the 120 MHz main PLL output) config.rcc.mux = ClockSrc::PLL; @@ -397,7 +397,7 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL18, divp: None, @@ -416,7 +416,7 @@ pub fn config() -> Config { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, @@ -432,7 +432,7 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 110Mhz clock (16 / 4 * 55 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL55, divp: None, @@ -462,9 +462,9 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, - mul: PLLMul::MUL4, - div: PLLDiv::DIV2, // 32Mhz clock (16 * 4 / 2) + source: PllSource::HSI, + mul: PllMul::MUL4, + div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) }); config.rcc.mux = ClockSrc::PLL1_P; } @@ -474,9 +474,9 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, - mul: PLLMul::MUL4, - div: PLLDiv::DIV2, // 32Mhz clock (16 * 4 / 2) + source: PllSource::HSI, + mul: PllMul::MUL4, + div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) }); config.rcc.mux = ClockSrc::PLL1_P; } From 066dc297ed4508c334effafcc134296cb776eb06 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 13 Nov 2023 01:05:07 +0100 Subject: [PATCH 130/188] stm32/rcc: unify l0l1 and l4l5. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/{l4l5.rs => l.rs} | 393 +++++++++++++++--------- embassy-stm32/src/rcc/l0l1.rs | 190 ------------ embassy-stm32/src/rcc/mod.rs | 3 +- tests/stm32/src/common.rs | 4 +- 5 files changed, 260 insertions(+), 334 deletions(-) rename embassy-stm32/src/rcc/{l4l5.rs => l.rs} (58%) delete mode 100644 embassy-stm32/src/rcc/l0l1.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 7b3a6c2b..37317276 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-1374ed622714ef4702826699ca21cc1f741f4133" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f" } 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-1374ed622714ef4702826699ca21cc1f741f4133", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l.rs similarity index 58% rename from embassy-stm32/src/rcc/l4l5.rs rename to embassy-stm32/src/rcc/l.rs index 97f231f6..257fd83f 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l.rs @@ -1,12 +1,13 @@ +#[cfg(any(stm32l0, stm32l1))] +pub use crate::pac::pwr::vals::Vos as VoltageScale; use crate::pac::rcc::regs::Cfgr; -#[cfg(any(stm32l4, stm32l5, stm32wb))] +#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] +pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; +#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; #[cfg(any(stm32wb, stm32wl))] pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; -pub use crate::pac::rcc::vals::{ - Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, - Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as ClockSrc, -}; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as ClockSrc}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -33,25 +34,6 @@ pub struct Hse { pub prescaler: HsePrescaler, } -#[derive(Clone, Copy)] -pub struct Pll { - /// PLL source - pub source: PllSource, - - /// PLL pre-divider (DIVM). - pub prediv: PllPreDiv, - - /// PLL multiplication factor. - pub mul: PllMul, - - /// PLL P division factor. If None, PLL P output is disabled. - 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, -} - /// Clocks configuration pub struct Config { // base clock sources @@ -79,13 +61,17 @@ pub struct Config { pub shared_ahb_pre: AHBPrescaler, // muxes - #[cfg(any(stm32l4, stm32l5, stm32wb))] + #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] pub clk48_src: Clk48Src, // low speed LSI/LSE/RTC pub ls: super::LsConfig, + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] pub adc_clock_source: AdcClockSource, + + #[cfg(any(stm32l0, stm32l1))] + pub voltage_scale: VoltageScale, } impl Default for Config { @@ -110,10 +96,13 @@ impl Default for Config { pllsai2: None, #[cfg(crs)] hsi48: Some(Default::default()), - #[cfg(any(stm32l4, stm32l5, stm32wb))] + #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] clk48_src: Clk48Src::HSI48, ls: Default::default(), + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] adc_clock_source: AdcClockSource::SYS, + #[cfg(any(stm32l0, stm32l1))] + voltage_scale: VoltageScale::RANGE1, } } } @@ -152,20 +141,26 @@ pub const WPAN_DEFAULT: Config = Config { adc_clock_source: AdcClockSource::SYS, }; +fn msi_enable(range: MSIRange) { + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] + RCC.cr().modify(|w| { + #[cfg(not(stm32wb))] + w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); + w.set_msirange(range); + w.set_msipllen(false); + }); + #[cfg(any(stm32l0, stm32l1))] + RCC.icscr().modify(|w| w.set_msirange(range)); + + RCC.cr().modify(|w| w.set_msion(true)); + while !RCC.cr().read().msirdy() {} +} + 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| { - #[cfg(not(stm32wb))] - w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); - w.set_msirange(MSIRange::RANGE4M); - w.set_msipllen(false); - w.set_msion(true) - }); - - // Wait until MSI is running - while !RCC.cr().read().msirdy() {} + msi_enable(MSIRange::RANGE4M) } if RCC.cfgr().read().sws() != ClockSrc::MSI { // Set MSI as a clock source, reset prescalers. @@ -174,6 +169,14 @@ pub(crate) unsafe fn init(config: Config) { while RCC.cfgr().read().sws() != ClockSrc::MSI {} } + // Set voltage scale + #[cfg(any(stm32l0, stm32l1))] + { + while crate::pac::PWR.csr().read().vosf() {} + crate::pac::PWR.cr().write(|w| w.set_vos(config.voltage_scale)); + while crate::pac::PWR.csr().read().vosf() {} + } + #[cfg(stm32l5)] crate::pac::PWR.cr1().modify(|w| { w.set_vos(crate::pac::pwr::vals::Vos::RANGE0); @@ -182,21 +185,16 @@ pub(crate) unsafe fn init(config: Config) { let rtc = config.ls.init(); let msi = config.msi.map(|range| { - // Enable MSI - RCC.cr().modify(|w| { - #[cfg(not(stm32wb))] - w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); - w.set_msirange(range); - w.set_msion(true); - - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(config.ls.lse.is_some()); - }); - while !RCC.cr().read().msirdy() {} - + msi_enable(range); msirange_to_hertz(range) }); + // If LSE is enabled and the right freq, enable calibration of MSI + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] + if config.ls.lse.map(|x| x.frequency) == Some(Hertz(32_768)) { + RCC.cr().modify(|w| w.set_msipllen(true)); + } + let hsi = config.hsi.then(|| { RCC.cr().modify(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} @@ -218,7 +216,10 @@ pub(crate) unsafe fn init(config: Config) { }); #[cfg(crs)] - let _hsi48 = config.hsi48.map(super::init_hsi48); + let _hsi48 = config.hsi48.map(|config| { + // + super::init_hsi48(config) + }); #[cfg(not(crs))] let _hsi48: Option = None; @@ -251,7 +252,12 @@ pub(crate) unsafe fn init(config: Config) { }), }; - let pll_input = PllInput { hse, hsi, msi }; + let pll_input = PllInput { + hse, + hsi, + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] + msi, + }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); #[cfg(any(stm32l4, stm32l5, stm32wb))] let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); @@ -265,10 +271,13 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::PLL1_R => pll.r.unwrap(), }; - #[cfg(stm32l4)] + #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); - #[cfg(stm32l5)] - RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); + #[cfg(any(rcc_l0_v2))] + let _clk48 = match config.clk48_src { + Clk48Src::HSI48 => _hsi48, + Clk48Src::PLL1_VCO_DIV_2 => pll.clk48, + }; #[cfg(any(stm32l4, stm32l5, stm32wb))] let _clk48 = match config.clk48_src { Clk48Src::HSI48 => _hsi48, @@ -285,16 +294,23 @@ pub(crate) unsafe fn init(config: Config) { let hclk1 = sys_clk / config.ahb_pre; let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); - #[cfg(not(any(stm32wl5x, stm32wb)))] + #[cfg(any(stm32l4, stm32l5, stm32wlex))] let hclk2 = hclk1; #[cfg(any(stm32wl5x, stm32wb))] let hclk2 = sys_clk / config.core2_ahb_pre; - #[cfg(not(any(stm32wl, stm32wb)))] + #[cfg(any(stm32l4, stm32l5, stm32wlex))] let hclk3 = hclk1; - #[cfg(any(stm32wl, stm32wb))] + #[cfg(any(stm32wl5x, stm32wb))] let hclk3 = sys_clk / config.shared_ahb_pre; // Set flash wait states + #[cfg(any(stm32l0, stm32l1))] + let latency = match (config.voltage_scale, sys_clk.0) { + (VoltageScale::RANGE1, ..=16_000_000) => false, + (VoltageScale::RANGE2, ..=8_000_000) => false, + (VoltageScale::RANGE3, ..=4_200_000) => false, + _ => true, + }; #[cfg(stm32l4)] let latency = match hclk1.0 { 0..=16_000_000 => 0, @@ -330,6 +346,10 @@ pub(crate) unsafe fn init(config: Config) { _ => 4, }; + #[cfg(stm32l1)] + FLASH.acr().write(|w| w.set_acc64(true)); + #[cfg(not(stm32l5))] + FLASH.acr().modify(|w| w.set_prften(true)); FLASH.acr().modify(|w| w.set_latency(latency)); while FLASH.acr().read().latency() != latency {} @@ -341,9 +361,7 @@ pub(crate) unsafe fn init(config: Config) { }); while RCC.cfgr().read().sws() != config.mux {} - #[cfg(stm32l5)] - RCC.ccipr1().modify(|w| w.set_adcsel(config.adc_clock_source)); - #[cfg(not(stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); #[cfg(any(stm32wl, stm32wb))] @@ -361,7 +379,9 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, hclk1, + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] hclk2, + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] hclk3, pclk1, pclk2, @@ -389,6 +409,12 @@ pub(crate) unsafe fn init(config: Config) { }); } +#[cfg(any(stm32l0, stm32l1))] +fn msirange_to_hertz(range: MSIRange) -> Hertz { + Hertz(32_768 * (1 << (range as u8 + 1))) +} + +#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] fn msirange_to_hertz(range: MSIRange) -> Hertz { match range { MSIRange::RANGE100K => Hertz(100_000), @@ -407,20 +433,6 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz { } } -struct PllInput { - hsi: Option, - hse: Option, - msi: Option, -} - -#[allow(unused)] -#[derive(Default)] -struct PllOutput { - p: Option, - q: Option, - r: Option, -} - #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, @@ -449,77 +461,182 @@ fn pll_enable(instance: PllInstance, enabled: bool) { } } -fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { - // Disable PLL - pll_enable(instance, false); +pub use pll::*; - let Some(pll) = config else { return PllOutput::default() }; +#[cfg(any(stm32l0, stm32l1))] +mod pll { + use super::{pll_enable, PllInstance}; + pub use crate::pac::rcc::vals::{Plldiv as PllDiv, Pllmul as PllMul, Pllsrc as PllSource}; + use crate::pac::RCC; + use crate::time::Hertz; - let pll_src = match pll.source { - PllSource::DISABLE => panic!("must not select PLL source as DISABLE"), - PllSource::HSE => input.hse, - PllSource::HSI => input.hsi, - PllSource::MSI => input.msi, - }; + #[derive(Clone, Copy)] + pub struct Pll { + /// PLL source + pub source: PllSource, - let pll_src = pll_src.unwrap(); + /// PLL multiplication factor. + pub mul: PllMul, - let vco_freq = pll_src / pll.prediv * pll.mul; - - let p = pll.divp.map(|div| vco_freq / div); - let q = pll.divq.map(|div| vco_freq / div); - let r = pll.divr.map(|div| vco_freq / div); - - #[cfg(stm32l5)] - if instance == PllInstance::Pllsai2 { - assert!(q.is_none(), "PLLSAI2_Q is not available on L5"); - assert!(r.is_none(), "PLLSAI2_R is not available on L5"); + /// PLL main output division factor. + pub div: PllDiv, } - macro_rules! write_fields { - ($w:ident) => { - $w.set_plln(pll.mul); - if let Some(divp) = pll.divp { - $w.set_pllp(divp); - $w.set_pllpen(true); - } - if let Some(divq) = pll.divq { - $w.set_pllq(divq); - $w.set_pllqen(true); - } - if let Some(divr) = pll.divr { - $w.set_pllr(divr); - $w.set_pllren(true); - } + pub(super) struct PllInput { + pub hsi: Option, + pub hse: Option, + } + + #[allow(unused)] + #[derive(Default)] + pub(super) struct PllOutput { + pub r: Option, + pub clk48: Option, + } + + pub(super) fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + pll_enable(instance, false); + + let Some(pll) = config else { return PllOutput::default() }; + + let pll_src = match pll.source { + PllSource::HSE => unwrap!(input.hse), + PllSource::HSI => unwrap!(input.hsi), }; + + let vco_freq = pll_src * pll.mul; + + let r = vco_freq / pll.div; + let clk48 = (vco_freq == Hertz(96_000_000)).then_some(Hertz(48_000_000)); + + assert!(r <= Hertz(32_000_000)); + + RCC.cfgr().write(move |w| { + w.set_pllmul(pll.mul); + w.set_plldiv(pll.div); + w.set_pllsrc(pll.source); + }); + + // Enable PLL + pll_enable(instance, true); + + PllOutput { r: Some(r), clk48 } + } +} + +#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] +mod pll { + use super::{pll_enable, PllInstance}; + pub use crate::pac::rcc::vals::{ + Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PllSource, + }; + use crate::pac::RCC; + use crate::time::Hertz; + + #[derive(Clone, Copy)] + pub struct Pll { + /// PLL source + pub source: PllSource, + + /// PLL pre-divider (DIVM). + pub prediv: PllPreDiv, + + /// PLL multiplication factor. + pub mul: PllMul, + + /// PLL P division factor. If None, PLL P output is disabled. + 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, + } + + pub(super) struct PllInput { + pub hsi: Option, + pub hse: Option, + pub msi: Option, + } + + #[allow(unused)] + #[derive(Default)] + pub(super) struct PllOutput { + pub p: Option, + pub q: Option, + pub r: Option, + } + + pub(super) fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + pll_enable(instance, false); + + let Some(pll) = config else { return PllOutput::default() }; + + let pll_src = match pll.source { + PllSource::DISABLE => panic!("must not select PLL source as DISABLE"), + PllSource::HSE => unwrap!(input.hse), + PllSource::HSI => unwrap!(input.hsi), + PllSource::MSI => unwrap!(input.msi), + }; + + let vco_freq = pll_src / pll.prediv * pll.mul; + + let p = pll.divp.map(|div| vco_freq / div); + let q = pll.divq.map(|div| vco_freq / div); + let r = pll.divr.map(|div| vco_freq / div); + + #[cfg(stm32l5)] + if instance == PllInstance::Pllsai2 { + assert!(q.is_none(), "PLLSAI2_Q is not available on L5"); + assert!(r.is_none(), "PLLSAI2_R is not available on L5"); + } + + macro_rules! write_fields { + ($w:ident) => { + $w.set_plln(pll.mul); + if let Some(divp) = pll.divp { + $w.set_pllp(divp); + $w.set_pllpen(true); + } + if let Some(divq) = pll.divq { + $w.set_pllq(divq); + $w.set_pllqen(true); + } + if let Some(divr) = pll.divr { + $w.set_pllr(divr); + $w.set_pllren(true); + } + }; + } + + match instance { + PllInstance::Pll => RCC.pllcfgr().write(|w| { + w.set_pllm(pll.prediv); + w.set_pllsrc(pll.source); + write_fields!(w); + }), + #[cfg(any(stm32l4, stm32l5, stm32wb))] + PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { + #[cfg(any(rcc_l4plus, stm32l5))] + w.set_pllm(pll.prediv); + #[cfg(stm32l5)] + w.set_pllsrc(pll.source); + write_fields!(w); + }), + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| { + #[cfg(any(rcc_l4plus, stm32l5))] + w.set_pllm(pll.prediv); + #[cfg(stm32l5)] + w.set_pllsrc(pll.source); + write_fields!(w); + }), + } + + // Enable PLL + pll_enable(instance, true); + + PllOutput { p, q, r } } - - match instance { - PllInstance::Pll => RCC.pllcfgr().write(|w| { - w.set_pllm(pll.prediv); - w.set_pllsrc(pll.source); - write_fields!(w); - }), - #[cfg(any(stm32l4, stm32l5, stm32wb))] - PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { - #[cfg(any(rcc_l4plus, stm32l5))] - w.set_pllm(pll.prediv); - #[cfg(stm32l5)] - w.set_pllsrc(pll.source); - write_fields!(w); - }), - #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] - PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| { - #[cfg(any(rcc_l4plus, stm32l5))] - w.set_pllm(pll.prediv); - #[cfg(stm32l5)] - w.set_pllsrc(pll.source); - write_fields!(w); - }), - } - - // Enable PLL - pll_enable(instance, true); - - PllOutput { p, q, r } } diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs deleted file mode 100644 index c3d58e8e..00000000 --- a/embassy-stm32/src/rcc/l0l1.rs +++ /dev/null @@ -1,190 +0,0 @@ -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, Pllsrc as PllSource, - Ppre as APBPrescaler, Sw as ClockSrc, -}; -use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum HseMode { - /// crystal/ceramic oscillator (HSEBYP=0) - Oscillator, - /// external analog clock (low swing) (HSEBYP=1) - Bypass, -} - -#[derive(Clone, Copy, Eq, PartialEq)] -pub struct Hse { - /// HSE frequency. - pub freq: Hertz, - /// HSE mode. - pub mode: HseMode, -} - -#[derive(Clone, Copy)] -pub struct Pll { - /// PLL source - pub source: PllSource, - - /// PLL multiplication factor. - pub mul: PllMul, - - /// PLL main output division factor. - pub div: PllDiv, -} - -/// Clocks configutation -pub struct Config { - // base clock sources - pub msi: Option, - pub hsi: bool, - pub hse: Option, - #[cfg(crs)] - pub hsi48: Option, - - pub pll: Option, - - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - - pub ls: super::LsConfig, - pub voltage_scale: VoltageScale, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - msi: Some(MSIRange::RANGE5), - hse: None, - hsi: false, - #[cfg(crs)] - hsi48: Some(Default::default()), - - pll: None, - - mux: ClockSrc::MSI, - ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - voltage_scale: VoltageScale::RANGE1, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - // Set voltage scale - while PWR.csr().read().vosf() {} - PWR.cr().write(|w| w.set_vos(config.voltage_scale)); - while PWR.csr().read().vosf() {} - - let rtc = config.ls.init(); - - let msi = config.msi.map(|range| { - RCC.icscr().modify(|w| w.set_msirange(range)); - - RCC.cr().modify(|w| w.set_msion(true)); - while !RCC.cr().read().msirdy() {} - - Hertz(32_768 * (1 << (range as u8 + 1))) - }); - - let hsi = config.hsi.then(|| { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - HSI_FREQ - }); - - let hse = config.hse.map(|hse| { - RCC.cr().modify(|w| { - w.set_hsebyp(hse.mode == HseMode::Bypass); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - - hse.freq - }); - - let pll = config.pll.map(|pll| { - let freq = match pll.source { - PllSource::HSE => hse.unwrap(), - PllSource::HSI => hsi.unwrap(), - }; - - // Disable PLL - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} - - let freq = freq * pll.mul / pll.div; - - assert!(freq <= Hertz(32_000_000)); - - RCC.cfgr().write(move |w| { - w.set_pllmul(pll.mul); - w.set_plldiv(pll.div); - w.set_pllsrc(pll.source); - }); - - // Enable PLL - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - - freq - }); - - let sys_clk = match config.mux { - ClockSrc::HSE => hse.unwrap(), - ClockSrc::HSI => hsi.unwrap(), - ClockSrc::MSI => msi.unwrap(), - ClockSrc::PLL1_P => pll.unwrap(), - }; - - 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, - }; - - #[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(config.mux); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - - let hclk1 = sys_clk / config.ahb_pre; - let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); - let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); - - #[cfg(crs)] - let _hsi48 = config.hsi48.map(|config| { - // Select HSI48 as USB clock - RCC.ccipr().modify(|w| w.set_hsi48msel(true)); - super::init_hsi48(config) - }); - - set_freqs(Clocks { - sys: sys_clk, - hclk1, - pclk1, - pclk2, - pclk1_tim, - pclk2_tim, - rtc, - }); -} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index e15f4fe4..debd16ca 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -23,8 +23,7 @@ pub use hsi48::*; #[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(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] -#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle, rcc_wb), path = "l4l5.rs")] +#[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl), path = "l.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] mod _version; diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 35f42d28..e7367d5e 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -466,7 +466,7 @@ pub fn config() -> Config { mul: PllMul::MUL4, div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) }); - config.rcc.mux = ClockSrc::PLL1_P; + config.rcc.mux = ClockSrc::PLL1_R; } #[cfg(any(feature = "stm32l152re"))] @@ -478,7 +478,7 @@ pub fn config() -> Config { mul: PllMul::MUL4, div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) }); - config.rcc.mux = ClockSrc::PLL1_P; + config.rcc.mux = ClockSrc::PLL1_R; } config From 2376b3bdfa573027c1ee4d66f8fdd6ca422a0fdd Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 13 Nov 2023 01:53:27 +0100 Subject: [PATCH 131/188] stm32/rcc: fix pll enum naming on f4, f7. --- embassy-stm32/src/rcc/f4f7.rs | 10 +++++----- examples/stm32f4/src/bin/eth.rs | 2 +- examples/stm32f4/src/bin/sdmmc.rs | 4 ++-- examples/stm32f4/src/bin/usb_ethernet.rs | 4 ++-- examples/stm32f4/src/bin/usb_raw.rs | 4 ++-- examples/stm32f4/src/bin/usb_serial.rs | 4 ++-- examples/stm32f7/src/bin/eth.rs | 2 +- examples/stm32f7/src/bin/sdmmc.rs | 4 ++-- examples/stm32f7/src/bin/usb_serial.rs | 4 ++-- tests/stm32/src/common.rs | 4 ++-- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs index 9e8c639d..718ba9b7 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -1,7 +1,7 @@ use crate::pac::pwr::vals::Vos; pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp, Pllq, Pllr, Pllsrc as PllSource, - Ppre as APBPrescaler, Sw as Sysclk, + Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, + Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, }; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -49,11 +49,11 @@ pub struct Pll { pub mul: PllMul, /// PLL P division factor. If None, PLL P output is disabled. - pub divp: Option, + pub divp: Option, /// PLL Q division factor. If None, PLL Q output is disabled. - pub divq: Option, + pub divq: Option, /// PLL R division factor. If None, PLL R output is disabled. - pub divr: Option, + pub divr: Option, } /// Configuration of the core clocks diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 1747bbf4..088d83c0 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -42,7 +42,7 @@ async fn main(spawner: Spawner) -> ! { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL180, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. divq: None, divr: None, }); diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs index 37e42384..91747b2d 100644 --- a/examples/stm32f4/src/bin/sdmmc.rs +++ b/examples/stm32f4/src/bin/sdmmc.rs @@ -30,8 +30,8 @@ async fn main(_spawner: Spawner) { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL168, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. - divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. divr: None, }); config.rcc.ahb_pre = AHBPrescaler::DIV1; diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index 34407b95..6bf5b1cb 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -56,8 +56,8 @@ async fn main(spawner: Spawner) { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL168, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. - divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. divr: None, }); config.rcc.ahb_pre = AHBPrescaler::DIV1; diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs index 689aea4f..719b22bb 100644 --- a/examples/stm32f4/src/bin/usb_raw.rs +++ b/examples/stm32f4/src/bin/usb_raw.rs @@ -85,8 +85,8 @@ async fn main(_spawner: Spawner) { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL168, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. - divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. divr: None, }); config.rcc.ahb_pre = AHBPrescaler::DIV1; diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index 3e05b0ef..e2ccc914 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs @@ -32,8 +32,8 @@ async fn main(_spawner: Spawner) { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL168, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. - divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. divr: None, }); config.rcc.ahb_pre = AHBPrescaler::DIV1; diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 7c6c419a..dd006944 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -43,7 +43,7 @@ async fn main(spawner: Spawner) -> ! { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL216, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz divq: None, divr: None, }); diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs index 430aa781..990de0ab 100644 --- a/examples/stm32f7/src/bin/sdmmc.rs +++ b/examples/stm32f7/src/bin/sdmmc.rs @@ -26,8 +26,8 @@ async fn main(_spawner: Spawner) { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL216, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz - divq: Some(Pllq::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: Some(PllQDiv::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz divr: None, }); config.rcc.ahb_pre = AHBPrescaler::DIV1; diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs index 6aca732b..4991edbf 100644 --- a/examples/stm32f7/src/bin/usb_serial.rs +++ b/examples/stm32f7/src/bin/usb_serial.rs @@ -32,8 +32,8 @@ async fn main(_spawner: Spawner) { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL216, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz - divq: Some(Pllq::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: Some(PllQDiv::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz divr: None, }); config.rcc.ahb_pre = AHBPrescaler::DIV1; diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index e7367d5e..fe694cbe 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -271,7 +271,7 @@ pub fn config() -> Config { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL180, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. divq: None, divr: None, }); @@ -292,7 +292,7 @@ pub fn config() -> Config { config.rcc.pll = Some(Pll { prediv: PllPreDiv::DIV4, mul: PllMul::MUL216, - divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz. + divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz. divq: None, divr: None, }); From ace52210802a18a551f506bc3ad163703e3f9efa Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 13 Nov 2023 01:56:28 +0100 Subject: [PATCH 132/188] stm32/rcc: unify f2 into f4/f7. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/{f4f7.rs => f.rs} | 143 ++++++++--- embassy-stm32/src/rcc/f2.rs | 320 ------------------------ embassy-stm32/src/rcc/mod.rs | 9 +- examples/stm32f2/src/bin/pll.rs | 55 ++-- tests/stm32/src/common.rs | 21 +- 6 files changed, 161 insertions(+), 391 deletions(-) rename embassy-stm32/src/rcc/{f4f7.rs => f.rs} (71%) delete mode 100644 embassy-stm32/src/rcc/f2.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 37317276..4b650cc8 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-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-fbb8f77326dd066aa6c0d66b3b46e76a569dda8b" } 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-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-fbb8f77326dd066aa6c0d66b3b46e76a569dda8b", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f.rs similarity index 71% rename from embassy-stm32/src/rcc/f4f7.rs rename to embassy-stm32/src/rcc/f.rs index 718ba9b7..36d9f178 100644 --- a/embassy-stm32/src/rcc/f4f7.rs +++ b/embassy-stm32/src/rcc/f.rs @@ -1,9 +1,12 @@ -use crate::pac::pwr::vals::Vos; +use stm32_metapac::flash::vals::Latency; + pub use crate::pac::rcc::vals::{ Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, }; -use crate::pac::{FLASH, PWR, RCC}; +#[cfg(any(stm32f4, stm32f7))] +use crate::pac::PWR; +use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -56,6 +59,22 @@ pub struct Pll { pub divr: Option, } +/// Voltage range of the power supply used. +/// +/// Used to calculate flash waitstates. See +/// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency +#[cfg(stm32f2)] +pub enum VoltageScale { + /// 2.7 to 3.6 V + Range0, + /// 2.4 to 2.7 V + Range1, + /// 2.1 to 2.4 V + Range2, + /// 1.8 to 2.1 V + Range3, +} + /// Configuration of the core clocks #[non_exhaustive] pub struct Config { @@ -66,7 +85,7 @@ pub struct Config { pub pll_src: PllSource, pub pll: Option, - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] pub plli2s: Option, #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] pub pllsai: Option, @@ -76,6 +95,9 @@ pub struct Config { pub apb2_pre: APBPrescaler, pub ls: super::LsConfig, + + #[cfg(stm32f2)] + pub voltage: VoltageScale, } impl Default for Config { @@ -86,7 +108,7 @@ impl Default for Config { sys: Sysclk::HSI, pll_src: PllSource::HSI, pll: None, - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] plli2s: None, #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] pllsai: None, @@ -96,6 +118,9 @@ impl Default for Config { apb2_pre: APBPrescaler::DIV1, ls: Default::default(), + + #[cfg(stm32f2)] + voltage: VoltageScale::Range3, } } } @@ -103,14 +128,13 @@ impl Default for Config { pub(crate) unsafe fn init(config: Config) { // set VOS to SCALE1, if use PLL // TODO: check real clock speed before set VOS + #[cfg(any(stm32f4, stm32f7))] if config.pll.is_some() { - PWR.cr1().modify(|w| w.set_vos(Vos::SCALE1)); + PWR.cr1().modify(|w| w.set_vos(crate::pac::pwr::vals::Vos::SCALE1)); } // always enable overdrive for now. Make it configurable in the future. - #[cfg(not(any( - stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f405, stm32f407, stm32f415, stm32f417 - )))] + #[cfg(any(stm32f446, stm32f4x9, stm32f427, stm32f437, stm32f7))] { PWR.cr1().modify(|w| w.set_oden(true)); while !PWR.csr1().read().odrdy() {} @@ -158,7 +182,7 @@ pub(crate) unsafe fn init(config: Config) { source: config.pll_src, }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); @@ -182,7 +206,48 @@ pub(crate) unsafe fn init(config: Config) { let rtc = config.ls.init(); - flash_setup(hclk); + #[cfg(stm32f2)] + let latency = match (config.voltage, hclk.0) { + (VoltageScale::Range3, ..=16_000_000) => Latency::WS0, + (VoltageScale::Range3, ..=32_000_000) => Latency::WS1, + (VoltageScale::Range3, ..=48_000_000) => Latency::WS2, + (VoltageScale::Range3, ..=64_000_000) => Latency::WS3, + (VoltageScale::Range3, ..=80_000_000) => Latency::WS4, + (VoltageScale::Range3, ..=96_000_000) => Latency::WS5, + (VoltageScale::Range3, ..=112_000_000) => Latency::WS6, + (VoltageScale::Range3, ..=120_000_000) => Latency::WS7, + (VoltageScale::Range2, ..=18_000_000) => Latency::WS0, + (VoltageScale::Range2, ..=36_000_000) => Latency::WS1, + (VoltageScale::Range2, ..=54_000_000) => Latency::WS2, + (VoltageScale::Range2, ..=72_000_000) => Latency::WS3, + (VoltageScale::Range2, ..=90_000_000) => Latency::WS4, + (VoltageScale::Range2, ..=108_000_000) => Latency::WS5, + (VoltageScale::Range2, ..=120_000_000) => Latency::WS6, + (VoltageScale::Range1, ..=24_000_000) => Latency::WS0, + (VoltageScale::Range1, ..=48_000_000) => Latency::WS1, + (VoltageScale::Range1, ..=72_000_000) => Latency::WS2, + (VoltageScale::Range1, ..=96_000_000) => Latency::WS3, + (VoltageScale::Range1, ..=120_000_000) => Latency::WS4, + (VoltageScale::Range0, ..=30_000_000) => Latency::WS0, + (VoltageScale::Range0, ..=60_000_000) => Latency::WS1, + (VoltageScale::Range0, ..=90_000_000) => Latency::WS2, + (VoltageScale::Range0, ..=120_000_000) => Latency::WS3, + _ => unreachable!(), + }; + + #[cfg(any(stm32f4, stm32f7))] + let latency = { + // Be conservative with voltage ranges + const FLASH_LATENCY_STEP: u32 = 30_000_000; + + let latency = (hclk.0 - 1) / FLASH_LATENCY_STEP; + debug!("flash: latency={}", latency); + + Latency::from_bits(latency as u8) + }; + + FLASH.acr().write(|w| w.set_latency(latency)); + while FLASH.acr().read().latency() != latency {} RCC.cfgr().modify(|w| { w.set_sw(config.sys); @@ -232,7 +297,7 @@ struct PllOutput { #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] Plli2s, #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] Pllsai, @@ -244,7 +309,7 @@ fn pll_enable(instance: PllInstance, enabled: bool) { RCC.cr().modify(|w| w.set_pllon(enabled)); while RCC.cr().read().pllrdy() != enabled {} } - #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] PllInstance::Plli2s => { RCC.cr().modify(|w| w.set_plli2son(enabled)); while RCC.cr().read().plli2srdy() != enabled {} @@ -275,6 +340,18 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let vco_freq = in_freq * pll.mul; assert!(max::PLL_VCO.contains(&vco_freq)); + // stm32f2 plls are like swiss cheese + #[cfg(stm32f2)] + match instance { + PllInstance::Pll => { + assert!(pll.divr.is_none()); + } + PllInstance::Plli2s => { + assert!(pll.divp.is_none()); + assert!(pll.divq.is_none()); + } + } + let p = pll.divp.map(|div| vco_freq / div); let q = pll.divq.map(|div| vco_freq / div); let r = pll.divr.map(|div| vco_freq / div); @@ -288,6 +365,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll if let Some(divq) = pll.divq { $w.set_pllq(divq); } + #[cfg(any(stm32f4, stm32f7))] if let Some(divr) = pll.divr { $w.set_pllr(divr); } @@ -304,6 +382,12 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll PllInstance::Plli2s => RCC.plli2scfgr().write(|w| { write_fields!(w); }), + #[cfg(stm32f2)] + PllInstance::Plli2s => RCC.plli2scfgr().write(|w| { + if let Some(divr) = pll.divr { + w.set_pllr(divr); + } + }), #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] PllInstance::Pllsai => RCC.pllsaicfgr().write(|w| { write_fields!(w); @@ -316,22 +400,6 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll PllOutput { p, q, r } } -fn flash_setup(clk: Hertz) { - use crate::pac::flash::vals::Latency; - - // Be conservative with voltage ranges - const FLASH_LATENCY_STEP: u32 = 30_000_000; - - let latency = (clk.0 - 1) / FLASH_LATENCY_STEP; - debug!("flash: latency={}", latency); - - let latency = Latency::from_bits(latency as u8); - FLASH.acr().write(|w| { - w.set_latency(latency); - }); - while FLASH.acr().read().latency() != latency {} -} - #[cfg(stm32f7)] mod max { use core::ops::RangeInclusive; @@ -380,3 +448,22 @@ mod max { pub(crate) const PLL_IN: RangeInclusive = Hertz(1_000_000)..=Hertz(2_100_000); pub(crate) const PLL_VCO: RangeInclusive = Hertz(100_000_000)..=Hertz(432_000_000); } + +#[cfg(stm32f2)] +mod max { + use core::ops::RangeInclusive; + + use crate::time::Hertz; + + pub(crate) const HSE_OSC: RangeInclusive = Hertz(4_000_000)..=Hertz(26_000_000); + pub(crate) const HSE_BYP: RangeInclusive = Hertz(1_000_000)..=Hertz(26_000_000); + + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(120_000_000); + + pub(crate) const HCLK: RangeInclusive = Hertz(0)..=Hertz(SYSCLK.end().0); + pub(crate) const PCLK1: RangeInclusive = Hertz(0)..=Hertz(SYSCLK.end().0 / 4); + pub(crate) const PCLK2: RangeInclusive = Hertz(0)..=Hertz(SYSCLK.end().0 / 2); + + pub(crate) const PLL_IN: RangeInclusive = Hertz(0_950_000)..=Hertz(2_100_000); + pub(crate) const PLL_VCO: RangeInclusive = Hertz(192_000_000)..=Hertz(432_000_000); +} diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs deleted file mode 100644 index 00480222..00000000 --- a/embassy-stm32/src/rcc/f2.rs +++ /dev/null @@ -1,320 +0,0 @@ -use crate::pac::flash::vals::Latency; -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 PllSource, - Ppre as APBPrescaler, -}; -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); - -#[derive(Clone, Copy)] -pub struct HSEConfig { - pub frequency: Hertz, - pub source: HSESrc, -} - -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - HSE, - HSI, - PLL, -} - -/// HSE clock source -#[derive(Clone, Copy)] -pub enum HSESrc { - /// Crystal/ceramic resonator - Crystal, - /// External clock source, HSE bypassed - Bypass, -} - -#[derive(Clone, Copy)] -pub struct Pll { - pub pre_div: PllPreDiv, - pub mul: PllMul, - pub divp: PllPDiv, - pub divq: PllQDiv, -} - -impl Default for Pll { - fn default() -> Self { - Pll { - pre_div: PllPreDiv::DIV16, - mul: PllMul::MUL192, - divp: PllPDiv::DIV2, - divq: PllQDiv::DIV4, - } - } -} - -impl Pll { - pub fn clocks(&self, src_freq: Hertz) -> PLLClocks { - let in_freq = src_freq / self.pre_div; - let vco_freq = src_freq / self.pre_div * self.mul; - let main_freq = vco_freq / self.divp; - let pll48_freq = vco_freq / self.divq; - PLLClocks { - in_freq, - vco_freq, - main_freq, - pll48_freq, - } - } -} -#[derive(Clone, Copy, PartialEq)] -pub struct PLLClocks { - pub in_freq: Hertz, - pub vco_freq: Hertz, - pub main_freq: Hertz, - pub pll48_freq: Hertz, -} - -/// Voltage range of the power supply used. -/// -/// Used to calculate flash waitstates. See -/// RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock frequency -pub enum VoltageScale { - /// 2.7 to 3.6 V - Range0, - /// 2.4 to 2.7 V - Range1, - /// 2.1 to 2.4 V - Range2, - /// 1.8 to 2.1 V - Range3, -} - -impl VoltageScale { - const fn wait_states(&self, ahb_freq: Hertz) -> Option { - let ahb_freq = ahb_freq.0; - // Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock - // frequency - match self { - VoltageScale::Range3 => { - if ahb_freq <= 16_000_000 { - Some(Latency::WS0) - } else if ahb_freq <= 32_000_000 { - Some(Latency::WS1) - } else if ahb_freq <= 48_000_000 { - Some(Latency::WS2) - } else if ahb_freq <= 64_000_000 { - Some(Latency::WS3) - } else if ahb_freq <= 80_000_000 { - Some(Latency::WS4) - } else if ahb_freq <= 96_000_000 { - Some(Latency::WS5) - } else if ahb_freq <= 112_000_000 { - Some(Latency::WS6) - } else if ahb_freq <= 120_000_000 { - Some(Latency::WS7) - } else { - None - } - } - VoltageScale::Range2 => { - if ahb_freq <= 18_000_000 { - Some(Latency::WS0) - } else if ahb_freq <= 36_000_000 { - Some(Latency::WS1) - } else if ahb_freq <= 54_000_000 { - Some(Latency::WS2) - } else if ahb_freq <= 72_000_000 { - Some(Latency::WS3) - } else if ahb_freq <= 90_000_000 { - Some(Latency::WS4) - } else if ahb_freq <= 108_000_000 { - Some(Latency::WS5) - } else if ahb_freq <= 120_000_000 { - Some(Latency::WS6) - } else { - None - } - } - VoltageScale::Range1 => { - if ahb_freq <= 24_000_000 { - Some(Latency::WS0) - } else if ahb_freq <= 48_000_000 { - Some(Latency::WS1) - } else if ahb_freq <= 72_000_000 { - Some(Latency::WS2) - } else if ahb_freq <= 96_000_000 { - Some(Latency::WS3) - } else if ahb_freq <= 120_000_000 { - Some(Latency::WS4) - } else { - None - } - } - VoltageScale::Range0 => { - if ahb_freq <= 30_000_000 { - Some(Latency::WS0) - } else if ahb_freq <= 60_000_000 { - Some(Latency::WS1) - } else if ahb_freq <= 90_000_000 { - Some(Latency::WS2) - } else if ahb_freq <= 120_000_000 { - Some(Latency::WS3) - } else { - None - } - } - } - } -} - -/// Clocks configuration -pub struct Config { - pub hse: Option, - pub hsi: bool, - pub pll_mux: PllSource, - pub pll: Pll, - pub mux: ClockSrc, - pub voltage: VoltageScale, - pub ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - pub ls: super::LsConfig, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - hse: None, - hsi: true, - pll_mux: PllSource::HSI, - pll: Pll::default(), - voltage: VoltageScale::Range3, - mux: ClockSrc::HSI, - ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - // Make sure HSI is enabled - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - if let Some(hse_config) = config.hse { - RCC.cr().modify(|w| { - w.set_hsebyp(match hse_config.source { - HSESrc::Bypass => true, - HSESrc::Crystal => false, - }); - w.set_hseon(true) - }); - while !RCC.cr().read().hserdy() {} - } - - let pll_src_freq = match config.pll_mux { - PllSource::HSE => { - let hse_config = config - .hse - .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input")); - hse_config.frequency - } - PllSource::HSI => HSI_FREQ, - }; - - // Reference: STM32F215xx/217xx datasheet Table 33. Main PLL characteristics - let pll_clocks = config.pll.clocks(pll_src_freq); - assert!(Hertz(950_000) <= pll_clocks.in_freq && pll_clocks.in_freq <= Hertz(2_100_000)); - assert!(Hertz(192_000_000) <= pll_clocks.vco_freq && pll_clocks.vco_freq <= Hertz(432_000_000)); - assert!(Hertz(24_000_000) <= pll_clocks.main_freq && pll_clocks.main_freq <= Hertz(120_000_000)); - // USB actually requires == 48 MHz, but other PLL48 peripherals are fine with <= 48MHz - assert!(pll_clocks.pll48_freq <= Hertz(48_000_000)); - - RCC.pllcfgr().write(|w| { - w.set_pllsrc(config.pll_mux); - w.set_pllm(config.pll.pre_div); - w.set_plln(config.pll.mul); - w.set_pllp(config.pll.divp); - w.set_pllq(config.pll.divq); - }); - - let (sys_clk, sw) = match config.mux { - ClockSrc::HSI => { - assert!(config.hsi, "HSI must be enabled to be used as system clock"); - (HSI_FREQ, Sw::HSI) - } - ClockSrc::HSE => { - let hse_config = config - .hse - .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input")); - (hse_config.frequency, Sw::HSE) - } - ClockSrc::PLL => { - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - (pll_clocks.main_freq, Sw::PLL1_P) - } - }; - // RM0033 Figure 9. Clock tree suggests max SYSCLK/HCLK is 168 MHz, but datasheet specifies PLL - // max output to be 120 MHz, so there's no way to get higher frequencies - assert!(sys_clk <= Hertz(120_000_000)); - - let ahb_freq = sys_clk / config.ahb_pre; - // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions - assert!(ahb_freq <= Hertz(120_000_000)); - - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, Hertz(freq.0 * 2)) - } - }; - // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions - assert!(apb1_freq <= Hertz(30_000_000)); - - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, Hertz(freq.0 * 2)) - } - }; - // Reference: STM32F215xx/217xx datasheet Table 13. General operating conditions - assert!(apb2_freq <= Hertz(60_000_000)); - - let flash_ws = unwrap!(config.voltage.wait_states(ahb_freq)); - FLASH.acr().modify(|w| w.set_latency(flash_ws)); - - RCC.cfgr().modify(|w| { - w.set_sw(sw.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() {} - - // Turn off HSI to save power if we don't need it - if !config.hsi { - RCC.cr().modify(|w| w.set_hsion(false)); - } - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: sys_clk, - hclk1: ahb_freq, - hclk2: ahb_freq, - hclk3: ahb_freq, - pclk1: apb1_freq, - pclk1_tim: apb1_tim_freq, - pclk2: apb2_freq, - pclk2_tim: apb2_tim_freq, - pll1_q: Some(pll_clocks.pll48_freq), - rtc, - }); -} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index debd16ca..2e144dc7 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -15,14 +15,13 @@ mod hsi48; pub use hsi48::*; #[cfg_attr(rcc_f0, path = "f0.rs")] -#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")] -#[cfg_attr(rcc_f2, path = "f2.rs")] -#[cfg_attr(any(rcc_f3, rcc_f3_v2), path = "f3.rs")] -#[cfg_attr(any(rcc_f4, rcc_f410, rcc_f7), path = "f4f7.rs")] +#[cfg_attr(any(stm32f1), path = "f1.rs")] +#[cfg_attr(any(stm32f3), path = "f3.rs")] +#[cfg_attr(any(stm32f2, stm32f4, stm32f7), path = "f.rs")] #[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_h7rm0433, rcc_h7ab), path = "h.rs")] +#[cfg_attr(any(stm32h5, stm32h7), path = "h.rs")] #[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl), path = "l.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs index feec9001..aae7637d 100644 --- a/examples/stm32f2/src/bin/pll.rs +++ b/examples/stm32f2/src/bin/pll.rs @@ -6,9 +6,6 @@ use core::convert::TryFrom; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ - APBPrescaler, ClockSrc, HSEConfig, HSESrc, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllSource, -}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; use embassy_time::Timer; @@ -19,29 +16,35 @@ async fn main(_spawner: Spawner) { // Example config for maximum performance on a NUCLEO-F207ZG board let mut config = Config::default(); - // 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 = PllSource::HSE; - config.rcc.pll = Pll { - // 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 - divp: PllPDiv::DIV2, - // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - divq: PllQDiv::DIV5, - }; - // 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; + + { + use embassy_stm32::rcc::*; + + // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + // PLL uses HSE as the clock source + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + // 8 MHz clock source / 8 = 1 MHz PLL input + prediv: 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 + divp: Some(PllPDiv::DIV2), + // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output + divq: Some(PllQDiv::DIV5), + divr: None, + }); + // System clock comes from PLL (= the 120 MHz main PLL output) + config.rcc.sys = Sysclk::PLL1_P; + // 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; + } let _p = embassy_stm32::init(config); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index fe694cbe..a44e8230 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -236,24 +236,25 @@ pub fn config() -> Config { { 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, + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, }); // PLL uses HSE as the clock source - config.rcc.pll_mux = PllSource::HSE; - config.rcc.pll = Pll { + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { // 8 MHz clock source / 8 = 1 MHz PLL input - pre_div: unwrap!(PllPreDiv::try_from(8)), + prediv: 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 - divp: PllPDiv::DIV2, + divp: Some(PllPDiv::DIV2), // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - divq: PllQDiv::DIV5, - }; + divq: Some(PllQDiv::DIV5), + divr: None, + }); // System clock comes from PLL (= the 120 MHz main PLL output) - config.rcc.mux = ClockSrc::PLL; + config.rcc.sys = Sysclk::PLL1_P; // 120 MHz / 4 = 30 MHz APB1 frequency config.rcc.apb1_pre = APBPrescaler::DIV4; // 120 MHz / 2 = 60 MHz APB2 frequency From 18c1f9dd562682f928aa3c1fc44c013a374ee280 Mon Sep 17 00:00:00 2001 From: Timo Date: Mon, 13 Nov 2023 11:25:11 +0100 Subject: [PATCH 133/188] Bump embassy-futures 0.1.0 -> 0.1.1 --- embassy-futures/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-futures/Cargo.toml b/embassy-futures/Cargo.toml index 89bb3af0..ee1f4c9a 100644 --- a/embassy-futures/Cargo.toml +++ b/embassy-futures/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-futures" -version = "0.1.0" +version = "0.1.1" edition = "2021" description = "no-std, no-alloc utilities for working with futures" repository = "https://github.com/embassy-rs/embassy" From 8eff7498238ca8863bfdd4496fcb4246cc2df8eb Mon Sep 17 00:00:00 2001 From: Torin Cooper-Bennun Date: Mon, 13 Nov 2023 15:13:25 +0000 Subject: [PATCH 134/188] stm32/gpdma: fix drop() to use RM's method for aborting transfer see e.g. STM32H503 RM section 15.4.4... 1. Write 1 into GPDMA_CxCR.SUSP 2. Poll GPDMA_CxSR.SUSPF until it is 1 3. Write 1 into GPDMA_CxCR.RESET (occurs upon next init, in new_inner()) --- embassy-stm32/src/dma/gpdma.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index b811da1f..b061415e 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -299,19 +299,15 @@ impl<'a, C: Channel> Transfer<'a, C> { pub fn request_stop(&mut self) { let ch = self.channel.regs().ch(self.channel.num()); - - // Disable the channel. Keep the IEs enabled so the irqs still fire. - ch.cr().write(|w| { - w.set_tcie(true); - w.set_useie(true); - w.set_dteie(true); - w.set_suspie(true); + ch.cr().modify(|w| { + w.set_susp(true); }) } pub fn is_running(&mut self) -> bool { let ch = self.channel.regs().ch(self.channel.num()); - !ch.sr().read().tcf() + let sr = ch.sr().read(); + !sr.tcf() && !sr.suspf() } /// Gets the total remaining transfers for the channel From 19ff043acd2108c7896fb8f959569c997ad345e1 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 13 Nov 2023 22:37:13 +0100 Subject: [PATCH 135/188] nrf/buffered_uarte: fix missing hwfc enable. --- embassy-nrf/src/buffered_uarte.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 10b8b0fb..ec84640d 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -282,6 +282,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { let r = U::regs(); + let hwfc = cts.is_some(); + rxd.conf().write(|w| w.input().connect().drive().h0h1()); r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); @@ -311,7 +313,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { // Configure r.config.write(|w| { - w.hwfc().bit(false); + w.hwfc().bit(hwfc); w.parity().variant(config.parity); w }); From c46418f123820e375778e65a90e8589d7d665311 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 14 Nov 2023 00:00:12 +0100 Subject: [PATCH 136/188] nrf/buffered_uarte: fix hang when buffer full due to PPI missing the endrx event. Fixes #2181 --- embassy-nrf/src/buffered_uarte.rs | 79 +++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index ec84640d..e4b556f0 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -12,7 +12,7 @@ use core::cmp::min; use core::future::poll_fn; use core::marker::PhantomData; use core::slice; -use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering}; +use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU8, AtomicUsize, Ordering}; use core::task::Poll; use embassy_hal_internal::atomic_ring_buffer::RingBuffer; @@ -41,7 +41,9 @@ mod sealed { pub rx_waker: AtomicWaker, pub rx_buf: RingBuffer, - pub rx_bufs: AtomicU8, + pub rx_started: AtomicBool, + pub rx_started_count: AtomicU8, + pub rx_ended_count: AtomicU8, pub rx_ppi_ch: AtomicU8, } } @@ -65,7 +67,9 @@ impl State { rx_waker: AtomicWaker::new(), rx_buf: RingBuffer::new(), - rx_bufs: AtomicU8::new(0), + rx_started: AtomicBool::new(false), + rx_started_count: AtomicU8::new(0), + rx_ended_count: AtomicU8::new(0), rx_ppi_ch: AtomicU8::new(0), } } @@ -104,28 +108,20 @@ impl interrupt::typelevel::Handler for Interrupt s.rx_waker.wake(); } - // If not RXing, start. - if s.rx_bufs.load(Ordering::Relaxed) == 0 { - let (ptr, len) = rx.push_buf(); - if len >= half_len { - //trace!(" irq_rx: starting {:?}", half_len); - s.rx_bufs.store(1, Ordering::Relaxed); + if r.events_endrx.read().bits() != 0 { + //trace!(" irq_rx: endrx"); + r.events_endrx.reset(); - // Set up the DMA read - r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); - r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) }); - - // Start UARTE Receive transaction - r.tasks_startrx.write(|w| unsafe { w.bits(1) }); - rx.push_done(half_len); - r.intenset.write(|w| w.rxstarted().set()); - } + let val = s.rx_ended_count.load(Ordering::Relaxed); + s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); } - if r.events_rxstarted.read().bits() != 0 { + if r.events_rxstarted.read().bits() != 0 || !s.rx_started.load(Ordering::Relaxed) { //trace!(" irq_rx: rxstarted"); let (ptr, len) = rx.push_buf(); if len >= half_len { + r.events_rxstarted.reset(); + //trace!(" irq_rx: starting second {:?}", half_len); // Set up the DMA read @@ -134,11 +130,50 @@ impl interrupt::typelevel::Handler for Interrupt let chn = s.rx_ppi_ch.load(Ordering::Relaxed); + // Enable endrx -> startrx PPI channel. + // From this point on, if endrx happens, startrx is automatically fired. ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) }); + // It is possible that endrx happened BEFORE enabling the PPI. In this case + // the PPI channel doesn't trigger, and we'd hang. We have to detect this + // and manually start. + + // check again in case endrx has happened between the last check and now. + if r.events_endrx.read().bits() != 0 { + //trace!(" irq_rx: endrx"); + r.events_endrx.reset(); + + let val = s.rx_ended_count.load(Ordering::Relaxed); + s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); + } + + let rx_ended = s.rx_ended_count.load(Ordering::Relaxed); + let rx_started = s.rx_started_count.load(Ordering::Relaxed); + + // If we started the same amount of transfers as ended, the last rxend has + // already occured. + let rxend_happened = rx_started == rx_ended; + + // Check if the PPI channel is still enabled. The PPI channel disables itself + // when it fires, so if it's still enabled it hasn't fired. + let ppi_ch_enabled = ppi::regs().chen.read().bits() & (1 << chn) != 0; + + // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed. + // this condition also naturally matches if `!started`, needed to kickstart the DMA. + if rxend_happened && ppi_ch_enabled { + //trace!("manually starting."); + + // disable the ppi ch, it's of no use anymore. + ppi::regs().chenclr.write(|w| unsafe { w.bits(1 << chn) }); + + // manually start + r.tasks_startrx.write(|w| unsafe { w.bits(1) }); + } + rx.push_done(half_len); - r.events_rxstarted.reset(); + s.rx_started_count.store(rx_started.wrapping_add(1), Ordering::Relaxed); + s.rx_started.store(true, Ordering::Relaxed); } else { //trace!(" irq_rx: rxstarted no buf"); r.intenclr.write(|w| w.rxstarted().clear()); @@ -305,7 +340,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { // Initialize state let s = U::buffered_state(); s.tx_count.store(0, Ordering::Relaxed); - s.rx_bufs.store(0, Ordering::Relaxed); + s.rx_started_count.store(0, Ordering::Relaxed); + s.rx_ended_count.store(0, Ordering::Relaxed); let len = tx_buffer.len(); unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; let len = rx_buffer.len(); @@ -335,6 +371,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { w.endtx().set(); w.rxstarted().set(); w.error().set(); + w.endrx().set(); w }); From 6ccd8c051e657a233fcdc9040ad0b6aaa2b357e5 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 14 Nov 2023 00:00:39 +0100 Subject: [PATCH 137/188] nrf/buffered_uarte: add test for recovering from buffer full. --- tests/nrf/Cargo.toml | 2 +- tests/nrf/src/bin/buffered_uart_full.rs | 72 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 tests/nrf/src/bin/buffered_uart_full.rs diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index f7a10409..a3393f7e 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -12,7 +12,7 @@ embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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" } +embedded-io-async = { version = "0.6.0", features = ["defmt-03"] } embassy-net = { version = "0.2.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/nrf/src/bin/buffered_uart_full.rs b/tests/nrf/src/bin/buffered_uart_full.rs new file mode 100644 index 00000000..2db8f88d --- /dev/null +++ b/tests/nrf/src/bin/buffered_uart_full.rs @@ -0,0 +1,72 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] +teleprobe_meta::target!(b"nrf52840-dk"); + +use defmt::{assert_eq, *}; +use embassy_executor::Spawner; +use embassy_nrf::buffered_uarte::{self, BufferedUarte}; +use embassy_nrf::{bind_interrupts, peripherals, uarte}; +use embedded_io_async::{Read, Write}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + UARTE0_UART0 => buffered_uarte::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + let mut config = uarte::Config::default(); + config.parity = uarte::Parity::EXCLUDED; + config.baudrate = uarte::Baudrate::BAUD1M; + + let mut tx_buffer = [0u8; 1024]; + let mut rx_buffer = [0u8; 1024]; + + let mut u = BufferedUarte::new( + p.UARTE0, + p.TIMER0, + p.PPI_CH0, + p.PPI_CH1, + p.PPI_GROUP0, + Irqs, + p.P1_03, + p.P1_02, + config.clone(), + &mut rx_buffer, + &mut tx_buffer, + ); + + info!("uarte initialized!"); + + let (mut rx, mut tx) = u.split(); + + let mut buf = [0; 1024]; + for (j, b) in buf.iter_mut().enumerate() { + *b = j as u8; + } + + // Write 1024b. This causes the rx buffer to get exactly full. + unwrap!(tx.write_all(&buf).await); + unwrap!(tx.flush().await); + + // Read those 1024b. + unwrap!(rx.read_exact(&mut buf).await); + for (j, b) in buf.iter().enumerate() { + assert_eq!(*b, j as u8); + } + + // The buffer should now be unclogged. Write 1024b again. + unwrap!(tx.write_all(&buf).await); + unwrap!(tx.flush().await); + + // Read should work again. + unwrap!(rx.read_exact(&mut buf).await); + for (j, b) in buf.iter().enumerate() { + assert_eq!(*b, j as u8); + } + + info!("Test OK"); + cortex_m::asm::bkpt(); +} From ef69f386ab1c44c2e2813f8bf934e7440e09852a Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 14 Nov 2023 08:30:39 +0100 Subject: [PATCH 138/188] Update smoltcp and fix errors from that --- embassy-net/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 0b029bd3..ef66078c 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -25,7 +25,7 @@ features = ["nightly", "defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "me default = [] std = [] -defmt = ["dep:defmt", "smoltcp/defmt", "embassy-net-driver/defmt"] +defmt = ["dep:defmt", "smoltcp/defmt", "embassy-net-driver/defmt", "heapless/defmt-03"] nightly = ["dep:embedded-io-async", "dep:embedded-nal-async"] @@ -46,7 +46,7 @@ igmp = ["smoltcp/proto-igmp"] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "9b791ae3057e10f7afcb70c67deb5daf714293a9", default-features = false, features = [ +smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp.git", rev = "b57e2f9e70e82a13f31d5ea17e55232c11cc2b2d", default-features = false, features = [ "socket", "async", ] } From fd670a9ae527b534293eb692273285d7a1221cdd Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 14 Nov 2023 08:31:02 +0100 Subject: [PATCH 139/188] Use smoltcp constant in results from DNS --- embassy-net/src/dns.rs | 6 +++++- embassy-net/src/lib.rs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/embassy-net/src/dns.rs b/embassy-net/src/dns.rs index 6b804f9e..69fc5cdf 100644 --- a/embassy-net/src/dns.rs +++ b/embassy-net/src/dns.rs @@ -63,7 +63,11 @@ where } /// Make a query for a given name and return the corresponding IP addresses. - pub async fn query(&self, name: &str, qtype: DnsQueryType) -> Result, Error> { + pub async fn query( + &self, + name: &str, + qtype: DnsQueryType, + ) -> Result, Error> { self.stack.dns_query(name, qtype).await } } diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index b9315079..6aa476aa 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -494,7 +494,11 @@ impl Stack { /// Make a query for a given name and return the corresponding IP addresses. #[cfg(feature = "dns")] - pub async fn dns_query(&self, name: &str, qtype: dns::DnsQueryType) -> Result, dns::Error> { + pub async fn dns_query( + &self, + name: &str, + qtype: dns::DnsQueryType, + ) -> Result, dns::Error> { // For A and AAAA queries we try detect whether `name` is just an IP address match qtype { #[cfg(feature = "proto-ipv4")] From a2c440ef8c8dcc863c5d017f9a2545b3f0f8c8f1 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 14 Nov 2023 08:45:24 +0100 Subject: [PATCH 140/188] Update changelog --- embassy-net/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/embassy-net/CHANGELOG.md b/embassy-net/CHANGELOG.md index ada34cb7..0319a5ed 100644 --- a/embassy-net/CHANGELOG.md +++ b/embassy-net/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - Avoid never resolving `TcpIo::read` when the output buffer is empty. +- Update to `smoltcp` git. +- Forward constants from `smoltcp` in DNS query results so changing DNS result size in `smoltcp` properly propagates. ## 0.2.1 - 2023-10-31 From 50a983fd9b8f10fa5153757593e9f8cfccc902ac Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 14 Nov 2023 18:45:23 +0100 Subject: [PATCH 141/188] executor: add missing `main` macro reexport on xtensa. --- embassy-executor/src/arch/xtensa.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/embassy-executor/src/arch/xtensa.rs b/embassy-executor/src/arch/xtensa.rs index 601d8500..d335594e 100644 --- a/embassy-executor/src/arch/xtensa.rs +++ b/embassy-executor/src/arch/xtensa.rs @@ -8,6 +8,9 @@ mod thread { use core::marker::PhantomData; use core::sync::atomic::{AtomicBool, Ordering}; + #[cfg(feature = "nightly")] + pub use embassy_macros::main_riscv as main; + use crate::{raw, Spawner}; /// global atomic used to keep track of whether there is work to do since sev() is not available on Xtensa From bef9b7a8539c3dddb1cf6ab46db161f1ca56b1a1 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 14 Nov 2023 22:32:48 +0100 Subject: [PATCH 142/188] executor: remove atomic-polyfill. --- embassy-executor/CHANGELOG.md | 5 + embassy-executor/Cargo.toml | 7 +- embassy-executor/src/arch/cortex_m.rs | 21 ++--- embassy-executor/src/arch/riscv32.rs | 2 +- embassy-executor/src/raw/mod.rs | 58 +++--------- .../{run_queue.rs => run_queue_atomics.rs} | 3 +- .../src/raw/run_queue_critical_section.rs | 75 +++++++++++++++ embassy-executor/src/raw/state_atomics.rs | 73 +++++++++++++++ .../src/raw/state_critical_section.rs | 93 +++++++++++++++++++ embassy-executor/src/raw/timer_queue.rs | 10 +- 10 files changed, 280 insertions(+), 67 deletions(-) rename embassy-executor/src/raw/{run_queue.rs => run_queue_atomics.rs} (98%) create mode 100644 embassy-executor/src/raw/run_queue_critical_section.rs create mode 100644 embassy-executor/src/raw/state_atomics.rs create mode 100644 embassy-executor/src/raw/state_critical_section.rs diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index e7914cbc..f45b2770 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/CHANGELOG.md @@ -5,6 +5,11 @@ 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). +## Unreleased + +- Add `main` macro reexport for Xtensa arch. +- Remove use of `atomic-polyfill`. The executor now has multiple implementations of its internal data structures for cases where the target supports atomics or doesn't. + ## 0.3.2 - 2023-11-06 - Use `atomic-polyfill` for `riscv32` diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index a85c5dff..4945455d 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -34,7 +34,7 @@ _arch = [] # some arch was picked arch-std = ["_arch", "critical-section/std"] arch-cortex-m = ["_arch", "dep:cortex-m"] arch-xtensa = ["_arch"] -arch-riscv32 = ["_arch"] +arch-riscv32 = ["_arch", "dep:portable-atomic"] arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"] # Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded archs) @@ -59,9 +59,12 @@ rtos-trace = { version = "0.1.2", optional = true } embassy-macros = { version = "0.2.1", path = "../embassy-macros" } embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true} -atomic-polyfill = "1.0.1" critical-section = "1.1" +# needed for riscv +# remove when https://github.com/rust-lang/rust/pull/114499 is merged +portable-atomic = { version = "1.5", optional = true } + # arch-cortex-m dependencies cortex-m = { version = "0.7.6", optional = true } diff --git a/embassy-executor/src/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs index fde862f3..55299c94 100644 --- a/embassy-executor/src/arch/cortex_m.rs +++ b/embassy-executor/src/arch/cortex_m.rs @@ -115,12 +115,12 @@ mod thread { pub use interrupt::*; #[cfg(feature = "executor-interrupt")] mod interrupt { - use core::cell::UnsafeCell; + use core::cell::{Cell, UnsafeCell}; use core::mem::MaybeUninit; - use atomic_polyfill::{AtomicBool, Ordering}; use cortex_m::interrupt::InterruptNumber; use cortex_m::peripheral::NVIC; + use critical_section::Mutex; use crate::raw; @@ -146,7 +146,7 @@ mod interrupt { /// It is somewhat more complex to use, it's recommended to use the thread-mode /// [`Executor`] instead, if it works for your use case. pub struct InterruptExecutor { - started: AtomicBool, + started: Mutex>, executor: UnsafeCell>, } @@ -158,7 +158,7 @@ mod interrupt { #[inline] pub const fn new() -> Self { Self { - started: AtomicBool::new(false), + started: Mutex::new(Cell::new(false)), executor: UnsafeCell::new(MaybeUninit::uninit()), } } @@ -167,7 +167,8 @@ mod interrupt { /// /// # Safety /// - /// You MUST call this from the interrupt handler, and from nowhere else. + /// - You MUST call this from the interrupt handler, and from nowhere else. + /// - You must not call this before calling `start()`. pub unsafe fn on_interrupt(&'static self) { let executor = unsafe { (&*self.executor.get()).assume_init_ref() }; executor.poll(); @@ -196,11 +197,7 @@ mod interrupt { /// do it after. /// pub fn start(&'static self, irq: impl InterruptNumber) -> crate::SendSpawner { - if self - .started - .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) - .is_err() - { + if critical_section::with(|cs| self.started.borrow(cs).replace(true)) { panic!("InterruptExecutor::start() called multiple times on the same executor."); } @@ -222,10 +219,10 @@ mod interrupt { /// This returns a [`SendSpawner`] you can use to spawn tasks on this /// executor. /// - /// This MUST only be called on an executor that has already been spawned. + /// This MUST only be called on an executor that has already been started. /// The function will panic otherwise. pub fn spawner(&'static self) -> crate::SendSpawner { - if !self.started.load(Ordering::Acquire) { + if !critical_section::with(|cs| self.started.borrow(cs).get()) { panic!("InterruptExecutor::spawner() called on uninitialized executor."); } let executor = unsafe { (&*self.executor.get()).assume_init_ref() }; diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs index e5c0ff2e..6814e784 100644 --- a/embassy-executor/src/arch/riscv32.rs +++ b/embassy-executor/src/arch/riscv32.rs @@ -7,9 +7,9 @@ pub use thread::*; mod thread { use core::marker::PhantomData; - use atomic_polyfill::{AtomicBool, Ordering}; #[cfg(feature = "nightly")] pub use embassy_macros::main_riscv as main; + use portable_atomic::{AtomicBool, Ordering}; use crate::{raw, Spawner}; diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 6d2c1c18..ed0bedd2 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -7,7 +7,14 @@ //! Using this module requires respecting subtle safety contracts. If you can, prefer using the safe //! [executor wrappers](crate::Executor) and the [`embassy_executor::task`](embassy_macros::task) macro, which are fully safe. +#[cfg_attr(target_has_atomic = "ptr", path = "run_queue_atomics.rs")] +#[cfg_attr(not(target_has_atomic = "ptr"), path = "run_queue_critical_section.rs")] mod run_queue; + +#[cfg_attr(target_has_atomic = "8", path = "state_atomics.rs")] +#[cfg_attr(not(target_has_atomic = "8"), path = "state_critical_section.rs")] +mod state; + #[cfg(feature = "integrated-timers")] mod timer_queue; pub(crate) mod util; @@ -21,7 +28,6 @@ use core::pin::Pin; use core::ptr::NonNull; use core::task::{Context, Poll}; -use atomic_polyfill::{AtomicU32, Ordering}; #[cfg(feature = "integrated-timers")] use embassy_time::driver::{self, AlarmHandle}; #[cfg(feature = "integrated-timers")] @@ -30,21 +36,14 @@ use embassy_time::Instant; use rtos_trace::trace; use self::run_queue::{RunQueue, RunQueueItem}; +use self::state::State; use self::util::{SyncUnsafeCell, UninitCell}; pub use self::waker::task_from_waker; use super::SpawnToken; -/// Task is spawned (has a future) -pub(crate) const STATE_SPAWNED: u32 = 1 << 0; -/// Task is in the executor run queue -pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; -/// Task is in the executor timer queue -#[cfg(feature = "integrated-timers")] -pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; - /// Raw task header for use in task pointers. pub(crate) struct TaskHeader { - pub(crate) state: AtomicU32, + pub(crate) state: State, pub(crate) run_queue_item: RunQueueItem, pub(crate) executor: SyncUnsafeCell>, poll_fn: SyncUnsafeCell>, @@ -116,7 +115,7 @@ impl TaskStorage { pub const fn new() -> Self { Self { raw: TaskHeader { - state: AtomicU32::new(0), + state: State::new(), run_queue_item: RunQueueItem::new(), executor: SyncUnsafeCell::new(None), // Note: this is lazily initialized so that a static `TaskStorage` will go in `.bss` @@ -161,7 +160,7 @@ impl TaskStorage { match future.poll(&mut cx) { Poll::Ready(_) => { this.future.drop_in_place(); - this.raw.state.fetch_and(!STATE_SPAWNED, Ordering::AcqRel); + this.raw.state.despawn(); #[cfg(feature = "integrated-timers")] this.raw.expires_at.set(Instant::MAX); @@ -193,11 +192,7 @@ impl AvailableTask { /// /// This function returns `None` if a task has already been spawned and has not finished running. pub fn claim(task: &'static TaskStorage) -> Option { - task.raw - .state - .compare_exchange(0, STATE_SPAWNED | STATE_RUN_QUEUED, Ordering::AcqRel, Ordering::Acquire) - .ok() - .map(|_| Self { task }) + task.raw.state.spawn().then(|| Self { task }) } fn initialize_impl(self, future: impl FnOnce() -> F) -> SpawnToken { @@ -394,8 +389,7 @@ impl SyncExecutor { #[cfg(feature = "integrated-timers")] task.expires_at.set(Instant::MAX); - let state = task.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); - if state & STATE_SPAWNED == 0 { + if !task.state.run_dequeue() { // If task is not running, ignore it. This can happen in the following scenario: // - Task gets dequeued, poll starts // - While task is being polled, it gets woken. It gets placed in the queue. @@ -546,18 +540,7 @@ impl Executor { /// You can obtain a `TaskRef` from a `Waker` using [`task_from_waker`]. pub fn wake_task(task: TaskRef) { let header = task.header(); - - let res = header.state.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| { - // If already scheduled, or if not started, - if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) { - None - } else { - // Mark it as scheduled - Some(state | STATE_RUN_QUEUED) - } - }); - - if res.is_ok() { + if header.state.run_enqueue() { // We have just marked the task as scheduled, so enqueue it. unsafe { let executor = header.executor.get().unwrap_unchecked(); @@ -571,18 +554,7 @@ pub fn wake_task(task: TaskRef) { /// You can obtain a `TaskRef` from a `Waker` using [`task_from_waker`]. pub fn wake_task_no_pend(task: TaskRef) { let header = task.header(); - - let res = header.state.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| { - // If already scheduled, or if not started, - if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) { - None - } else { - // Mark it as scheduled - Some(state | STATE_RUN_QUEUED) - } - }); - - if res.is_ok() { + if header.state.run_enqueue() { // We have just marked the task as scheduled, so enqueue it. unsafe { let executor = header.executor.get().unwrap_unchecked(); diff --git a/embassy-executor/src/raw/run_queue.rs b/embassy-executor/src/raw/run_queue_atomics.rs similarity index 98% rename from embassy-executor/src/raw/run_queue.rs rename to embassy-executor/src/raw/run_queue_atomics.rs index f1ec19ac..90907cfd 100644 --- a/embassy-executor/src/raw/run_queue.rs +++ b/embassy-executor/src/raw/run_queue_atomics.rs @@ -1,7 +1,6 @@ use core::ptr; use core::ptr::NonNull; - -use atomic_polyfill::{AtomicPtr, Ordering}; +use core::sync::atomic::{AtomicPtr, Ordering}; use super::{TaskHeader, TaskRef}; use crate::raw::util::SyncUnsafeCell; diff --git a/embassy-executor/src/raw/run_queue_critical_section.rs b/embassy-executor/src/raw/run_queue_critical_section.rs new file mode 100644 index 00000000..ba59c8f2 --- /dev/null +++ b/embassy-executor/src/raw/run_queue_critical_section.rs @@ -0,0 +1,75 @@ +use core::cell::Cell; + +use critical_section::{CriticalSection, Mutex}; + +use super::TaskRef; + +pub(crate) struct RunQueueItem { + next: Mutex>>, +} + +impl RunQueueItem { + pub const fn new() -> Self { + Self { + next: Mutex::new(Cell::new(None)), + } + } +} + +/// Atomic task queue using a very, very simple lock-free linked-list queue: +/// +/// To enqueue a task, task.next is set to the old head, and head is atomically set to task. +/// +/// Dequeuing is done in batches: the queue is emptied by atomically replacing head with +/// null. Then the batch is iterated following the next pointers until null is reached. +/// +/// Note that batches will be iterated in the reverse order as they were enqueued. This is OK +/// for our purposes: it can't create fairness problems since the next batch won't run until the +/// current batch is completely processed, so even if a task enqueues itself instantly (for example +/// by waking its own waker) can't prevent other tasks from running. +pub(crate) struct RunQueue { + head: Mutex>>, +} + +impl RunQueue { + pub const fn new() -> Self { + Self { + head: Mutex::new(Cell::new(None)), + } + } + + /// Enqueues an item. Returns true if the queue was empty. + /// + /// # Safety + /// + /// `item` must NOT be already enqueued in any queue. + #[inline(always)] + pub(crate) unsafe fn enqueue(&self, task: TaskRef) -> bool { + critical_section::with(|cs| { + let prev = self.head.borrow(cs).replace(Some(task)); + task.header().run_queue_item.next.borrow(cs).set(prev); + + prev.is_none() + }) + } + + /// Empty the queue, then call `on_task` for each task that was in the queue. + /// NOTE: It is OK for `on_task` to enqueue more tasks. In this case they're left in the queue + /// and will be processed by the *next* call to `dequeue_all`, *not* the current one. + pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { + // Atomically empty the queue. + let mut next = critical_section::with(|cs| self.head.borrow(cs).take()); + + // Iterate the linked list of tasks that were previously in the queue. + while let Some(task) = next { + // If the task re-enqueues itself, the `next` pointer will get overwritten. + // Therefore, first read the next pointer, and only then process the task. + + // safety: we know if the task is enqueued, no one else will touch the `next` pointer. + let cs = unsafe { CriticalSection::new() }; + next = task.header().run_queue_item.next.borrow(cs).get(); + + on_task(task); + } + } +} diff --git a/embassy-executor/src/raw/state_atomics.rs b/embassy-executor/src/raw/state_atomics.rs new file mode 100644 index 00000000..e1279ac0 --- /dev/null +++ b/embassy-executor/src/raw/state_atomics.rs @@ -0,0 +1,73 @@ +use core::sync::atomic::{AtomicU32, Ordering}; + +/// Task is spawned (has a future) +pub(crate) const STATE_SPAWNED: u32 = 1 << 0; +/// Task is in the executor run queue +pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; +/// Task is in the executor timer queue +#[cfg(feature = "integrated-timers")] +pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; + +pub(crate) struct State { + state: AtomicU32, +} + +impl State { + pub const fn new() -> State { + Self { + state: AtomicU32::new(0), + } + } + + /// If task is idle, mark it as spawned + run_queued and return true. + #[inline(always)] + pub fn spawn(&self) -> bool { + self.state + .compare_exchange(0, STATE_SPAWNED | STATE_RUN_QUEUED, Ordering::AcqRel, Ordering::Acquire) + .is_ok() + } + + /// Unmark the task as spawned. + #[inline(always)] + pub fn despawn(&self) { + self.state.fetch_and(!STATE_SPAWNED, Ordering::AcqRel); + } + + /// Mark the task as run-queued if it's spawned and isn't already run-queued. Return true on success. + #[inline(always)] + pub fn run_enqueue(&self) -> bool { + self.state + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| { + // If already scheduled, or if not started, + if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) { + None + } else { + // Mark it as scheduled + Some(state | STATE_RUN_QUEUED) + } + }) + .is_ok() + } + + /// Unmark the task as run-queued. Return whether the task is spawned. + #[inline(always)] + pub fn run_dequeue(&self) -> bool { + let state = self.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); + state & STATE_SPAWNED != 0 + } + + /// Mark the task as timer-queued. Return whether it was newly queued (i.e. not queued before) + #[cfg(feature = "integrated-timers")] + #[inline(always)] + pub fn timer_enqueue(&self) -> bool { + let old_state = self.state.fetch_or(STATE_TIMER_QUEUED, Ordering::AcqRel); + old_state & STATE_TIMER_QUEUED == 0 + } + + /// Unmark the task as timer-queued. + #[cfg(feature = "integrated-timers")] + #[inline(always)] + pub fn timer_dequeue(&self) { + self.state.fetch_and(!STATE_TIMER_QUEUED, Ordering::AcqRel); + } +} diff --git a/embassy-executor/src/raw/state_critical_section.rs b/embassy-executor/src/raw/state_critical_section.rs new file mode 100644 index 00000000..c3cc1b0b --- /dev/null +++ b/embassy-executor/src/raw/state_critical_section.rs @@ -0,0 +1,93 @@ +use core::cell::Cell; + +use critical_section::Mutex; + +/// Task is spawned (has a future) +pub(crate) const STATE_SPAWNED: u32 = 1 << 0; +/// Task is in the executor run queue +pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; +/// Task is in the executor timer queue +#[cfg(feature = "integrated-timers")] +pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; + +pub(crate) struct State { + state: Mutex>, +} + +impl State { + pub const fn new() -> State { + Self { + state: Mutex::new(Cell::new(0)), + } + } + + fn update(&self, f: impl FnOnce(&mut u32) -> R) -> R { + critical_section::with(|cs| { + let s = self.state.borrow(cs); + let mut val = s.get(); + let r = f(&mut val); + s.set(val); + r + }) + } + + /// If task is idle, mark it as spawned + run_queued and return true. + #[inline(always)] + pub fn spawn(&self) -> bool { + self.update(|s| { + if *s == 0 { + *s = STATE_SPAWNED | STATE_RUN_QUEUED; + true + } else { + false + } + }) + } + + /// Unmark the task as spawned. + #[inline(always)] + pub fn despawn(&self) { + self.update(|s| *s &= !STATE_SPAWNED); + } + + /// Mark the task as run-queued if it's spawned and isn't already run-queued. Return true on success. + #[inline(always)] + pub fn run_enqueue(&self) -> bool { + self.update(|s| { + if (*s & STATE_RUN_QUEUED != 0) || (*s & STATE_SPAWNED == 0) { + false + } else { + *s |= STATE_RUN_QUEUED; + true + } + }) + } + + /// Unmark the task as run-queued. Return whether the task is spawned. + #[inline(always)] + pub fn run_dequeue(&self) -> bool { + self.update(|s| { + let ok = *s & STATE_SPAWNED != 0; + *s &= !STATE_RUN_QUEUED; + ok + }) + } + + /// Mark the task as timer-queued. Return whether it was newly queued (i.e. not queued before) + #[cfg(feature = "integrated-timers")] + #[inline(always)] + pub fn timer_enqueue(&self) -> bool { + self.update(|s| { + let ok = *s & STATE_TIMER_QUEUED == 0; + *s |= STATE_TIMER_QUEUED; + ok + }) + } + + /// Unmark the task as timer-queued. + #[cfg(feature = "integrated-timers")] + #[inline(always)] + pub fn timer_dequeue(&self) { + self.update(|s| *s &= !STATE_TIMER_QUEUED); + } +} diff --git a/embassy-executor/src/raw/timer_queue.rs b/embassy-executor/src/raw/timer_queue.rs index dc71c95b..59a3b43f 100644 --- a/embassy-executor/src/raw/timer_queue.rs +++ b/embassy-executor/src/raw/timer_queue.rs @@ -1,9 +1,8 @@ use core::cmp::min; -use atomic_polyfill::Ordering; use embassy_time::Instant; -use super::{TaskRef, STATE_TIMER_QUEUED}; +use super::TaskRef; use crate::raw::util::SyncUnsafeCell; pub(crate) struct TimerQueueItem { @@ -32,10 +31,7 @@ impl TimerQueue { pub(crate) unsafe fn update(&self, p: TaskRef) { let task = p.header(); if task.expires_at.get() != Instant::MAX { - let old_state = task.state.fetch_or(STATE_TIMER_QUEUED, Ordering::AcqRel); - let is_new = old_state & STATE_TIMER_QUEUED == 0; - - if is_new { + if task.state.timer_enqueue() { task.timer_queue_item.next.set(self.head.get()); self.head.set(Some(p)); } @@ -75,7 +71,7 @@ impl TimerQueue { } else { // Remove it prev.set(task.timer_queue_item.next.get()); - task.state.fetch_and(!STATE_TIMER_QUEUED, Ordering::AcqRel); + task.state.timer_dequeue(); } } } From 1f9b649f80b52323be3e16fff064e1aec77d5ae8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 14 Nov 2023 18:47:15 +0100 Subject: [PATCH 143/188] executor: release v0.3.3 --- embassy-executor/CHANGELOG.md | 2 +- embassy-executor/Cargo.toml | 2 +- embassy-rp/Cargo.toml | 2 +- embassy-stm32/Cargo.toml | 2 +- embassy-time/Cargo.toml | 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/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/stm32f334/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/riscv32/Cargo.toml | 2 +- tests/rp/Cargo.toml | 2 +- tests/stm32/Cargo.toml | 2 +- 44 files changed, 44 insertions(+), 44 deletions(-) diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index f45b2770..559717da 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/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). -## Unreleased +## 0.3.3 - 2023-11-15 - Add `main` macro reexport for Xtensa arch. - Remove use of `atomic-polyfill`. The executor now has multiple implementations of its internal data structures for cases where the target supports atomics or doesn't. diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 4945455d..3a623e99 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-executor" -version = "0.3.2" +version = "0.3.3" edition = "2021" license = "MIT OR Apache-2.0" description = "async/await executor designed for embedded usage" diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 6be9f4bb..eb79cfd3 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -94,5 +94,5 @@ pio = {version= "0.2.1" } rp2040-boot2 = "0.3" [dev-dependencies] -embassy-executor = { version = "0.3.1", path = "../embassy-executor", features = ["nightly", "arch-std", "executor-thread"] } +embassy-executor = { version = "0.3.3", path = "../embassy-executor", features = ["nightly", "arch-std", "executor-thread"] } static_cell = { version = "2" } diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 4b650cc8..65434cec 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -39,7 +39,7 @@ embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", fea embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } -embassy-executor = { version = "0.3.1", path = "../embassy-executor", optional = true } +embassy-executor = { version = "0.3.3", path = "../embassy-executor", optional = true } 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} diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 37b79d0c..3cabb237 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -258,4 +258,4 @@ wasm-timer = { version = "0.2.5", optional = true } [dev-dependencies] serial_test = "0.9" critical-section = { version = "1.1", features = ["std"] } -embassy-executor = { version = "0.3.1", path = "../embassy-executor", features = ["nightly"] } +embassy-executor = { version = "0.3.3", path = "../embassy-executor", features = ["nightly"] } diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 98c15b1a..8489be5a 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 061e7b86..e22d0c89 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index f15467b0..c9cecd65 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index 80ff485d..7464adcb 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index 29b5e202..887c53b8 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index 8d4ec07b..5a2492f0 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 4a937999..148adc11 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index 1c8b15f8..27e1ff9a 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index eaa17de2..7f57eb88 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index e1bb00b1..e30b13f2 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -17,7 +17,7 @@ log = [ [dependencies] embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time" } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 7bf904ee..df5b1f3b 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -30,7 +30,7 @@ nightly = [ [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 4196d61a..032ec980 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -9,7 +9,7 @@ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = [ "defmt", ] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "defmt", "integrated-timers", diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index b2383634..7e752bad 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index ee35ef49..75ed74b5 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["log"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["log", "std", "nightly"] } embassy-net = { version = "0.2.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" } diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index 9824aa95..ec5b78b0 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32c031c6 to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 3f781d76..71b3aaa7 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -15,7 +15,7 @@ defmt = "0.3" defmt-rtt = "0.4" panic-probe = "0.3" embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } static_cell = { version = "2", features = ["nightly"]} portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index dbe09757..29483ec5 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f103c8 to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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 6eb883ac..f4262e20 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f207zg to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 96096f79..e556b2a4 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f303ze to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml index 344409ce..e9670ab0 100644 --- a/examples/stm32f334/Cargo.toml +++ b/examples/stm32f334/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 2ef044d0..772d873c 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f429zi to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index f451eb48..d418f813 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f767zi to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } embedded-io-async = { version = "0.6.0" } diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 8c25406c..437f1e75 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32g071rb to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index abca22f2..f5b2ab32 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32g491re to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index 4d3bf0b8..e8d17cee 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32h563zi to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } embedded-io-async = { version = "0.6.0" } diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 77b026d4..05523d00 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # 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", "chrono"] } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } embedded-io-async = { version = "0.6.0" } diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index a5506469..2b89ac27 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -13,7 +13,7 @@ nightly = ["embassy-stm32/nightly", "embassy-time/nightly", "embassy-time/unstab # Change stm32l072cz to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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 } diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index b9d88884..f8f5c776 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 66f9ce71..f4eaf647 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32l4s5vi to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 5ba95313..1b9b026f 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32l552ze to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 07dc88d7..3d316ab3 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32u585ai to your chip name, if necessary. embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 132823a8..19fdeb6f 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 04136f4f..cac6753c 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index bf2e7f07..645ca84d 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32wl55jc-cm4 to your chip name, if necessary. 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.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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"] } diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index a7250cb7..c6e95e61 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["log"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } wasm-logger = "0.2.0" diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index a3393f7e..76f94238 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -9,7 +9,7 @@ teleprobe-meta = "1" embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt", "nightly"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } embassy-time = { version = "0.1.5", 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", features = ["defmt-03"] } diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index 56db42dd..24597a03 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] critical-section = { version = "1.1.1", features = ["restore-state-bool"] } embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] } embassy-time = { version = "0.1.5", path = "../../embassy-time" } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 1bf149c9..1629cc8b 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" teleprobe-meta = "1.1" embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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" } diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 9b9273a5..ab701616 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -48,7 +48,7 @@ cm0 = ["portable-atomic/unsafe-assume-single-core"] teleprobe-meta = "1" embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.5", 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" } From 27e6634c9d7ddde5e4387416db94bdccf649ac2e Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 15 Nov 2023 01:19:32 +0100 Subject: [PATCH 144/188] executor: add faster ARM-specific impl. Does a wake+poll in 79 cycles in nrf52840. --- embassy-executor/src/raw/mod.rs | 3 +- embassy-executor/src/raw/state_atomics_arm.rs | 103 ++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 embassy-executor/src/raw/state_atomics_arm.rs diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index ed0bedd2..e9137f8f 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -11,7 +11,8 @@ #[cfg_attr(not(target_has_atomic = "ptr"), path = "run_queue_critical_section.rs")] mod run_queue; -#[cfg_attr(target_has_atomic = "8", path = "state_atomics.rs")] +#[cfg_attr(all(cortex_m, target_has_atomic = "8"), path = "state_atomics_arm.rs")] +#[cfg_attr(all(not(cortex_m), target_has_atomic = "8"), path = "state_atomics.rs")] #[cfg_attr(not(target_has_atomic = "8"), path = "state_critical_section.rs")] mod state; diff --git a/embassy-executor/src/raw/state_atomics_arm.rs b/embassy-executor/src/raw/state_atomics_arm.rs new file mode 100644 index 00000000..e4dfe509 --- /dev/null +++ b/embassy-executor/src/raw/state_atomics_arm.rs @@ -0,0 +1,103 @@ +use core::arch::asm; +use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU32, Ordering}; + +// Must be kept in sync with the layout of `State`! +pub(crate) const STATE_SPAWNED: u32 = 1 << 0; +pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 8; + +#[repr(C, align(4))] +pub(crate) struct State { + /// Task is spawned (has a future) + spawned: AtomicBool, + /// Task is in the executor run queue + run_queued: AtomicBool, + /// Task is in the executor timer queue + timer_queued: AtomicBool, + pad: AtomicBool, +} + +impl State { + pub const fn new() -> State { + Self { + spawned: AtomicBool::new(false), + run_queued: AtomicBool::new(false), + timer_queued: AtomicBool::new(false), + pad: AtomicBool::new(false), + } + } + + fn as_u32(&self) -> &AtomicU32 { + unsafe { &*(self as *const _ as *const AtomicU32) } + } + + /// If task is idle, mark it as spawned + run_queued and return true. + #[inline(always)] + pub fn spawn(&self) -> bool { + compiler_fence(Ordering::Release); + let r = self + .as_u32() + .compare_exchange( + 0, + STATE_SPAWNED | STATE_RUN_QUEUED, + Ordering::Relaxed, + Ordering::Relaxed, + ) + .is_ok(); + compiler_fence(Ordering::Acquire); + r + } + + /// Unmark the task as spawned. + #[inline(always)] + pub fn despawn(&self) { + compiler_fence(Ordering::Release); + self.spawned.store(false, Ordering::Relaxed); + } + + /// Mark the task as run-queued if it's spawned and isn't already run-queued. Return true on success. + #[inline(always)] + pub fn run_enqueue(&self) -> bool { + unsafe { + loop { + let state: u32; + asm!("ldrex {}, [{}]", out(reg) state, in(reg) self, options(nostack)); + + if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) { + asm!("clrex", options(nomem, nostack)); + return false; + } + + let outcome: usize; + let new_state = state | STATE_RUN_QUEUED; + asm!("strex {}, {}, [{}]", out(reg) outcome, in(reg) new_state, in(reg) self, options(nostack)); + if outcome == 0 { + return true; + } + } + } + } + + /// Unmark the task as run-queued. Return whether the task is spawned. + #[inline(always)] + pub fn run_dequeue(&self) -> bool { + compiler_fence(Ordering::Release); + + let r = self.spawned.load(Ordering::Relaxed); + self.run_queued.store(false, Ordering::Relaxed); + r + } + + /// Mark the task as timer-queued. Return whether it was newly queued (i.e. not queued before) + #[cfg(feature = "integrated-timers")] + #[inline(always)] + pub fn timer_enqueue(&self) -> bool { + !self.timer_queued.swap(true, Ordering::Relaxed) + } + + /// Unmark the task as timer-queued. + #[cfg(feature = "integrated-timers")] + #[inline(always)] + pub fn timer_dequeue(&self) { + self.timer_queued.store(false, Ordering::Relaxed); + } +} From e3ee24017d35834648ac07b2c6df446ee71a49bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C4=8Cavoj?= Date: Tue, 14 Nov 2023 01:44:42 +0000 Subject: [PATCH 145/188] cyw43: Add Control method to add multicast HW address --- cyw43/src/control.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++ cyw43/src/lib.rs | 2 +- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index ffcf2d9b..826edfe1 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs @@ -1,4 +1,5 @@ use core::cmp::{max, min}; +use core::iter::zip; use embassy_net_driver_channel as ch; use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; @@ -16,6 +17,12 @@ pub struct Error { pub status: u32, } +#[derive(Debug)] +pub enum AddMulticastAddressError { + NotMulticast, + NoFreeSlots, +} + pub struct Control<'a> { state_ch: ch::StateRunner<'a>, events: &'a Events, @@ -316,6 +323,54 @@ impl<'a> Control<'a> { self.set_iovar_u32x2("bss", 0, 1).await; // bss = BSS_UP } + /// Add specified address to the list of hardware addresses the device + /// listens on. The address must be a Group address (I/G bit set). Up + /// to 10 addresses are supported by the firmware. Returns the number of + /// address slots filled after adding, or an error. + pub async fn add_multicast_address(&mut self, address: [u8; 6]) -> Result { + // The firmware seems to ignore non-multicast addresses, so let's + // prevent the user from adding them and wasting space. + if address[0] & 0x01 != 1 { + return Err(AddMulticastAddressError::NotMulticast); + } + + let mut buf = [0; 64]; + self.get_iovar("mcast_list", &mut buf).await; + + let n = u32::from_le_bytes(buf[..4].try_into().unwrap()) as usize; + let (used, free) = buf[4..].split_at_mut(n * 6); + + if used.chunks(6).any(|a| a == address) { + return Ok(n); + } + + if free.len() < 6 { + return Err(AddMulticastAddressError::NoFreeSlots); + } + + free[..6].copy_from_slice(&address); + let n = n + 1; + buf[..4].copy_from_slice(&(n as u32).to_le_bytes()); + + self.set_iovar_v::<80>("mcast_list", &buf).await; + Ok(n) + } + + /// Retrieve the list of configured multicast hardware addresses. + pub async fn list_mulistcast_addresses(&mut self, result: &mut [[u8; 6]; 10]) -> usize { + let mut buf = [0; 64]; + self.get_iovar("mcast_list", &mut buf).await; + + let n = u32::from_le_bytes(buf[..4].try_into().unwrap()) as usize; + let used = &buf[4..][..n * 6]; + + for (addr, output) in zip(used.chunks(6), result.iter_mut()) { + output.copy_from_slice(addr) + } + + n + } + async fn set_iovar_u32x2(&mut self, name: &str, val1: u32, val2: u32) { let mut buf = [0; 8]; buf[0..4].copy_from_slice(&val1.to_le_bytes()); diff --git a/cyw43/src/lib.rs b/cyw43/src/lib.rs index e60f87d0..04847bfa 100644 --- a/cyw43/src/lib.rs +++ b/cyw43/src/lib.rs @@ -27,7 +27,7 @@ use ioctl::IoctlState; use crate::bus::Bus; pub use crate::bus::SpiBusCyw43; -pub use crate::control::{Control, Error as ControlError, Scanner}; +pub use crate::control::{AddMulticastAddressError, Control, Error as ControlError, Scanner}; pub use crate::runner::Runner; pub use crate::structs::BssInfo; From 4947b136156e923447456edd8a28fe391e158dcd Mon Sep 17 00:00:00 2001 From: RobertTDowling Date: Wed, 15 Nov 2023 17:11:16 -0800 Subject: [PATCH 146/188] stm32h7 ADC: Fix stalled clock in default h7 config --- embassy-stm32/src/rcc/h.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 4407d9e9..bdae850f 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -168,7 +168,12 @@ impl Default for Config { apb4_pre: APBPrescaler::DIV1, per_clock_source: PerClockSource::HSI, - adc_clock_source: AdcClockSource::from_bits(0), // PLL2_P on H7, HCLK on H5 + + #[cfg(stm32h5)] + adc_clock_source: AdcClockSource::from_bits(0), // HCLK on H5 + #[cfg(stm32h7)] + adc_clock_source: AdcClockSource::from_bits(2), // PCLK on H7 + timer_prescaler: TimerPrescaler::DefaultX2, voltage_scale: VoltageScale::Scale0, ls: Default::default(), From ca0d02933b2551e89f0862493be217d1fb9097f1 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Sat, 18 Nov 2023 14:21:43 +0000 Subject: [PATCH 147/188] Priority channel using binary heap --- embassy-sync/src/lib.rs | 1 + embassy-sync/src/priority_channel.rs | 744 +++++++++++++++++++++++++++ 2 files changed, 745 insertions(+) create mode 100644 embassy-sync/src/priority_channel.rs diff --git a/embassy-sync/src/lib.rs b/embassy-sync/src/lib.rs index c40fa3b6..3ffcb913 100644 --- a/embassy-sync/src/lib.rs +++ b/embassy-sync/src/lib.rs @@ -15,6 +15,7 @@ pub mod blocking_mutex; pub mod channel; pub mod mutex; pub mod pipe; +pub mod priority_channel; pub mod pubsub; pub mod signal; pub mod waitqueue; diff --git a/embassy-sync/src/priority_channel.rs b/embassy-sync/src/priority_channel.rs new file mode 100644 index 00000000..04148b56 --- /dev/null +++ b/embassy-sync/src/priority_channel.rs @@ -0,0 +1,744 @@ +//! A queue for sending values between asynchronous tasks. +//! +//! Similar to a [`Channel`](crate::channel::Channel), however [`PriorityChannel`] sifts higher priority items to the front of the queue. + +use core::cell::RefCell; +use core::future::Future; +use core::pin::Pin; +use core::task::{Context, Poll}; + +use heapless::BinaryHeap; + +use crate::blocking_mutex::raw::RawMutex; +use crate::blocking_mutex::Mutex; +use crate::waitqueue::WakerRegistration; + +/// Send-only access to a [`PriorityChannel`]. +pub struct Sender<'ch, M, T, K, const N: usize> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + channel: &'ch PriorityChannel, +} + +impl<'ch, M, T, K, const N: usize> Clone for Sender<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + fn clone(&self) -> Self { + Sender { channel: self.channel } + } +} + +impl<'ch, M, T, K, const N: usize> Copy for Sender<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ +} + +impl<'ch, M, T, K, const N: usize> Sender<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + /// Sends a value. + /// + /// See [`PriorityChannel::send()`] + pub fn send(&self, message: T) -> SendFuture<'ch, M, T, K, N> { + self.channel.send(message) + } + + /// Attempt to immediately send a message. + /// + /// See [`PriorityChannel::send()`] + pub fn try_send(&self, message: T) -> Result<(), TrySendError> { + self.channel.try_send(message) + } + + /// Allows a poll_fn to poll until the channel is ready to send + /// + /// See [`PriorityChannel::poll_ready_to_send()`] + pub fn poll_ready_to_send(&self, cx: &mut Context<'_>) -> Poll<()> { + self.channel.poll_ready_to_send(cx) + } +} + +/// Send-only access to a [`PriorityChannel`] without knowing channel size. +pub struct DynamicSender<'ch, T> { + channel: &'ch dyn DynamicChannel, +} + +impl<'ch, T> Clone for DynamicSender<'ch, T> { + fn clone(&self) -> Self { + DynamicSender { channel: self.channel } + } +} + +impl<'ch, T> Copy for DynamicSender<'ch, T> {} + +impl<'ch, M, T, K, const N: usize> From> for DynamicSender<'ch, T> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + fn from(s: Sender<'ch, M, T, K, N>) -> Self { + Self { channel: s.channel } + } +} + +impl<'ch, T> DynamicSender<'ch, T> { + /// Sends a value. + /// + /// See [`PriorityChannel::send()`] + pub fn send(&self, message: T) -> DynamicSendFuture<'ch, T> { + DynamicSendFuture { + channel: self.channel, + message: Some(message), + } + } + + /// Attempt to immediately send a message. + /// + /// See [`PriorityChannel::send()`] + pub fn try_send(&self, message: T) -> Result<(), TrySendError> { + self.channel.try_send_with_context(message, None) + } + + /// Allows a poll_fn to poll until the channel is ready to send + /// + /// See [`PriorityChannel::poll_ready_to_send()`] + pub fn poll_ready_to_send(&self, cx: &mut Context<'_>) -> Poll<()> { + self.channel.poll_ready_to_send(cx) + } +} + +/// Receive-only access to a [`PriorityChannel`]. +pub struct Receiver<'ch, M, T, K, const N: usize> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + channel: &'ch PriorityChannel, +} + +impl<'ch, M, T, K, const N: usize> Clone for Receiver<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + fn clone(&self) -> Self { + Receiver { channel: self.channel } + } +} + +impl<'ch, M, T, K, const N: usize> Copy for Receiver<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ +} + +impl<'ch, M, T, K, const N: usize> Receiver<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + /// Receive the next value. + /// + /// See [`PriorityChannel::receive()`]. + pub fn receive(&self) -> ReceiveFuture<'_, M, T, K, N> { + self.channel.receive() + } + + /// Attempt to immediately receive the next value. + /// + /// See [`PriorityChannel::try_receive()`] + pub fn try_receive(&self) -> Result { + self.channel.try_receive() + } + + /// Allows a poll_fn to poll until the channel is ready to receive + /// + /// See [`PriorityChannel::poll_ready_to_receive()`] + pub fn poll_ready_to_receive(&self, cx: &mut Context<'_>) -> Poll<()> { + self.channel.poll_ready_to_receive(cx) + } + + /// Poll the channel for the next item + /// + /// See [`PriorityChannel::poll_receive()`] + pub fn poll_receive(&self, cx: &mut Context<'_>) -> Poll { + self.channel.poll_receive(cx) + } +} + +/// Receive-only access to a [`PriorityChannel`] without knowing channel size. +pub struct DynamicReceiver<'ch, T> { + channel: &'ch dyn DynamicChannel, +} + +impl<'ch, T> Clone for DynamicReceiver<'ch, T> { + fn clone(&self) -> Self { + DynamicReceiver { channel: self.channel } + } +} + +impl<'ch, T> Copy for DynamicReceiver<'ch, T> {} + +impl<'ch, T> DynamicReceiver<'ch, T> { + /// Receive the next value. + /// + /// See [`PriorityChannel::receive()`]. + pub fn receive(&self) -> DynamicReceiveFuture<'_, T> { + DynamicReceiveFuture { channel: self.channel } + } + + /// Attempt to immediately receive the next value. + /// + /// See [`PriorityChannel::try_receive()`] + pub fn try_receive(&self) -> Result { + self.channel.try_receive_with_context(None) + } + + /// Allows a poll_fn to poll until the channel is ready to receive + /// + /// See [`PriorityChannel::poll_ready_to_receive()`] + pub fn poll_ready_to_receive(&self, cx: &mut Context<'_>) -> Poll<()> { + self.channel.poll_ready_to_receive(cx) + } + + /// Poll the channel for the next item + /// + /// See [`PriorityChannel::poll_receive()`] + pub fn poll_receive(&self, cx: &mut Context<'_>) -> Poll { + self.channel.poll_receive(cx) + } +} + +impl<'ch, M, T, K, const N: usize> From> for DynamicReceiver<'ch, T> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + fn from(s: Receiver<'ch, M, T, K, N>) -> Self { + Self { channel: s.channel } + } +} + +/// Future returned by [`PriorityChannel::receive`] and [`Receiver::receive`]. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct ReceiveFuture<'ch, M, T, K, const N: usize> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + channel: &'ch PriorityChannel, +} + +impl<'ch, M, T, K, const N: usize> Future for ReceiveFuture<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + type Output = T; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.channel.poll_receive(cx) + } +} + +/// Future returned by [`DynamicReceiver::receive`]. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct DynamicReceiveFuture<'ch, T> { + channel: &'ch dyn DynamicChannel, +} + +impl<'ch, T> Future for DynamicReceiveFuture<'ch, T> { + type Output = T; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.channel.try_receive_with_context(Some(cx)) { + Ok(v) => Poll::Ready(v), + Err(TryReceiveError::Empty) => Poll::Pending, + } + } +} + +/// Future returned by [`PriorityChannel::send`] and [`Sender::send`]. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct SendFuture<'ch, M, T, K, const N: usize> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + channel: &'ch PriorityChannel, + message: Option, +} + +impl<'ch, M, T, K, const N: usize> Future for SendFuture<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.message.take() { + Some(m) => match self.channel.try_send_with_context(m, Some(cx)) { + Ok(..) => Poll::Ready(()), + Err(TrySendError::Full(m)) => { + self.message = Some(m); + Poll::Pending + } + }, + None => panic!("Message cannot be None"), + } + } +} + +impl<'ch, M, T, K, const N: usize> Unpin for SendFuture<'ch, M, T, K, N> +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ +} + +/// Future returned by [`DynamicSender::send`]. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct DynamicSendFuture<'ch, T> { + channel: &'ch dyn DynamicChannel, + message: Option, +} + +impl<'ch, T> Future for DynamicSendFuture<'ch, T> { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.message.take() { + Some(m) => match self.channel.try_send_with_context(m, Some(cx)) { + Ok(..) => Poll::Ready(()), + Err(TrySendError::Full(m)) => { + self.message = Some(m); + Poll::Pending + } + }, + None => panic!("Message cannot be None"), + } + } +} + +impl<'ch, T> Unpin for DynamicSendFuture<'ch, T> {} + +trait DynamicChannel { + fn try_send_with_context(&self, message: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError>; + + fn try_receive_with_context(&self, cx: Option<&mut Context<'_>>) -> Result; + + fn poll_ready_to_send(&self, cx: &mut Context<'_>) -> Poll<()>; + fn poll_ready_to_receive(&self, cx: &mut Context<'_>) -> Poll<()>; + + fn poll_receive(&self, cx: &mut Context<'_>) -> Poll; +} + +/// Error returned by [`try_receive`](PriorityChannel::try_receive). +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TryReceiveError { + /// A message could not be received because the channel is empty. + Empty, +} + +/// Error returned by [`try_send`](PriorityChannel::try_send). +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TrySendError { + /// The data could not be sent on the channel because the channel is + /// currently full and sending would require blocking. + Full(T), +} + +struct ChannelState { + queue: BinaryHeap, + receiver_waker: WakerRegistration, + senders_waker: WakerRegistration, +} + +impl ChannelState +where + T: Ord, + K: heapless::binary_heap::Kind, +{ + const fn new() -> Self { + ChannelState { + queue: BinaryHeap::new(), + receiver_waker: WakerRegistration::new(), + senders_waker: WakerRegistration::new(), + } + } + + fn try_receive(&mut self) -> Result { + self.try_receive_with_context(None) + } + + fn try_receive_with_context(&mut self, cx: Option<&mut Context<'_>>) -> Result { + if self.queue.len() == self.queue.capacity() { + self.senders_waker.wake(); + } + + if let Some(message) = self.queue.pop() { + Ok(message) + } else { + if let Some(cx) = cx { + self.receiver_waker.register(cx.waker()); + } + Err(TryReceiveError::Empty) + } + } + + fn poll_receive(&mut self, cx: &mut Context<'_>) -> Poll { + if self.queue.len() == self.queue.capacity() { + self.senders_waker.wake(); + } + + if let Some(message) = self.queue.pop() { + Poll::Ready(message) + } else { + self.receiver_waker.register(cx.waker()); + Poll::Pending + } + } + + fn poll_ready_to_receive(&mut self, cx: &mut Context<'_>) -> Poll<()> { + self.receiver_waker.register(cx.waker()); + + if !self.queue.is_empty() { + Poll::Ready(()) + } else { + Poll::Pending + } + } + + fn try_send(&mut self, message: T) -> Result<(), TrySendError> { + self.try_send_with_context(message, None) + } + + fn try_send_with_context(&mut self, message: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError> { + match self.queue.push(message) { + Ok(()) => { + self.receiver_waker.wake(); + Ok(()) + } + Err(message) => { + if let Some(cx) = cx { + self.senders_waker.register(cx.waker()); + } + Err(TrySendError::Full(message)) + } + } + } + + fn poll_ready_to_send(&mut self, cx: &mut Context<'_>) -> Poll<()> { + self.senders_waker.register(cx.waker()); + + if !self.queue.len() == self.queue.capacity() { + Poll::Ready(()) + } else { + Poll::Pending + } + } +} + +/// A bounded channel for communicating between asynchronous tasks +/// with backpressure. +/// +/// The channel will buffer up to the provided number of messages. Once the +/// buffer is full, attempts to `send` new messages will wait until a message is +/// received from the channel. +/// +/// All data sent will become available in the same order as it was sent. +pub struct PriorityChannel +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + inner: Mutex>>, +} + +impl PriorityChannel +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + /// Establish a new bounded channel. For example, to create one with a NoopMutex: + /// + /// ``` + /// use embassy_sync::channel::PriorityChannel; + /// use embassy_sync::blocking_mutex::raw::NoopRawMutex; + /// + /// // Declare a bounded channel of 3 u32s. + /// let mut channel = PriorityChannel::::new(); + /// ``` + pub const fn new() -> Self { + Self { + inner: Mutex::new(RefCell::new(ChannelState::new())), + } + } + + fn lock(&self, f: impl FnOnce(&mut ChannelState) -> R) -> R { + self.inner.lock(|rc| f(&mut *unwrap!(rc.try_borrow_mut()))) + } + + fn try_receive_with_context(&self, cx: Option<&mut Context<'_>>) -> Result { + self.lock(|c| c.try_receive_with_context(cx)) + } + + /// Poll the channel for the next message + pub fn poll_receive(&self, cx: &mut Context<'_>) -> Poll { + self.lock(|c| c.poll_receive(cx)) + } + + fn try_send_with_context(&self, m: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError> { + self.lock(|c| c.try_send_with_context(m, cx)) + } + + /// Allows a poll_fn to poll until the channel is ready to receive + pub fn poll_ready_to_receive(&self, cx: &mut Context<'_>) -> Poll<()> { + self.lock(|c| c.poll_ready_to_receive(cx)) + } + + /// Allows a poll_fn to poll until the channel is ready to send + pub fn poll_ready_to_send(&self, cx: &mut Context<'_>) -> Poll<()> { + self.lock(|c| c.poll_ready_to_send(cx)) + } + + /// Get a sender for this channel. + pub fn sender(&self) -> Sender<'_, M, T, K, N> { + Sender { channel: self } + } + + /// Get a receiver for this channel. + pub fn receiver(&self) -> Receiver<'_, M, T, K, N> { + Receiver { channel: self } + } + + /// Send a value, waiting until there is capacity. + /// + /// Sending completes when the value has been pushed to the channel's queue. + /// This doesn't mean the value has been received yet. + pub fn send(&self, message: T) -> SendFuture<'_, M, T, K, N> { + SendFuture { + channel: self, + message: Some(message), + } + } + + /// Attempt to immediately send a message. + /// + /// This method differs from [`send`](PriorityChannel::send) by returning immediately if the channel's + /// buffer is full, instead of waiting. + /// + /// # Errors + /// + /// If the channel capacity has been reached, i.e., the channel has `n` + /// buffered values where `n` is the argument passed to [`PriorityChannel`], then an + /// error is returned. + pub fn try_send(&self, message: T) -> Result<(), TrySendError> { + self.lock(|c| c.try_send(message)) + } + + /// Receive the next value. + /// + /// If there are no messages in the channel's buffer, this method will + /// wait until a message is sent. + pub fn receive(&self) -> ReceiveFuture<'_, M, T, K, N> { + ReceiveFuture { channel: self } + } + + /// Attempt to immediately receive a message. + /// + /// This method will either receive a message from the channel immediately or return an error + /// if the channel is empty. + pub fn try_receive(&self) -> Result { + self.lock(|c| c.try_receive()) + } +} + +/// Implements the DynamicChannel to allow creating types that are unaware of the queue size with the +/// tradeoff cost of dynamic dispatch. +impl DynamicChannel for PriorityChannel +where + T: Ord, + K: heapless::binary_heap::Kind, + M: RawMutex, +{ + fn try_send_with_context(&self, m: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError> { + PriorityChannel::try_send_with_context(self, m, cx) + } + + fn try_receive_with_context(&self, cx: Option<&mut Context<'_>>) -> Result { + PriorityChannel::try_receive_with_context(self, cx) + } + + fn poll_ready_to_send(&self, cx: &mut Context<'_>) -> Poll<()> { + PriorityChannel::poll_ready_to_send(self, cx) + } + + fn poll_ready_to_receive(&self, cx: &mut Context<'_>) -> Poll<()> { + PriorityChannel::poll_ready_to_receive(self, cx) + } + + fn poll_receive(&self, cx: &mut Context<'_>) -> Poll { + PriorityChannel::poll_receive(self, cx) + } +} + +#[cfg(test)] +mod tests { + use core::time::Duration; + + use futures_executor::ThreadPool; + use futures_timer::Delay; + use futures_util::task::SpawnExt; + use static_cell::StaticCell; + + use super::*; + use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; + + fn capacity(c: &ChannelState) -> usize { + c.queue.capacity() - c.queue.len() + } + + #[test] + fn sending_once() { + let mut c = ChannelState::::new(); + assert!(c.try_send(1).is_ok()); + assert_eq!(capacity(&c), 2); + } + + #[test] + fn sending_when_full() { + let mut c = ChannelState::::new(); + let _ = c.try_send(1); + let _ = c.try_send(1); + let _ = c.try_send(1); + match c.try_send(2) { + Err(TrySendError::Full(2)) => assert!(true), + _ => assert!(false), + } + assert_eq!(capacity(&c), 0); + } + + #[test] + fn receiving_once_with_one_send() { + let mut c = ChannelState::::new(); + assert!(c.try_send(1).is_ok()); + assert_eq!(c.try_receive().unwrap(), 1); + assert_eq!(capacity(&c), 3); + } + + #[test] + fn receiving_when_empty() { + let mut c = ChannelState::::new(); + match c.try_receive() { + Err(TryReceiveError::Empty) => assert!(true), + _ => assert!(false), + } + assert_eq!(capacity(&c), 3); + } + + #[test] + fn simple_send_and_receive() { + let c = PriorityChannel::::new(); + assert!(c.try_send(1).is_ok()); + assert_eq!(c.try_receive().unwrap(), 1); + } + + #[test] + fn cloning() { + let c = PriorityChannel::::new(); + let r1 = c.receiver(); + let s1 = c.sender(); + + let _ = r1.clone(); + let _ = s1.clone(); + } + + #[test] + fn dynamic_dispatch() { + let c = PriorityChannel::::new(); + let s: DynamicSender<'_, u32> = c.sender().into(); + let r: DynamicReceiver<'_, u32> = c.receiver().into(); + + assert!(s.try_send(1).is_ok()); + assert_eq!(r.try_receive().unwrap(), 1); + } + + #[futures_test::test] + async fn receiver_receives_given_try_send_async() { + let executor = ThreadPool::new().unwrap(); + + static CHANNEL: StaticCell> = StaticCell::new(); + let c = &*CHANNEL.init(PriorityChannel::new()); + let c2 = c; + assert!(executor + .spawn(async move { + assert!(c2.try_send(1).is_ok()); + }) + .is_ok()); + assert_eq!(c.receive().await, 1); + } + + #[futures_test::test] + async fn sender_send_completes_if_capacity() { + let c = PriorityChannel::::new(); + c.send(1).await; + assert_eq!(c.receive().await, 1); + } + + #[futures_test::test] + async fn senders_sends_wait_until_capacity() { + let executor = ThreadPool::new().unwrap(); + + static CHANNEL: StaticCell> = StaticCell::new(); + let c = &*CHANNEL.init(PriorityChannel::new()); + assert!(c.try_send(1).is_ok()); + + let c2 = c; + let send_task_1 = executor.spawn_with_handle(async move { c2.send(2).await }); + let c2 = c; + let send_task_2 = executor.spawn_with_handle(async move { c2.send(3).await }); + // Wish I could think of a means of determining that the async send is waiting instead. + // However, I've used the debugger to observe that the send does indeed wait. + Delay::new(Duration::from_millis(500)).await; + assert_eq!(c.receive().await, 1); + assert!(executor + .spawn(async move { + loop { + c.receive().await; + } + }) + .is_ok()); + send_task_1.unwrap().await; + send_task_2.unwrap().await; + } +} From 270ec324b0f4bdf400043bbb4023a32c6c7d94d4 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Sat, 18 Nov 2023 14:31:09 +0000 Subject: [PATCH 148/188] Reduce duplication, fix tests --- embassy-sync/src/channel.rs | 2 +- embassy-sync/src/priority_channel.rs | 100 +++++++++++---------------- 2 files changed, 41 insertions(+), 61 deletions(-) diff --git a/embassy-sync/src/channel.rs b/embassy-sync/src/channel.rs index a512e0c4..aa267471 100644 --- a/embassy-sync/src/channel.rs +++ b/embassy-sync/src/channel.rs @@ -321,7 +321,7 @@ impl<'ch, T> Future for DynamicSendFuture<'ch, T> { impl<'ch, T> Unpin for DynamicSendFuture<'ch, T> {} -trait DynamicChannel { +pub(crate) trait DynamicChannel { fn try_send_with_context(&self, message: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError>; fn try_receive_with_context(&self, cx: Option<&mut Context<'_>>) -> Result; diff --git a/embassy-sync/src/priority_channel.rs b/embassy-sync/src/priority_channel.rs index 04148b56..13c407c2 100644 --- a/embassy-sync/src/priority_channel.rs +++ b/embassy-sync/src/priority_channel.rs @@ -7,17 +7,19 @@ use core::future::Future; use core::pin::Pin; use core::task::{Context, Poll}; +use heapless::binary_heap::Kind; use heapless::BinaryHeap; use crate::blocking_mutex::raw::RawMutex; use crate::blocking_mutex::Mutex; +use crate::channel::{DynamicChannel, TryReceiveError, TrySendError}; use crate::waitqueue::WakerRegistration; /// Send-only access to a [`PriorityChannel`]. pub struct Sender<'ch, M, T, K, const N: usize> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { channel: &'ch PriorityChannel, @@ -26,7 +28,7 @@ where impl<'ch, M, T, K, const N: usize> Clone for Sender<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { fn clone(&self) -> Self { @@ -37,7 +39,7 @@ where impl<'ch, M, T, K, const N: usize> Copy for Sender<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { } @@ -45,7 +47,7 @@ where impl<'ch, M, T, K, const N: usize> Sender<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { /// Sends a value. @@ -86,7 +88,7 @@ impl<'ch, T> Copy for DynamicSender<'ch, T> {} impl<'ch, M, T, K, const N: usize> From> for DynamicSender<'ch, T> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { fn from(s: Sender<'ch, M, T, K, N>) -> Self { @@ -124,7 +126,7 @@ impl<'ch, T> DynamicSender<'ch, T> { pub struct Receiver<'ch, M, T, K, const N: usize> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { channel: &'ch PriorityChannel, @@ -133,7 +135,7 @@ where impl<'ch, M, T, K, const N: usize> Clone for Receiver<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { fn clone(&self) -> Self { @@ -144,7 +146,7 @@ where impl<'ch, M, T, K, const N: usize> Copy for Receiver<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { } @@ -152,7 +154,7 @@ where impl<'ch, M, T, K, const N: usize> Receiver<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { /// Receive the next value. @@ -230,7 +232,7 @@ impl<'ch, T> DynamicReceiver<'ch, T> { impl<'ch, M, T, K, const N: usize> From> for DynamicReceiver<'ch, T> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { fn from(s: Receiver<'ch, M, T, K, N>) -> Self { @@ -243,7 +245,7 @@ where pub struct ReceiveFuture<'ch, M, T, K, const N: usize> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { channel: &'ch PriorityChannel, @@ -252,7 +254,7 @@ where impl<'ch, M, T, K, const N: usize> Future for ReceiveFuture<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { type Output = T; @@ -284,7 +286,7 @@ impl<'ch, T> Future for DynamicReceiveFuture<'ch, T> { pub struct SendFuture<'ch, M, T, K, const N: usize> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { channel: &'ch PriorityChannel, @@ -294,7 +296,7 @@ where impl<'ch, M, T, K, const N: usize> Future for SendFuture<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { type Output = (); @@ -316,7 +318,7 @@ where impl<'ch, M, T, K, const N: usize> Unpin for SendFuture<'ch, M, T, K, N> where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { } @@ -347,34 +349,6 @@ impl<'ch, T> Future for DynamicSendFuture<'ch, T> { impl<'ch, T> Unpin for DynamicSendFuture<'ch, T> {} -trait DynamicChannel { - fn try_send_with_context(&self, message: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError>; - - fn try_receive_with_context(&self, cx: Option<&mut Context<'_>>) -> Result; - - fn poll_ready_to_send(&self, cx: &mut Context<'_>) -> Poll<()>; - fn poll_ready_to_receive(&self, cx: &mut Context<'_>) -> Poll<()>; - - fn poll_receive(&self, cx: &mut Context<'_>) -> Poll; -} - -/// Error returned by [`try_receive`](PriorityChannel::try_receive). -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum TryReceiveError { - /// A message could not be received because the channel is empty. - Empty, -} - -/// Error returned by [`try_send`](PriorityChannel::try_send). -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum TrySendError { - /// The data could not be sent on the channel because the channel is - /// currently full and sending would require blocking. - Full(T), -} - struct ChannelState { queue: BinaryHeap, receiver_waker: WakerRegistration, @@ -384,7 +358,7 @@ struct ChannelState { impl ChannelState where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, { const fn new() -> Self { ChannelState { @@ -477,7 +451,7 @@ where pub struct PriorityChannel where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { inner: Mutex>>, @@ -486,17 +460,18 @@ where impl PriorityChannel where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { /// Establish a new bounded channel. For example, to create one with a NoopMutex: /// /// ``` - /// use embassy_sync::channel::PriorityChannel; + /// # use heapless::binary_heap::Max; + /// use embassy_sync::priority_channel::PriorityChannel; /// use embassy_sync::blocking_mutex::raw::NoopRawMutex; /// /// // Declare a bounded channel of 3 u32s. - /// let mut channel = PriorityChannel::::new(); + /// let mut channel = PriorityChannel::::new(); /// ``` pub const fn new() -> Self { Self { @@ -588,7 +563,7 @@ where impl DynamicChannel for PriorityChannel where T: Ord, - K: heapless::binary_heap::Kind, + K: Kind, M: RawMutex, { fn try_send_with_context(&self, m: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError> { @@ -619,25 +594,30 @@ mod tests { use futures_executor::ThreadPool; use futures_timer::Delay; use futures_util::task::SpawnExt; + use heapless::binary_heap::{Kind, Max}; use static_cell::StaticCell; use super::*; use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; - fn capacity(c: &ChannelState) -> usize { + fn capacity(c: &ChannelState) -> usize + where + T: Ord, + K: Kind, + { c.queue.capacity() - c.queue.len() } #[test] fn sending_once() { - let mut c = ChannelState::::new(); + let mut c = ChannelState::::new(); assert!(c.try_send(1).is_ok()); assert_eq!(capacity(&c), 2); } #[test] fn sending_when_full() { - let mut c = ChannelState::::new(); + let mut c = ChannelState::::new(); let _ = c.try_send(1); let _ = c.try_send(1); let _ = c.try_send(1); @@ -650,7 +630,7 @@ mod tests { #[test] fn receiving_once_with_one_send() { - let mut c = ChannelState::::new(); + let mut c = ChannelState::::new(); assert!(c.try_send(1).is_ok()); assert_eq!(c.try_receive().unwrap(), 1); assert_eq!(capacity(&c), 3); @@ -658,7 +638,7 @@ mod tests { #[test] fn receiving_when_empty() { - let mut c = ChannelState::::new(); + let mut c = ChannelState::::new(); match c.try_receive() { Err(TryReceiveError::Empty) => assert!(true), _ => assert!(false), @@ -668,14 +648,14 @@ mod tests { #[test] fn simple_send_and_receive() { - let c = PriorityChannel::::new(); + let c = PriorityChannel::::new(); assert!(c.try_send(1).is_ok()); assert_eq!(c.try_receive().unwrap(), 1); } #[test] fn cloning() { - let c = PriorityChannel::::new(); + let c = PriorityChannel::::new(); let r1 = c.receiver(); let s1 = c.sender(); @@ -685,7 +665,7 @@ mod tests { #[test] fn dynamic_dispatch() { - let c = PriorityChannel::::new(); + let c = PriorityChannel::::new(); let s: DynamicSender<'_, u32> = c.sender().into(); let r: DynamicReceiver<'_, u32> = c.receiver().into(); @@ -697,7 +677,7 @@ mod tests { async fn receiver_receives_given_try_send_async() { let executor = ThreadPool::new().unwrap(); - static CHANNEL: StaticCell> = StaticCell::new(); + static CHANNEL: StaticCell> = StaticCell::new(); let c = &*CHANNEL.init(PriorityChannel::new()); let c2 = c; assert!(executor @@ -710,7 +690,7 @@ mod tests { #[futures_test::test] async fn sender_send_completes_if_capacity() { - let c = PriorityChannel::::new(); + let c = PriorityChannel::::new(); c.send(1).await; assert_eq!(c.receive().await, 1); } @@ -719,7 +699,7 @@ mod tests { async fn senders_sends_wait_until_capacity() { let executor = ThreadPool::new().unwrap(); - static CHANNEL: StaticCell> = StaticCell::new(); + static CHANNEL: StaticCell> = StaticCell::new(); let c = &*CHANNEL.init(PriorityChannel::new()); assert!(c.try_send(1).is_ok()); From 2efa73f4313aeaad9b65b634425b689520096b9a Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Sat, 18 Nov 2023 14:37:15 +0000 Subject: [PATCH 149/188] docs and simple test for priority --- embassy-sync/src/priority_channel.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/embassy-sync/src/priority_channel.rs b/embassy-sync/src/priority_channel.rs index 13c407c2..6f419aa6 100644 --- a/embassy-sync/src/priority_channel.rs +++ b/embassy-sync/src/priority_channel.rs @@ -1,6 +1,7 @@ //! A queue for sending values between asynchronous tasks. //! //! Similar to a [`Channel`](crate::channel::Channel), however [`PriorityChannel`] sifts higher priority items to the front of the queue. +//! Priority is determined by the `Ord` trait. Priority behavior is determined by the [`Kind`](heapless::binary_heap::Kind) parameter of the channel. use core::cell::RefCell; use core::future::Future; @@ -628,6 +629,16 @@ mod tests { assert_eq!(capacity(&c), 0); } + #[test] + fn send_priority() { + // Prio channel with kind `Max` sifts larger numbers to the front of the queue + let mut c = ChannelState::::new(); + assert!(c.try_send(1).is_ok()); + assert!(c.try_send(3).is_ok()); + assert_eq!(c.try_receive().unwrap(), 3); + assert_eq!(c.try_receive().unwrap(), 1); + } + #[test] fn receiving_once_with_one_send() { let mut c = ChannelState::::new(); From 7589b5e13e0e01922804e603918fea0aa4dac30a Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Sat, 18 Nov 2023 14:56:29 +0000 Subject: [PATCH 150/188] reduce duplication further by sharing Dynamic sender/receiver --- embassy-sync/src/channel.rs | 4 +- embassy-sync/src/priority_channel.rs | 84 +--------------------------- 2 files changed, 3 insertions(+), 85 deletions(-) diff --git a/embassy-sync/src/channel.rs b/embassy-sync/src/channel.rs index aa267471..ff712930 100644 --- a/embassy-sync/src/channel.rs +++ b/embassy-sync/src/channel.rs @@ -76,7 +76,7 @@ where /// Send-only access to a [`Channel`] without knowing channel size. pub struct DynamicSender<'ch, T> { - channel: &'ch dyn DynamicChannel, + pub(crate) channel: &'ch dyn DynamicChannel, } impl<'ch, T> Clone for DynamicSender<'ch, T> { @@ -176,7 +176,7 @@ where /// Receive-only access to a [`Channel`] without knowing channel size. pub struct DynamicReceiver<'ch, T> { - channel: &'ch dyn DynamicChannel, + pub(crate) channel: &'ch dyn DynamicChannel, } impl<'ch, T> Clone for DynamicReceiver<'ch, T> { diff --git a/embassy-sync/src/priority_channel.rs b/embassy-sync/src/priority_channel.rs index 6f419aa6..14366281 100644 --- a/embassy-sync/src/priority_channel.rs +++ b/embassy-sync/src/priority_channel.rs @@ -13,7 +13,7 @@ use heapless::BinaryHeap; use crate::blocking_mutex::raw::RawMutex; use crate::blocking_mutex::Mutex; -use crate::channel::{DynamicChannel, TryReceiveError, TrySendError}; +use crate::channel::{DynamicChannel, DynamicReceiver, DynamicSender, TryReceiveError, TrySendError}; use crate::waitqueue::WakerRegistration; /// Send-only access to a [`PriorityChannel`]. @@ -73,19 +73,6 @@ where } } -/// Send-only access to a [`PriorityChannel`] without knowing channel size. -pub struct DynamicSender<'ch, T> { - channel: &'ch dyn DynamicChannel, -} - -impl<'ch, T> Clone for DynamicSender<'ch, T> { - fn clone(&self) -> Self { - DynamicSender { channel: self.channel } - } -} - -impl<'ch, T> Copy for DynamicSender<'ch, T> {} - impl<'ch, M, T, K, const N: usize> From> for DynamicSender<'ch, T> where T: Ord, @@ -97,32 +84,6 @@ where } } -impl<'ch, T> DynamicSender<'ch, T> { - /// Sends a value. - /// - /// See [`PriorityChannel::send()`] - pub fn send(&self, message: T) -> DynamicSendFuture<'ch, T> { - DynamicSendFuture { - channel: self.channel, - message: Some(message), - } - } - - /// Attempt to immediately send a message. - /// - /// See [`PriorityChannel::send()`] - pub fn try_send(&self, message: T) -> Result<(), TrySendError> { - self.channel.try_send_with_context(message, None) - } - - /// Allows a poll_fn to poll until the channel is ready to send - /// - /// See [`PriorityChannel::poll_ready_to_send()`] - pub fn poll_ready_to_send(&self, cx: &mut Context<'_>) -> Poll<()> { - self.channel.poll_ready_to_send(cx) - } -} - /// Receive-only access to a [`PriorityChannel`]. pub struct Receiver<'ch, M, T, K, const N: usize> where @@ -187,49 +148,6 @@ where } } -/// Receive-only access to a [`PriorityChannel`] without knowing channel size. -pub struct DynamicReceiver<'ch, T> { - channel: &'ch dyn DynamicChannel, -} - -impl<'ch, T> Clone for DynamicReceiver<'ch, T> { - fn clone(&self) -> Self { - DynamicReceiver { channel: self.channel } - } -} - -impl<'ch, T> Copy for DynamicReceiver<'ch, T> {} - -impl<'ch, T> DynamicReceiver<'ch, T> { - /// Receive the next value. - /// - /// See [`PriorityChannel::receive()`]. - pub fn receive(&self) -> DynamicReceiveFuture<'_, T> { - DynamicReceiveFuture { channel: self.channel } - } - - /// Attempt to immediately receive the next value. - /// - /// See [`PriorityChannel::try_receive()`] - pub fn try_receive(&self) -> Result { - self.channel.try_receive_with_context(None) - } - - /// Allows a poll_fn to poll until the channel is ready to receive - /// - /// See [`PriorityChannel::poll_ready_to_receive()`] - pub fn poll_ready_to_receive(&self, cx: &mut Context<'_>) -> Poll<()> { - self.channel.poll_ready_to_receive(cx) - } - - /// Poll the channel for the next item - /// - /// See [`PriorityChannel::poll_receive()`] - pub fn poll_receive(&self, cx: &mut Context<'_>) -> Poll { - self.channel.poll_receive(cx) - } -} - impl<'ch, M, T, K, const N: usize> From> for DynamicReceiver<'ch, T> where T: Ord, From f482a105b8491f3c21d41cb7e6f52fe6d778258f Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Sat, 18 Nov 2023 15:01:12 +0000 Subject: [PATCH 151/188] more clean up, refactor channel into module to share code --- embassy-sync/src/channel.rs | 8 ++-- .../priority.rs} | 45 +------------------ embassy-sync/src/lib.rs | 1 - 3 files changed, 6 insertions(+), 48 deletions(-) rename embassy-sync/src/{priority_channel.rs => channel/priority.rs} (92%) diff --git a/embassy-sync/src/channel.rs b/embassy-sync/src/channel.rs index ff712930..1843bbae 100644 --- a/embassy-sync/src/channel.rs +++ b/embassy-sync/src/channel.rs @@ -29,6 +29,8 @@ use crate::blocking_mutex::raw::RawMutex; use crate::blocking_mutex::Mutex; use crate::waitqueue::WakerRegistration; +pub mod priority; + /// Send-only access to a [`Channel`]. pub struct Sender<'ch, M, T, const N: usize> where @@ -76,7 +78,7 @@ where /// Send-only access to a [`Channel`] without knowing channel size. pub struct DynamicSender<'ch, T> { - pub(crate) channel: &'ch dyn DynamicChannel, + channel: &'ch dyn DynamicChannel, } impl<'ch, T> Clone for DynamicSender<'ch, T> { @@ -176,7 +178,7 @@ where /// Receive-only access to a [`Channel`] without knowing channel size. pub struct DynamicReceiver<'ch, T> { - pub(crate) channel: &'ch dyn DynamicChannel, + channel: &'ch dyn DynamicChannel, } impl<'ch, T> Clone for DynamicReceiver<'ch, T> { @@ -321,7 +323,7 @@ impl<'ch, T> Future for DynamicSendFuture<'ch, T> { impl<'ch, T> Unpin for DynamicSendFuture<'ch, T> {} -pub(crate) trait DynamicChannel { +trait DynamicChannel { fn try_send_with_context(&self, message: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError>; fn try_receive_with_context(&self, cx: Option<&mut Context<'_>>) -> Result; diff --git a/embassy-sync/src/priority_channel.rs b/embassy-sync/src/channel/priority.rs similarity index 92% rename from embassy-sync/src/priority_channel.rs rename to embassy-sync/src/channel/priority.rs index 14366281..1fd137db 100644 --- a/embassy-sync/src/priority_channel.rs +++ b/embassy-sync/src/channel/priority.rs @@ -183,23 +183,6 @@ where } } -/// Future returned by [`DynamicReceiver::receive`]. -#[must_use = "futures do nothing unless you `.await` or poll them"] -pub struct DynamicReceiveFuture<'ch, T> { - channel: &'ch dyn DynamicChannel, -} - -impl<'ch, T> Future for DynamicReceiveFuture<'ch, T> { - type Output = T; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - match self.channel.try_receive_with_context(Some(cx)) { - Ok(v) => Poll::Ready(v), - Err(TryReceiveError::Empty) => Poll::Pending, - } - } -} - /// Future returned by [`PriorityChannel::send`] and [`Sender::send`]. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct SendFuture<'ch, M, T, K, const N: usize> @@ -242,32 +225,6 @@ where { } -/// Future returned by [`DynamicSender::send`]. -#[must_use = "futures do nothing unless you `.await` or poll them"] -pub struct DynamicSendFuture<'ch, T> { - channel: &'ch dyn DynamicChannel, - message: Option, -} - -impl<'ch, T> Future for DynamicSendFuture<'ch, T> { - type Output = (); - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - match self.message.take() { - Some(m) => match self.channel.try_send_with_context(m, Some(cx)) { - Ok(..) => Poll::Ready(()), - Err(TrySendError::Full(m)) => { - self.message = Some(m); - Poll::Pending - } - }, - None => panic!("Message cannot be None"), - } - } -} - -impl<'ch, T> Unpin for DynamicSendFuture<'ch, T> {} - struct ChannelState { queue: BinaryHeap, receiver_waker: WakerRegistration, @@ -386,7 +343,7 @@ where /// /// ``` /// # use heapless::binary_heap::Max; - /// use embassy_sync::priority_channel::PriorityChannel; + /// use embassy_sync::channel::priority::PriorityChannel; /// use embassy_sync::blocking_mutex::raw::NoopRawMutex; /// /// // Declare a bounded channel of 3 u32s. diff --git a/embassy-sync/src/lib.rs b/embassy-sync/src/lib.rs index 3ffcb913..c40fa3b6 100644 --- a/embassy-sync/src/lib.rs +++ b/embassy-sync/src/lib.rs @@ -15,7 +15,6 @@ pub mod blocking_mutex; pub mod channel; pub mod mutex; pub mod pipe; -pub mod priority_channel; pub mod pubsub; pub mod signal; pub mod waitqueue; From 5a60024af71b70c059d4a2a2eacdfd7f73a3398d Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Sat, 18 Nov 2023 15:08:16 +0000 Subject: [PATCH 152/188] docs --- embassy-sync/README.md | 1 + embassy-sync/src/channel/priority.rs | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/embassy-sync/README.md b/embassy-sync/README.md index cc65cf6e..55618f72 100644 --- a/embassy-sync/README.md +++ b/embassy-sync/README.md @@ -5,6 +5,7 @@ An [Embassy](https://embassy.dev) project. Synchronization primitives and data structures with async support: - [`Channel`](channel::Channel) - A Multiple Producer Multiple Consumer (MPMC) channel. Each message is only received by a single consumer. +- [`PriorityChannel`](channel::priority::PriorityChannel) - A Multiple Producer Multiple Consumer (MPMC) channel. Each message is only received by a single consumer. Higher priority items are sifted to the front of the channel. - [`PubSubChannel`](pubsub::PubSubChannel) - A broadcast channel (publish-subscribe) channel. Each message is received by all consumers. - [`Signal`](signal::Signal) - Signalling latest value to a single consumer. - [`Mutex`](mutex::Mutex) - Mutex for synchronizing state between asynchronous tasks. diff --git a/embassy-sync/src/channel/priority.rs b/embassy-sync/src/channel/priority.rs index 1fd137db..61dc7be6 100644 --- a/embassy-sync/src/channel/priority.rs +++ b/embassy-sync/src/channel/priority.rs @@ -323,7 +323,9 @@ where /// buffer is full, attempts to `send` new messages will wait until a message is /// received from the channel. /// -/// All data sent will become available in the same order as it was sent. +/// Sent data may be reordered based on their priorty within the channel. +/// For example, in a [`Max`](heapless::binary_heap::Max) [`PriorityChannel`] +/// containing `u32`'s, data sent in the following order `[1, 2, 3]` will be recieved as `[3, 2, 1]`. pub struct PriorityChannel where T: Ord, @@ -509,8 +511,10 @@ mod tests { // Prio channel with kind `Max` sifts larger numbers to the front of the queue let mut c = ChannelState::::new(); assert!(c.try_send(1).is_ok()); + assert!(c.try_send(2).is_ok()); assert!(c.try_send(3).is_ok()); assert_eq!(c.try_receive().unwrap(), 3); + assert_eq!(c.try_receive().unwrap(), 2); assert_eq!(c.try_receive().unwrap(), 1); } From 814e096d226b05a439095e51008da83020a24f53 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sat, 18 Nov 2023 19:37:56 +0000 Subject: [PATCH 153/188] STM32: Don't enable opamps in new(), wait until configured. --- embassy-stm32/src/opamp.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index 89db6d14..a8401083 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -54,19 +54,12 @@ pub struct OpAmp<'d, T: Instance> { impl<'d, T: Instance> OpAmp<'d, T> { /// Create a new driver instance. /// - /// Enables the OpAmp and configures the speed, but - /// does not set any other configuration. + /// Does not enable the opamp, but does set the speed mode on some families. pub fn new(opamp: impl Peripheral

+ 'd, #[cfg(opamp_g4)] speed: OpAmpSpeed) -> 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); w.set_opahsm(speed.into()); }); @@ -74,7 +67,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { } /// Configure the OpAmp as a buffer for the provided input pin, - /// outputting to the provided output pin. + /// outputting to the provided output pin, and enable the opamp. /// /// The input pin is configured for analogue mode but not consumed, /// so it may subsequently be used for ADC or comparator inputs. @@ -129,7 +122,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { } /// Configure the OpAmp as a buffer for the provided input pin, - /// with the output only used internally. + /// with the output only used internally, and enable the opamp. /// /// The input pin is configured for analogue mode but not consumed, /// so it may be subsequently used for ADC or comparator inputs. From 5221705495a46edeb6fc45a88dceff8200d339aa Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 19 Nov 2023 22:02:57 +0100 Subject: [PATCH 154/188] stm32/sai: fix build on chips with only SAI4 (like stm32h725re), improve sync config. --- ci.sh | 1 + embassy-stm32/build.rs | 1 + embassy-stm32/src/sai/mod.rs | 70 +++++++++++++++++++----------------- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/ci.sh b/ci.sh index 2e6bbae8..78a6eeb8 100755 --- a/ci.sh +++ b/ci.sh @@ -110,6 +110,7 @@ cargo batch \ --- 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,stm32h725re,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 \ diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 6b41cd39..a7dac5f9 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -61,6 +61,7 @@ fn main() { let mut singletons: Vec = Vec::new(); for p in METADATA.peripherals { if let Some(r) = &p.registers { + println!("cargo:rustc-cfg=peri_{}", p.name.to_ascii_lowercase()); match r.kind { // Generate singletons per pin, not per port "gpio" => { diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index a0b4ddac..a16d38af 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs @@ -207,27 +207,40 @@ impl Protocol { } #[derive(Copy, Clone, PartialEq)] -pub enum SyncEnable { - Asynchronous, +pub enum SyncInput { + /// Not synced to any other SAI unit. + None, /// Syncs with the other A/B sub-block within the SAI unit Internal, - /// Syncs with a sub-block in the other SAI unit - use set_sync_output() and set_sync_input() - #[cfg(any(sai_v4))] - External, + /// Syncs with a sub-block in the other SAI unit + #[cfg(sai_v4)] + External(SyncInputInstance), } -impl SyncEnable { - #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] +impl SyncInput { pub const fn syncen(&self) -> vals::Syncen { match self { - SyncEnable::Asynchronous => vals::Syncen::ASYNCHRONOUS, - SyncEnable::Internal => vals::Syncen::INTERNAL, + SyncInput::None => vals::Syncen::ASYNCHRONOUS, + SyncInput::Internal => vals::Syncen::INTERNAL, #[cfg(any(sai_v4))] - SyncEnable::External => vals::Syncen::EXTERNAL, + SyncInput::External(_) => vals::Syncen::EXTERNAL, } } } +#[cfg(sai_v4)] +#[derive(Copy, Clone, PartialEq)] +pub enum SyncInputInstance { + #[cfg(peri_sai1)] + Sai1 = 0, + #[cfg(peri_sai2)] + Sai2 = 1, + #[cfg(peri_sai3)] + Sai3 = 2, + #[cfg(peri_sai4)] + Sai4 = 3, +} + #[derive(Copy, Clone, PartialEq)] pub enum StereoMono { Stereo, @@ -428,8 +441,8 @@ impl MasterClockDivider { pub struct Config { pub mode: Mode, pub tx_rx: TxRx, - pub sync_enable: SyncEnable, - pub is_sync_output: bool, + pub sync_input: SyncInput, + pub sync_output: bool, pub protocol: Protocol, pub slot_size: SlotSize, pub slot_count: word::U4, @@ -459,8 +472,8 @@ impl Default for Config { Self { mode: Mode::Master, tx_rx: TxRx::Transmitter, - is_sync_output: false, - sync_enable: SyncEnable::Asynchronous, + sync_output: false, + sync_input: SyncInput::None, protocol: Protocol::Free, slot_size: SlotSize::DataSize, slot_count: word::U4(2), @@ -608,18 +621,18 @@ impl<'d, T: Instance> Sai<'d, T> { fn update_synchronous_config(config: &mut Config) { config.mode = Mode::Slave; - config.is_sync_output = false; + config.sync_output = false; #[cfg(any(sai_v1, sai_v2, sai_v3))] { - config.sync_enable = SyncEnable::Internal; + config.sync_input = SyncInput::Internal; } #[cfg(any(sai_v4))] { //this must either be Internal or External - //The asynchronous sub-block on the same SAI needs to enable is_sync_output - assert!(config.sync_enable != SyncEnable::Asynchronous); + //The asynchronous sub-block on the same SAI needs to enable sync_output + assert!(config.sync_input != SyncInput::None); } } @@ -866,20 +879,13 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { #[cfg(any(sai_v4))] { - // Not totally clear from the datasheet if this is right - // This is only used if using SyncEnable::External on the other SAI unit - // Syncing from SAIX subblock A to subblock B does not require this - // Only syncing from SAI1 subblock A/B to SAI2 subblock A/B - let value: u8 = if T::REGS.as_ptr() == stm32_metapac::SAI1.as_ptr() { - 1 //this is SAI1, so sync with SAI2 - } else { - 0 //this is SAI2, so sync with SAI1 - }; - T::REGS.gcr().modify(|w| { - w.set_syncin(value); - }); + if let SyncInput::External(i) = config.sync_input { + T::REGS.gcr().modify(|w| { + w.set_syncin(i as u8); + }); + } - if config.is_sync_output { + if config.sync_output { let syncout: u8 = match sub_block { WhichSubBlock::A => 0b01, WhichSubBlock::B => 0b10, @@ -903,7 +909,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { w.set_ds(config.data_size.ds()); w.set_lsbfirst(config.bit_order.lsbfirst()); w.set_ckstr(config.clock_strobe.ckstr()); - w.set_syncen(config.sync_enable.syncen()); + w.set_syncen(config.sync_input.syncen()); w.set_mono(config.stereo_mono.mono()); w.set_outdriv(config.output_drive.outdriv()); w.set_mckdiv(config.master_clock_divider.mckdiv()); From 30424d83ff127506cff088a9b8a6e9079ca5d3e9 Mon Sep 17 00:00:00 2001 From: James Munns Date: Sat, 4 Nov 2023 13:17:54 +0100 Subject: [PATCH 155/188] Update RP2040 memory.x The RP2040 has 264KiB of memory, not 256KiB. --- examples/rp/memory.x | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/rp/memory.x b/examples/rp/memory.x index aba861aa..6ed98493 100644 --- a/examples/rp/memory.x +++ b/examples/rp/memory.x @@ -1,5 +1,5 @@ MEMORY { BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 - RAM : ORIGIN = 0x20000000, LENGTH = 256K -} \ No newline at end of file + RAM : ORIGIN = 0x20000000, LENGTH = 264K +} From f3c77e59c43b04e1002374fd91185cdee3883160 Mon Sep 17 00:00:00 2001 From: James Munns Date: Sun, 19 Nov 2023 23:09:53 +0100 Subject: [PATCH 156/188] Add docs, touch all linker fragments --- examples/boot/application/rp/memory.x | 14 +++++++++++++- examples/boot/bootloader/rp/memory.x | 14 +++++++++++++- examples/rp/memory.x | 12 ++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/examples/boot/application/rp/memory.x b/examples/boot/application/rp/memory.x index c1947311..2f8434b8 100644 --- a/examples/boot/application/rp/memory.x +++ b/examples/boot/application/rp/memory.x @@ -5,7 +5,19 @@ MEMORY BOOTLOADER_STATE : ORIGIN = 0x10006000, LENGTH = 4K FLASH : ORIGIN = 0x10007000, LENGTH = 512K DFU : ORIGIN = 0x10087000, LENGTH = 516K - RAM : ORIGIN = 0x20000000, LENGTH = 256K + + /* Pick one of the two options for RAM layout */ + + /* OPTION A: Use all RAM banks as one big block */ + /* Reasonable, unless you are doing something */ + /* really particular with DMA or other concurrent */ + /* access that would benefit from striping */ + RAM : ORIGIN = 0x20000000, LENGTH = 264K + + /* OPTION B: Keep the unstriped sections separate */ + /* RAM: ORIGIN = 0x20000000, LENGTH = 256K */ + /* SCRATCH_A: ORIGIN = 0x20040000, LENGTH = 4K */ + /* SCRATCH_B: ORIGIN = 0x20041000, LENGTH = 4K */ } __bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOT2); diff --git a/examples/boot/bootloader/rp/memory.x b/examples/boot/bootloader/rp/memory.x index d6ef3846..c3b54976 100644 --- a/examples/boot/bootloader/rp/memory.x +++ b/examples/boot/bootloader/rp/memory.x @@ -6,7 +6,19 @@ MEMORY BOOTLOADER_STATE : ORIGIN = 0x10006000, LENGTH = 4K ACTIVE : ORIGIN = 0x10007000, LENGTH = 512K DFU : ORIGIN = 0x10087000, LENGTH = 516K - RAM : ORIGIN = 0x20000000, LENGTH = 256K + + /* Pick one of the two options for RAM layout */ + + /* OPTION A: Use all RAM banks as one big block */ + /* Reasonable, unless you are doing something */ + /* really particular with DMA or other concurrent */ + /* access that would benefit from striping */ + RAM : ORIGIN = 0x20000000, LENGTH = 264K + + /* OPTION B: Keep the unstriped sections separate */ + /* RAM: ORIGIN = 0x20000000, LENGTH = 256K */ + /* SCRATCH_A: ORIGIN = 0x20040000, LENGTH = 4K */ + /* SCRATCH_B: ORIGIN = 0x20041000, LENGTH = 4K */ } __bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOT2); diff --git a/examples/rp/memory.x b/examples/rp/memory.x index 6ed98493..ef19dffe 100644 --- a/examples/rp/memory.x +++ b/examples/rp/memory.x @@ -1,5 +1,17 @@ MEMORY { BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 + + /* Pick one of the two options for RAM layout */ + + /* OPTION A: Use all RAM banks as one big block */ + /* Reasonable, unless you are doing something */ + /* really particular with DMA or other concurrent */ + /* access that would benefit from striping */ RAM : ORIGIN = 0x20000000, LENGTH = 264K + + /* OPTION B: Keep the unstriped sections separate */ + /* RAM: ORIGIN = 0x20000000, LENGTH = 256K */ + /* SCRATCH_A: ORIGIN = 0x20040000, LENGTH = 4K */ + /* SCRATCH_B: ORIGIN = 0x20041000, LENGTH = 4K */ } From be17e1b363338c1f5bc445ee45067506e2571954 Mon Sep 17 00:00:00 2001 From: Stephan Wolski Date: Sun, 19 Nov 2023 17:08:46 -0500 Subject: [PATCH 157/188] populate `medium` in DriverAdapter struct in IGMP code --- embassy-net/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 6aa476aa..58310b20 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -616,9 +616,11 @@ impl Stack { let addr = addr.into(); self.with_mut(|s, i| { + let (_hardware_addr, medium) = to_smoltcp_hardware_address(i.device.hardware_address()); let mut smoldev = DriverAdapter { cx: Some(cx), inner: &mut i.device, + medium, }; match s @@ -653,9 +655,11 @@ impl Stack { let addr = addr.into(); self.with_mut(|s, i| { + let (_hardware_addr, medium) = to_smoltcp_hardware_address(i.device.hardware_address()); let mut smoldev = DriverAdapter { cx: Some(cx), inner: &mut i.device, + medium, }; match s From b8e9e00b44665edea6f433788a320c1981f96885 Mon Sep 17 00:00:00 2001 From: Stephan Wolski Date: Sun, 19 Nov 2023 17:26:16 -0500 Subject: [PATCH 158/188] add build with `igmp` enabled to ci.sh --- ci.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci.sh b/ci.sh index 78a6eeb8..aff88353 100755 --- a/ci.sh +++ b/ci.sh @@ -38,6 +38,7 @@ cargo batch \ --- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \ --- 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,proto-ipv4,igmp,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,dhcpv4-hostname \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \ From 7f258cd3c403fc2fe1837afbecc1bf88da46cb5a Mon Sep 17 00:00:00 2001 From: RobertTDowling Date: Sun, 19 Nov 2023 15:56:34 -0800 Subject: [PATCH 159/188] PR feedback --- embassy-stm32/src/rcc/h.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index bdae850f..1a9603d0 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -170,9 +170,9 @@ impl Default for Config { per_clock_source: PerClockSource::HSI, #[cfg(stm32h5)] - adc_clock_source: AdcClockSource::from_bits(0), // HCLK on H5 + adc_clock_source: AdcClockSource::HCLK1, #[cfg(stm32h7)] - adc_clock_source: AdcClockSource::from_bits(2), // PCLK on H7 + adc_clock_source: AdcClockSource::PER, timer_prescaler: TimerPrescaler::DefaultX2, voltage_scale: VoltageScale::Scale0, From 454828accbfa3eecfbe782a6a23435c7a01ee29b Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Mon, 20 Nov 2023 11:28:31 +0000 Subject: [PATCH 160/188] revert module changes, reexport heapless relevant items --- embassy-sync/src/channel.rs | 8 +++----- embassy-sync/src/lib.rs | 1 + .../src/{channel/priority.rs => priority_channel.rs} | 5 ++--- 3 files changed, 6 insertions(+), 8 deletions(-) rename embassy-sync/src/{channel/priority.rs => priority_channel.rs} (99%) diff --git a/embassy-sync/src/channel.rs b/embassy-sync/src/channel.rs index 1843bbae..ff712930 100644 --- a/embassy-sync/src/channel.rs +++ b/embassy-sync/src/channel.rs @@ -29,8 +29,6 @@ use crate::blocking_mutex::raw::RawMutex; use crate::blocking_mutex::Mutex; use crate::waitqueue::WakerRegistration; -pub mod priority; - /// Send-only access to a [`Channel`]. pub struct Sender<'ch, M, T, const N: usize> where @@ -78,7 +76,7 @@ where /// Send-only access to a [`Channel`] without knowing channel size. pub struct DynamicSender<'ch, T> { - channel: &'ch dyn DynamicChannel, + pub(crate) channel: &'ch dyn DynamicChannel, } impl<'ch, T> Clone for DynamicSender<'ch, T> { @@ -178,7 +176,7 @@ where /// Receive-only access to a [`Channel`] without knowing channel size. pub struct DynamicReceiver<'ch, T> { - channel: &'ch dyn DynamicChannel, + pub(crate) channel: &'ch dyn DynamicChannel, } impl<'ch, T> Clone for DynamicReceiver<'ch, T> { @@ -323,7 +321,7 @@ impl<'ch, T> Future for DynamicSendFuture<'ch, T> { impl<'ch, T> Unpin for DynamicSendFuture<'ch, T> {} -trait DynamicChannel { +pub(crate) trait DynamicChannel { fn try_send_with_context(&self, message: T, cx: Option<&mut Context<'_>>) -> Result<(), TrySendError>; fn try_receive_with_context(&self, cx: Option<&mut Context<'_>>) -> Result; diff --git a/embassy-sync/src/lib.rs b/embassy-sync/src/lib.rs index c40fa3b6..3ffcb913 100644 --- a/embassy-sync/src/lib.rs +++ b/embassy-sync/src/lib.rs @@ -15,6 +15,7 @@ pub mod blocking_mutex; pub mod channel; pub mod mutex; pub mod pipe; +pub mod priority_channel; pub mod pubsub; pub mod signal; pub mod waitqueue; diff --git a/embassy-sync/src/channel/priority.rs b/embassy-sync/src/priority_channel.rs similarity index 99% rename from embassy-sync/src/channel/priority.rs rename to embassy-sync/src/priority_channel.rs index 61dc7be6..bd75c013 100644 --- a/embassy-sync/src/channel/priority.rs +++ b/embassy-sync/src/priority_channel.rs @@ -8,7 +8,7 @@ use core::future::Future; use core::pin::Pin; use core::task::{Context, Poll}; -use heapless::binary_heap::Kind; +pub use heapless::binary_heap::{Kind, Max, Min}; use heapless::BinaryHeap; use crate::blocking_mutex::raw::RawMutex; @@ -344,8 +344,7 @@ where /// Establish a new bounded channel. For example, to create one with a NoopMutex: /// /// ``` - /// # use heapless::binary_heap::Max; - /// use embassy_sync::channel::priority::PriorityChannel; + /// use embassy_sync::priority_channel::{PriorityChannel, Max}; /// use embassy_sync::blocking_mutex::raw::NoopRawMutex; /// /// // Declare a bounded channel of 3 u32s. From 2386619f1f8b9630166b0b55c275bb74125e4b9d Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Mon, 20 Nov 2023 21:17:09 +0000 Subject: [PATCH 161/188] STM32: Disable opamp when OpAmpOutput is dropped, not when the parent OpAmp is dropped --- embassy-stm32/src/opamp.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index a8401083..4a607e8a 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -74,7 +74,8 @@ impl<'d, T: Instance> OpAmp<'d, T> { /// /// The output pin is held within the returned [`OpAmpOutput`] struct, /// preventing it being used elsewhere. The `OpAmpOutput` can then be - /// directly used as an ADC input. + /// directly used as an ADC input. The opamp will be disabled when the + /// [`OpAmpOutput`] is dropped. pub fn buffer_ext<'a, 'b, IP, OP>( &'a mut self, in_pin: &IP, @@ -128,6 +129,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { /// so it may be subsequently used for ADC or comparator inputs. /// /// The returned `OpAmpInternalOutput` struct may be used as an ADC input. + /// The opamp output will be disabled when it is dropped. #[cfg(opamp_g4)] pub fn buffer_int<'a, P>(&'a mut self, pin: &P, gain: OpAmpGain) -> OpAmpInternalOutput<'a, T> where @@ -156,7 +158,21 @@ impl<'d, T: Instance> OpAmp<'d, T> { } } -impl<'d, T: Instance> Drop for OpAmp<'d, T> { +impl<'d, 'p, T: Instance, P: OutputPin> Drop for OpAmpOutput<'d, 'p, T, P> { + fn drop(&mut self) { + #[cfg(opamp_f3)] + T::regs().opampcsr().modify(|w| { + w.set_opampen(false); + }); + + #[cfg(opamp_g4)] + T::regs().opamp_csr().modify(|w| { + w.set_opaen(false); + }); + } +} + +impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> { fn drop(&mut self) { #[cfg(opamp_f3)] T::regs().opampcsr().modify(|w| { From d1af6966051486fd605aff902b347b0346d2d889 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Mon, 20 Nov 2023 21:35:05 +0000 Subject: [PATCH 162/188] STM32 opamp: use impl Peripheral instead of directly taking pins --- embassy-stm32/src/opamp.rs | 46 +++++++++++++---------------- examples/stm32f334/src/bin/opamp.rs | 2 +- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index 4a607e8a..e1eb031d 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -31,12 +31,9 @@ impl From for crate::pac::opamp::vals::OpampCsrOpahsm { /// OpAmp external outputs, wired to a GPIO pad. /// -/// The GPIO output pad is held by this struct to ensure it cannot be used elsewhere. -/// /// This struct can also be used as an ADC input. -pub struct OpAmpOutput<'d, 'p, T: Instance, P: OutputPin> { +pub struct OpAmpOutput<'d, T: Instance> { _inner: &'d OpAmp<'d, T>, - _output: &'p mut P, } /// OpAmp internal outputs, wired directly to ADC inputs. @@ -76,16 +73,14 @@ impl<'d, T: Instance> OpAmp<'d, T> { /// preventing it being used elsewhere. The `OpAmpOutput` can then be /// directly used as an ADC input. The opamp will be disabled when the /// [`OpAmpOutput`] is dropped. - pub fn buffer_ext<'a, 'b, IP, OP>( - &'a mut self, - in_pin: &IP, - out_pin: &'b mut OP, + pub fn buffer_ext( + &'d mut self, + in_pin: impl Peripheral

+ crate::gpio::sealed::Pin>, + out_pin: impl Peripheral

+ crate::gpio::sealed::Pin> + 'd, gain: OpAmpGain, - ) -> OpAmpOutput<'a, 'b, T, OP> - where - IP: NonInvertingPin + crate::gpio::sealed::Pin, - OP: OutputPin + crate::gpio::sealed::Pin, - { + ) -> OpAmpOutput<'d, T> { + into_ref!(in_pin); + into_ref!(out_pin); in_pin.set_as_analog(); out_pin.set_as_analog(); @@ -116,10 +111,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { w.set_opaen(true); }); - OpAmpOutput { - _inner: self, - _output: out_pin, - } + OpAmpOutput { _inner: self } } /// Configure the OpAmp as a buffer for the provided input pin, @@ -131,10 +123,12 @@ impl<'d, T: Instance> OpAmp<'d, T> { /// The returned `OpAmpInternalOutput` struct may be used as an ADC input. /// The opamp output will be disabled when it is dropped. #[cfg(opamp_g4)] - pub fn buffer_int<'a, P>(&'a mut self, pin: &P, gain: OpAmpGain) -> OpAmpInternalOutput<'a, T> - where - P: NonInvertingPin + crate::gpio::sealed::Pin, - { + pub fn buffer_int( + &'d mut self, + pin: impl Peripheral

+ crate::gpio::sealed::Pin>, + gain: OpAmpGain, + ) -> OpAmpInternalOutput<'d, T> { + into_ref!(pin); pin.set_as_analog(); let (vm_sel, pga_gain) = match gain { @@ -158,7 +152,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { } } -impl<'d, 'p, T: Instance, P: OutputPin> Drop for OpAmpOutput<'d, 'p, T, P> { +impl<'d, T: Instance> Drop for OpAmpOutput<'d, T> { fn drop(&mut self) { #[cfg(opamp_f3)] T::regs().opampcsr().modify(|w| { @@ -212,16 +206,16 @@ macro_rules! impl_opamp_external_output { ($inst:ident, $adc:ident, $ch:expr) => { foreach_adc!( ($adc, $common_inst:ident, $adc_clock:ident) => { - impl<'d, 'p, P: OutputPin> crate::adc::sealed::AdcPin - for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> + impl<'d> crate::adc::sealed::AdcPin + for OpAmpOutput<'d, crate::peripherals::$inst> { fn channel(&self) -> u8 { $ch } } - impl<'d, 'p, P: OutputPin> crate::adc::AdcPin - for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> + impl<'d> crate::adc::AdcPin + for OpAmpOutput<'d, crate::peripherals::$inst> { } }; diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index 137fc9e6..10e7b354 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs @@ -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_ext(&p.PA7, &mut p.PA6, OpAmpGain::Mul1); + let mut buffer = opamp.buffer_ext(&mut p.PA7, &mut p.PA6, OpAmpGain::Mul1); loop { let vref = adc.read(&mut vrefint).await; From 06a83c0f897d0fe39c59e33b14d9b4f0cd705a0b Mon Sep 17 00:00:00 2001 From: Tommas Bakker Date: Wed, 25 Oct 2023 13:56:23 +0200 Subject: [PATCH 163/188] Refactor bxcan split. --- embassy-stm32/src/can/bxcan.rs | 70 +++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 0d4bf692..85dbe714 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -1,4 +1,3 @@ -use core::cell::{RefCell, RefMut}; use core::future::poll_fn; use core::marker::PhantomData; use core::ops::{Deref, DerefMut}; @@ -84,7 +83,7 @@ impl interrupt::typelevel::Handler for SceInterrup } pub struct Can<'d, T: Instance> { - pub can: RefCell>>, + pub can: bxcan::Can>, } #[derive(Debug)] @@ -175,14 +174,12 @@ impl<'d, T: Instance> Can<'d, T> { tx.set_as_af(tx.af_num(), AFType::OutputPushPull); let can = bxcan::Can::builder(BxcanInstance(peri)).leave_disabled(); - let can_ref_cell = RefCell::new(can); - Self { can: can_ref_cell } + Self { can } } pub fn set_bitrate(&mut self, bitrate: u32) { let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap(); self.can - .borrow_mut() .modify_config() .set_bit_timing(bit_timing) .leave_disabled(); @@ -193,55 +190,56 @@ impl<'d, T: Instance> Can<'d, T> { /// This will wait for 11 consecutive recessive bits (bus idle state). /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting. pub async fn enable(&mut self) { - while self.borrow_mut().enable_non_blocking().is_err() { + while self.enable_non_blocking().is_err() { // SCE interrupt is only generated for entering sleep mode, but not leaving. // Yield to allow other tasks to execute while can bus is initializing. embassy_futures::yield_now().await; } } + /// Queues the message to be sent but exerts backpressure pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { - CanTx { can: &self.can }.write(frame).await + self.split().0.write(frame).await } /// Attempts to transmit a frame without blocking. /// /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. pub fn try_write(&mut self, frame: &Frame) -> Result { - CanTx { can: &self.can }.try_write(frame) + self.split().0.try_write(frame) } /// Waits for a specific transmit mailbox to become empty pub async fn flush(&self, mb: bxcan::Mailbox) { - CanTx { can: &self.can }.flush(mb).await + CanTx::::_flush(mb).await } /// Waits until any of the transmit mailboxes become empty pub async fn flush_any(&self) { - CanTx { can: &self.can }.flush_any().await + CanTx::::_flush_any().await } /// Waits until all of the transmit mailboxes become empty pub async fn flush_all(&self) { - CanTx { can: &self.can }.flush_all().await + CanTx::::_flush_all().await } /// Returns a tuple of the time the message was received and the message frame pub async fn read(&mut self) -> Result { - CanRx { can: &self.can }.read().await + self.split().1.read().await } /// Attempts to read a can frame without blocking. /// /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. pub fn try_read(&mut self) -> Result { - CanRx { can: &self.can }.try_read() + self.split().1.try_read() } /// Waits while receive queue is empty. pub async fn wait_not_empty(&mut self) { - CanRx { can: &self.can }.wait_not_empty().await + self.split().1.wait_not_empty().await } unsafe fn receive_fifo(fifo: RxFifo) { @@ -385,24 +383,25 @@ impl<'d, T: Instance> Can<'d, T> { Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler - 1)) } - pub fn split<'c>(&'c self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) { - (CanTx { can: &self.can }, CanRx { can: &self.can }) + pub fn split<'c>(&'c mut self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) { + let (tx, rx0, rx1) = self.can.split_by_ref(); + (CanTx { tx }, CanRx { rx0, rx1 }) } - pub fn as_mut(&self) -> RefMut<'_, bxcan::Can>> { - self.can.borrow_mut() + pub fn as_mut(&mut self) -> &mut bxcan::Can> { + &mut self.can } } pub struct CanTx<'c, 'd, T: Instance> { - can: &'c RefCell>>, + tx: &'c mut bxcan::Tx>, } impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { poll_fn(|cx| { T::state().tx_waker.register(cx.waker()); - if let Ok(status) = self.can.borrow_mut().transmit(frame) { + if let Ok(status) = self.tx.transmit(frame) { return Poll::Ready(status); } @@ -415,11 +414,10 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { /// /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. pub fn try_write(&mut self, frame: &Frame) -> Result { - self.can.borrow_mut().transmit(frame).map_err(|_| TryWriteError::Full) + self.tx.transmit(frame).map_err(|_| TryWriteError::Full) } - /// Waits for a specific transmit mailbox to become empty - pub async fn flush(&self, mb: bxcan::Mailbox) { + pub async fn _flush(mb: bxcan::Mailbox) { poll_fn(|cx| { T::state().tx_waker.register(cx.waker()); if T::regs().tsr().read().tme(mb.index()) { @@ -431,8 +429,13 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { .await; } + /// Waits for a specific transmit mailbox to become empty + pub async fn flush(&self, mb: bxcan::Mailbox) { + Self::_flush(mb).await + } + /// Waits until any of the transmit mailboxes become empty - pub async fn flush_any(&self) { + pub async fn _flush_any() { poll_fn(|cx| { T::state().tx_waker.register(cx.waker()); @@ -449,8 +452,13 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { .await; } + /// Waits until any of the transmit mailboxes become empty + pub async fn flush_any(&self) { + Self::_flush_any().await + } + /// Waits until all of the transmit mailboxes become empty - pub async fn flush_all(&self) { + pub async fn _flush_all() { poll_fn(|cx| { T::state().tx_waker.register(cx.waker()); @@ -466,11 +474,19 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { }) .await; } + + + + /// Waits until all of the transmit mailboxes become empty + pub async fn flush_all(&self) { + Self::_flush_all().await + } } #[allow(dead_code)] pub struct CanRx<'c, 'd, T: Instance> { - can: &'c RefCell>>, + rx0: &'c mut bxcan::Rx0>, + rx1: &'c mut bxcan::Rx1>, } impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { @@ -538,7 +554,7 @@ impl<'d, T: Instance> Drop for Can<'d, T> { } impl<'d, T: Instance> Deref for Can<'d, T> { - type Target = RefCell>>; + type Target = bxcan::Can>; fn deref(&self) -> &Self::Target { &self.can From 19ba7da3fde7ad4d0c5896812fbeb902791cc5bc Mon Sep 17 00:00:00 2001 From: Mick van Gelderen Date: Tue, 21 Nov 2023 15:37:38 +0100 Subject: [PATCH 164/188] Rename _flush* methods --- embassy-stm32/src/can/bxcan.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 85dbe714..13fffd74 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -212,17 +212,17 @@ impl<'d, T: Instance> Can<'d, T> { /// Waits for a specific transmit mailbox to become empty pub async fn flush(&self, mb: bxcan::Mailbox) { - CanTx::::_flush(mb).await + CanTx::::flush_inner(mb).await } /// Waits until any of the transmit mailboxes become empty pub async fn flush_any(&self) { - CanTx::::_flush_any().await + CanTx::::flush_any_inner().await } /// Waits until all of the transmit mailboxes become empty pub async fn flush_all(&self) { - CanTx::::_flush_all().await + CanTx::::flush_all_inner().await } /// Returns a tuple of the time the message was received and the message frame @@ -417,7 +417,7 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { self.tx.transmit(frame).map_err(|_| TryWriteError::Full) } - pub async fn _flush(mb: bxcan::Mailbox) { + async fn flush_inner(mb: bxcan::Mailbox) { poll_fn(|cx| { T::state().tx_waker.register(cx.waker()); if T::regs().tsr().read().tme(mb.index()) { @@ -431,11 +431,10 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { /// Waits for a specific transmit mailbox to become empty pub async fn flush(&self, mb: bxcan::Mailbox) { - Self::_flush(mb).await + Self::flush_inner(mb).await } - /// Waits until any of the transmit mailboxes become empty - pub async fn _flush_any() { + async fn flush_any_inner() { poll_fn(|cx| { T::state().tx_waker.register(cx.waker()); @@ -454,11 +453,10 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { /// Waits until any of the transmit mailboxes become empty pub async fn flush_any(&self) { - Self::_flush_any().await + Self::flush_any_inner().await } - /// Waits until all of the transmit mailboxes become empty - pub async fn _flush_all() { + async fn flush_all_inner() { poll_fn(|cx| { T::state().tx_waker.register(cx.waker()); @@ -479,7 +477,7 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { /// Waits until all of the transmit mailboxes become empty pub async fn flush_all(&self) { - Self::_flush_all().await + Self::flush_all_inner().await } } From aedd41eac4ab2930b9dbded4b410da5f26bda1ef Mon Sep 17 00:00:00 2001 From: James Munns Date: Tue, 21 Nov 2023 15:38:33 +0100 Subject: [PATCH 165/188] Add FAQ with one question from chat --- docs/modules/ROOT/nav.adoc | 1 + docs/modules/ROOT/pages/faq.adoc | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 docs/modules/ROOT/pages/faq.adoc diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index ee559a82..7e178df6 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -10,3 +10,4 @@ * xref:examples.adoc[Examples] * xref:developer.adoc[Developer] ** xref:developer_stm32.adoc[Developer: STM32] +* xref:faq.adoc[Frequently Asked Questions] diff --git a/docs/modules/ROOT/pages/faq.adoc b/docs/modules/ROOT/pages/faq.adoc new file mode 100644 index 00000000..5b58580d --- /dev/null +++ b/docs/modules/ROOT/pages/faq.adoc @@ -0,0 +1,24 @@ += Frequently Asked Questions + +These are a list of unsorted, commonly asked questions and answers. + +Please feel free to add items to link:https://github.com/embassy-rs/embassy/edit/main/docs/modules/ROOT/pages/faq.adoc[this page], especially if someone in the chat answered a question for you! + +== Missing main macro + +If you see an error like this: + +[source,rust] +--- +#[embassy_executor::main] +| ^^^^ could not find `main` in `embassy_executor` +--- + +You are likely missing some features of the `embassy-executor` crate. + +For Cortex-M targets, consider making sure that ALL of the following features are active in your `Cargo.toml` for the `embassy-executor` crate: + +* `arch-cortex-m` +* `executor-thread` +* `nightly` + From 88f893da4541ba42553fa14ba12845d9f3f2d133 Mon Sep 17 00:00:00 2001 From: Mick van Gelderen Date: Tue, 21 Nov 2023 15:40:07 +0100 Subject: [PATCH 166/188] Format --- embassy-stm32/src/can/bxcan.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 13fffd74..2f741734 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -179,10 +179,7 @@ impl<'d, T: Instance> Can<'d, T> { pub fn set_bitrate(&mut self, bitrate: u32) { let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap(); - self.can - .modify_config() - .set_bit_timing(bit_timing) - .leave_disabled(); + self.can.modify_config().set_bit_timing(bit_timing).leave_disabled(); } /// Enables the peripheral and synchronizes with the bus. @@ -197,7 +194,6 @@ impl<'d, T: Instance> Can<'d, T> { } } - /// Queues the message to be sent but exerts backpressure pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { self.split().0.write(frame).await @@ -473,8 +469,6 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { .await; } - - /// Waits until all of the transmit mailboxes become empty pub async fn flush_all(&self) { Self::flush_all_inner().await From c211d51c0667b19dc0e70473da4a2742d7405b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 21 Nov 2023 15:51:56 +0100 Subject: [PATCH 167/188] Add note for Xtensa --- docs/modules/ROOT/pages/faq.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/modules/ROOT/pages/faq.adoc b/docs/modules/ROOT/pages/faq.adoc index 5b58580d..733ddbc5 100644 --- a/docs/modules/ROOT/pages/faq.adoc +++ b/docs/modules/ROOT/pages/faq.adoc @@ -22,3 +22,4 @@ For Cortex-M targets, consider making sure that ALL of the following features ar * `executor-thread` * `nightly` +For Xtensa ESP32, consider using the executors and `#[main]` macro provided by your appropriate link:https://crates.io/crates/esp-hal-common[HAL crate]. From bd2e6b0422cb43b1a0fc4efb443b31170d6e73c3 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 21 Nov 2023 16:01:46 +0100 Subject: [PATCH 168/188] Update faq.adoc --- docs/modules/ROOT/pages/faq.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/modules/ROOT/pages/faq.adoc b/docs/modules/ROOT/pages/faq.adoc index 733ddbc5..8aa9a1a7 100644 --- a/docs/modules/ROOT/pages/faq.adoc +++ b/docs/modules/ROOT/pages/faq.adoc @@ -9,10 +9,10 @@ Please feel free to add items to link:https://github.com/embassy-rs/embassy/edit If you see an error like this: [source,rust] ---- +---- #[embassy_executor::main] | ^^^^ could not find `main` in `embassy_executor` ---- +---- You are likely missing some features of the `embassy-executor` crate. From ba9cc102e295634035a3f9bac1b4656e735c5fc6 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 21 Nov 2023 16:53:28 +0100 Subject: [PATCH 169/188] ci: cache lockfiles - Removes the slow "updating crates.io index, updating git" at start of the job. - Avoids CI being randomly slower if a widely-used dep (like serde) gets bumped causing rebuilding everything. --- .github/ci/build-stable.sh | 10 ++++++++++ .github/ci/build.sh | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/.github/ci/build-stable.sh b/.github/ci/build-stable.sh index 8012f692..ffaebeb3 100755 --- a/.github/ci/build-stable.sh +++ b/.github/ci/build-stable.sh @@ -12,9 +12,19 @@ export CARGO_TARGET_DIR=/ci/cache/target # used when pointing stm32-metapac to a CI-built one. export CARGO_NET_GIT_FETCH_WITH_CLI=true +# Restore lockfiles +if [ -f /ci/cache/lockfiles.tar ]; then + echo Restoring lockfiles... + tar xf /ci/cache/lockfiles.tar +fi + hashtime restore /ci/cache/filetime.json || true hashtime save /ci/cache/filetime.json sed -i 's/channel.*/channel = "stable"/g' rust-toolchain.toml ./ci_stable.sh + +# Save lockfiles +echo Saving lockfiles... +find . -type f -name Cargo.lock -exec tar -cf /ci/cache/lockfiles.tar '{}' \+ \ No newline at end of file diff --git a/.github/ci/build.sh b/.github/ci/build.sh index 78ab976d..e7a6c0d8 100755 --- a/.github/ci/build.sh +++ b/.github/ci/build.sh @@ -18,7 +18,17 @@ fi # used when pointing stm32-metapac to a CI-built one. export CARGO_NET_GIT_FETCH_WITH_CLI=true +# Restore lockfiles +if [ -f /ci/cache/lockfiles.tar ]; then + echo Restoring lockfiles... + tar xf /ci/cache/lockfiles.tar +fi + hashtime restore /ci/cache/filetime.json || true hashtime save /ci/cache/filetime.json ./ci.sh + +# Save lockfiles +echo Saving lockfiles... +find . -type f -name Cargo.lock -exec tar -cf /ci/cache/lockfiles.tar '{}' \+ \ No newline at end of file From dec7c1a28bfb89dd6b925e164fb89c6baab8f255 Mon Sep 17 00:00:00 2001 From: jan <108279865+aspizu@users.noreply.github.com> Date: Fri, 24 Nov 2023 04:10:13 +0530 Subject: [PATCH 170/188] add faq for deploying to RP2040 using elf2uf2-rs --- docs/modules/ROOT/pages/faq.adoc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/modules/ROOT/pages/faq.adoc b/docs/modules/ROOT/pages/faq.adoc index 8aa9a1a7..6032985f 100644 --- a/docs/modules/ROOT/pages/faq.adoc +++ b/docs/modules/ROOT/pages/faq.adoc @@ -4,6 +4,19 @@ These are a list of unsorted, commonly asked questions and answers. Please feel free to add items to link:https://github.com/embassy-rs/embassy/edit/main/docs/modules/ROOT/pages/faq.adoc[this page], especially if someone in the chat answered a question for you! +== How to deploy to RP2040 without a debugging probe. + +Install link:https://github.com/JoNil/elf2uf2-rs[elf2uf2-rs] for converting the generated elf binary into a uf2 file. + +Configure the runner to use this tool, add this to `.cargo/config.toml`: +[source,toml] +---- +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "elf2uf2-rs --deploy --serial --verbose" +---- + +The command-line parameters `--deploy` will detect your device and upload the binary, `--serial` starts a serial connection. See the documentation for more info. + == Missing main macro If you see an error like this: From 4f8c79c9118d826b85755fa903df5d1a4aea5b18 Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Fri, 24 Nov 2023 15:56:19 +0200 Subject: [PATCH 171/188] stm32 i2c: allow EHA traits without time feature --- embassy-stm32/src/i2c/v2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 062a6225..40bcaa9b 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -1187,7 +1187,7 @@ mod eh1 { } } -#[cfg(all(feature = "unstable-traits", feature = "nightly", feature = "time"))] +#[cfg(all(feature = "unstable-traits", feature = "nightly"))] mod eha { use super::super::{RxDma, TxDma}; use super::*; From 5528c336495ffc5868d91af2867f6f8e22be8283 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 24 Nov 2023 18:44:55 +0100 Subject: [PATCH 172/188] embassy-embedded-hal: don't use feature(try_blocks). --- embassy-embedded-hal/src/lib.rs | 2 +- .../src/shared_bus/asynch/spi.rs | 52 +++++++++++++------ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/embassy-embedded-hal/src/lib.rs b/embassy-embedded-hal/src/lib.rs index f836d9f7..ce5fac3f 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, impl_trait_projections))] #![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))] #![warn(missing_docs)] diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index 5d3cf658..17d5f367 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs @@ -66,19 +66,29 @@ where let mut bus = self.bus.lock().await; self.cs.set_low().map_err(SpiDeviceError::Cs)?; - let op_res: Result<(), BUS::Error> = try { + let op_res = 'ops: { for op in operations { - match op { - Operation::Read(buf) => bus.read(buf).await?, - Operation::Write(buf) => bus.write(buf).await?, - Operation::Transfer(read, write) => bus.transfer(read, write).await?, - Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?, + let res = match op { + Operation::Read(buf) => bus.read(buf).await, + Operation::Write(buf) => bus.write(buf).await, + Operation::Transfer(read, write) => bus.transfer(read, write).await, + Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await, #[cfg(not(feature = "time"))] - Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), + Operation::DelayUs(us) => return Err(SpiDeviceError::DelayUsNotSupported), #[cfg(feature = "time")] - Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await, + Operation::DelayUs(us) => match bus.flush().await { + Err(e) => Err(e), + Ok(()) => { + embassy_time::Timer::after_micros(*us as _).await; + Ok(()) + } + }, + }; + if let Err(e) = res { + break 'ops Err(e); } } + Ok(()) }; // On failure, it's important to still flush and deassert CS. @@ -131,19 +141,29 @@ where bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?; self.cs.set_low().map_err(SpiDeviceError::Cs)?; - let op_res: Result<(), BUS::Error> = try { + let op_res = 'ops: { for op in operations { - match op { - Operation::Read(buf) => bus.read(buf).await?, - Operation::Write(buf) => bus.write(buf).await?, - Operation::Transfer(read, write) => bus.transfer(read, write).await?, - Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?, + let res = match op { + Operation::Read(buf) => bus.read(buf).await, + Operation::Write(buf) => bus.write(buf).await, + Operation::Transfer(read, write) => bus.transfer(read, write).await, + Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await, #[cfg(not(feature = "time"))] - Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), + Operation::DelayUs(us) => return Err(SpiDeviceError::DelayUsNotSupported), #[cfg(feature = "time")] - Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await, + Operation::DelayUs(us) => match bus.flush().await { + Err(e) => Err(e), + Ok(()) => { + embassy_time::Timer::after_micros(*us as _).await; + Ok(()) + } + }, + }; + if let Err(e) = res { + break 'ops Err(e); } } + Ok(()) }; // On failure, it's important to still flush and deassert CS. From 259cf6192b920dff4cce0486488d929bf4e05b96 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 24 Nov 2023 19:05:31 +0100 Subject: [PATCH 173/188] executor: Remove non-functional rtos-trace-interrupt. --- embassy-executor/Cargo.toml | 3 --- embassy-executor/src/lib.rs | 23 +---------------------- embassy-macros/Cargo.toml | 4 +--- examples/nrf-rtos-trace/Cargo.toml | 2 +- 4 files changed, 3 insertions(+), 29 deletions(-) diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 3a623e99..54ea1a54 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -49,9 +49,6 @@ turbowakers = [] integrated-timers = ["dep:embassy-time"] -# Trace interrupt invocations with rtos-trace. -rtos-trace-interrupt = ["rtos-trace", "embassy-macros/rtos-trace-interrupt"] - [dependencies] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index f2c86d8e..3b61b4ba 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -44,25 +44,4 @@ pub use spawner::*; /// Implementation details for embassy macros. /// Do not use. Used for macros and HALs only. Not covered by semver guarantees. #[doc(hidden)] -pub mod _export { - #[cfg(feature = "rtos-trace")] - pub use rtos_trace::trace; - - /// Expands the given block of code when `embassy-executor` is compiled with - /// the `rtos-trace-interrupt` feature. - #[doc(hidden)] - #[macro_export] - #[cfg(feature = "rtos-trace-interrupt")] - macro_rules! rtos_trace_interrupt { - ($($tt:tt)*) => { $($tt)* }; - } - - /// Does not expand the given block of code when `embassy-executor` is - /// compiled without the `rtos-trace-interrupt` feature. - #[doc(hidden)] - #[macro_export] - #[cfg(not(feature = "rtos-trace-interrupt"))] - macro_rules! rtos_trace_interrupt { - ($($tt:tt)*) => {}; - } -} +pub mod _export {} diff --git a/embassy-macros/Cargo.toml b/embassy-macros/Cargo.toml index a893cd30..4e94bf83 100644 --- a/embassy-macros/Cargo.toml +++ b/embassy-macros/Cargo.toml @@ -20,6 +20,4 @@ proc-macro2 = "1.0.29" [lib] proc-macro = true -[features] -# Enabling this cause interrupt::take! to require embassy-executor -rtos-trace-interrupt = [] +[features] \ No newline at end of file diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index e30b13f2..e3524deb 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -17,7 +17,7 @@ log = [ [dependencies] embassy-sync = { version = "0.4.0", path = "../../embassy-sync" } -embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] } +embassy-executor = { version = "0.3.3", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "integrated-timers"] } embassy-time = { version = "0.1.5", path = "../../embassy-time" } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } From 1fbc150fd6392d8268aa35d15380c02e363c4eb8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 24 Nov 2023 21:33:30 +0100 Subject: [PATCH 174/188] executor: add some tests. --- .github/ci/test.sh | 2 + embassy-executor/Cargo.toml | 3 + embassy-executor/tests/test.rs | 137 +++++++++++++++++++++++++++++++++ rust-toolchain.toml | 2 +- 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 embassy-executor/tests/test.rs diff --git a/.github/ci/test.sh b/.github/ci/test.sh index af0f21c2..e48d6e65 100755 --- a/.github/ci/test.sh +++ b/.github/ci/test.sh @@ -15,6 +15,8 @@ export CARGO_NET_GIT_FETCH_WITH_CLI=true hashtime restore /ci/cache/filetime.json || true hashtime save /ci/cache/filetime.json +MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml --features nightly + cargo test --manifest-path ./embassy-sync/Cargo.toml cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml cargo test --manifest-path ./embassy-hal-internal/Cargo.toml diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 54ea1a54..f0e85a2c 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -68,3 +68,6 @@ cortex-m = { version = "0.7.6", optional = true } # arch-wasm dependencies wasm-bindgen = { version = "0.2.82", optional = true } js-sys = { version = "0.3", optional = true } + +[dev-dependencies] +critical-section = { version = "1.1", features = ["std"] } diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs new file mode 100644 index 00000000..0dbd391e --- /dev/null +++ b/embassy-executor/tests/test.rs @@ -0,0 +1,137 @@ +#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))] + +use std::boxed::Box; +use std::future::poll_fn; +use std::sync::{Arc, Mutex}; +use std::task::Poll; + +use embassy_executor::raw::Executor; +use embassy_executor::task; + +#[export_name = "__pender"] +fn __pender(context: *mut ()) { + unsafe { + let trace = &*(context as *const Trace); + trace.push("pend"); + } +} + +#[derive(Clone)] +struct Trace { + trace: Arc>>, +} + +impl Trace { + fn new() -> Self { + Self { + trace: Arc::new(Mutex::new(Vec::new())), + } + } + fn push(&self, value: &'static str) { + self.trace.lock().unwrap().push(value) + } + + fn get(&self) -> Vec<&'static str> { + self.trace.lock().unwrap().clone() + } +} + +fn setup() -> (&'static Executor, Trace) { + let trace = Trace::new(); + let context = Box::leak(Box::new(trace.clone())) as *mut _ as *mut (); + let executor = &*Box::leak(Box::new(Executor::new(context))); + (executor, trace) +} + +#[test] +fn executor_noop() { + let (executor, trace) = setup(); + unsafe { executor.poll() }; + assert!(trace.get().is_empty()) +} + +#[test] +fn executor_task() { + #[task] + async fn task1(trace: Trace) { + trace.push("poll task1") + } + + let (executor, trace) = setup(); + executor.spawner().spawn(task1(trace.clone())).unwrap(); + + unsafe { executor.poll() }; + unsafe { executor.poll() }; + + assert_eq!( + trace.get(), + &[ + "pend", // spawning a task pends the executor + "poll task1", // poll only once. + ] + ) +} + +#[test] +fn executor_task_self_wake() { + #[task] + async fn task1(trace: Trace) { + poll_fn(|cx| { + trace.push("poll task1"); + cx.waker().wake_by_ref(); + Poll::Pending + }) + .await + } + + let (executor, trace) = setup(); + executor.spawner().spawn(task1(trace.clone())).unwrap(); + + unsafe { executor.poll() }; + unsafe { executor.poll() }; + + assert_eq!( + trace.get(), + &[ + "pend", // spawning a task pends the executor + "poll task1", // + "pend", // task self-wakes + "poll task1", // + "pend", // task self-wakes + ] + ) +} + +#[test] +fn executor_task_self_wake_twice() { + #[task] + async fn task1(trace: Trace) { + poll_fn(|cx| { + trace.push("poll task1"); + cx.waker().wake_by_ref(); + trace.push("poll task1 wake 2"); + cx.waker().wake_by_ref(); + Poll::Pending + }) + .await + } + + let (executor, trace) = setup(); + executor.spawner().spawn(task1(trace.clone())).unwrap(); + + unsafe { executor.poll() }; + unsafe { executor.poll() }; + + assert_eq!( + trace.get(), + &[ + "pend", // spawning a task pends the executor + "poll task1", // + "pend", // task self-wakes + "poll task1 wake 2", // task self-wakes again, shouldn't pend + "poll task1", // + "pend", // task self-wakes + "poll task1 wake 2", // task self-wakes again, shouldn't pend + ] + ) +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 419c3108..11f53ee4 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -2,7 +2,7 @@ # https://rust-lang.github.io/rustup-components-history [toolchain] channel = "nightly-2023-11-01" -components = [ "rust-src", "rustfmt", "llvm-tools" ] +components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ] targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", From 171cdb94c7906670723b0965ca66d72a2352ac73 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 24 Nov 2023 21:37:27 +0100 Subject: [PATCH 175/188] executor: add support for main/task macros in stable (allocates tasks in an arena) --- .github/ci/test.sh | 1 + embassy-executor/Cargo.toml | 2 +- embassy-executor/src/arch/cortex_m.rs | 1 - embassy-executor/src/arch/riscv32.rs | 1 - embassy-executor/src/arch/std.rs | 1 - embassy-executor/src/arch/wasm.rs | 1 - embassy-executor/src/arch/xtensa.rs | 1 - embassy-executor/src/lib.rs | 95 ++++++++++++++++++++++++++- embassy-macros/Cargo.toml | 3 +- embassy-macros/src/macros/task.rs | 9 +++ 10 files changed, 105 insertions(+), 10 deletions(-) diff --git a/.github/ci/test.sh b/.github/ci/test.sh index e48d6e65..dfc2b08c 100755 --- a/.github/ci/test.sh +++ b/.github/ci/test.sh @@ -15,6 +15,7 @@ export CARGO_NET_GIT_FETCH_WITH_CLI=true hashtime restore /ci/cache/filetime.json || true hashtime save /ci/cache/filetime.json +MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml --features nightly cargo test --manifest-path ./embassy-sync/Cargo.toml diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index f0e85a2c..3ff8440c 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -43,7 +43,7 @@ executor-thread = [] executor-interrupt = [] # Enable nightly-only features -nightly = [] +nightly = ["embassy-macros/nightly"] turbowakers = [] diff --git a/embassy-executor/src/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs index 55299c94..4a6d5857 100644 --- a/embassy-executor/src/arch/cortex_m.rs +++ b/embassy-executor/src/arch/cortex_m.rs @@ -51,7 +51,6 @@ mod thread { use core::arch::asm; use core::marker::PhantomData; - #[cfg(feature = "nightly")] pub use embassy_macros::main_cortex_m as main; use crate::{raw, Spawner}; diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs index 6814e784..ca12c340 100644 --- a/embassy-executor/src/arch/riscv32.rs +++ b/embassy-executor/src/arch/riscv32.rs @@ -7,7 +7,6 @@ pub use thread::*; mod thread { use core::marker::PhantomData; - #[cfg(feature = "nightly")] pub use embassy_macros::main_riscv as main; use portable_atomic::{AtomicBool, Ordering}; diff --git a/embassy-executor/src/arch/std.rs b/embassy-executor/src/arch/std.rs index 5b2f7e2e..598bb050 100644 --- a/embassy-executor/src/arch/std.rs +++ b/embassy-executor/src/arch/std.rs @@ -8,7 +8,6 @@ mod thread { use std::marker::PhantomData; use std::sync::{Condvar, Mutex}; - #[cfg(feature = "nightly")] pub use embassy_macros::main_std as main; use crate::{raw, Spawner}; diff --git a/embassy-executor/src/arch/wasm.rs b/embassy-executor/src/arch/wasm.rs index 15aed867..3faa9257 100644 --- a/embassy-executor/src/arch/wasm.rs +++ b/embassy-executor/src/arch/wasm.rs @@ -8,7 +8,6 @@ mod thread { use core::marker::PhantomData; - #[cfg(feature = "nightly")] pub use embassy_macros::main_wasm as main; use js_sys::Promise; use wasm_bindgen::prelude::*; diff --git a/embassy-executor/src/arch/xtensa.rs b/embassy-executor/src/arch/xtensa.rs index d335594e..6ed9f9e7 100644 --- a/embassy-executor/src/arch/xtensa.rs +++ b/embassy-executor/src/arch/xtensa.rs @@ -8,7 +8,6 @@ mod thread { use core::marker::PhantomData; use core::sync::atomic::{AtomicBool, Ordering}; - #[cfg(feature = "nightly")] pub use embassy_macros::main_riscv as main; use crate::{raw, Spawner}; diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 3b61b4ba..ac7dbb03 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -1,5 +1,5 @@ #![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)] -#![cfg_attr(all(feature = "nightly", feature = "arch-xtensa"), feature(asm_experimental_arch))] +#![cfg_attr(feature = "arch-xtensa", feature(asm_experimental_arch))] #![allow(clippy::new_without_default)] #![doc = include_str!("../README.md")] #![warn(missing_docs)] @@ -7,7 +7,6 @@ // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; -#[cfg(feature = "nightly")] pub use embassy_macros::task; macro_rules! check_at_most_one { @@ -44,4 +43,94 @@ pub use spawner::*; /// Implementation details for embassy macros. /// Do not use. Used for macros and HALs only. Not covered by semver guarantees. #[doc(hidden)] -pub mod _export {} +#[cfg(not(feature = "nightly"))] +pub mod _export { + use core::alloc::Layout; + use core::cell::{Cell, UnsafeCell}; + use core::future::Future; + use core::mem::MaybeUninit; + use core::ptr::null_mut; + + use critical_section::{CriticalSection, Mutex}; + + use crate::raw::TaskPool; + + struct Arena { + buf: UnsafeCell>, + ptr: Mutex>, + } + + unsafe impl Sync for Arena {} + unsafe impl Send for Arena {} + + impl Arena { + const fn new() -> Self { + Self { + buf: UnsafeCell::new(MaybeUninit::uninit()), + ptr: Mutex::new(Cell::new(null_mut())), + } + } + + fn alloc(&'static self, cs: CriticalSection) -> &'static mut MaybeUninit { + let layout = Layout::new::(); + + let start = self.buf.get().cast::(); + let end = unsafe { start.add(N) }; + + let mut ptr = self.ptr.borrow(cs).get(); + if ptr.is_null() { + ptr = self.buf.get().cast::(); + } + + let bytes_left = (end as usize) - (ptr as usize); + let align_offset = (ptr as usize).next_multiple_of(layout.align()) - (ptr as usize); + + if align_offset + layout.size() > bytes_left { + panic!("arena full"); + } + + let res = unsafe { ptr.add(align_offset) }; + let ptr = unsafe { ptr.add(align_offset + layout.size()) }; + + self.ptr.borrow(cs).set(ptr); + + unsafe { &mut *(res as *mut MaybeUninit) } + } + } + + const ARENA_SIZE: usize = 16 * 1024; + static ARENA: Arena = Arena::new(); + + pub struct TaskPoolRef { + // type-erased `&'static mut TaskPool` + // Needed because statics can't have generics. + ptr: Mutex>, + } + unsafe impl Sync for TaskPoolRef {} + unsafe impl Send for TaskPoolRef {} + + impl TaskPoolRef { + pub const fn new() -> Self { + Self { + ptr: Mutex::new(Cell::new(null_mut())), + } + } + + /// Get the pool for this ref, allocating it from the arena the first time. + /// + /// safety: for a given TaskPoolRef instance, must always call with the exact + /// same generic params. + pub unsafe fn get(&'static self) -> &'static TaskPool { + critical_section::with(|cs| { + let ptr = self.ptr.borrow(cs); + if ptr.get().is_null() { + let pool = ARENA.alloc::>(cs); + pool.write(TaskPool::new()); + ptr.set(pool as *mut _ as _); + } + + unsafe { &*(ptr.get() as *const _) } + }) + } + } +} diff --git a/embassy-macros/Cargo.toml b/embassy-macros/Cargo.toml index 4e94bf83..e13104cf 100644 --- a/embassy-macros/Cargo.toml +++ b/embassy-macros/Cargo.toml @@ -20,4 +20,5 @@ proc-macro2 = "1.0.29" [lib] proc-macro = true -[features] \ No newline at end of file +[features] +nightly = [] \ No newline at end of file diff --git a/embassy-macros/src/macros/task.rs b/embassy-macros/src/macros/task.rs index 1d30434e..5161e102 100644 --- a/embassy-macros/src/macros/task.rs +++ b/embassy-macros/src/macros/task.rs @@ -79,6 +79,7 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result ::embassy_executor::SpawnToken { type Fut = impl ::core::future::Future + 'static; @@ -87,6 +88,14 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result ::embassy_executor::SpawnToken { + const POOL_SIZE: usize = #pool_size; + static POOL: ::embassy_executor::_export::TaskPoolRef = ::embassy_executor::_export::TaskPoolRef::new(); + unsafe { POOL.get::<_, POOL_SIZE>()._spawn_async_fn(move || #task_inner_ident(#(#arg_names,)*)) } + } + }; task_outer.attrs.append(&mut task_inner.attrs.clone()); From 996c3c1f7e389b1e7d26ca6f02524fff3d63212e Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 24 Nov 2023 22:39:08 +0100 Subject: [PATCH 176/188] executor: make task arena size configurable. --- embassy-executor/Cargo.toml | 90 ++++++++++++++++++++++++-------- embassy-executor/README.md | 28 +++++++++- embassy-executor/build.rs | 93 +++++++++++++++++++++++++++++++++- embassy-executor/gen_config.py | 82 ++++++++++++++++++++++++++++++ embassy-executor/src/lib.rs | 10 ++-- 5 files changed, 276 insertions(+), 27 deletions(-) create mode 100644 embassy-executor/gen_config.py diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 3ff8440c..ae46b17c 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -27,28 +27,6 @@ default-target = "thumbv7em-none-eabi" targets = ["thumbv7em-none-eabi"] features = ["nightly", "defmt", "arch-cortex-m", "executor-thread", "executor-interrupt"] -[features] - -# Architecture -_arch = [] # some arch was picked -arch-std = ["_arch", "critical-section/std"] -arch-cortex-m = ["_arch", "dep:cortex-m"] -arch-xtensa = ["_arch"] -arch-riscv32 = ["_arch", "dep:portable-atomic"] -arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"] - -# Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded archs) -executor-thread = [] -# Enable the interrupt-mode executor (available in Cortex-M only) -executor-interrupt = [] - -# Enable nightly-only features -nightly = ["embassy-macros/nightly"] - -turbowakers = [] - -integrated-timers = ["dep:embassy-time"] - [dependencies] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } @@ -71,3 +49,71 @@ js-sys = { version = "0.3", optional = true } [dev-dependencies] critical-section = { version = "1.1", features = ["std"] } + + +[features] + +# Architecture +_arch = [] # some arch was picked +arch-std = ["_arch", "critical-section/std"] +arch-cortex-m = ["_arch", "dep:cortex-m"] +arch-xtensa = ["_arch"] +arch-riscv32 = ["_arch", "dep:portable-atomic"] +arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"] + +# Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded archs) +executor-thread = [] +# Enable the interrupt-mode executor (available in Cortex-M only) +executor-interrupt = [] + +# Enable nightly-only features +nightly = ["embassy-macros/nightly"] + +turbowakers = [] + +integrated-timers = ["dep:embassy-time"] + +# BEGIN AUTOGENERATED CONFIG FEATURES +# Generated by gen_config.py. DO NOT EDIT. +task-arena-size-64 = [] +task-arena-size-128 = [] +task-arena-size-192 = [] +task-arena-size-256 = [] +task-arena-size-320 = [] +task-arena-size-384 = [] +task-arena-size-512 = [] +task-arena-size-640 = [] +task-arena-size-768 = [] +task-arena-size-1024 = [] +task-arena-size-1280 = [] +task-arena-size-1536 = [] +task-arena-size-2048 = [] +task-arena-size-2560 = [] +task-arena-size-3072 = [] +task-arena-size-4096 = [] # Default +task-arena-size-5120 = [] +task-arena-size-6144 = [] +task-arena-size-8192 = [] +task-arena-size-10240 = [] +task-arena-size-12288 = [] +task-arena-size-16384 = [] +task-arena-size-20480 = [] +task-arena-size-24576 = [] +task-arena-size-32768 = [] +task-arena-size-40960 = [] +task-arena-size-49152 = [] +task-arena-size-65536 = [] +task-arena-size-81920 = [] +task-arena-size-98304 = [] +task-arena-size-131072 = [] +task-arena-size-163840 = [] +task-arena-size-196608 = [] +task-arena-size-262144 = [] +task-arena-size-327680 = [] +task-arena-size-393216 = [] +task-arena-size-524288 = [] +task-arena-size-655360 = [] +task-arena-size-786432 = [] +task-arena-size-1048576 = [] + +# END AUTOGENERATED CONFIG FEATURES diff --git a/embassy-executor/README.md b/embassy-executor/README.md index 3c1448a1..80ecfc71 100644 --- a/embassy-executor/README.md +++ b/embassy-executor/README.md @@ -2,10 +2,36 @@ An async/await executor designed for embedded usage. -- No `alloc`, no heap needed. Task futures are statically allocated. +- No `alloc`, no heap needed. +- With nightly Rust, task futures can be fully statically allocated. - No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. - Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. - 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. + +## Task arena + +When the `nightly` Cargo feature is not enabled, `embassy-executor` allocates tasks out of an arena (a very simple bump allocator). + +If the task arena gets full, the program will panic at runtime. To guarantee this doesn't happen, you must set the size to the sum of sizes of all tasks. + +Tasks are allocated from the arena when spawned for the first time. If the task exists, the allocation is not released to the arena, but can be reused to spawn the task again. For multiple-instance tasks (like `#[embassy_executor::task(pool_size = 4)]`), the first spawn will allocate memory for all instances. This is done for performance and to increase predictability (for example, spawning at least 1 instance of every task at boot guarantees an immediate panic if the arena is too small, while allocating instances on-demand could delay the panic to only when the program is under load). + +The arena size can be configured in two ways: + +- Via Cargo features: enable a Cargo feature like `task-arena-size-8192`. Only a selection of values + is available, check `Cargo.toml` for the list. +- Via environment variables at build time: set the variable named `EMBASSY_EXECUTOR_TASK_ARENA_SIZE`. For example + `EMBASSY_EXECUTOR_TASK_ARENA_SIZE=4321 cargo build`. You can also set them in the `[env]` section of `.cargo/config.toml`. + Any value can be set, unlike with Cargo features. + +Environment variables take precedence over Cargo features. If two Cargo features are enabled for the same setting +with different values, compilation fails. + +## Statically allocating tasks + +When using nightly Rust, enable the `nightly` Cargo feature. This will make `embassy-executor` use the `type_alias_impl_trait` feature to allocate all tasks in `static`s. Each task gets its own `static`, with the exact size to hold the task (or multiple instances of it, if using `pool_size`) calculated automatically at compile time. If tasks don't fit in RAM, this is detected at compile time by the linker. Runtime panics due to running out of memory are not possible. + +The configured arena size is ignored, no arena is used at all. diff --git a/embassy-executor/build.rs b/embassy-executor/build.rs index 6fe82b44..07f31e3f 100644 --- a/embassy-executor/build.rs +++ b/embassy-executor/build.rs @@ -1,6 +1,97 @@ -use std::env; +use std::collections::HashMap; +use std::fmt::Write; +use std::path::PathBuf; +use std::{env, fs}; + +static CONFIGS: &[(&str, usize)] = &[ + // BEGIN AUTOGENERATED CONFIG FEATURES + // Generated by gen_config.py. DO NOT EDIT. + ("TASK_ARENA_SIZE", 4096), + // END AUTOGENERATED CONFIG FEATURES +]; + +struct ConfigState { + value: usize, + seen_feature: bool, + seen_env: bool, +} fn main() { + let crate_name = env::var("CARGO_PKG_NAME") + .unwrap() + .to_ascii_uppercase() + .replace('-', "_"); + + // only rebuild if build.rs changed. Otherwise Cargo will rebuild if any + // other file changed. + println!("cargo:rerun-if-changed=build.rs"); + + // Rebuild if config envvar changed. + for (name, _) in CONFIGS { + println!("cargo:rerun-if-env-changed={crate_name}_{name}"); + } + + let mut configs = HashMap::new(); + for (name, default) in CONFIGS { + configs.insert( + *name, + ConfigState { + value: *default, + seen_env: false, + seen_feature: false, + }, + ); + } + + let prefix = format!("{crate_name}_"); + for (var, value) in env::vars() { + if let Some(name) = var.strip_prefix(&prefix) { + let Some(cfg) = configs.get_mut(name) else { + panic!("Unknown env var {name}") + }; + + let Ok(value) = value.parse::() else { + panic!("Invalid value for env var {name}: {value}") + }; + + cfg.value = value; + cfg.seen_env = true; + } + + if let Some(feature) = var.strip_prefix("CARGO_FEATURE_") { + if let Some(i) = feature.rfind('_') { + let name = &feature[..i]; + let value = &feature[i + 1..]; + if let Some(cfg) = configs.get_mut(name) { + let Ok(value) = value.parse::() else { + panic!("Invalid value for feature {name}: {value}") + }; + + // envvars take priority. + if !cfg.seen_env { + if cfg.seen_feature { + panic!("multiple values set for feature {}: {} and {}", name, cfg.value, value); + } + + cfg.value = value; + cfg.seen_feature = true; + } + } + } + } + } + + let mut data = String::new(); + + for (name, cfg) in &configs { + writeln!(&mut data, "pub const {}: usize = {};", name, cfg.value).unwrap(); + } + + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let out_file = out_dir.join("config.rs").to_string_lossy().to_string(); + fs::write(out_file, data).unwrap(); + + // cortex-m targets let target = env::var("TARGET").unwrap(); if target.starts_with("thumbv6m-") { diff --git a/embassy-executor/gen_config.py b/embassy-executor/gen_config.py new file mode 100644 index 00000000..e427d29f --- /dev/null +++ b/embassy-executor/gen_config.py @@ -0,0 +1,82 @@ +import os + +abspath = os.path.abspath(__file__) +dname = os.path.dirname(abspath) +os.chdir(dname) + +features = [] + + +def feature(name, default, min=None, max=None, pow2=None, vals=None, factors=[]): + if vals is None: + assert min is not None + assert max is not None + + vals = set() + val = min + while val <= max: + vals.add(val) + for f in factors: + if val * f <= max: + vals.add(val * f) + if (pow2 == True or (isinstance(pow2, int) and val >= pow2)) and val > 0: + val *= 2 + else: + val += 1 + vals.add(default) + vals = sorted(list(vals)) + + features.append( + { + "name": name, + "default": default, + "vals": vals, + } + ) + + +feature( + "task_arena_size", default=4096, min=64, max=1024 * 1024, pow2=True, factors=[3, 5] +) + +# ========= Update Cargo.toml + +things = "" +for f in features: + name = f["name"].replace("_", "-") + for val in f["vals"]: + things += f"{name}-{val} = []" + if val == f["default"]: + things += " # Default" + things += "\n" + things += "\n" + +SEPARATOR_START = "# BEGIN AUTOGENERATED CONFIG FEATURES\n" +SEPARATOR_END = "# END AUTOGENERATED CONFIG FEATURES\n" +HELP = "# Generated by gen_config.py. DO NOT EDIT.\n" +with open("Cargo.toml", "r") as f: + data = f.read() +before, data = data.split(SEPARATOR_START, maxsplit=1) +_, after = data.split(SEPARATOR_END, maxsplit=1) +data = before + SEPARATOR_START + HELP + things + SEPARATOR_END + after +with open("Cargo.toml", "w") as f: + f.write(data) + + +# ========= Update build.rs + +things = "" +for f in features: + name = f["name"].upper() + things += f' ("{name}", {f["default"]}),\n' + +SEPARATOR_START = "// BEGIN AUTOGENERATED CONFIG FEATURES\n" +SEPARATOR_END = "// END AUTOGENERATED CONFIG FEATURES\n" +HELP = " // Generated by gen_config.py. DO NOT EDIT.\n" +with open("build.rs", "r") as f: + data = f.read() +before, data = data.split(SEPARATOR_START, maxsplit=1) +_, after = data.split(SEPARATOR_END, maxsplit=1) +data = before + SEPARATOR_START + HELP + things + " " + SEPARATOR_END + after +with open("build.rs", "w") as f: + f.write(data) diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index ac7dbb03..d8ac4893 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -40,6 +40,11 @@ pub mod raw; mod spawner; pub use spawner::*; +mod config { + #![allow(unused)] + include!(concat!(env!("OUT_DIR"), "/config.rs")); +} + /// Implementation details for embassy macros. /// Do not use. Used for macros and HALs only. Not covered by semver guarantees. #[doc(hidden)] @@ -86,7 +91,7 @@ pub mod _export { let align_offset = (ptr as usize).next_multiple_of(layout.align()) - (ptr as usize); if align_offset + layout.size() > bytes_left { - panic!("arena full"); + panic!("embassy-executor: task arena is full. You must increase the arena size, see the documentation for details: https://docs.embassy.dev/embassy-executor/"); } let res = unsafe { ptr.add(align_offset) }; @@ -98,8 +103,7 @@ pub mod _export { } } - const ARENA_SIZE: usize = 16 * 1024; - static ARENA: Arena = Arena::new(); + static ARENA: Arena<{ crate::config::TASK_ARENA_SIZE }> = Arena::new(); pub struct TaskPoolRef { // type-erased `&'static mut TaskPool` From bc65b8f7ec1df181c793846b7c0657f689963d3a Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 18 Nov 2023 01:18:23 +0100 Subject: [PATCH 177/188] stm32/i2c: add async, dual interrupt scaffolding. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/build.rs | 20 +++ embassy-stm32/src/i2c/mod.rs | 157 +++++++++++++++++- embassy-stm32/src/i2c/v1.rs | 122 ++++---------- embassy-stm32/src/i2c/v2.rs | 157 ++---------------- examples/stm32f4/src/bin/i2c.rs | 3 +- examples/stm32h5/src/bin/i2c.rs | 3 +- examples/stm32h7/src/bin/camera.rs | 3 +- examples/stm32h7/src/bin/i2c.rs | 3 +- examples/stm32l4/src/bin/i2c.rs | 3 +- .../stm32l4/src/bin/i2c_blocking_async.rs | 3 +- examples/stm32l4/src/bin/i2c_dma.rs | 3 +- .../src/bin/spe_adin1110_http_server.rs | 3 +- 13 files changed, 239 insertions(+), 245 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 65434cec..d04000a1 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-fbb8f77326dd066aa6c0d66b3b46e76a569dda8b" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f6d1ffc1a25f208b5cd6b1024bff246592da1949" } 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-fbb8f77326dd066aa6c0d66b3b46e76a569dda8b", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f6d1ffc1a25f208b5cd6b1024bff246592da1949", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index a7dac5f9..4aae5822 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1138,6 +1138,23 @@ fn main() { } } + // ======== + // Write peripheral_interrupts module. + let mut mt = TokenStream::new(); + for p in METADATA.peripherals { + let mut pt = TokenStream::new(); + + for irq in p.interrupts { + let iname = format_ident!("{}", irq.interrupt); + let sname = format_ident!("{}", irq.signal); + pt.extend(quote!(pub type #sname = crate::interrupt::typelevel::#iname;)); + } + + let pname = format_ident!("{}", p.name); + mt.extend(quote!(pub mod #pname { #pt })); + } + g.extend(quote!(#[allow(non_camel_case_types)] pub mod peripheral_interrupts { #mt })); + // ======== // Write foreach_foo! macrotables @@ -1296,6 +1313,9 @@ fn main() { let mut m = String::new(); + // DO NOT ADD more macros like these. + // These turned to be a bad idea! + // Instead, make build.rs generate the final code. make_table(&mut m, "foreach_flash_region", &flash_regions_table); make_table(&mut m, "foreach_interrupt", &interrupts_table); make_table(&mut m, "foreach_peripheral", &peripherals_table); diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index dde1a504..19346d70 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -1,11 +1,14 @@ #![macro_use] +use core::marker::PhantomData; + use crate::interrupt; #[cfg_attr(i2c_v1, path = "v1.rs")] #[cfg_attr(i2c_v2, path = "v2.rs")] mod _version; pub use _version::*; +use embassy_sync::waitqueue::AtomicWaker; use crate::peripherals; @@ -23,6 +26,20 @@ pub enum Error { pub(crate) mod sealed { use super::*; + + pub struct State { + #[allow(unused)] + pub waker: AtomicWaker, + } + + impl State { + pub const fn new() -> Self { + Self { + waker: AtomicWaker::new(), + } + } + } + pub trait Instance: crate::rcc::RccPeripheral { fn regs() -> crate::pac::i2c::I2c; fn state() -> &'static State; @@ -30,7 +47,8 @@ pub(crate) mod sealed { } pub trait Instance: sealed::Instance + 'static { - type Interrupt: interrupt::typelevel::Interrupt; + type EventInterrupt: interrupt::typelevel::Interrupt; + type ErrorInterrupt: interrupt::typelevel::Interrupt; } pin_trait!(SclPin, Instance); @@ -38,21 +56,148 @@ pin_trait!(SdaPin, Instance); dma_trait!(RxDma, Instance); dma_trait!(TxDma, Instance); -foreach_interrupt!( - ($inst:ident, i2c, $block:ident, EV, $irq:ident) => { +/// Interrupt handler. +pub struct EventInterruptHandler { + _phantom: PhantomData, +} + +impl interrupt::typelevel::Handler for EventInterruptHandler { + unsafe fn on_interrupt() { + _version::on_interrupt::() + } +} + +pub struct ErrorInterruptHandler { + _phantom: PhantomData, +} + +impl interrupt::typelevel::Handler for ErrorInterruptHandler { + unsafe fn on_interrupt() { + _version::on_interrupt::() + } +} + +foreach_peripheral!( + (i2c, $inst:ident) => { impl sealed::Instance for peripherals::$inst { fn regs() -> crate::pac::i2c::I2c { crate::pac::$inst } - fn state() -> &'static State { - static STATE: State = State::new(); + fn state() -> &'static sealed::State { + static STATE: sealed::State = sealed::State::new(); &STATE } } impl Instance for peripherals::$inst { - type Interrupt = crate::interrupt::typelevel::$irq; + type EventInterrupt = crate::_generated::peripheral_interrupts::$inst::EV; + type ErrorInterrupt = crate::_generated::peripheral_interrupts::$inst::ER; } }; ); + +mod eh02 { + use super::*; + + impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { + type Error = Error; + + fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + self.blocking_read(address, buffer) + } + } + + impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> { + type Error = Error; + + fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { + self.blocking_write(address, write) + } + } + + impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> { + type Error = Error; + + fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { + self.blocking_write_read(address, write, read) + } + } +} + +#[cfg(feature = "unstable-traits")] +mod eh1 { + use super::*; + use crate::dma::NoDma; + + impl embedded_hal_1::i2c::Error for Error { + fn kind(&self) -> embedded_hal_1::i2c::ErrorKind { + match *self { + Self::Bus => embedded_hal_1::i2c::ErrorKind::Bus, + Self::Arbitration => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss, + Self::Nack => { + embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Unknown) + } + Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other, + Self::Crc => embedded_hal_1::i2c::ErrorKind::Other, + Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun, + Self::ZeroLengthTransfer => embedded_hal_1::i2c::ErrorKind::Other, + } + } + } + + impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for I2c<'d, T, TXDMA, RXDMA> { + type Error = Error; + } + + impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T, NoDma, NoDma> { + 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!(); + } + } +} + +#[cfg(all(feature = "unstable-traits", feature = "nightly"))] +mod eha { + use super::*; + + impl<'d, T: Instance, TXDMA: TxDma, RXDMA: RxDma> embedded_hal_async::i2c::I2c for I2c<'d, T, TXDMA, RXDMA> { + async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { + self.read(address, read).await + } + + async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { + self.write(address, write).await + } + + async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { + self.write_read(address, write, read).await + } + + async fn transaction( + &mut self, + address: u8, + operations: &mut [embedded_hal_1::i2c::Operation<'_>], + ) -> Result<(), Self::Error> { + let _ = address; + let _ = operations; + todo!() + } + } +} diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index ab59f5ab..03f07c4f 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -3,21 +3,17 @@ use core::marker::PhantomData; use embassy_embedded_hal::SetConfig; use embassy_hal_internal::{into_ref, PeripheralRef}; +use super::*; use crate::dma::NoDma; use crate::gpio::sealed::AFType; use crate::gpio::Pull; -use crate::i2c::{Error, Instance, SclPin, SdaPin}; +use crate::interrupt::typelevel::Interrupt; use crate::pac::i2c; use crate::time::Hertz; use crate::{interrupt, Peripheral}; -/// Interrupt handler. -pub struct InterruptHandler { - _phantom: PhantomData, -} - -impl interrupt::typelevel::Handler for InterruptHandler { - unsafe fn on_interrupt() {} +pub unsafe fn on_interrupt() { + // todo } #[non_exhaustive] @@ -27,14 +23,6 @@ pub struct Config { pub scl_pullup: bool, } -pub struct State {} - -impl State { - pub(crate) const fn new() -> Self { - Self {} - } -} - pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { phantom: PhantomData<&'d mut T>, #[allow(dead_code)] @@ -48,7 +36,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { _peri: impl Peripheral

+ 'd, scl: impl Peripheral

> + 'd, sda: impl Peripheral

> + 'd, - _irq: impl interrupt::typelevel::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + + interrupt::typelevel::Binding> + + 'd, tx_dma: impl Peripheral

+ 'd, rx_dma: impl Peripheral

+ 'd, freq: Hertz, @@ -98,6 +88,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { reg.set_pe(true); }); + unsafe { T::EventInterrupt::enable() }; + unsafe { T::ErrorInterrupt::enable() }; + Self { phantom: PhantomData, tx_dma, @@ -336,6 +329,30 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { self.blocking_write_read_timeout(addr, write, read, || Ok(())) } + + // Async + + pub async fn write(&mut self, _address: u8, _write: &[u8]) -> Result<(), Error> + where + TXDMA: crate::i2c::TxDma, + { + todo!() + } + + pub async fn read(&mut self, _address: u8, _buffer: &mut [u8]) -> Result<(), Error> + where + RXDMA: crate::i2c::RxDma, + { + todo!() + } + + pub async fn write_read(&mut self, _address: u8, _write: &[u8], _read: &mut [u8]) -> Result<(), Error> + where + RXDMA: crate::i2c::RxDma, + TXDMA: crate::i2c::TxDma, + { + todo!() + } } impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { @@ -344,77 +361,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { } } -impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { - type Error = Error; - - fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> { - self.blocking_read(addr, read) - } -} - -impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> { - type Error = Error; - - fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> { - self.blocking_write(addr, write) - } -} - -impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> { - 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 embedded_hal_1::i2c::Error for Error { - fn kind(&self) -> embedded_hal_1::i2c::ErrorKind { - match *self { - Self::Bus => embedded_hal_1::i2c::ErrorKind::Bus, - Self::Arbitration => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss, - Self::Nack => { - embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Unknown) - } - Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other, - Self::Crc => embedded_hal_1::i2c::ErrorKind::Other, - Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun, - Self::ZeroLengthTransfer => embedded_hal_1::i2c::ErrorKind::Other, - } - } - } - - impl<'d, T: Instance> embedded_hal_1::i2c::ErrorType for I2c<'d, T> { - type Error = Error; - } - - impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T> { - 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!(); - } - } -} - enum Mode { Fast, Standard, diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 40bcaa9b..8c20e1c5 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -1,19 +1,17 @@ use core::cmp; use core::future::poll_fn; -use core::marker::PhantomData; use core::task::Poll; 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 super::*; use crate::dma::{NoDma, Transfer}; use crate::gpio::sealed::AFType; use crate::gpio::Pull; -use crate::i2c::{Error, Instance, SclPin, SdaPin}; use crate::interrupt::typelevel::Interrupt; use crate::pac::i2c; use crate::time::Hertz; @@ -36,25 +34,18 @@ pub fn no_timeout_fn() -> impl Fn() -> Result<(), Error> { move || Ok(()) } -/// Interrupt handler. -pub struct InterruptHandler { - _phantom: PhantomData, -} +pub unsafe fn on_interrupt() { + let regs = T::regs(); + let isr = regs.isr().read(); -impl interrupt::typelevel::Handler for InterruptHandler { - unsafe fn on_interrupt() { - let regs = T::regs(); - let isr = regs.isr().read(); - - if isr.tcr() || isr.tc() { - T::state().waker.wake(); - } - // The flag can only be cleared by writting to nbytes, we won't do that here, so disable - // the interrupt - critical_section::with(|_| { - regs.cr1().modify(|w| w.set_tcie(false)); - }); + if isr.tcr() || isr.tc() { + T::state().waker.wake(); } + // The flag can only be cleared by writting to nbytes, we won't do that here, so disable + // the interrupt + critical_section::with(|_| { + regs.cr1().modify(|w| w.set_tcie(false)); + }); } #[non_exhaustive] @@ -77,18 +68,6 @@ impl Default for Config { } } -pub struct State { - waker: AtomicWaker, -} - -impl State { - pub(crate) const fn new() -> Self { - Self { - waker: AtomicWaker::new(), - } - } -} - pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { _peri: PeripheralRef<'d, T>, #[allow(dead_code)] @@ -104,7 +83,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { peri: impl Peripheral

+ 'd, scl: impl Peripheral

> + 'd, sda: impl Peripheral

> + 'd, - _irq: impl interrupt::typelevel::Binding> + 'd, + _irq: impl interrupt::typelevel::Binding> + + interrupt::typelevel::Binding> + + 'd, tx_dma: impl Peripheral

+ 'd, rx_dma: impl Peripheral

+ 'd, freq: Hertz, @@ -150,8 +131,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { reg.set_pe(true); }); - T::Interrupt::unpend(); - unsafe { T::Interrupt::enable() }; + unsafe { T::EventInterrupt::enable() }; + unsafe { T::ErrorInterrupt::enable() }; Self { _peri: peri, @@ -987,35 +968,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { } } -#[cfg(feature = "time")] -mod eh02 { - use super::*; - - impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { - type Error = Error; - - fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { - self.blocking_read(address, buffer) - } - } - - impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> { - type Error = Error; - - fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { - self.blocking_write(address, write) - } - } - - impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> { - type Error = Error; - - fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { - self.blocking_write_read(address, write, read) - } - } -} - /// I2C Stop Configuration /// /// Peripheral options for generating the STOP condition @@ -1140,83 +1092,6 @@ impl Timings { } } -#[cfg(feature = "unstable-traits")] -mod eh1 { - use super::*; - - impl embedded_hal_1::i2c::Error for Error { - fn kind(&self) -> embedded_hal_1::i2c::ErrorKind { - match *self { - Self::Bus => embedded_hal_1::i2c::ErrorKind::Bus, - Self::Arbitration => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss, - Self::Nack => { - embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Unknown) - } - Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other, - Self::Crc => embedded_hal_1::i2c::ErrorKind::Other, - Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun, - Self::ZeroLengthTransfer => embedded_hal_1::i2c::ErrorKind::Other, - } - } - } - - impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for I2c<'d, T, TXDMA, RXDMA> { - type Error = Error; - } - - impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T, NoDma, NoDma> { - 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!(); - } - } -} - -#[cfg(all(feature = "unstable-traits", feature = "nightly"))] -mod eha { - use super::super::{RxDma, TxDma}; - use super::*; - - impl<'d, T: Instance, TXDMA: TxDma, RXDMA: RxDma> embedded_hal_async::i2c::I2c for I2c<'d, T, TXDMA, RXDMA> { - async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { - self.read(address, read).await - } - - async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { - self.write(address, write).await - } - - async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { - self.write_read(address, write, read).await - } - - async fn transaction( - &mut self, - address: u8, - operations: &mut [embedded_hal_1::i2c::Operation<'_>], - ) -> Result<(), Self::Error> { - let _ = address; - let _ = operations; - todo!() - } - } -} - impl<'d, T: Instance> SetConfig for I2c<'d, T> { type Config = Hertz; type ConfigError = (); diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs index 032bd97e..4f4adde2 100644 --- a/examples/stm32f4/src/bin/i2c.rs +++ b/examples/stm32f4/src/bin/i2c.rs @@ -14,7 +14,8 @@ const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; bind_interrupts!(struct Irqs { - I2C2_EV => i2c::InterruptHandler; + I2C2_EV => i2c::EventInterruptHandler; + I2C2_ER => i2c::ErrorInterruptHandler; }); #[embassy_executor::main] diff --git a/examples/stm32h5/src/bin/i2c.rs b/examples/stm32h5/src/bin/i2c.rs index 8b1662f3..31783a2b 100644 --- a/examples/stm32h5/src/bin/i2c.rs +++ b/examples/stm32h5/src/bin/i2c.rs @@ -13,7 +13,8 @@ const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; bind_interrupts!(struct Irqs { - I2C2_EV => i2c::InterruptHandler; + I2C2_EV => i2c::EventInterruptHandler; + I2C2_ER => i2c::ErrorInterruptHandler; }); #[embassy_executor::main] diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index 23ece1c3..489fb03d 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs @@ -19,7 +19,8 @@ const HEIGHT: usize = 100; static mut FRAME: [u32; WIDTH * HEIGHT / 2] = [0u32; WIDTH * HEIGHT / 2]; bind_interrupts!(struct Irqs { - I2C1_EV => i2c::InterruptHandler; + I2C1_EV => i2c::EventInterruptHandler; + I2C1_ER => i2c::ErrorInterruptHandler; DCMI => dcmi::InterruptHandler; }); diff --git a/examples/stm32h7/src/bin/i2c.rs b/examples/stm32h7/src/bin/i2c.rs index 9aa0ca08..aea21ec6 100644 --- a/examples/stm32h7/src/bin/i2c.rs +++ b/examples/stm32h7/src/bin/i2c.rs @@ -13,7 +13,8 @@ const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; bind_interrupts!(struct Irqs { - I2C2_EV => i2c::InterruptHandler; + I2C2_EV => i2c::EventInterruptHandler; + I2C2_ER => i2c::ErrorInterruptHandler; }); #[embassy_executor::main] diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs index d0060d20..07dc12e8 100644 --- a/examples/stm32l4/src/bin/i2c.rs +++ b/examples/stm32l4/src/bin/i2c.rs @@ -14,7 +14,8 @@ const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; bind_interrupts!(struct Irqs { - I2C2_EV => i2c::InterruptHandler; + I2C2_EV => i2c::EventInterruptHandler; + I2C2_ER => i2c::ErrorInterruptHandler; }); #[embassy_executor::main] diff --git a/examples/stm32l4/src/bin/i2c_blocking_async.rs b/examples/stm32l4/src/bin/i2c_blocking_async.rs index eca59087..60a4e2eb 100644 --- a/examples/stm32l4/src/bin/i2c_blocking_async.rs +++ b/examples/stm32l4/src/bin/i2c_blocking_async.rs @@ -16,7 +16,8 @@ const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; bind_interrupts!(struct Irqs { - I2C2_EV => i2c::InterruptHandler; + I2C2_EV => i2c::EventInterruptHandler; + I2C2_ER => i2c::ErrorInterruptHandler; }); #[embassy_executor::main] diff --git a/examples/stm32l4/src/bin/i2c_dma.rs b/examples/stm32l4/src/bin/i2c_dma.rs index cf6f3da6..4c2c224a 100644 --- a/examples/stm32l4/src/bin/i2c_dma.rs +++ b/examples/stm32l4/src/bin/i2c_dma.rs @@ -13,7 +13,8 @@ const ADDRESS: u8 = 0x5F; const WHOAMI: u8 = 0x0F; bind_interrupts!(struct Irqs { - I2C2_EV => i2c::InterruptHandler; + I2C2_EV => i2c::EventInterruptHandler; + I2C2_ER => i2c::ErrorInterruptHandler; }); #[embassy_executor::main] diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 3a7e5370..4826e0be 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -40,7 +40,8 @@ use static_cell::make_static; use {embassy_stm32 as hal, panic_probe as _}; bind_interrupts!(struct Irqs { - I2C3_EV => i2c::InterruptHandler; + I2C3_EV => i2c::EventInterruptHandler; + I2C3_ER => i2c::ErrorInterruptHandler; RNG => rng::InterruptHandler; }); From 3efc3eee5700d2a39e397f1b1b821885301c0862 Mon Sep 17 00:00:00 2001 From: Barnaby Walters Date: Mon, 20 Nov 2023 01:29:02 +0100 Subject: [PATCH 178/188] stm32/i2c: implement async i2c v1. --- embassy-stm32/src/i2c/v1.rs | 404 +++++++++++++++++++-- examples/stm32f4/src/bin/i2c_async.rs | 62 ++++ examples/stm32f4/src/bin/i2c_comparison.rs | 135 +++++++ 3 files changed, 578 insertions(+), 23 deletions(-) create mode 100644 examples/stm32f4/src/bin/i2c_async.rs create mode 100644 examples/stm32f4/src/bin/i2c_comparison.rs diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 03f07c4f..b62ee824 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -1,10 +1,14 @@ +use core::future::poll_fn; use core::marker::PhantomData; +use core::task::Poll; use embassy_embedded_hal::SetConfig; +use embassy_futures::select::{select, Either}; +use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::{into_ref, PeripheralRef}; use super::*; -use crate::dma::NoDma; +use crate::dma::{NoDma, Transfer}; use crate::gpio::sealed::AFType; use crate::gpio::Pull; use crate::interrupt::typelevel::Interrupt; @@ -13,7 +17,17 @@ use crate::time::Hertz; use crate::{interrupt, Peripheral}; pub unsafe fn on_interrupt() { - // todo + let regs = T::regs(); + // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of + // other stuff, so we wake the task on every interrupt. + T::state().waker.wake(); + critical_section::with(|_| { + // Clear event interrupt flag. + regs.cr2().modify(|w| { + w.set_itevten(false); + w.set_iterren(false); + }); + }); } #[non_exhaustive] @@ -98,40 +112,58 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } } - fn check_and_clear_error_flags(&self) -> Result { + fn check_and_clear_error_flags() -> Result { // Note that flags should only be cleared once they have been registered. If flags are // cleared otherwise, there may be an inherent race condition and flags may be missed. let sr1 = T::regs().sr1().read(); if sr1.timeout() { - T::regs().sr1().modify(|reg| reg.set_timeout(false)); + T::regs().sr1().write(|reg| { + reg.0 = !0; + reg.set_timeout(false); + }); return Err(Error::Timeout); } if sr1.pecerr() { - T::regs().sr1().modify(|reg| reg.set_pecerr(false)); + T::regs().sr1().write(|reg| { + reg.0 = !0; + reg.set_pecerr(false); + }); return Err(Error::Crc); } if sr1.ovr() { - T::regs().sr1().modify(|reg| reg.set_ovr(false)); + T::regs().sr1().write(|reg| { + reg.0 = !0; + reg.set_ovr(false); + }); return Err(Error::Overrun); } if sr1.af() { - T::regs().sr1().modify(|reg| reg.set_af(false)); + T::regs().sr1().write(|reg| { + reg.0 = !0; + reg.set_af(false); + }); return Err(Error::Nack); } if sr1.arlo() { - T::regs().sr1().modify(|reg| reg.set_arlo(false)); + T::regs().sr1().write(|reg| { + reg.0 = !0; + reg.set_arlo(false); + }); return Err(Error::Arbitration); } // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and // clearing the BERR bit instead. if sr1.berr() { - T::regs().sr1().modify(|reg| reg.set_berr(false)); + T::regs().sr1().write(|reg| { + reg.0 = !0; + reg.set_berr(false); + }); } Ok(sr1) @@ -150,13 +182,13 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { }); // Wait until START condition was generated - while !self.check_and_clear_error_flags()?.start() { + while !Self::check_and_clear_error_flags()?.start() { check_timeout()?; } // Also wait until signalled we're master and everything is waiting for us while { - self.check_and_clear_error_flags()?; + Self::check_and_clear_error_flags()?; let sr2 = T::regs().sr2().read(); !sr2.msl() && !sr2.busy() @@ -170,7 +202,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Wait until address was sent // Wait for the address to be acknowledged // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. - while !self.check_and_clear_error_flags()?.addr() { + while !Self::check_and_clear_error_flags()?.addr() { check_timeout()?; } @@ -190,7 +222,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Wait until we're ready for sending while { // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. - !self.check_and_clear_error_flags()?.txe() + !Self::check_and_clear_error_flags()?.txe() } { check_timeout()?; } @@ -201,7 +233,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Wait until byte is transferred while { // Check for any potential error conditions. - !self.check_and_clear_error_flags()?.btf() + !Self::check_and_clear_error_flags()?.btf() } { check_timeout()?; } @@ -212,7 +244,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { fn recv_byte(&self, check_timeout: impl Fn() -> Result<(), Error>) -> Result { while { // Check for any potential error conditions. - self.check_and_clear_error_flags()?; + Self::check_and_clear_error_flags()?; !T::regs().sr1().read().rxne() } { @@ -237,7 +269,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { }); // Wait until START condition was generated - while !self.check_and_clear_error_flags()?.start() { + while !Self::check_and_clear_error_flags()?.start() { check_timeout()?; } @@ -254,7 +286,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Wait until address was sent // Wait for the address to be acknowledged - while !self.check_and_clear_error_flags()?.addr() { + while !Self::check_and_clear_error_flags()?.addr() { check_timeout()?; } @@ -332,26 +364,352 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { // Async - pub async fn write(&mut self, _address: u8, _write: &[u8]) -> Result<(), Error> + #[inline] // pretty sure this should always be inlined + fn enable_interrupts() -> () { + T::regs().cr2().modify(|w| { + w.set_iterren(true); + w.set_itevten(true); + }); + } + + async fn write_with_stop(&mut self, address: u8, write: &[u8], send_stop: bool) -> Result<(), Error> where TXDMA: crate::i2c::TxDma, { - todo!() + let dma_transfer = unsafe { + let regs = T::regs(); + regs.cr2().modify(|w| { + // DMA mode can be enabled for transmission by setting the DMAEN bit in the I2C_CR2 register. + w.set_dmaen(true); + w.set_itbufen(false); + }); + // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved to this address from the memory after each TxE event. + let dst = regs.dr().as_ptr() as *mut u8; + + let ch = &mut self.tx_dma; + let request = ch.request(); + Transfer::new_write(ch, request, write, dst, Default::default()) + }; + + let on_drop = OnDrop::new(|| { + let regs = T::regs(); + regs.cr2().modify(|w| { + w.set_dmaen(false); + w.set_iterren(false); + w.set_itevten(false); + }) + }); + + Self::enable_interrupts(); + + // Send a START condition + T::regs().cr1().modify(|reg| { + reg.set_start(true); + }); + + let state = T::state(); + + // Wait until START condition was generated + poll_fn(|cx| { + state.waker.register(cx.waker()); + + match Self::check_and_clear_error_flags() { + Err(e) => Poll::Ready(Err(e)), + Ok(sr1) => { + if sr1.start() { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + } + }) + .await?; + + // Also wait until signalled we're master and everything is waiting for us + Self::enable_interrupts(); + poll_fn(|cx| { + state.waker.register(cx.waker()); + + match Self::check_and_clear_error_flags() { + Err(e) => Poll::Ready(Err(e)), + Ok(_) => { + let sr2 = T::regs().sr2().read(); + if !sr2.msl() && !sr2.busy() { + Poll::Pending + } else { + Poll::Ready(Ok(())) + } + } + } + }) + .await?; + + // Set up current address, we're trying to talk to + Self::enable_interrupts(); + T::regs().dr().write(|reg| reg.set_dr(address << 1)); + + poll_fn(|cx| { + state.waker.register(cx.waker()); + match Self::check_and_clear_error_flags() { + Err(e) => Poll::Ready(Err(e)), + Ok(sr1) => { + if sr1.addr() { + // Clear the ADDR condition by reading SR2. + T::regs().sr2().read(); + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + } + }) + .await?; + Self::enable_interrupts(); + let poll_error = poll_fn(|cx| { + state.waker.register(cx.waker()); + + match Self::check_and_clear_error_flags() { + // Unclear why the Err turbofish is necessary here? The compiler didn’t require it in the other + // identical poll_fn check_and_clear matches. + Err(e) => Poll::Ready(Err::(e)), + Ok(_) => Poll::Pending, + } + }); + + // Wait for either the DMA transfer to successfully finish, or an I2C error to occur. + match select(dma_transfer, poll_error).await { + Either::Second(Err(e)) => Err(e), + _ => Ok(()), + }?; + + // The I2C transfer itself will take longer than the DMA transfer, so wait for that to finish too. + + // 18.3.8 “Master transmitter: In the interrupt routine after the EOT interrupt, disable DMA + // requests then wait for a BTF event before programming the Stop condition.” + + // TODO: If this has to be done “in the interrupt routine after the EOT interrupt”, where to put it? + T::regs().cr2().modify(|w| { + w.set_dmaen(false); + }); + + Self::enable_interrupts(); + poll_fn(|cx| { + state.waker.register(cx.waker()); + + match Self::check_and_clear_error_flags() { + Err(e) => Poll::Ready(Err(e)), + Ok(sr1) => { + if sr1.btf() { + if send_stop { + T::regs().cr1().modify(|w| { + w.set_stop(true); + }); + } + + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + } + }) + .await?; + + drop(on_drop); + + // Fallthrough is success + Ok(()) } - pub async fn read(&mut self, _address: u8, _buffer: &mut [u8]) -> Result<(), Error> + pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> + where + TXDMA: crate::i2c::TxDma, + { + self.write_with_stop(address, write, true).await?; + + // Wait for STOP condition to transmit. + Self::enable_interrupts(); + poll_fn(|cx| { + T::state().waker.register(cx.waker()); + // TODO: error interrupts are enabled here, should we additional check for and return errors? + if T::regs().cr1().read().stop() { + Poll::Pending + } else { + Poll::Ready(Ok(())) + } + }) + .await?; + + Ok(()) + } + + pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> where RXDMA: crate::i2c::RxDma, { - todo!() + let state = T::state(); + let buffer_len = buffer.len(); + + let dma_transfer = unsafe { + let regs = T::regs(); + regs.cr2().modify(|w| { + // DMA mode can be enabled for transmission by setting the DMAEN bit in the I2C_CR2 register. + w.set_itbufen(false); + w.set_dmaen(true); + }); + // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved to this address from the memory after each TxE event. + let src = regs.dr().as_ptr() as *mut u8; + + let ch = &mut self.rx_dma; + let request = ch.request(); + Transfer::new_read(ch, request, src, buffer, Default::default()) + }; + + let on_drop = OnDrop::new(|| { + let regs = T::regs(); + regs.cr2().modify(|w| { + w.set_dmaen(false); + w.set_iterren(false); + w.set_itevten(false); + }) + }); + + Self::enable_interrupts(); + + // Send a START condition and set ACK bit + T::regs().cr1().modify(|reg| { + reg.set_start(true); + reg.set_ack(true); + }); + + // Wait until START condition was generated + poll_fn(|cx| { + state.waker.register(cx.waker()); + + match Self::check_and_clear_error_flags() { + Err(e) => Poll::Ready(Err(e)), + Ok(sr1) => { + if sr1.start() { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + } + }) + .await?; + + // Also wait until signalled we're master and everything is waiting for us + Self::enable_interrupts(); + poll_fn(|cx| { + state.waker.register(cx.waker()); + + // blocking read didn’t have a check_and_clear call here, but blocking write did so + // I’m adding it here in case that was an oversight. + match Self::check_and_clear_error_flags() { + Err(e) => Poll::Ready(Err(e)), + Ok(_) => { + let sr2 = T::regs().sr2().read(); + if !sr2.msl() && !sr2.busy() { + Poll::Pending + } else { + Poll::Ready(Ok(())) + } + } + } + }) + .await?; + + // Set up current address, we're trying to talk to + T::regs().dr().write(|reg| reg.set_dr((address << 1) + 1)); + + // Wait for the address to be acknowledged + + Self::enable_interrupts(); + poll_fn(|cx| { + state.waker.register(cx.waker()); + + match Self::check_and_clear_error_flags() { + Err(e) => Poll::Ready(Err(e)), + Ok(sr1) => { + if sr1.addr() { + // 18.3.8: When a single byte must be received: the NACK must be programmed during EV6 + // event, i.e. program ACK=0 when ADDR=1, before clearing ADDR flag. + if buffer_len == 1 { + T::regs().cr1().modify(|w| { + w.set_ack(false); + }); + } + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + } + }) + .await?; + + // Clear ADDR condition by reading SR2 + T::regs().sr2().read(); + + // 18.3.8: When a single byte must be received: [snip] Then the + // user can program the STOP condition either after clearing ADDR flag, or in the + // DMA Transfer Complete interrupt routine. + if buffer_len == 1 { + T::regs().cr1().modify(|w| { + w.set_stop(true); + }); + } else { + // If, in the I2C_CR2 register, the LAST bit is set, I2C + // automatically sends a NACK after the next byte following EOT_1. The user can + // generate a Stop condition in the DMA Transfer Complete interrupt routine if enabled. + T::regs().cr2().modify(|w| { + w.set_last(true); + }) + } + + // Wait for bytes to be received, or an error to occur. + Self::enable_interrupts(); + let poll_error = poll_fn(|cx| { + state.waker.register(cx.waker()); + + match Self::check_and_clear_error_flags() { + Err(e) => Poll::Ready(Err::(e)), + _ => Poll::Pending, + } + }); + + match select(dma_transfer, poll_error).await { + Either::Second(Err(e)) => Err(e), + _ => Ok(()), + }?; + + // Wait for the STOP to be sent (STOP bit cleared). + Self::enable_interrupts(); + poll_fn(|cx| { + state.waker.register(cx.waker()); + // TODO: error interrupts are enabled here, should we additional check for and return errors? + if T::regs().cr1().read().stop() { + Poll::Pending + } else { + Poll::Ready(Ok(())) + } + }) + .await?; + drop(on_drop); + + // Fallthrough is success + Ok(()) } - pub async fn write_read(&mut self, _address: u8, _write: &[u8], _read: &mut [u8]) -> Result<(), Error> + pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> where RXDMA: crate::i2c::RxDma, TXDMA: crate::i2c::TxDma, { - todo!() + self.write_with_stop(address, write, false).await?; + self.read(address, read).await } } diff --git a/examples/stm32f4/src/bin/i2c_async.rs b/examples/stm32f4/src/bin/i2c_async.rs new file mode 100644 index 00000000..9f59e4d4 --- /dev/null +++ b/examples/stm32f4/src/bin/i2c_async.rs @@ -0,0 +1,62 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +// Example originally designed for stm32f411ceu6 reading an A1454 hall effect sensor on I2C1 +// DMA peripherals changed to compile for stm32f429zi, for the CI. + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::i2c::I2c; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, i2c, peripherals}; +use {defmt_rtt as _, panic_probe as _}; + +const ADDRESS: u8 = 96; + +bind_interrupts!(struct Irqs { + I2C1_EV => i2c::EventInterruptHandler; + I2C1_ER => i2c::ErrorInterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Hello world!"); + let p = embassy_stm32::init(Default::default()); + + let mut i2c = I2c::new( + p.I2C1, + p.PB8, + p.PB7, + Irqs, + p.DMA1_CH6, + p.DMA1_CH0, + Hertz(100_000), + Default::default(), + ); + + loop { + let a1454_read_sensor_command = [0x1F]; + let mut sensor_data_buffer: [u8; 4] = [0, 0, 0, 0]; + + match i2c + .write_read(ADDRESS, &a1454_read_sensor_command, &mut sensor_data_buffer) + .await + { + Ok(()) => { + // Convert 12-bit signed integer into 16-bit signed integer. + // Is the 12 bit number negative? + if (sensor_data_buffer[2] & 0b00001000) == 0b0001000 { + sensor_data_buffer[2] = sensor_data_buffer[2] | 0b11110000; + } + + let mut sensor_value_raw: u16 = sensor_data_buffer[3].into(); + sensor_value_raw |= (sensor_data_buffer[2] as u16) << 8; + let sensor_value: u16 = sensor_value_raw.into(); + let sensor_value = sensor_value as i16; + info!("Data: {}", sensor_value); + } + Err(e) => error!("I2C Error during read: {:?}", e), + } + } +} diff --git a/examples/stm32f4/src/bin/i2c_comparison.rs b/examples/stm32f4/src/bin/i2c_comparison.rs new file mode 100644 index 00000000..6d23c0ed --- /dev/null +++ b/examples/stm32f4/src/bin/i2c_comparison.rs @@ -0,0 +1,135 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +// Example originally designed for stm32f411ceu6 with three A1454 hall effect sensors, connected to I2C1, 2 and 3 +// on the pins referenced in the peripheral definitions. +// Pins and DMA peripherals changed to compile for stm32f429zi, to work with the CI. +// MUST be compiled in release mode to see actual performance, otherwise the async transactions take 2x +// as long to complete as the blocking ones! + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::i2c::I2c; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, i2c, peripherals}; +use embassy_time::Instant; +use futures::future::try_join3; +use {defmt_rtt as _, panic_probe as _}; + +const ADDRESS: u8 = 96; + +bind_interrupts!(struct Irqs { + I2C1_EV => i2c::EventInterruptHandler; + I2C1_ER => i2c::ErrorInterruptHandler; + I2C2_EV => i2c::EventInterruptHandler; + I2C2_ER => i2c::ErrorInterruptHandler; + I2C3_EV => i2c::EventInterruptHandler; + I2C3_ER => i2c::ErrorInterruptHandler; +}); + +/// Convert 12-bit signed integer within a 4 byte long buffer into 16-bit signed integer. +fn a1454_buf_to_i16(buffer: &[u8; 4]) -> i16 { + let lower = buffer[3]; + let mut upper = buffer[2]; + // Fill in additional 1s if the 12 bit number is negative. + if (upper & 0b00001000) == 0b0001000 { + upper = upper | 0b11110000; + } + + let mut sensor_value_raw: u16 = lower.into(); + sensor_value_raw |= (upper as u16) << 8; + let sensor_value: u16 = sensor_value_raw.into(); + let sensor_value = sensor_value as i16; + sensor_value +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Setting up peripherals."); + let p = embassy_stm32::init(Default::default()); + + let mut i2c1 = I2c::new( + p.I2C1, + p.PB8, + p.PB7, + Irqs, + p.DMA1_CH6, + p.DMA1_CH0, + Hertz(100_000), + Default::default(), + ); + + let mut i2c2 = I2c::new( + p.I2C2, + p.PB10, + p.PB11, + Irqs, + p.DMA1_CH7, + p.DMA1_CH3, + Hertz(100_000), + Default::default(), + ); + + let mut i2c3 = I2c::new( + p.I2C3, + p.PA8, + p.PC9, + Irqs, + p.DMA1_CH4, + p.DMA1_CH2, + Hertz(100_000), + Default::default(), + ); + + let a1454_read_sensor_command = [0x1F]; + let mut i2c1_buffer: [u8; 4] = [0, 0, 0, 0]; + let mut i2c2_buffer: [u8; 4] = [0, 0, 0, 0]; + let mut i2c3_buffer: [u8; 4] = [0, 0, 0, 0]; + loop { + // Blocking reads one after the other. Completes in about 2000us. + let blocking_read_start_us = Instant::now().as_micros(); + match i2c1.blocking_write_read(ADDRESS, &a1454_read_sensor_command, &mut i2c1_buffer) { + Ok(()) => {} + Err(e) => error!("I2C Error: {:?}", e), + } + match i2c2.blocking_write_read(ADDRESS, &a1454_read_sensor_command, &mut i2c2_buffer) { + Ok(()) => {} + Err(e) => error!("I2C Error: {:?}", e), + } + match i2c3.blocking_write_read(ADDRESS, &a1454_read_sensor_command, &mut i2c3_buffer) { + Ok(()) => {} + Err(e) => error!("I2C Error: {:?}", e), + } + let blocking_read_total_us = Instant::now().as_micros() - blocking_read_start_us; + info!( + "Blocking reads completed in {}us: i2c1: {} i2c2: {} i2c3: {}", + blocking_read_total_us, + a1454_buf_to_i16(&i2c1_buffer), + a1454_buf_to_i16(&i2c2_buffer), + a1454_buf_to_i16(&i2c3_buffer) + ); + + // Async reads overlapping. Completes in about 1000us. + let async_read_start_us = Instant::now().as_micros(); + + let i2c1_result = i2c1.write_read(ADDRESS, &a1454_read_sensor_command, &mut i2c1_buffer); + let i2c2_result = i2c2.write_read(ADDRESS, &a1454_read_sensor_command, &mut i2c2_buffer); + let i2c3_result = i2c3.write_read(ADDRESS, &a1454_read_sensor_command, &mut i2c3_buffer); + + // Wait for all three transactions to finish, or any one of them to fail. + match try_join3(i2c1_result, i2c2_result, i2c3_result).await { + Ok(_) => { + let async_read_total_us = Instant::now().as_micros() - async_read_start_us; + info!( + "Async reads completed in {}us: i2c1: {} i2c2: {} i2c3: {}", + async_read_total_us, + a1454_buf_to_i16(&i2c1_buffer), + a1454_buf_to_i16(&i2c2_buffer), + a1454_buf_to_i16(&i2c3_buffer) + ); + } + Err(e) => error!("I2C Error during async write-read: {}", e), + }; + } +} From 2218d30c8039b994ead02acc26130d25599d78ac Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 19 Nov 2023 03:06:30 +0000 Subject: [PATCH 179/188] STM32: Remove vestigal build.rs cfgs, add new flashsize_X and package_X cfgs, use in F3 RCC --- embassy-stm32/build.rs | 18 ++++-------------- embassy-stm32/src/rcc/f3.rs | 5 +---- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 4aae5822..d92d9217 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -65,7 +65,6 @@ fn main() { match r.kind { // Generate singletons per pin, not per port "gpio" => { - println!("{}", p.name); let port_letter = p.name.strip_prefix("GPIO").unwrap(); for pin_num in 0..16 { singletons.push(format!("P{}{}", port_letter, pin_num)); @@ -1352,15 +1351,6 @@ fn main() { if let Some(core) = core_name { println!("cargo:rustc-cfg={}_{}", &chip_name[..chip_name.len() - 2], core); - } else { - println!("cargo:rustc-cfg={}", &chip_name[..chip_name.len() - 2]); - } - - // ======== - // stm32f3 wildcard features used in RCC - - if chip_name.starts_with("stm32f3") { - println!("cargo:rustc-cfg={}x{}", &chip_name[..9], &chip_name[10..11]); } // ======= @@ -1375,17 +1365,17 @@ fn main() { if &chip_name[..8] == "stm32wba" { println!("cargo:rustc-cfg={}", &chip_name[..8]); // stm32wba println!("cargo:rustc-cfg={}", &chip_name[..10]); // stm32wba52 + println!("cargo:rustc-cfg=package_{}", &chip_name[10..11]); + println!("cargo:rustc-cfg=flashsize_{}", &chip_name[11..12]); } else { println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4 println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429 println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9 + println!("cargo:rustc-cfg=package_{}", &chip_name[9..10]); + println!("cargo:rustc-cfg=flashsize_{}", &chip_name[10..11]); } - // Handle time-driver-XXXX features. - if env::var("CARGO_FEATURE_TIME_DRIVER_ANY").is_ok() {} - println!("cargo:rustc-cfg={}", &chip_name[..chip_name.len() - 2]); - println!("cargo:rerun-if-changed=build.rs"); } diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 9dcd50df..bf035fd2 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -346,10 +346,7 @@ fn calc_pll(config: &Config, Hertz(sysclk): Hertz) -> (Hertz, PllConfig) { None => { cfg_if::cfg_if! { // For some chips PREDIV is always two, and cannot be changed - if #[cfg(any( - stm32f302xd, stm32f302xe, stm32f303xd, - stm32f303xe, stm32f398xe - ))] { + if #[cfg(any(flashsize_d, flashsize_e))] { let (multiplier, divisor) = get_mul_div(sysclk, HSI_FREQ.0); ( Hertz((HSI_FREQ.0 / divisor) * multiplier), From 897663e023fa0e7fc84b6023a4f190af28b57295 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 19 Nov 2023 04:26:36 +0000 Subject: [PATCH 180/188] STM32: Add cfg to differentiate L4 and L4+ families --- embassy-stm32/build.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index d92d9217..2011fd17 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1376,6 +1376,15 @@ fn main() { println!("cargo:rustc-cfg=flashsize_{}", &chip_name[10..11]); } + // Mark the L4+ chips as they have many differences to regular L4. + if &chip_name[..7] == "stm32l4" { + if "pqrs".contains(&chip_name[7..8]) { + println!("cargo:rustc-cfg=stm32l4_plus"); + } else { + println!("cargo:rustc-cfg=stm32l4_nonplus"); + } + } + println!("cargo:rerun-if-changed=build.rs"); } From 135f3500208cae05293fe588763edde99ed409be Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 19 Nov 2023 04:29:29 +0000 Subject: [PATCH 181/188] STM32 DAC: Use new Mode enum for setting channel mode --- embassy-stm32/src/dac/mod.rs | 65 ++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 3d1a820e..b87d6e49 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -5,10 +5,53 @@ use core::marker::PhantomData; use embassy_hal_internal::{into_ref, PeripheralRef}; +#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] use crate::pac::dac; use crate::rcc::RccPeripheral; use crate::{peripherals, Peripheral}; +#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum Mode { + /// Normal mode, channel is connected to external pin with buffer enabled. + NormalExternalBuffered, + /// Normal mode, channel is connected to external pin and internal peripherals + /// with buffer enabled. + NormalBothBuffered, + /// Normal mode, channel is connected to external pin with buffer disabled. + NormalExternalUnbuffered, + /// Normal mode, channel is connected to internal peripherals with buffer disabled. + NormalInternalUnbuffered, + /// Sample-and-hold mode, channel is connected to external pin with buffer enabled. + SampleHoldExternalBuffered, + /// Sample-and-hold mode, channel is connected to external pin and internal peripherals + /// with buffer enabled. + SampleHoldBothBuffered, + /// Sample-and-hold mode, channel is connected to external pin and internal peripherals + /// with buffer disabled. + SampleHoldBothUnbuffered, + /// Sample-and-hold mode, channel is connected to internal peripherals with buffer disabled. + SampleHoldInternalUnbuffered, +} + +#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] +impl Mode { + fn mode(&self) -> dac::vals::Mode { + match self { + Mode::NormalExternalBuffered => dac::vals::Mode::NORMAL_EXT_BUFEN, + Mode::NormalBothBuffered => dac::vals::Mode::NORMAL_EXT_INT_BUFEN, + Mode::NormalExternalUnbuffered => dac::vals::Mode::NORMAL_EXT_BUFDIS, + Mode::NormalInternalUnbuffered => dac::vals::Mode::NORMAL_INT_BUFDIS, + Mode::SampleHoldExternalBuffered => dac::vals::Mode::SAMPHOLD_EXT_BUFEN, + Mode::SampleHoldBothBuffered => dac::vals::Mode::SAMPHOLD_EXT_INT_BUFEN, + Mode::SampleHoldBothUnbuffered => dac::vals::Mode::SAMPHOLD_EXT_INT_BUFDIS, + Mode::SampleHoldInternalUnbuffered => dac::vals::Mode::SAMPHOLD_INT_BUFDIS, + } + } +} + + #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] /// Custom Errors @@ -164,10 +207,10 @@ pub trait DacChannel { } /// Set mode register of the given channel - #[cfg(any(dac_v2, dac_v3))] - fn set_channel_mode(&mut self, val: u8) -> Result<(), Error> { + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + fn set_channel_mode(&mut self, mode: Mode) -> Result<(), Error> { T::regs().mcr().modify(|reg| { - reg.set_mode(Self::CHANNEL.index(), val); + reg.set_mode(Self::CHANNEL.index(), mode.mode()); }); Ok(()) } @@ -261,8 +304,8 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { // Configure each activated channel. All results can be `unwrap`ed since they // will only error if the channel is not configured (i.e. ch1, ch2 are false) - #[cfg(any(dac_v2, dac_v3))] - dac.set_channel_mode(0).unwrap(); + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + dac.set_channel_mode(Mode::NormalExternalBuffered).unwrap(); dac.enable_channel().unwrap(); dac.set_trigger_enable(true).unwrap(); @@ -374,8 +417,8 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { // Configure each activated channel. All results can be `unwrap`ed since they // will only error if the channel is not configured (i.e. ch1, ch2 are false) - #[cfg(any(dac_v2, dac_v3))] - dac.set_channel_mode(0).unwrap(); + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + dac.set_channel_mode(Mode::NormalExternalBuffered).unwrap(); dac.enable_channel().unwrap(); dac.set_trigger_enable(true).unwrap(); @@ -495,13 +538,13 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> { // Configure each activated channel. All results can be `unwrap`ed since they // will only error if the channel is not configured (i.e. ch1, ch2 are false) - #[cfg(any(dac_v2, dac_v3))] - dac_ch1.set_channel_mode(0).unwrap(); + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v73))] + dac_ch1.set_channel_mode(Mode::NormalExternalBuffered).unwrap(); dac_ch1.enable_channel().unwrap(); dac_ch1.set_trigger_enable(true).unwrap(); - #[cfg(any(dac_v2, dac_v3))] - dac_ch2.set_channel_mode(0).unwrap(); + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + dac_ch2.set_channel_mode(Mode::NormalExternalBuffered).unwrap(); dac_ch2.enable_channel().unwrap(); dac_ch2.set_trigger_enable(true).unwrap(); From 31fc337e2f988720b7909575501e95af8707c1be Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 19 Nov 2023 04:30:28 +0000 Subject: [PATCH 182/188] STM32 DAC: Swap to new TSEL enum entirely in-HAL --- embassy-stm32/src/dac/mod.rs | 140 +++----------- embassy-stm32/src/dac/tsel.rs | 282 ++++++++++++++++++++++++++++ examples/stm32h7/src/bin/dac_dma.rs | 4 +- examples/stm32l4/src/bin/dac_dma.rs | 4 +- 4 files changed, 310 insertions(+), 120 deletions(-) create mode 100644 embassy-stm32/src/dac/tsel.rs diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index b87d6e49..6d51c1e9 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -10,6 +10,9 @@ use crate::pac::dac; use crate::rcc::RccPeripheral; use crate::{peripherals, Peripheral}; +mod tsel; +pub use tsel::TriggerSel; + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -51,7 +54,6 @@ impl Mode { } } - #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] /// Custom Errors @@ -77,100 +79,6 @@ impl Channel { } } -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Trigger sources for CH1 -pub enum Ch1Trigger { - #[cfg(dac_v3)] - Tim1, - Tim2, - #[cfg(not(dac_v3))] - Tim3, - #[cfg(dac_v3)] - Tim4, - #[cfg(dac_v3)] - Tim5, - Tim6, - Tim7, - #[cfg(dac_v3)] - Tim8, - Tim15, - #[cfg(dac_v3)] - Hrtim1Dactrg1, - #[cfg(dac_v3)] - Hrtim1Dactrg2, - #[cfg(dac_v3)] - Lptim1, - #[cfg(dac_v3)] - Lptim2, - #[cfg(dac_v3)] - Lptim3, - Exti9, - Software, -} - -impl Ch1Trigger { - fn tsel(&self) -> dac::vals::Tsel1 { - match self { - #[cfg(dac_v3)] - Ch1Trigger::Tim1 => dac::vals::Tsel1::TIM1_TRGO, - Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_TRGO, - #[cfg(not(dac_v3))] - Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM3_TRGO, - #[cfg(dac_v3)] - Ch1Trigger::Tim4 => dac::vals::Tsel1::TIM4_TRGO, - #[cfg(dac_v3)] - Ch1Trigger::Tim5 => dac::vals::Tsel1::TIM5_TRGO, - Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO, - Ch1Trigger::Tim7 => dac::vals::Tsel1::TIM7_TRGO, - #[cfg(dac_v3)] - Ch1Trigger::Tim8 => dac::vals::Tsel1::TIM8_TRGO, - Ch1Trigger::Tim15 => dac::vals::Tsel1::TIM15_TRGO, - #[cfg(dac_v3)] - Ch1Trigger::Hrtim1Dactrg1 => dac::vals::Tsel1::HRTIM1_DACTRG1, - #[cfg(dac_v3)] - Ch1Trigger::Hrtim1Dactrg2 => dac::vals::Tsel1::HRTIM1_DACTRG2, - #[cfg(dac_v3)] - Ch1Trigger::Lptim1 => dac::vals::Tsel1::LPTIM1_OUT, - #[cfg(dac_v3)] - Ch1Trigger::Lptim2 => dac::vals::Tsel1::LPTIM2_OUT, - #[cfg(dac_v3)] - Ch1Trigger::Lptim3 => dac::vals::Tsel1::LPTIM3_OUT, - Ch1Trigger::Exti9 => dac::vals::Tsel1::EXTI9, - Ch1Trigger::Software => dac::vals::Tsel1::SOFTWARE, - } - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Trigger sources for CH2 -pub enum Ch2Trigger { - Tim6, - Tim8, - Tim7, - Tim5, - Tim2, - Tim4, - Exti9, - Software, -} - -impl Ch2Trigger { - fn tsel(&self) -> dac::vals::Tsel2 { - match self { - Ch2Trigger::Tim6 => dac::vals::Tsel2::TIM6_TRGO, - Ch2Trigger::Tim8 => dac::vals::Tsel2::TIM8_TRGO, - Ch2Trigger::Tim7 => dac::vals::Tsel2::TIM7_TRGO, - Ch2Trigger::Tim5 => dac::vals::Tsel2::TIM5_TRGO, - Ch2Trigger::Tim2 => dac::vals::Tsel2::TIM2_TRGO, - Ch2Trigger::Tim4 => dac::vals::Tsel2::TIM4_TRGO, - Ch2Trigger::Exti9 => dac::vals::Tsel2::EXTI9, - Ch2Trigger::Software => dac::vals::Tsel2::SOFTWARE, - } - } -} - #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] /// Single 8 or 12 bit value that can be output by the DAC @@ -315,10 +223,10 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { /// Select a new trigger for this channel /// /// **Important**: This disables the channel! - pub fn select_trigger(&mut self, trigger: Ch1Trigger) -> Result<(), Error> { + pub fn select_trigger(&mut self, trigger: TriggerSel) -> Result<(), Error> { unwrap!(self.disable_channel()); T::regs().cr().modify(|reg| { - reg.set_tsel1(trigger.tsel()); + reg.set_tsel(0, trigger.tsel()); }); Ok(()) } @@ -426,10 +334,10 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { } /// Select a new trigger for this channel - pub fn select_trigger(&mut self, trigger: Ch2Trigger) -> Result<(), Error> { + pub fn select_trigger(&mut self, trigger: TriggerSel) -> Result<(), Error> { unwrap!(self.disable_channel()); T::regs().cr().modify(|reg| { - reg.set_tsel2(trigger.tsel()); + reg.set_tsel(1, trigger.tsel()); }); Ok(()) } @@ -603,26 +511,26 @@ 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().pclk1 }) - } + // 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().pclk1 }) + } - 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 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_with_cs(_cs: critical_section::CriticalSection) { - 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)) + } + } - #[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/dac/tsel.rs b/embassy-stm32/src/dac/tsel.rs new file mode 100644 index 00000000..f38dd8fd --- /dev/null +++ b/embassy-stm32/src/dac/tsel.rs @@ -0,0 +1,282 @@ +/// Trigger selection for STM32F0. +#[cfg(stm32f0)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim3 = 1, + Tim7 = 2, + Tim15 = 3, + Tim2 = 4, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F1. +#[cfg(stm32f1)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + #[cfg(any(stm32f100, stm32f105, stm32f107))] + Tim3 = 1, + #[cfg(any(stm32f101, stm32f103))] + Tim8 = 1, + Tim7 = 2, + #[cfg(any(stm32f101, stm32f103, stm32f105, stm32f107))] + Tim5 = 3, + #[cfg(all(stm32f100, any(flashsize_4, flashsize_6, flashsize_8, flashsize_b)))] + Tim15 = 3, + #[cfg(all(stm32f100, any(flashsize_c, flashsize_d, flashsize_e)))] + /// Can be remapped to TIM15 with MISC_REMAP in AFIO_MAPR2. + Tim5Or15 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F2/F4/F7/L4, except F410 or L4+. +#[cfg(all(any(stm32f2, stm32f4, stm32f7, stm32l4_nonplus), not(stm32f410)))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim8 = 1, + #[cfg(not(any(stm32l45x, stm32l46x)))] + Tim7 = 2, + Tim5 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F410. +#[cfg(stm32f410)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim5 = 3, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F301/2 and 318. +#[cfg(any(stm32f301, stm32f302, stm32f318))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + #[cfg(stm32f302)] + /// Requires DAC_TRIG_RMP set in SYSCFG_CFGR1. + Tim3 = 1, + Tim15 = 3, + Tim2 = 4, + #[cfg(all(stm32f302, any(flashsize_6, flashsize_8)))] + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F303/3x8 (excluding 318 which is like 301, and 378 which is 37x). +#[cfg(any(stm32f303, stm32f328, stm32f358, stm32f398))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + /// * DAC1: defaults to TIM8 but can be remapped to TIM3 with DAC_TRIG_RMP in SYSCFG_CFGR1 + /// * DAC2: always TIM3 + Tim8Or3 = 1, + Tim7 = 2, + Tim15 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F37x. +#[cfg(any(stm32f373, stm32f378))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim3 = 1, + Tim7 = 2, + /// TIM5 on DAC1, TIM18 on DAC2 + Dac1Tim5Dac2Tim18 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F334. +#[cfg(stm32f334)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + /// Requires DAC_TRIG_RMP set in SYSCFG_CFGR1. + Tim3 = 1, + Tim7 = 2, + /// Can be remapped to HRTIM_DACTRG1 using DAC1_TRIG3_RMP in SYSCFG_CFGR3. + Tim15OrHrtimDacTrg1 = 3, + Tim2 = 4, + /// Requires DAC_TRIG5_RMP set in SYSCFG_CFGR3. + HrtimDacTrg2 = 5, +} + +/// Trigger selection for STM32L0. +#[cfg(stm32l0)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim3 = 1, + Tim3Ch3 = 2, + Tim21 = 3, + Tim2 = 4, + Tim7 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32L1. +#[cfg(stm32l1)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim7 = 2, + Tim9 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for L4+, L5, U5, H7. +#[cfg(any(stm32l4_plus, stm32l5, stm32u5, stm32h7))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + Tim4 = 3, + Tim5 = 4, + Tim6 = 5, + Tim7 = 6, + Tim8 = 7, + Tim15 = 8, + #[cfg(all(stm32h7, hrtim))] + Hrtim1DacTrg1 = 9, + #[cfg(all(stm32h7, hrtim))] + Hrtim1DacTrg2 = 10, + Lptim1 = 11, + #[cfg(not(stm32u5))] + Lptim2 = 12, + #[cfg(stm32u5)] + Lptim3 = 12, + Exti9 = 13, + #[cfg(any(stm32h7ax, stm32h7bx))] + /// RM0455 suggests this might be LPTIM2 on DAC1 and LPTIM3 on DAC2, + /// but it's probably wrong. Please let us know if you find out. + Lptim3 = 14, + #[cfg(any(stm32h72x, stm32h73x))] + Tim23 = 14, + #[cfg(any(stm32h72x, stm32h73x))] + Tim24 = 15, +} + +/// Trigger selection for H5. +#[cfg(stm32h5)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + #[cfg(any(stm32h56x, stm32h57x))] + Tim4 = 3, + #[cfg(stm32h503)] + Tim3 = 3, + #[cfg(any(stm32h56x, stm32h57x))] + Tim5 = 4, + Tim6 = 5, + Tim7 = 6, + #[cfg(any(stm32h56x, stm32h57x))] + Tim8 = 7, + #[cfg(any(stm32h56x, stm32h57x))] + Tim15 = 8, + Lptim1 = 11, + Lptim2 = 12, + Exti9 = 13, +} + +/// Trigger selection for G0. +#[cfg(stm32g0)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + Tim3 = 3, + Tim6 = 5, + Tim7 = 6, + Tim15 = 8, + Lptim1 = 11, + Lptim2 = 12, + Exti9 = 13, +} + +/// Trigger selection for G4. +#[cfg(stm32g4)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + /// * DAC1, DAC2, DAC4: TIM8 + /// * DAC3: TIM1 + Dac124Tim8Dac3Tim1 = 1, + Tim7 = 2, + Tim15 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Tim6 = 7, + Tim3 = 8, + HrtimDacRstTrg1 = 9, + HrtimDacRstTrg2 = 10, + HrtimDacRstTrg3 = 11, + HrtimDacRstTrg4 = 12, + HrtimDacRstTrg5 = 13, + HrtimDacRstTrg6 = 14, + /// * DAC1, DAC4: HRTIM_DAC_TRG1 + /// * DAC2: HRTIM_DAC_TRG2 + /// * DAC3: HRTIM_DAC_TRG3 + HrtimDacTrg123 = 15, +} + +/// Trigger selection for WL. +#[cfg(stm32wl)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + Lptim1 = 11, + Lptim2 = 12, + Lptim3 = 13, + Exti9 = 14, +} + +impl TriggerSel { + pub fn tsel(&self) -> u8 { + *self as u8 + } +} diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index e141fc48..12783464 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -77,7 +77,7 @@ async fn dac_task1(mut dac: Dac1Type) { error!("Reload value {} below threshold!", reload); } - dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap(); + dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim6).unwrap(); dac.enable_channel().unwrap(); TIM6::enable_and_reset(); @@ -127,7 +127,7 @@ async fn dac_task2(mut dac: Dac2Type) { w.set_cen(true); }); - dac.select_trigger(embassy_stm32::dac::Ch2Trigger::Tim7).unwrap(); + dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim7).unwrap(); debug!( "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index 98f37f90..c9f0a4cf 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs @@ -48,7 +48,7 @@ async fn dac_task1(mut dac: Dac1Type) { error!("Reload value {} below threshold!", reload); } - dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap(); + dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim6).unwrap(); dac.enable_channel().unwrap(); TIM6::enable_and_reset(); @@ -98,7 +98,7 @@ async fn dac_task2(mut dac: Dac2Type) { w.set_cen(true); }); - dac.select_trigger(embassy_stm32::dac::Ch2Trigger::Tim7).unwrap(); + dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim7).unwrap(); debug!( "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", From 267cbaebe6a4a7160c3bc9239fcbd3dfa4a0d9a9 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 19 Nov 2023 13:57:19 +0000 Subject: [PATCH 183/188] STM32 DAC: Disable circular writes with GPDMA as it doesn't yet support circular transfers --- embassy-stm32/src/dac/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 6d51c1e9..2f101023 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -238,6 +238,7 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. /// /// **Important:** Channel 1 has to be configured for the DAC instance! + #[cfg(not(gpdma))] pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> where Tx: DmaCh1, @@ -349,6 +350,7 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. /// /// **Important:** Channel 2 has to be configured for the DAC instance! + #[cfg(not(gpdma))] pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> where Tx: DmaCh2, From 09d7950313427d25be255e4a46a29b6c21113826 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Tue, 21 Nov 2023 03:12:36 +0000 Subject: [PATCH 184/188] STM32 DAC: Rework DAC driver, support all families. --- embassy-stm32/build.rs | 4 +- embassy-stm32/src/dac/mod.rs | 750 ++++++++++++++-------------- examples/stm32f4/src/bin/dac.rs | 5 +- examples/stm32h7/src/bin/dac.rs | 5 +- examples/stm32h7/src/bin/dac_dma.rs | 31 +- examples/stm32l4/src/bin/dac.rs | 5 +- examples/stm32l4/src/bin/dac_dma.rs | 31 +- tests/stm32/src/bin/dac.rs | 10 +- 8 files changed, 406 insertions(+), 435 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 2011fd17..7bfd290d 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -996,8 +996,8 @@ fn main() { // SDMMCv1 uses the same channel for both directions, so just implement for RX (("sdmmc", "RX"), quote!(crate::sdmmc::SdmmcDma)), (("quadspi", "QUADSPI"), quote!(crate::qspi::QuadDma)), - (("dac", "CH1"), quote!(crate::dac::DmaCh1)), - (("dac", "CH2"), quote!(crate::dac::DmaCh2)), + (("dac", "CH1"), quote!(crate::dac::DacDma1)), + (("dac", "CH2"), quote!(crate::dac::DacDma2)), ] .into(); diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 2f101023..3caa7caa 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -1,10 +1,11 @@ +//! Provide access to the STM32 digital-to-analog converter (DAC). #![macro_use] -//! Provide access to the STM32 digital-to-analog converter (DAC). use core::marker::PhantomData; use embassy_hal_internal::{into_ref, PeripheralRef}; +use crate::dma::NoDma; #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] use crate::pac::dac; use crate::rcc::RccPeripheral; @@ -13,6 +14,7 @@ use crate::{peripherals, Peripheral}; mod tsel; pub use tsel::TriggerSel; +/// Operating mode for DAC channel #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -56,32 +58,9 @@ impl Mode { #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Custom Errors -pub enum Error { - UnconfiguredChannel, - InvalidValue, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// DAC Channels -pub enum Channel { - Ch1, - Ch2, -} - -impl Channel { - const fn index(&self) -> usize { - match self { - Channel::Ch1 => 0, - Channel::Ch2 => 1, - } - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Single 8 or 12 bit value that can be output by the DAC +/// Single 8 or 12 bit value that can be output by the DAC. +/// +/// 12-bit values outside the permitted range are silently truncated. pub enum Value { // 8 bit value Bit8(u8), @@ -93,7 +72,21 @@ pub enum Value { #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Array variant of [`Value`] +/// Dual 8 or 12 bit values that can be output by the DAC channels 1 and 2 simultaneously. +/// +/// 12-bit values outside the permitted range are silently truncated. +pub enum DualValue { + // 8 bit value + Bit8(u8, u8), + // 12 bit value stored in a u16, left-aligned + Bit12Left(u16, u16), + // 12 bit value stored in a u16, right-aligned + Bit12Right(u16, u16), +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Array variant of [`Value`]. pub enum ValueArray<'a> { // 8 bit values Bit8(&'a [u8]), @@ -102,400 +95,395 @@ pub enum ValueArray<'a> { // 12 bit values stored in a u16, right-aligned Bit12Right(&'a [u16]), } -/// Provide common functions for DAC channels -pub trait DacChannel { - const CHANNEL: Channel; - /// Enable trigger of the given channel - fn set_trigger_enable(&mut self, on: bool) -> Result<(), Error> { - T::regs().cr().modify(|reg| { - reg.set_ten(Self::CHANNEL.index(), on); - }); - Ok(()) - } - - /// Set mode register of the given channel - #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] - fn set_channel_mode(&mut self, mode: Mode) -> Result<(), Error> { - T::regs().mcr().modify(|reg| { - reg.set_mode(Self::CHANNEL.index(), mode.mode()); - }); - Ok(()) - } - - /// Set enable register of the given channel - fn set_channel_enable(&mut self, on: bool) -> Result<(), Error> { - T::regs().cr().modify(|reg| { - reg.set_en(Self::CHANNEL.index(), on); - }); - Ok(()) - } - - /// Enable the DAC channel `ch` - fn enable_channel(&mut self) -> Result<(), Error> { - self.set_channel_enable(true) - } - - /// Disable the DAC channel `ch` - fn disable_channel(&mut self) -> Result<(), Error> { - self.set_channel_enable(false) - } - - /// Perform a software trigger on `ch` - fn trigger(&mut self) { - T::regs().swtrigr().write(|reg| { - reg.set_swtrig(Self::CHANNEL.index(), true); - }); - } - - /// Set a value to be output by the DAC on trigger. - /// - /// The `value` is written to the corresponding "data holding register". - fn set(&mut self, value: Value) -> Result<(), Error> { - match value { - Value::Bit8(v) => T::regs().dhr8r(Self::CHANNEL.index()).write(|reg| reg.set_dhr(v)), - Value::Bit12Left(v) => T::regs().dhr12l(Self::CHANNEL.index()).write(|reg| reg.set_dhr(v)), - Value::Bit12Right(v) => T::regs().dhr12r(Self::CHANNEL.index()).write(|reg| reg.set_dhr(v)), - } - Ok(()) - } -} - -/// Hold two DAC channels +/// Driver for a single DAC channel. /// -/// Note: This consumes the DAC `Instance` only once, allowing to get both channels simultaneously. -/// -/// # Example for obtaining both DAC channels -/// -/// ```ignore -/// // DMA channels and pins may need to be changed for your controller -/// let (dac_ch1, dac_ch2) = -/// embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split(); -/// ``` -pub struct Dac<'d, T: Instance, TxCh1, TxCh2> { - ch1: DacCh1<'d, T, TxCh1>, - ch2: DacCh2<'d, T, TxCh2>, -} - -/// DAC CH1 -/// -/// Note: This consumes the DAC `Instance`. Use [`Dac::new`] to get both channels simultaneously. -pub struct DacCh1<'d, T: Instance, Tx> { - /// To consume T - _peri: PeripheralRef<'d, T>, - #[allow(unused)] // For chips whose DMA is not (yet) supported - dma: PeripheralRef<'d, Tx>, -} - -/// DAC CH2 -/// -/// Note: This consumes the DAC `Instance`. Use [`Dac::new`] to get both channels simultaneously. -pub struct DacCh2<'d, T: Instance, Tx> { - /// Instead of PeripheralRef to consume T +/// If you want to use both channels, either together or independently, +/// create a [`Dac`] first and use it to access each channel. +pub struct DacChannel<'d, T: Instance, const N: u8, DMA = NoDma> { phantom: PhantomData<&'d mut T>, - #[allow(unused)] // For chips whose DMA is not (yet) supported - dma: PeripheralRef<'d, Tx>, + #[allow(unused)] + dma: PeripheralRef<'d, DMA>, } -impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { - /// Obtain DAC CH1 - pub fn new( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, - pin: impl Peripheral

> + crate::gpio::sealed::Pin + 'd, - ) -> Self { - pin.set_as_analog(); - into_ref!(peri, dma); - T::enable_and_reset(); +pub type DacCh1<'d, T, DMA = NoDma> = DacChannel<'d, T, 1, DMA>; +pub type DacCh2<'d, T, DMA = NoDma> = DacChannel<'d, T, 2, DMA>; - let mut dac = Self { _peri: peri, dma }; +impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { + const IDX: usize = (N - 1) as usize; - // Configure each activated channel. All results can be `unwrap`ed since they - // will only error if the channel is not configured (i.e. ch1, ch2 are false) - #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] - dac.set_channel_mode(Mode::NormalExternalBuffered).unwrap(); - dac.enable_channel().unwrap(); - dac.set_trigger_enable(true).unwrap(); - - dac - } - - /// Select a new trigger for this channel + /// Create a new `DacChannel` instance, consuming the underlying DAC peripheral. /// - /// **Important**: This disables the channel! - pub fn select_trigger(&mut self, trigger: TriggerSel) -> Result<(), Error> { - unwrap!(self.disable_channel()); - T::regs().cr().modify(|reg| { - reg.set_tsel(0, trigger.tsel()); - }); - Ok(()) - } - - /// Write `data` to the DAC CH1 via DMA. + /// If you're not using DMA, pass [`dma::NoDma`] for the `dma` argument. /// - /// To prevent delays/glitches when outputting a periodic waveform, the `circular` flag can be set. - /// This will configure a circular DMA transfer that periodically outputs the `data`. - /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. + /// The channel is enabled on creation and begins to drive the output pin. + /// Note that some methods, such as `set_trigger()` and `set_mode()`, will + /// disable the channel; you must re-enable it with `enable()`. /// - /// **Important:** Channel 1 has to be configured for the DAC instance! - #[cfg(not(gpdma))] - pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> - where - Tx: DmaCh1, - { - let channel = Channel::Ch1.index(); - debug!("Writing to channel {}", channel); - - // Enable DAC and DMA - T::regs().cr().modify(|w| { - w.set_en(channel, true); - w.set_dmaen(channel, true); - }); - - let tx_request = self.dma.request(); - let dma_channel = &mut self.dma; - - let tx_options = crate::dma::TransferOptions { - circular, - half_transfer_ir: false, - complete_transfer_ir: !circular, - ..Default::default() - }; - - // Initiate the correct type of DMA transfer depending on what data is passed - let tx_f = match data { - ValueArray::Bit8(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr8r(channel).as_ptr() as *mut u8, - tx_options, - ) - }, - ValueArray::Bit12Left(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr12l(channel).as_ptr() as *mut u16, - tx_options, - ) - }, - ValueArray::Bit12Right(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr12r(channel).as_ptr() as *mut u16, - tx_options, - ) - }, - }; - - tx_f.await; - - // finish dma - // TODO: Do we need to check any status registers here? - T::regs().cr().modify(|w| { - // Disable the DAC peripheral - w.set_en(channel, false); - // Disable the DMA. TODO: Is this necessary? - w.set_dmaen(channel, false); - }); - - Ok(()) - } -} - -impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { - /// Obtain DAC CH2 + /// By default, triggering is disabled, but it can be enabled using + /// [`DacChannel::set_trigger()`]. pub fn new( _peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, - pin: impl Peripheral

> + crate::gpio::sealed::Pin + 'd, + dma: impl Peripheral

+ 'd, + pin: impl Peripheral

+ crate::gpio::sealed::Pin> + 'd, ) -> Self { + into_ref!(dma, pin); pin.set_as_analog(); - into_ref!(_peri, dma); T::enable_and_reset(); - let mut dac = Self { phantom: PhantomData, dma, }; - - // Configure each activated channel. All results can be `unwrap`ed since they - // will only error if the channel is not configured (i.e. ch1, ch2 are false) - #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] - dac.set_channel_mode(Mode::NormalExternalBuffered).unwrap(); - dac.enable_channel().unwrap(); - dac.set_trigger_enable(true).unwrap(); - + #[cfg(any(dac_v5, dac_v6, dac_v7))] + dac.set_hfsel(); + dac.enable(); dac } - /// Select a new trigger for this channel - pub fn select_trigger(&mut self, trigger: TriggerSel) -> Result<(), Error> { - unwrap!(self.disable_channel()); - T::regs().cr().modify(|reg| { - reg.set_tsel(1, trigger.tsel()); - }); - Ok(()) - } - - /// Write `data` to the DAC CH2 via DMA. + /// Create a new `DacChannel` instance where the external output pin is not used, + /// so the DAC can only be used to generate internal signals. + /// The GPIO pin is therefore available to be used for other functions. /// - /// To prevent delays/glitches when outputting a periodic waveform, the `circular` flag can be set. - /// This will configure a circular DMA transfer that periodically outputs the `data`. - /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. + /// The channel is set to [`Mode::NormalInternalUnbuffered`] and enabled on creation. + /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the + /// channel; you must re-enable it with `enable()`. /// - /// **Important:** Channel 2 has to be configured for the DAC instance! - #[cfg(not(gpdma))] - pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> - where - Tx: DmaCh2, - { - let channel = Channel::Ch2.index(); - debug!("Writing to channel {}", channel); - - // Enable DAC and DMA - T::regs().cr().modify(|w| { - w.set_en(channel, true); - w.set_dmaen(channel, true); - }); - - let tx_request = self.dma.request(); - let dma_channel = &mut self.dma; - - let tx_options = crate::dma::TransferOptions { - circular, - half_transfer_ir: false, - complete_transfer_ir: !circular, - ..Default::default() - }; - - // Initiate the correct type of DMA transfer depending on what data is passed - let tx_f = match data { - ValueArray::Bit8(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr8r(channel).as_ptr() as *mut u8, - tx_options, - ) - }, - ValueArray::Bit12Left(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr12l(channel).as_ptr() as *mut u16, - tx_options, - ) - }, - ValueArray::Bit12Right(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr12r(channel).as_ptr() as *mut u16, - tx_options, - ) - }, - }; - - tx_f.await; - - // finish dma - // TODO: Do we need to check any status registers here? - T::regs().cr().modify(|w| { - // Disable the DAC peripheral - w.set_en(channel, false); - // Disable the DMA. TODO: Is this necessary? - w.set_dmaen(channel, false); - }); - - Ok(()) - } -} - -impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> { - /// Create a new DAC instance with both channels. + /// If you're not using DMA, pass [`dma::NoDma`] for the `dma` argument. /// - /// This is used to obtain two independent channels via `split()` for use e.g. with DMA. - pub fn new( - peri: impl Peripheral

+ 'd, - dma_ch1: impl Peripheral

+ 'd, - dma_ch2: impl Peripheral

+ 'd, - pin_ch1: impl Peripheral

> + crate::gpio::sealed::Pin + 'd, - pin_ch2: impl Peripheral

> + crate::gpio::sealed::Pin + 'd, - ) -> Self { - pin_ch1.set_as_analog(); - pin_ch2.set_as_analog(); - into_ref!(peri, dma_ch1, dma_ch2); + /// By default, triggering is disabled, but it can be enabled using + /// [`DacChannel::set_trigger()`]. + #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] + pub fn new_internal(_peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd) -> Self { + into_ref!(dma); T::enable_and_reset(); - - let mut dac_ch1 = DacCh1 { - _peri: peri, - dma: dma_ch1, - }; - - let mut dac_ch2 = DacCh2 { + let mut dac = Self { phantom: PhantomData, - dma: dma_ch2, + dma, }; + #[cfg(any(dac_v5, dac_v6, dac_v7))] + dac.set_hfsel(); + dac.set_mode(Mode::NormalInternalUnbuffered); + dac.enable(); + dac + } - // Configure each activated channel. All results can be `unwrap`ed since they - // will only error if the channel is not configured (i.e. ch1, ch2 are false) - #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v73))] - dac_ch1.set_channel_mode(Mode::NormalExternalBuffered).unwrap(); - dac_ch1.enable_channel().unwrap(); - dac_ch1.set_trigger_enable(true).unwrap(); + /// Enable or disable this channel. + pub fn set_enable(&mut self, on: bool) { + critical_section::with(|_| { + T::regs().cr().modify(|reg| { + reg.set_en(Self::IDX, on); + }); + }); + } - #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] - dac_ch2.set_channel_mode(Mode::NormalExternalBuffered).unwrap(); - dac_ch2.enable_channel().unwrap(); - dac_ch2.set_trigger_enable(true).unwrap(); + /// Enable this channel. + pub fn enable(&mut self) { + self.set_enable(true) + } - Self { - ch1: dac_ch1, - ch2: dac_ch2, + /// Disable this channel. + pub fn disable(&mut self) { + self.set_enable(false) + } + + /// Set the trigger source for this channel. + /// + /// This method disables the channel, so you may need to re-enable afterwards. + pub fn set_trigger(&mut self, source: TriggerSel) { + critical_section::with(|_| { + T::regs().cr().modify(|reg| { + reg.set_en(Self::IDX, false); + reg.set_tsel(Self::IDX, source as u8); + }); + }); + } + + /// Enable or disable triggering for this channel. + pub fn set_triggering(&mut self, on: bool) { + critical_section::with(|_| { + T::regs().cr().modify(|reg| { + reg.set_ten(Self::IDX, on); + }); + }); + } + + /// Software trigger this channel. + pub fn trigger(&mut self) { + T::regs().swtrigr().write(|reg| { + reg.set_swtrig(Self::IDX, true); + }); + } + + /// Set mode of this channel. + /// + /// This method disables the channel, so you may need to re-enable afterwards. + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + pub fn set_mode(&mut self, mode: Mode) { + critical_section::with(|_| { + T::regs().cr().modify(|reg| { + reg.set_en(Self::IDX, false); + }); + T::regs().mcr().modify(|reg| { + reg.set_mode(Self::IDX, mode.mode()); + }); + }); + } + + /// Write a new value to this channel. + /// + /// If triggering is not enabled, the new value is immediately output; otherwise, + /// it will be output after the next trigger. + pub fn set(&mut self, value: Value) { + match value { + Value::Bit8(v) => T::regs().dhr8r(Self::IDX).write(|reg| reg.set_dhr(v)), + Value::Bit12Left(v) => T::regs().dhr12l(Self::IDX).write(|reg| reg.set_dhr(v)), + Value::Bit12Right(v) => T::regs().dhr12r(Self::IDX).write(|reg| reg.set_dhr(v)), } } - /// Split the DAC into CH1 and CH2 for independent use. - pub fn split(self) -> (DacCh1<'d, T, TxCh1>, DacCh2<'d, T, TxCh2>) { + /// Read the current output value of the DAC. + pub fn read(&self) -> u16 { + T::regs().dor(Self::IDX).read().dor() + } + + /// Set HFSEL as appropriate for the current peripheral clock frequency. + #[cfg(dac_v5)] + fn set_hfsel(&mut self) { + if T::frequency() >= crate::time::mhz(80) { + critical_section::with(|_| { + T::regs().cr().modify(|reg| { + reg.set_hfsel(true); + }); + }); + } + } + + /// Set HFSEL as appropriate for the current peripheral clock frequency. + #[cfg(any(dac_v6, dac_v7))] + fn set_hfsel(&mut self) { + if T::frequency() >= crate::time::mhz(160) { + critical_section::with(|_| { + T::regs().mcr().modify(|reg| { + reg.set_hfsel(0b10); + }); + }); + } else if T::frequency() >= crate::time::mhz(80) { + critical_section::with(|_| { + T::regs().mcr().modify(|reg| { + reg.set_hfsel(0b01); + }); + }); + } + } +} + +macro_rules! impl_dma_methods { + ($n:literal, $trait:ident) => { + impl<'d, T: Instance, DMA> DacChannel<'d, T, $n, DMA> + where + DMA: $trait, + { + /// Write `data` to this channel via DMA. + /// + /// To prevent delays or glitches when outputing a periodic waveform, the `circular` + /// flag can be set. This configures a circular DMA transfer that continually outputs + /// `data`. Note that for performance reasons in circular mode the transfer-complete + /// interrupt is disabled. + #[cfg(not(gpdma))] + pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) { + // Enable DAC and DMA + T::regs().cr().modify(|w| { + w.set_en(Self::IDX, true); + w.set_dmaen(Self::IDX, true); + }); + + let tx_request = self.dma.request(); + let dma_channel = &mut self.dma; + + let tx_options = crate::dma::TransferOptions { + circular, + half_transfer_ir: false, + complete_transfer_ir: !circular, + ..Default::default() + }; + + // Initiate the correct type of DMA transfer depending on what data is passed + let tx_f = match data { + ValueArray::Bit8(buf) => unsafe { + crate::dma::Transfer::new_write( + dma_channel, + tx_request, + buf, + T::regs().dhr8r(Self::IDX).as_ptr() as *mut u8, + tx_options, + ) + }, + ValueArray::Bit12Left(buf) => unsafe { + crate::dma::Transfer::new_write( + dma_channel, + tx_request, + buf, + T::regs().dhr12l(Self::IDX).as_ptr() as *mut u16, + tx_options, + ) + }, + ValueArray::Bit12Right(buf) => unsafe { + crate::dma::Transfer::new_write( + dma_channel, + tx_request, + buf, + T::regs().dhr12r(Self::IDX).as_ptr() as *mut u16, + tx_options, + ) + }, + }; + + tx_f.await; + + T::regs().cr().modify(|w| { + w.set_en(Self::IDX, false); + w.set_dmaen(Self::IDX, false); + }); + } + } + }; +} + +impl_dma_methods!(1, DacDma1); +impl_dma_methods!(2, DacDma1); + +impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> { + fn drop(&mut self) { + T::disable(); + } +} + +/// DAC driver. +/// +/// Use this struct when you want to use both channels, either together or independently. +/// +/// # Example +/// +/// ```ignore +/// // Pins may need to be changed for your specific device. +/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC, NoDma, NoDma, p.PA4, p.PA5).split(); +/// ``` +pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> { + ch1: DacChannel<'d, T, 1, DMACh1>, + ch2: DacChannel<'d, T, 2, DMACh2>, +} + +impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { + /// Create a new `Dac` instance, consuming the underlying DAC peripheral. + /// + /// This struct allows you to access both channels of the DAC, where available. You can either + /// call `split()` to obtain separate `DacChannel`s, or use methods on `Dac` to use + /// the two channels together. + /// + /// The channels are enabled on creation and begins to drive their output pins. + /// Note that some methods, such as `set_trigger()` and `set_mode()`, will + /// disable the channel; you must re-enable them with `enable()`. + /// + /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` + /// method on the underlying channels. + pub fn new( + _peri: impl Peripheral

+ 'd, + dma_ch1: impl Peripheral

+ 'd, + dma_ch2: impl Peripheral

+ 'd, + pin_ch1: impl Peripheral

+ crate::gpio::sealed::Pin> + 'd, + pin_ch2: impl Peripheral

+ crate::gpio::sealed::Pin> + 'd, + ) -> Self { + into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); + pin_ch1.set_as_analog(); + pin_ch2.set_as_analog(); + // Enable twice to increment the DAC refcount for each channel. + T::enable_and_reset(); + T::enable_and_reset(); + Self { + ch1: DacCh1 { + phantom: PhantomData, + dma: dma_ch1, + }, + ch2: DacCh2 { + phantom: PhantomData, + dma: dma_ch2, + }, + } + } + + /// Create a new `Dac` instance where the external output pins are not used, + /// so the DAC can only be used to generate internal signals but the GPIO + /// pins remain available for other functions. + /// + /// This struct allows you to access both channels of the DAC, where available. You can either + /// call `split()` to obtain separate `DacChannel`s, or use methods on `Dac` to use the two + /// channels together. + /// + /// The channels are set to [`Mode::NormalInternalUnbuffered`] and enabled on creation. + /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the + /// channel; you must re-enable them with `enable()`. + /// + /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` + /// method on the underlying channels. + #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] + pub fn new_internal( + _peri: impl Peripheral

+ 'd, + dma_ch1: impl Peripheral

+ 'd, + dma_ch2: impl Peripheral

+ 'd, + ) -> Self { + into_ref!(dma_ch1, dma_ch2); + // Enable twice to increment the DAC refcount for each channel. + T::enable_and_reset(); + T::enable_and_reset(); + Self { + ch1: DacCh1 { + phantom: PhantomData, + dma: dma_ch1, + }, + ch2: DacCh2 { + phantom: PhantomData, + dma: dma_ch2, + }, + } + } + + /// Split this `Dac` into separate channels. + /// + /// You can access and move the channels around separately after splitting. + pub fn split(self) -> (DacCh1<'d, T, DMACh1>, DacCh2<'d, T, DMACh2>) { (self.ch1, self.ch2) } - /// Get mutable reference to CH1 - pub fn ch1_mut(&mut self) -> &mut DacCh1<'d, T, TxCh1> { + /// Temporarily access channel 1. + pub fn ch1(&mut self) -> &mut DacCh1<'d, T, DMACh1> { &mut self.ch1 } - /// Get mutable reference to CH2 - pub fn ch2_mut(&mut self) -> &mut DacCh2<'d, T, TxCh2> { + /// Temporarily access channel 2. + pub fn ch2(&mut self) -> &mut DacCh2<'d, T, DMACh2> { &mut self.ch2 } - /// Get reference to CH1 - pub fn ch1(&mut self) -> &DacCh1<'d, T, TxCh1> { - &self.ch1 + /// Simultaneously update channels 1 and 2 with a new value. + /// + /// If triggering is not enabled, the new values are immediately output; + /// otherwise, they will be output after the next trigger. + pub fn set(&mut self, values: DualValue) { + match values { + DualValue::Bit8(v1, v2) => T::regs().dhr8rd().write(|reg| { + reg.set_dhr(0, v1); + reg.set_dhr(1, v2); + }), + DualValue::Bit12Left(v1, v2) => T::regs().dhr12ld().write(|reg| { + reg.set_dhr(0, v1); + reg.set_dhr(1, v2); + }), + DualValue::Bit12Right(v1, v2) => T::regs().dhr12rd().write(|reg| { + reg.set_dhr(0, v1); + reg.set_dhr(1, v2); + }), + } } - - /// Get reference to CH2 - pub fn ch2(&mut self) -> &DacCh2<'d, T, TxCh2> { - &self.ch2 - } -} - -impl<'d, T: Instance, Tx> DacChannel for DacCh1<'d, T, Tx> { - const CHANNEL: Channel = Channel::Ch1; -} - -impl<'d, T: Instance, Tx> DacChannel for DacCh2<'d, T, Tx> { - const CHANNEL: Channel = Channel::Ch2; } pub(crate) mod sealed { @@ -505,8 +493,8 @@ pub(crate) mod sealed { } pub trait Instance: sealed::Instance + RccPeripheral + 'static {} -dma_trait!(DmaCh1, Instance); -dma_trait!(DmaCh2, Instance); +dma_trait!(DacDma1, Instance); +dma_trait!(DacDma2, Instance); /// Marks a pin that can be used with the DAC pub trait DacPin: crate::gpio::Pin + 'static {} @@ -521,12 +509,14 @@ foreach_peripheral!( } fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { + // TODO: Increment refcount? 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_with_cs(_cs: critical_section::CriticalSection) { + // TODO: Decrement refcount? crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)) } } diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs index aaedcfec..8f14d607 100644 --- a/examples/stm32f4/src/bin/dac.rs +++ b/examples/stm32f4/src/bin/dac.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dac::{DacCh1, DacChannel, Value}; +use embassy_stm32::dac::{DacCh1, Value}; use embassy_stm32::dma::NoDma; use {defmt_rtt as _, panic_probe as _}; @@ -14,11 +14,10 @@ async fn main(_spawner: Spawner) -> ! { info!("Hello World, dude!"); let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4); - unwrap!(dac.set_trigger_enable(false)); loop { for v in 0..=255 { - unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); + dac.set(Value::Bit8(to_sine_wave(v))); } } } diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index 35fd6550..f6626815 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs @@ -4,7 +4,7 @@ use cortex_m_rt::entry; use defmt::*; -use embassy_stm32::dac::{DacCh1, DacChannel, Value}; +use embassy_stm32::dac::{DacCh1, Value}; use embassy_stm32::dma::NoDma; use embassy_stm32::Config; use {defmt_rtt as _, panic_probe as _}; @@ -46,11 +46,10 @@ fn main() -> ! { let p = embassy_stm32::init(config); let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); - unwrap!(dac.set_trigger_enable(false)); loop { for v in 0..=255 { - unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); + dac.set(Value::Bit8(to_sine_wave(v))); } } } diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 12783464..c19fdd62 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -4,21 +4,15 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dac::{DacChannel, ValueArray}; +use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; use embassy_stm32::pac::timer::vals::{Mms, Opm}; -use embassy_stm32::peripherals::{TIM6, TIM7}; +use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; use embassy_stm32::rcc::low_level::RccPeripheral; use embassy_stm32::time::Hertz; use embassy_stm32::timer::low_level::Basic16bitInstance; use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; -pub type Dac1Type = - embassy_stm32::dac::DacCh1<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH3>; - -pub type Dac2Type = - embassy_stm32::dac::DacCh2<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH4>; - #[embassy_executor::main] async fn main(spawner: Spawner) { let mut config = embassy_stm32::Config::default(); @@ -63,7 +57,7 @@ async fn main(spawner: Spawner) { } #[embassy_executor::task] -async fn dac_task1(mut dac: Dac1Type) { +async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM6 frequency is {}", TIM6::frequency()); @@ -77,8 +71,9 @@ async fn dac_task1(mut dac: Dac1Type) { error!("Reload value {} below threshold!", reload); } - dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim6).unwrap(); - dac.enable_channel().unwrap(); + dac.set_trigger(embassy_stm32::dac::TriggerSel::Tim6); + dac.set_triggering(true); + dac.enable(); TIM6::enable_and_reset(); TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); @@ -100,14 +95,12 @@ async fn dac_task1(mut dac: Dac1Type) { // Loop technically not necessary if DMA circular mode is enabled loop { info!("Loop DAC1"); - if let Err(e) = dac.write(ValueArray::Bit8(data), true).await { - error!("Could not write to dac: {}", e); - } + dac.write(ValueArray::Bit8(data), true).await; } } #[embassy_executor::task] -async fn dac_task2(mut dac: Dac2Type) { +async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM7 frequency is {}", TIM7::frequency()); @@ -127,7 +120,9 @@ async fn dac_task2(mut dac: Dac2Type) { w.set_cen(true); }); - dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim7).unwrap(); + dac.set_trigger(embassy_stm32::dac::TriggerSel::Tim7); + dac.set_triggering(true); + dac.enable(); debug!( "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", @@ -138,9 +133,7 @@ async fn dac_task2(mut dac: Dac2Type) { data.len() ); - if let Err(e) = dac.write(ValueArray::Bit8(data), true).await { - error!("Could not write to dac: {}", e); - } + dac.write(ValueArray::Bit8(data), true).await; } fn to_sine_wave(v: u8) -> u8 { diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs index 0193a248..d6a7ff62 100644 --- a/examples/stm32l4/src/bin/dac.rs +++ b/examples/stm32l4/src/bin/dac.rs @@ -3,7 +3,7 @@ #![feature(type_alias_impl_trait)] use defmt::*; -use embassy_stm32::dac::{DacCh1, DacChannel, Value}; +use embassy_stm32::dac::{DacCh1, Value}; use embassy_stm32::dma::NoDma; use {defmt_rtt as _, panic_probe as _}; @@ -13,11 +13,10 @@ fn main() -> ! { info!("Hello World!"); let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); - unwrap!(dac.set_trigger_enable(false)); loop { for v in 0..=255 { - unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); + dac.set(Value::Bit8(to_sine_wave(v))); } } } diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index c9f0a4cf..dc86dbf4 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs @@ -4,21 +4,15 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::dac::{DacChannel, ValueArray}; +use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; use embassy_stm32::pac::timer::vals::{Mms, Opm}; -use embassy_stm32::peripherals::{TIM6, TIM7}; +use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; use embassy_stm32::rcc::low_level::RccPeripheral; use embassy_stm32::time::Hertz; use embassy_stm32::timer::low_level::Basic16bitInstance; use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; -pub type Dac1Type = - embassy_stm32::dac::DacCh1<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH3>; - -pub type Dac2Type = - embassy_stm32::dac::DacCh2<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH4>; - #[embassy_executor::main] async fn main(spawner: Spawner) { let config = embassy_stm32::Config::default(); @@ -34,7 +28,7 @@ async fn main(spawner: Spawner) { } #[embassy_executor::task] -async fn dac_task1(mut dac: Dac1Type) { +async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM6 frequency is {}", TIM6::frequency()); @@ -48,8 +42,9 @@ async fn dac_task1(mut dac: Dac1Type) { error!("Reload value {} below threshold!", reload); } - dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim6).unwrap(); - dac.enable_channel().unwrap(); + dac.set_trigger(embassy_stm32::dac::TriggerSel::Tim6); + dac.set_triggering(true); + dac.enable(); TIM6::enable_and_reset(); TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); @@ -71,14 +66,12 @@ async fn dac_task1(mut dac: Dac1Type) { // Loop technically not necessary if DMA circular mode is enabled loop { info!("Loop DAC1"); - if let Err(e) = dac.write(ValueArray::Bit8(data), true).await { - error!("Could not write to dac: {}", e); - } + dac.write(ValueArray::Bit8(data), true).await; } } #[embassy_executor::task] -async fn dac_task2(mut dac: Dac2Type) { +async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM7 frequency is {}", TIM7::frequency()); @@ -98,7 +91,9 @@ async fn dac_task2(mut dac: Dac2Type) { w.set_cen(true); }); - dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim7).unwrap(); + dac.set_trigger(embassy_stm32::dac::TriggerSel::Tim7); + dac.set_triggering(true); + dac.enable(); debug!( "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", @@ -109,9 +104,7 @@ async fn dac_task2(mut dac: Dac2Type) { data.len() ); - if let Err(e) = dac.write(ValueArray::Bit8(data), true).await { - error!("Could not write to dac: {}", e); - } + dac.write(ValueArray::Bit8(data), true).await; } fn to_sine_wave(v: u8) -> u8 { diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs index 10e3c3e8..824eb880 100644 --- a/tests/stm32/src/bin/dac.rs +++ b/tests/stm32/src/bin/dac.rs @@ -10,7 +10,7 @@ use common::*; use defmt::assert; use embassy_executor::Spawner; use embassy_stm32::adc::Adc; -use embassy_stm32::dac::{DacCh1, DacChannel, Value}; +use embassy_stm32::dac::{DacCh1, Value}; use embassy_stm32::dma::NoDma; use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -26,9 +26,7 @@ async fn main(_spawner: Spawner) { #[cfg(any(feature = "stm32h755zi", feature = "stm32g071rb"))] let dac_peripheral = p.DAC1; - let mut dac: DacCh1<'_, _, NoDma> = DacCh1::new(dac_peripheral, NoDma, p.PA4); - unwrap!(dac.set_trigger_enable(false)); - + let mut dac = DacCh1::new(dac_peripheral, NoDma, p.PA4); let mut adc = Adc::new(p.ADC1, &mut Delay); #[cfg(feature = "stm32h755zi")] @@ -36,7 +34,7 @@ async fn main(_spawner: Spawner) { #[cfg(any(feature = "stm32f429zi", feature = "stm32g071rb"))] let normalization_factor: i32 = 16; - unwrap!(dac.set(Value::Bit8(0))); + dac.set(Value::Bit8(0)); // Now wait a little to obtain a stable value Timer::after_millis(30).await; let offset = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); @@ -44,7 +42,7 @@ async fn main(_spawner: Spawner) { for v in 0..=255 { // First set the DAC output value let dac_output_val = to_sine_wave(v); - unwrap!(dac.set(Value::Bit8(dac_output_val))); + dac.set(Value::Bit8(dac_output_val)); // Now wait a little to obtain a stable value Timer::after_millis(30).await; From cf84c8bfd13fb69dfbd3b62c5d0a73cc033f8698 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 19 Nov 2023 04:47:57 +0000 Subject: [PATCH 185/188] WIP: use generated metapac from corresponding PR for CI --- 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 d04000a1..292902ac 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-f6d1ffc1a25f208b5cd6b1024bff246592da1949" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7117ad49c06fa00c388130a34977e029910083bd" } 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-f6d1ffc1a25f208b5cd6b1024bff246592da1949", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7117ad49c06fa00c388130a34977e029910083bd", default-features = false, features = ["metadata"]} [features] From a3ea01473a37451dbd80552ae501e854175055db Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 25 Nov 2023 00:08:13 +0100 Subject: [PATCH 186/188] stm32: fix dac trait --- embassy-stm32/src/dac/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 3caa7caa..500eac4c 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -350,7 +350,7 @@ macro_rules! impl_dma_methods { } impl_dma_methods!(1, DacDma1); -impl_dma_methods!(2, DacDma1); +impl_dma_methods!(2, DacDma2); impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> { fn drop(&mut self) { From 03d500f548ac681d201b24c55ab0d6e15f19679b Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 25 Nov 2023 01:06:43 +0100 Subject: [PATCH 187/188] cyw43: remove feature(concat_bytes). --- cyw43/src/lib.rs | 2 +- cyw43/src/nvram.rs | 102 ++++++++++++++++------------------ embassy-stm32-wpan/src/lib.rs | 1 - 3 files changed, 49 insertions(+), 56 deletions(-) diff --git a/cyw43/src/lib.rs b/cyw43/src/lib.rs index 04847bfa..4a1d015a 100644 --- a/cyw43/src/lib.rs +++ b/cyw43/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] #![no_main] -#![feature(async_fn_in_trait, type_alias_impl_trait, concat_bytes)] +#![feature(async_fn_in_trait, type_alias_impl_trait)] #![allow(stable_features, unknown_lints, async_fn_in_trait)] #![deny(unused_must_use)] diff --git a/cyw43/src/nvram.rs b/cyw43/src/nvram.rs index 964a3128..3d1b5352 100644 --- a/cyw43/src/nvram.rs +++ b/cyw43/src/nvram.rs @@ -1,54 +1,48 @@ -macro_rules! nvram { - ($($s:literal,)*) => { - concat_bytes!($($s, b"\x00",)* b"\x00\x00") - }; -} - -pub static NVRAM: &'static [u8] = &*nvram!( - b"NVRAMRev=$Rev$", - b"manfid=0x2d0", - b"prodid=0x0727", - b"vendid=0x14e4", - b"devid=0x43e2", - b"boardtype=0x0887", - b"boardrev=0x1100", - b"boardnum=22", - b"macaddr=00:A0:50:b5:59:5e", - b"sromrev=11", - b"boardflags=0x00404001", - b"boardflags3=0x04000000", - b"xtalfreq=37400", - b"nocrc=1", - b"ag0=255", - b"aa2g=1", - b"ccode=ALL", - b"pa0itssit=0x20", - b"extpagain2g=0", - b"pa2ga0=-168,6649,-778", - b"AvVmid_c0=0x0,0xc8", - b"cckpwroffset0=5", - b"maxp2ga0=84", - b"txpwrbckof=6", - b"cckbw202gpo=0", - b"legofdmbw202gpo=0x66111111", - b"mcsbw202gpo=0x77711111", - b"propbw202gpo=0xdd", - b"ofdmdigfilttype=18", - b"ofdmdigfilttypebe=18", - b"papdmode=1", - b"papdvalidtest=1", - b"pacalidx2g=45", - b"papdepsoffset=-30", - b"papdendidx=58", - b"ltecxmux=0", - b"ltecxpadnum=0x0102", - b"ltecxfnsel=0x44", - b"ltecxgcigpio=0x01", - b"il0macaddr=00:90:4c:c5:12:38", - b"wl0id=0x431b", - b"deadman_to=0xffffffff", - b"muxenab=0x100", - b"spurconfig=0x3", - b"glitch_based_crsmin=1", - b"btc_mode=1", -); +pub static NVRAM: &'static [u8] = b" + NVRAMRev=$Rev$\x00\ + manfid=0x2d0\x00\ + prodid=0x0727\x00\ + vendid=0x14e4\x00\ + devid=0x43e2\x00\ + boardtype=0x0887\x00\ + boardrev=0x1100\x00\ + boardnum=22\x00\ + macaddr=00:A0:50:b5:59:5e\x00\ + sromrev=11\x00\ + boardflags=0x00404001\x00\ + boardflags3=0x04000000\x00\ + xtalfreq=37400\x00\ + nocrc=1\x00\ + ag0=255\x00\ + aa2g=1\x00\ + ccode=ALL\x00\ + pa0itssit=0x20\x00\ + extpagain2g=0\x00\ + pa2ga0=-168,6649,-778\x00\ + AvVmid_c0=0x0,0xc8\x00\ + cckpwroffset0=5\x00\ + maxp2ga0=84\x00\ + txpwrbckof=6\x00\ + cckbw202gpo=0\x00\ + legofdmbw202gpo=0x66111111\x00\ + mcsbw202gpo=0x77711111\x00\ + propbw202gpo=0xdd\x00\ + ofdmdigfilttype=18\x00\ + ofdmdigfilttypebe=18\x00\ + papdmode=1\x00\ + papdvalidtest=1\x00\ + pacalidx2g=45\x00\ + papdepsoffset=-30\x00\ + papdendidx=58\x00\ + ltecxmux=0\x00\ + ltecxpadnum=0x0102\x00\ + ltecxfnsel=0x44\x00\ + ltecxgcigpio=0x01\x00\ + il0macaddr=00:90:4c:c5:12:38\x00\ + wl0id=0x431b\x00\ + deadman_to=0xffffffff\x00\ + muxenab=0x100\x00\ + spurconfig=0x3\x00\ + glitch_based_crsmin=1\x00\ + btc_mode=1\x00\ + \x00"; diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs index 69a3d082..84cf0a02 100644 --- a/embassy-stm32-wpan/src/lib.rs +++ b/embassy-stm32-wpan/src/lib.rs @@ -4,7 +4,6 @@ any(feature = "ble", feature = "mac"), allow(stable_features, unknown_lints, async_fn_in_trait) )] -#![cfg_attr(feature = "mac", feature(type_alias_impl_trait, concat_bytes))] // This must go FIRST so that all the other modules see its macros. mod fmt; From d5dcbadbbeb96a5021b4c3a735fdc576f7c6e679 Mon Sep 17 00:00:00 2001 From: James Munns Date: Sat, 25 Nov 2023 22:31:03 +0100 Subject: [PATCH 188/188] Minor readme typo --- embassy-usb-driver/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-usb-driver/README.md b/embassy-usb-driver/README.md index 012663c3..93aef759 100644 --- a/embassy-usb-driver/README.md +++ b/embassy-usb-driver/README.md @@ -4,7 +4,7 @@ This crate contains the driver traits for [`embassy-usb`]. HAL/BSP crates can im traits to add support for using `embassy-usb` for a given chip/platform. The traits are kept in a separate crate so that breaking changes in the higher-level [`embassy-usb`] -APIs don't cause a semver-major bump of thsi crate. This allows existing HALs/BSPs to be used +APIs don't cause a semver-major bump of this crate. This allows existing HALs/BSPs to be used with the newer `embassy-usb` without needing updates. If you're writing an application using USB, you should depend on the main [`embassy-usb`] crate