diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml index e4524af5..a77ed003 100644 --- a/embassy-lora/Cargo.toml +++ b/embassy-lora/Cargo.toml @@ -12,7 +12,7 @@ target = "thumbv7em-none-eabi" [features] stm32wl = ["dep:embassy-stm32"] -time = [] +time = ["embassy-time", "lorawan-device"] defmt = ["dep:defmt", "lorawan-device/defmt"] [dependencies] @@ -20,18 +20,11 @@ defmt = ["dep:defmt", "lorawan-device/defmt"] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -embassy-time = { version = "0.1.2", path = "../embassy-time" } +embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } embassy-sync = { version = "0.2.0", path = "../embassy-sync" } embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } -embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } embedded-hal-async = { version = "=0.2.0-alpha.2" } -embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false } -futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } embedded-hal = { version = "0.2", features = ["unproven"] } -bit_field = { version = "0.10" } lora-phy = { version = "1" } -lorawan-device = { version = "0.10.0", default-features = false, features = ["async"] } - -[patch.crates-io] -lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } +lorawan-device = { version = "0.10.0", default-features = false, features = ["async"], optional = true } diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 6cd12220..2c6089c5 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -26,7 +26,7 @@ aligned = "0.4.1" bit_field = "0.10.2" stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } -stm32wb-hci = { version = "0.1.3", optional = true } +stm32wb-hci = { version = "0.1.4", optional = true } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } bitflags = { version = "2.3.3", optional = true } diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 5a015346..8b8244d4 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -161,6 +161,18 @@ impl<'d, T: Instance> Can<'d, T> { .leave_disabled(); } + /// Enables the peripheral and synchronizes with the bus. + /// + /// 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() { + // 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 { poll_fn(|cx| { diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 3d58914b..979748bb 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -38,11 +38,30 @@ impl Channel { #[cfg_attr(feature = "defmt", derive(defmt::Format))] /// Trigger sources for CH1 pub enum Ch1Trigger { - Tim6, - Tim3, - Tim7, - Tim15, + #[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, } @@ -50,14 +69,30 @@ pub enum Ch1Trigger { impl Ch1Trigger { fn tsel(&self) -> dac::vals::Tsel1 { match self { - Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO, + #[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::Tim3 => dac::vals::Tsel1::TIM1_TRGO, + 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, - Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_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, } @@ -129,7 +164,7 @@ pub trait DacChannel { } /// Set mode register of the given channel - #[cfg(dac_v2)] + #[cfg(any(dac_v2, dac_v3))] fn set_channel_mode(&mut self, val: u8) -> Result<(), Error> { T::regs().mcr().modify(|reg| { reg.set_mode(Self::CHANNEL.index(), val); @@ -216,8 +251,9 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { pub fn new( peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _pin: impl Peripheral

> + 'd, + pin: impl Peripheral

> + crate::gpio::sealed::Pin + 'd, ) -> Self { + pin.set_as_analog(); into_ref!(peri, dma); T::enable(); T::reset(); @@ -226,7 +262,7 @@ 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(dac_v2)] + #[cfg(any(dac_v2, dac_v3))] dac.set_channel_mode(0).unwrap(); dac.enable_channel().unwrap(); dac.set_trigger_enable(true).unwrap(); @@ -252,7 +288,6 @@ 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(all(bdma, not(dma)))] // It currently only works with BDMA-only chips (DMA should theoretically work though) pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> where Tx: DmaCh1, @@ -327,8 +362,9 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { pub fn new( _peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - _pin: impl Peripheral

> + 'd, + pin: impl Peripheral

> + crate::gpio::sealed::Pin + 'd, ) -> Self { + pin.set_as_analog(); into_ref!(_peri, dma); T::enable(); T::reset(); @@ -340,7 +376,7 @@ 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(dac_v2)] + #[cfg(any(dac_v2, dac_v3))] dac.set_channel_mode(0).unwrap(); dac.enable_channel().unwrap(); dac.set_trigger_enable(true).unwrap(); @@ -364,7 +400,6 @@ 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(all(bdma, not(dma)))] // It currently only works with BDMA-only chips (DMA should theoretically work though) pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> where Tx: DmaCh2, @@ -442,9 +477,11 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> { peri: impl Peripheral

+ 'd, dma_ch1: impl Peripheral

+ 'd, dma_ch2: impl Peripheral

+ 'd, - _pin_ch1: impl Peripheral

> + 'd, - _pin_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); T::enable(); T::reset(); @@ -461,12 +498,12 @@ 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(dac_v2)] + #[cfg(any(dac_v2, dac_v3))] dac_ch1.set_channel_mode(0).unwrap(); dac_ch1.enable_channel().unwrap(); dac_ch1.set_trigger_enable(true).unwrap(); - #[cfg(dac_v2)] + #[cfg(any(dac_v2, dac_v3))] dac_ch2.set_channel_mode(0).unwrap(); dac_ch2.enable_channel().unwrap(); dac_ch2.set_trigger_enable(true).unwrap(); diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 5a87888b..68c78123 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -466,15 +466,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> { self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); } - /// Read bytes from the ring buffer + /// Read elements from the ring buffer /// Return a tuple of the length read and the length remaining in the buffer - /// If not all of the bytes were read, then there will be some bytes in the buffer remaining - /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read + /// If not all of the elements were read, then there will be some elements in the buffer remaining + /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) } + /// Read an exact number of elements from the ringbuffer. + /// + /// Returns the remaining number of elements available for immediate reading. + /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. + /// + /// Async/Wake Behavior: + /// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point, + /// and when it wraps around. This means that when called with a buffer of length 'M', when this + /// ring buffer was created with a buffer of size 'N': + /// - If M equals N/2 or N/2 divides evenly into M, this function will return every N/2 elements read on the DMA source. + /// - Otherwise, this function may need up to N/2 extra elements to arrive before returning. + pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result { + use core::future::poll_fn; + use core::sync::atomic::compiler_fence; + + let mut read_data = 0; + let buffer_len = buffer.len(); + + poll_fn(|cx| { + self.set_waker(cx.waker()); + + compiler_fence(Ordering::SeqCst); + + match self.read(&mut buffer[read_data..buffer_len]) { + Ok((len, remaining)) => { + read_data += len; + if read_data == buffer_len { + Poll::Ready(Ok(remaining)) + } else { + Poll::Pending + } + } + Err(e) => Poll::Ready(Err(e)), + } + }) + .await + } + /// The capacity of the ringbuffer pub fn cap(&self) -> usize { self.ringbuf.cap() diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 58d438af..c27ec7bd 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -28,6 +28,12 @@ pub struct TransferOptions { pub flow_ctrl: FlowControl, /// FIFO threshold for DMA FIFO mode. If none, direct mode is used. pub fifo_threshold: Option, + /// Enable circular DMA + pub circular: bool, + /// Enable half transfer interrupt + pub half_transfer_ir: bool, + /// Enable transfer complete interrupt + pub complete_transfer_ir: bool, } impl Default for TransferOptions { @@ -37,6 +43,9 @@ impl Default for TransferOptions { mburst: Burst::Single, flow_ctrl: FlowControl::Dma, fifo_threshold: None, + circular: false, + half_transfer_ir: false, + complete_transfer_ir: true, } } } @@ -365,7 +374,13 @@ impl<'a, C: Channel> Transfer<'a, C> { }); w.set_pinc(vals::Inc::FIXED); w.set_teie(true); - w.set_tcie(true); + w.set_tcie(options.complete_transfer_ir); + if options.circular { + w.set_circ(vals::Circ::ENABLED); + debug!("Setting circular mode"); + } else { + w.set_circ(vals::Circ::DISABLED); + } #[cfg(dma_v1)] w.set_trbuff(true); @@ -646,7 +661,7 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> { w.set_minc(vals::Inc::INCREMENTED); w.set_pinc(vals::Inc::FIXED); w.set_teie(true); - w.set_htie(true); + w.set_htie(options.half_transfer_ir); w.set_tcie(true); w.set_circ(vals::Circ::ENABLED); #[cfg(dma_v1)] @@ -696,15 +711,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> { self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); } - /// Read bytes from the ring buffer + /// Read elements from the ring buffer /// Return a tuple of the length read and the length remaining in the buffer - /// If not all of the bytes were read, then there will be some bytes in the buffer remaining - /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read + /// If not all of the elements were read, then there will be some elements in the buffer remaining + /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) } + /// Read an exact number of elements from the ringbuffer. + /// + /// Returns the remaining number of elements available for immediate reading. + /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. + /// + /// Async/Wake Behavior: + /// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point, + /// and when it wraps around. This means that when called with a buffer of length 'M', when this + /// ring buffer was created with a buffer of size 'N': + /// - If M equals N/2 or N/2 divides evenly into M, this function will return every N/2 elements read on the DMA source. + /// - Otherwise, this function may need up to N/2 extra elements to arrive before returning. + pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result { + use core::future::poll_fn; + use core::sync::atomic::compiler_fence; + + let mut read_data = 0; + let buffer_len = buffer.len(); + + poll_fn(|cx| { + self.set_waker(cx.waker()); + + compiler_fence(Ordering::SeqCst); + + match self.read(&mut buffer[read_data..buffer_len]) { + Ok((len, remaining)) => { + read_data += len; + if read_data == buffer_len { + Poll::Ready(Ok(remaining)) + } else { + Poll::Pending + } + } + Err(e) => Poll::Ready(Err(e)), + } + }) + .await + } + // The capacity of the ringbuffer pub fn cap(&self) -> usize { self.ringbuf.cap() diff --git a/embassy-stm32/src/dma/ringbuffer.rs b/embassy-stm32/src/dma/ringbuffer.rs index a2bde986..19079397 100644 --- a/embassy-stm32/src/dma/ringbuffer.rs +++ b/embassy-stm32/src/dma/ringbuffer.rs @@ -72,10 +72,10 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { self.cap() - remaining_transfers } - /// Read bytes from the ring buffer + /// Read elements from the ring buffer /// Return a tuple of the length read and the length remaining in the buffer - /// If not all of the bytes were read, then there will be some bytes in the buffer remaining - /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read + /// If not all of the elements were read, then there will be some elements in the buffer remaining + /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. pub fn read(&mut self, mut dma: impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { /* @@ -95,11 +95,11 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { */ let end = self.pos(dma.get_remaining_transfers()); if self.start == end && dma.get_complete_count() == 0 { - // No bytes are available in the buffer + // No elements are available in the buffer Ok((0, self.cap())) } else if self.start < end { // The available, unread portion in the ring buffer DOES NOT wrap - // Copy out the bytes from the dma buffer + // Copy out the elements from the dma buffer let len = self.copy_to(buf, self.start..end); compiler_fence(Ordering::SeqCst); @@ -128,7 +128,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { // The DMA writer has wrapped since we last read and is currently // writing (or the next byte added will be) in the beginning of the ring buffer. - // The provided read buffer is not large enough to include all bytes from the tail of the dma buffer. + // The provided read buffer is not large enough to include all elements from the tail of the dma buffer. // Copy out from the dma buffer let len = self.copy_to(buf, self.start..self.cap()); @@ -154,8 +154,8 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { // The DMA writer has wrapped since we last read and is currently // writing (or the next byte added will be) in the beginning of the ring buffer. - // The provided read buffer is large enough to include all bytes from the tail of the dma buffer, - // so the next read will not have any unread tail bytes in the ring buffer. + // The provided read buffer is large enough to include all elements from the tail of the dma buffer, + // so the next read will not have any unread tail elements in the ring buffer. // Copy out from the dma buffer let tail = self.copy_to(buf, self.start..self.cap()); @@ -180,7 +180,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { } /// Copy from the dma buffer at `data_range` into `buf` fn copy_to(&mut self, buf: &mut [W], data_range: Range) -> usize { - // Limit the number of bytes that can be copied + // Limit the number of elements that can be copied let length = usize::min(data_range.len(), buf.len()); // Copy from dma buffer into read buffer diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index a24cba9f..e100ca5c 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -265,63 +265,9 @@ pub(crate) mod sealed { } fn _configure_pwr() { - // TODO: move this to RCC - - let pwr = crate::pac::PWR; + // TODO: move the rest of this to rcc let rcc = crate::pac::RCC; - rcc.cfgr().modify(|w| w.set_stopwuck(true)); - - pwr.cr1().modify(|w| w.set_dbp(true)); - pwr.cr1().modify(|w| w.set_dbp(true)); - - // configure LSE - rcc.bdcr().modify(|w| w.set_lseon(true)); - - // select system clock source = PLL - // set PLL coefficients - // m: 2, - // n: 12, - // r: 3, - // q: 4, - // p: 3, - let src_bits = 0b11; - let pllp = (3 - 1) & 0b11111; - let pllq = (4 - 1) & 0b111; - let pllr = (3 - 1) & 0b111; - let plln = 12 & 0b1111111; - let pllm = (2 - 1) & 0b111; - rcc.pllcfgr().modify(|w| { - w.set_pllsrc(src_bits); - w.set_pllm(pllm); - w.set_plln(plln); - w.set_pllr(pllr); - w.set_pllp(pllp); - w.set_pllpen(true); - w.set_pllq(pllq); - w.set_pllqen(true); - }); - // enable PLL - rcc.cr().modify(|w| w.set_pllon(true)); - rcc.cr().write(|w| w.set_hsion(false)); - // while !rcc.cr().read().pllrdy() {} - - // configure SYSCLK mux to use PLL clocl - rcc.cfgr().modify(|w| w.set_sw(0b11)); - - // configure CPU1 & CPU2 dividers - rcc.cfgr().modify(|w| w.set_hpre(0)); // not divided - rcc.extcfgr().modify(|w| { - w.set_c2hpre(0b1000); // div2 - w.set_shdhpre(0); // not divided - }); - - // apply APB1 / APB2 values - rcc.cfgr().modify(|w| { - w.set_ppre1(0b000); // not divided - w.set_ppre2(0b000); // not divided - }); - // TODO: required // set RF wake-up clock = LSE rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 886fc0b9..4ae65d3e 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -78,6 +78,14 @@ pub struct Clocks { /// The existence of this value indicates that the clock configuration can no longer be changed static mut CLOCK_FREQS: MaybeUninit = MaybeUninit::uninit(); +#[cfg(stm32wb)] +/// RCC initialization function +pub(crate) unsafe fn init(config: Config) { + set_freqs(compute_clocks(&config)); + + configure_clocks(&config); +} + /// Sets the clock frequencies /// /// Safety: Sets a mutable global. diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index e6123821..4322b950 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs @@ -1,6 +1,5 @@ -use crate::pac::RCC; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; +use crate::rcc::Clocks; +use crate::time::{khz, mhz, Hertz}; /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, /// and with the addition of the init function to configure a system clock. @@ -13,11 +12,94 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); /// LSI speed pub const LSI_FREQ: Hertz = Hertz(32_000); -/// System clock mux source #[derive(Clone, Copy)] -pub enum ClockSrc { - HSE(Hertz), - HSI16, +pub enum HsePrescaler { + NotDivided, + Div2, +} + +impl From for bool { + fn from(value: HsePrescaler) -> Self { + match value { + HsePrescaler::NotDivided => false, + HsePrescaler::Div2 => true, + } + } +} + +pub struct Hse { + pub prediv: HsePrescaler, + + pub frequency: Hertz, +} + +/// System clock mux source +#[derive(Clone, Copy, PartialEq)] +pub enum Sysclk { + /// MSI selected as sysclk + MSI, + /// HSI selected as sysclk + HSI, + /// HSE selected as sysclk + HSE, + /// PLL selected as sysclk + Pll, +} + +impl From for u8 { + fn from(value: Sysclk) -> Self { + match value { + Sysclk::MSI => 0b00, + Sysclk::HSI => 0b01, + Sysclk::HSE => 0b10, + Sysclk::Pll => 0b11, + } + } +} + +#[derive(Clone, Copy, PartialEq)] +pub enum PllSource { + Hsi, + Msi, + Hse, +} + +impl From for u8 { + fn from(value: PllSource) -> Self { + match value { + PllSource::Msi => 0b01, + PllSource::Hsi => 0b10, + PllSource::Hse => 0b11, + } + } +} + +pub enum Pll48Source { + PllSai, + Pll, + Msi, + Hsi48, +} + +pub struct PllMux { + /// Source clock selection. + pub source: PllSource, + + /// PLL pre-divider (DIVM). Must be between 1 and 63. + pub prediv: u8, +} + +pub struct Pll { + /// PLL multiplication factor. Must be between 4 and 512. + pub mul: u16, + + /// 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, } /// AHB prescaler @@ -84,86 +166,250 @@ impl Into for AHBPrescaler { /// Clocks configutation pub struct Config { - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, + pub hse: Option, + pub lse: Option, + pub sys: Sysclk, + pub mux: Option, + pub pll48: Option, + + 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 const WPAN_DEFAULT: Config = Config { + hse: Some(Hse { + frequency: mhz(32), + prediv: HsePrescaler::NotDivided, + }), + lse: Some(khz(32)), + sys: Sysclk::Pll, + mux: Some(PllMux { + source: PllSource::Hse, + prediv: 2, + }), + pll48: None, + + pll: Some(Pll { + mul: 12, + divp: Some(3), + divq: Some(4), + divr: Some(3), + }), + pllsai: None, + + ahb1_pre: AHBPrescaler::NotDivided, + ahb2_pre: AHBPrescaler::Div2, + ahb3_pre: AHBPrescaler::NotDivided, + apb1_pre: APBPrescaler::NotDivided, + apb2_pre: APBPrescaler::NotDivided, +}; + impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::HSI16, - ahb_pre: AHBPrescaler::NotDivided, + hse: None, + lse: None, + sys: Sysclk::HSI, + mux: None, + pll48: None, + pll: None, + pllsai: None, + + ahb1_pre: AHBPrescaler::NotDivided, + ahb2_pre: AHBPrescaler::NotDivided, + ahb3_pre: AHBPrescaler::NotDivided, apb1_pre: APBPrescaler::NotDivided, apb2_pre: APBPrescaler::NotDivided, } } } -pub(crate) unsafe fn init(config: Config) { - let (sys_clk, sw) = match config.mux { - ClockSrc::HSI16 => { - // Enable HSI16 - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - (HSI_FREQ.0, 0x01) - } - ClockSrc::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - - (freq.0, 0x02) - } - }; - - RCC.cfgr().modify(|w| { - w.set_sw(sw.into()); - w.set_hpre(config.ahb_pre.into()); - w.set_ppre1(config.apb1_pre.into()); - w.set_ppre2(config.apb2_pre.into()); +pub(crate) fn compute_clocks(config: &Config) -> Clocks { + let hse_clk = config.hse.as_ref().map(|hse| match hse.prediv { + HsePrescaler::NotDivided => hse.frequency, + HsePrescaler::Div2 => hse.frequency / 2u32, }); - let ahb_freq: u32 = match config.ahb_pre { + 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::Pll => pll_r.unwrap(), + _ => unreachable!(), + }; + + let ahb1_clk = match config.ahb1_pre { AHBPrescaler::NotDivided => sys_clk, pre => { let pre: u8 = pre.into(); - let pre = 1 << (pre as u32 - 7); + let pre = 1u32 << (pre as u32 - 7); sys_clk / pre } }; - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::NotDivided => (ahb_freq, ahb_freq), + let ahb2_clk = match config.ahb2_pre { + AHBPrescaler::NotDivided => sys_clk, pre => { let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let pre = 1u32 << (pre as u32 - 7); + sys_clk / pre } }; - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::NotDivided => (ahb_freq, ahb_freq), + let ahb3_clk = match config.ahb3_pre { + AHBPrescaler::NotDivided => sys_clk, pre => { let pre: u8 = pre.into(); - let pre: u8 = 1 << (pre - 3); - let freq = ahb_freq / pre as u32; - (freq, freq * 2) + let pre = 1u32 << (pre as u32 - 7); + sys_clk / pre } }; - set_freqs(Clocks { - sys: Hertz(sys_clk), - ahb1: Hertz(ahb_freq), - ahb2: Hertz(ahb_freq), - ahb3: Hertz(ahb_freq), - apb1: Hertz(apb1_freq), - apb2: Hertz(apb2_freq), - apb1_tim: Hertz(apb1_tim_freq), - apb2_tim: Hertz(apb2_tim_freq), + let (apb1_clk, apb1_tim_clk) = match config.apb1_pre { + APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk), + pre => { + let pre: u8 = pre.into(); + let pre: u8 = 1 << (pre - 3); + let freq = ahb1_clk / pre as u32; + (freq, freq * 2u32) + } + }; + + let (apb2_clk, apb2_tim_clk) = match config.apb2_pre { + APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk), + pre => { + let pre: u8 = pre.into(); + let pre: u8 = 1 << (pre - 3); + let freq = ahb1_clk / pre as u32; + (freq, freq * 2u32) + } + }; + + 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, + } +} + +pub(crate) fn configure_clocks(config: &Config) { + let pwr = crate::pac::PWR; + 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() {} + } + + match &config.lse { + Some(_) => { + rcc.cfgr().modify(|w| w.set_stopwuck(true)); + + pwr.cr1().modify(|w| w.set_dbp(true)); + pwr.cr1().modify(|w| w.set_dbp(true)); + + rcc.bdcr().modify(|w| w.set_lseon(true)); + } + _ => {} + } + + match &config.hse { + Some(hse) => { + rcc.cr().modify(|w| { + w.set_hsepre(hse.prediv.into()); + 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 as u8); + pll.divp.map(|divp| { + w.set_pllpen(true); + w.set_pllp((divp - 1) as u8) + }); + pll.divq.map(|divq| { + w.set_pllqen(true); + w.set_pllq((divq - 1) as u8) + }); + pll.divr.map(|divr| { + // w.set_pllren(true); + w.set_pllr((divr - 1) as u8); + }); + }); + + rcc.cr().modify(|w| w.set_pllon(true)); + + while !rcc.cr().read().pllrdy() {} + } + _ => {} + } + + rcc.cfgr().modify(|w| { + w.set_sw(config.sys.into()); + w.set_hpre(config.ahb1_pre.into()); + w.set_ppre1(config.apb1_pre.into()); + w.set_ppre2(config.apb2_pre.into()); + }); + + rcc.extcfgr().modify(|w| { + w.set_c2hpre(config.ahb2_pre.into()); + w.set_shdhpre(config.ahb3_pre.into()); }); } diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 698292bf..434c56a4 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -225,6 +225,9 @@ const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOp mburst: crate::dma::Burst::Incr4, flow_ctrl: crate::dma::FlowControl::Peripheral, fifo_threshold: Some(crate::dma::FifoThreshold::Full), + circular: false, + half_transfer_ir: false, + complete_transfer_ir: true, }; #[cfg(all(sdmmc_v1, not(dma)))] const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions { diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index 30b67b7b..068474e7 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -34,3 +34,6 @@ log = { version = "0.4.17", optional = true } [[bin]] name = "rtos_trace" required-features = ["nightly"] + +[profile.release] +debug = 2 diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index ded3b7db..715f1ecf 100644 --- a/examples/nrf52840-rtic/Cargo.toml +++ b/examples/nrf52840-rtic/Cargo.toml @@ -19,3 +19,6 @@ 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"] } + +[profile.release] +debug = 2 diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 9b41ec5a..780aaeac 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -57,5 +57,5 @@ embedded-hal-async = { version = "0.2.0-alpha.2", optional = true } num-integer = { version = "0.1.45", default-features = false } microfft = "0.5.0" -[patch.crates-io] -lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } +[profile.release] +debug = 2 diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index f1d45f33..b0e51dcf 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -53,3 +53,6 @@ rand = { version = "0.8.4", default-features = false } embedded-storage = "0.3.0" usbd-hid = "0.6.0" serde = { version = "1.0.136", default-features = false } + +[profile.release] +debug = 2 diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index c812cb3e..8c61dc5e 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -53,7 +53,4 @@ pio = "0.2.1" rand = { version = "0.8.5", default-features = false } [profile.release] -debug = true - -[patch.crates-io] -lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } +debug = 2 diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 92933ab5..42adede1 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -23,3 +23,6 @@ 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"]} + +[profile.release] +debug = 2 diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index e74c5357..8534921a 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -20,3 +20,6 @@ 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 } + +[profile.release] +debug = 2 diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 620a139a..46b6db45 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -18,3 +18,6 @@ embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } static_cell = { version = "1.1", features = ["nightly"]} + +[profile.release] +debug = 2 diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 8450c541..5d32992c 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -26,3 +26,6 @@ nb = "1.0.0" [profile.dev] opt-level = "s" + +[profile.release] +debug = 2 diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index 147e2ecb..9857fb63 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -21,3 +21,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 } nb = "1.0.0" + +[profile.release] +debug = 2 diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 6ac5d57e..bd594d16 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -25,3 +25,6 @@ heapless = { version = "0.7.5", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" static_cell = { version = "1.1", features = ["nightly"]} + +[profile.release] +debug = 2 diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index e1ef40f9..fdd3b7d4 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.2.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers", "arch-cortex-m", "executor-thread", "executor-interrupt"] } +embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.1.2", 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/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs index 08bed88d..f84f74d3 100644 --- a/examples/stm32f4/src/bin/can.rs +++ b/examples/stm32f4/src/bin/can.rs @@ -40,10 +40,13 @@ async fn main(_spawner: Spawner) { can.as_mut() .modify_config() - .set_bit_timing(0x001c0003) // http://www.bittiming.can-wiki.info/ .set_loopback(true) // Receive own frames .set_silent(true) - .enable(); + .leave_disabled(); + + can.set_bitrate(1_000_000); + + can.enable().await; let mut i: u8 = 0; loop { diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs index 3a621671..aaedcfec 100644 --- a/examples/stm32f4/src/bin/dac.rs +++ b/examples/stm32f4/src/bin/dac.rs @@ -14,11 +14,11 @@ 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.trigger(); } } } diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index bbc99fee..a6964c7b 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -28,3 +28,6 @@ rand_core = "0.6.3" critical-section = "1.1" embedded-storage = "0.3.0" static_cell = { version = "1.1", features = ["nightly"]} + +[profile.release] +debug = 2 diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 4a14568a..b4dfe3c6 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -20,3 +20,6 @@ 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 } + +[profile.release] +debug = 2 diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 935997a7..ce883860 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -22,3 +22,6 @@ 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 } + +[profile.release] +debug = 2 diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index 586b4154..ee078286 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs @@ -21,11 +21,11 @@ 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.trigger(); } } } diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index e6a5a4c1..c325751c 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -34,5 +34,5 @@ heapless = { version = "0.7.5", default-features = false } embedded-hal = "0.2.6" static_cell = "1.1" -[patch.crates-io] -lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } +[profile.release] +debug = 2 diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index dcca1cc3..329d44ca 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -20,3 +20,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 } embedded-storage = "0.3.0" + +[profile.release] +debug = 2 diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 41c9869b..0f770e2f 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false } chrono = { version = "^0.4", default-features = false } micromath = "2.0.0" + +[profile.release] +debug = 2 diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs index ade43eb3..0193a248 100644 --- a/examples/stm32l4/src/bin/dac.rs +++ b/examples/stm32l4/src/bin/dac.rs @@ -13,11 +13,11 @@ 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.trigger(); } } } diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 5d66c59c..1afd0039 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false } rand_core = { version = "0.6.3", default-features = false } embedded-io = { version = "0.4.0", features = ["async"] } static_cell = { version = "1.1", features = ["nightly"]} + +[profile.release] +debug = 2 diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index a43a5590..db251eaf 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -23,3 +23,6 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa heapless = { version = "0.7.5", default-features = false } micromath = "2.0.0" + +[profile.release] +debug = 2 diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 48e34026..1a5aff35 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -52,3 +52,6 @@ required-features = ["ble"] [[bin]] name = "gatt_server" required-features = ["ble"] + +[profile.release] +debug = 2 diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 6e6f269a..48b69c8d 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -28,5 +28,5 @@ 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 } -[patch.crates-io] -lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } +[profile.release] +debug = 2 diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index 3679e385..2791cc34 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml @@ -17,3 +17,6 @@ wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] } log = "0.4.11" critical-section = { version = "1.1", features = ["std"] } + +[profile.release] +debug = 2 diff --git a/tests/stm32/src/bin/wpan_ble.rs b/tests/stm32/src/bin/wpan_ble.rs index 3ad8aca4..452da77a 100644 --- a/tests/stm32/src/bin/wpan_ble.rs +++ b/tests/stm32/src/bin/wpan_ble.rs @@ -12,6 +12,7 @@ use common::*; use embassy_executor::Spawner; use embassy_stm32::bind_interrupts; use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; +use embassy_stm32::rcc::WPAN_DEFAULT; use embassy_stm32_wpan::hci::host::uart::UartHci; use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; use embassy_stm32_wpan::hci::types::AdvertisingType; @@ -40,7 +41,10 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) { #[embassy_executor::main] async fn main(spawner: Spawner) { - let p = embassy_stm32::init(config()); + let mut config = config(); + config.rcc = WPAN_DEFAULT; + + let p = embassy_stm32::init(config); info!("Hello World!"); let config = Config::default(); diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs index b04a19ee..7eab2fd3 100644 --- a/tests/stm32/src/bin/wpan_mac.rs +++ b/tests/stm32/src/bin/wpan_mac.rs @@ -10,6 +10,7 @@ use common::*; use embassy_executor::Spawner; use embassy_stm32::bind_interrupts; use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; +use embassy_stm32::rcc::WPAN_DEFAULT; use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest}; use embassy_stm32_wpan::mac::event::MacEvent; use embassy_stm32_wpan::mac::typedefs::{ @@ -31,7 +32,10 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) { #[embassy_executor::main] async fn main(spawner: Spawner) { - let p = embassy_stm32::init(config()); + let mut config = config(); + config.rcc = WPAN_DEFAULT; + + let p = embassy_stm32::init(config); info!("Hello World!"); let config = Config::default();