diff options
| author | Michael van Niekerk <[email protected]> | 2023-07-28 11:38:45 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-07-28 11:38:45 +0200 |
| commit | 1d4e1092c455956b6a90756cf385f9ae75d89fc6 (patch) | |
| tree | 411abdaaae979320b76a2940b64ee435e1249a22 | |
| parent | 0f1ff77fcc3c085f9969bac4963d784c022e6044 (diff) | |
| parent | 44c8db2911f0f9d82e6517e31944777454c4e459 (diff) | |
Merge branch 'embassy-rs:main' into main
40 files changed, 563 insertions, 165 deletions
diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml index e4524af5b..a77ed003e 100644 --- a/embassy-lora/Cargo.toml +++ b/embassy-lora/Cargo.toml | |||
| @@ -12,7 +12,7 @@ target = "thumbv7em-none-eabi" | |||
| 12 | 12 | ||
| 13 | [features] | 13 | [features] |
| 14 | stm32wl = ["dep:embassy-stm32"] | 14 | stm32wl = ["dep:embassy-stm32"] |
| 15 | time = [] | 15 | time = ["embassy-time", "lorawan-device"] |
| 16 | defmt = ["dep:defmt", "lorawan-device/defmt"] | 16 | defmt = ["dep:defmt", "lorawan-device/defmt"] |
| 17 | 17 | ||
| 18 | [dependencies] | 18 | [dependencies] |
| @@ -20,18 +20,11 @@ defmt = ["dep:defmt", "lorawan-device/defmt"] | |||
| 20 | defmt = { version = "0.3", optional = true } | 20 | defmt = { version = "0.3", optional = true } |
| 21 | log = { version = "0.4.14", optional = true } | 21 | log = { version = "0.4.14", optional = true } |
| 22 | 22 | ||
| 23 | embassy-time = { version = "0.1.2", path = "../embassy-time" } | 23 | embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } |
| 24 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } | 24 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } |
| 25 | embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } | 25 | embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } |
| 26 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } | ||
| 27 | embedded-hal-async = { version = "=0.2.0-alpha.2" } | 26 | embedded-hal-async = { version = "=0.2.0-alpha.2" } |
| 28 | embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false } | ||
| 29 | futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } | ||
| 30 | embedded-hal = { version = "0.2", features = ["unproven"] } | 27 | embedded-hal = { version = "0.2", features = ["unproven"] } |
| 31 | bit_field = { version = "0.10" } | ||
| 32 | 28 | ||
| 33 | lora-phy = { version = "1" } | 29 | lora-phy = { version = "1" } |
| 34 | lorawan-device = { version = "0.10.0", default-features = false, features = ["async"] } | 30 | lorawan-device = { version = "0.10.0", default-features = false, features = ["async"], optional = true } |
| 35 | |||
| 36 | [patch.crates-io] | ||
| 37 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | ||
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 6cd122200..2c6089c56 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml | |||
| @@ -26,7 +26,7 @@ aligned = "0.4.1" | |||
| 26 | 26 | ||
| 27 | bit_field = "0.10.2" | 27 | bit_field = "0.10.2" |
| 28 | stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } | 28 | stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } |
| 29 | stm32wb-hci = { version = "0.1.3", optional = true } | 29 | stm32wb-hci = { version = "0.1.4", optional = true } |
| 30 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 30 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 31 | bitflags = { version = "2.3.3", optional = true } | 31 | bitflags = { version = "2.3.3", optional = true } |
| 32 | 32 | ||
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 5a0153464..8b8244d4f 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> { | |||
| 161 | .leave_disabled(); | 161 | .leave_disabled(); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | /// Enables the peripheral and synchronizes with the bus. | ||
| 165 | /// | ||
| 166 | /// This will wait for 11 consecutive recessive bits (bus idle state). | ||
| 167 | /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting. | ||
| 168 | pub async fn enable(&mut self) { | ||
| 169 | while self.borrow_mut().enable_non_blocking().is_err() { | ||
| 170 | // SCE interrupt is only generated for entering sleep mode, but not leaving. | ||
| 171 | // Yield to allow other tasks to execute while can bus is initializing. | ||
| 172 | embassy_futures::yield_now().await; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 164 | /// Queues the message to be sent but exerts backpressure | 176 | /// Queues the message to be sent but exerts backpressure |
| 165 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { | 177 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { |
| 166 | poll_fn(|cx| { | 178 | poll_fn(|cx| { |
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 3d58914b3..979748bb4 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs | |||
| @@ -38,11 +38,30 @@ impl Channel { | |||
| 38 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 38 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 39 | /// Trigger sources for CH1 | 39 | /// Trigger sources for CH1 |
| 40 | pub enum Ch1Trigger { | 40 | pub enum Ch1Trigger { |
| 41 | Tim6, | 41 | #[cfg(dac_v3)] |
| 42 | Tim1, | ||
| 43 | Tim2, | ||
| 44 | #[cfg(not(dac_v3))] | ||
| 42 | Tim3, | 45 | Tim3, |
| 46 | #[cfg(dac_v3)] | ||
| 47 | Tim4, | ||
| 48 | #[cfg(dac_v3)] | ||
| 49 | Tim5, | ||
| 50 | Tim6, | ||
| 43 | Tim7, | 51 | Tim7, |
| 52 | #[cfg(dac_v3)] | ||
| 53 | Tim8, | ||
| 44 | Tim15, | 54 | Tim15, |
| 45 | Tim2, | 55 | #[cfg(dac_v3)] |
| 56 | Hrtim1Dactrg1, | ||
| 57 | #[cfg(dac_v3)] | ||
| 58 | Hrtim1Dactrg2, | ||
| 59 | #[cfg(dac_v3)] | ||
| 60 | Lptim1, | ||
| 61 | #[cfg(dac_v3)] | ||
| 62 | Lptim2, | ||
| 63 | #[cfg(dac_v3)] | ||
| 64 | Lptim3, | ||
| 46 | Exti9, | 65 | Exti9, |
| 47 | Software, | 66 | Software, |
| 48 | } | 67 | } |
| @@ -50,14 +69,30 @@ pub enum Ch1Trigger { | |||
| 50 | impl Ch1Trigger { | 69 | impl Ch1Trigger { |
| 51 | fn tsel(&self) -> dac::vals::Tsel1 { | 70 | fn tsel(&self) -> dac::vals::Tsel1 { |
| 52 | match self { | 71 | match self { |
| 53 | Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO, | 72 | #[cfg(dac_v3)] |
| 73 | Ch1Trigger::Tim1 => dac::vals::Tsel1::TIM1_TRGO, | ||
| 74 | Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_TRGO, | ||
| 54 | #[cfg(not(dac_v3))] | 75 | #[cfg(not(dac_v3))] |
| 55 | Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM3_TRGO, | 76 | Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM3_TRGO, |
| 56 | #[cfg(dac_v3)] | 77 | #[cfg(dac_v3)] |
| 57 | Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM1_TRGO, | 78 | Ch1Trigger::Tim4 => dac::vals::Tsel1::TIM4_TRGO, |
| 79 | #[cfg(dac_v3)] | ||
| 80 | Ch1Trigger::Tim5 => dac::vals::Tsel1::TIM5_TRGO, | ||
| 81 | Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO, | ||
| 58 | Ch1Trigger::Tim7 => dac::vals::Tsel1::TIM7_TRGO, | 82 | Ch1Trigger::Tim7 => dac::vals::Tsel1::TIM7_TRGO, |
| 83 | #[cfg(dac_v3)] | ||
| 84 | Ch1Trigger::Tim8 => dac::vals::Tsel1::TIM8_TRGO, | ||
| 59 | Ch1Trigger::Tim15 => dac::vals::Tsel1::TIM15_TRGO, | 85 | Ch1Trigger::Tim15 => dac::vals::Tsel1::TIM15_TRGO, |
| 60 | Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_TRGO, | 86 | #[cfg(dac_v3)] |
| 87 | Ch1Trigger::Hrtim1Dactrg1 => dac::vals::Tsel1::HRTIM1_DACTRG1, | ||
| 88 | #[cfg(dac_v3)] | ||
| 89 | Ch1Trigger::Hrtim1Dactrg2 => dac::vals::Tsel1::HRTIM1_DACTRG2, | ||
| 90 | #[cfg(dac_v3)] | ||
| 91 | Ch1Trigger::Lptim1 => dac::vals::Tsel1::LPTIM1_OUT, | ||
| 92 | #[cfg(dac_v3)] | ||
| 93 | Ch1Trigger::Lptim2 => dac::vals::Tsel1::LPTIM2_OUT, | ||
| 94 | #[cfg(dac_v3)] | ||
| 95 | Ch1Trigger::Lptim3 => dac::vals::Tsel1::LPTIM3_OUT, | ||
| 61 | Ch1Trigger::Exti9 => dac::vals::Tsel1::EXTI9, | 96 | Ch1Trigger::Exti9 => dac::vals::Tsel1::EXTI9, |
| 62 | Ch1Trigger::Software => dac::vals::Tsel1::SOFTWARE, | 97 | Ch1Trigger::Software => dac::vals::Tsel1::SOFTWARE, |
| 63 | } | 98 | } |
| @@ -129,7 +164,7 @@ pub trait DacChannel<T: Instance, Tx> { | |||
| 129 | } | 164 | } |
| 130 | 165 | ||
| 131 | /// Set mode register of the given channel | 166 | /// Set mode register of the given channel |
| 132 | #[cfg(dac_v2)] | 167 | #[cfg(any(dac_v2, dac_v3))] |
| 133 | fn set_channel_mode(&mut self, val: u8) -> Result<(), Error> { | 168 | fn set_channel_mode(&mut self, val: u8) -> Result<(), Error> { |
| 134 | T::regs().mcr().modify(|reg| { | 169 | T::regs().mcr().modify(|reg| { |
| 135 | reg.set_mode(Self::CHANNEL.index(), val); | 170 | reg.set_mode(Self::CHANNEL.index(), val); |
| @@ -216,8 +251,9 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { | |||
| 216 | pub fn new( | 251 | pub fn new( |
| 217 | peri: impl Peripheral<P = T> + 'd, | 252 | peri: impl Peripheral<P = T> + 'd, |
| 218 | dma: impl Peripheral<P = Tx> + 'd, | 253 | dma: impl Peripheral<P = Tx> + 'd, |
| 219 | _pin: impl Peripheral<P = impl DacPin<T, 1>> + 'd, | 254 | pin: impl Peripheral<P = impl DacPin<T, 1>> + crate::gpio::sealed::Pin + 'd, |
| 220 | ) -> Self { | 255 | ) -> Self { |
| 256 | pin.set_as_analog(); | ||
| 221 | into_ref!(peri, dma); | 257 | into_ref!(peri, dma); |
| 222 | T::enable(); | 258 | T::enable(); |
| 223 | T::reset(); | 259 | T::reset(); |
| @@ -226,7 +262,7 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { | |||
| 226 | 262 | ||
| 227 | // Configure each activated channel. All results can be `unwrap`ed since they | 263 | // Configure each activated channel. All results can be `unwrap`ed since they |
| 228 | // will only error if the channel is not configured (i.e. ch1, ch2 are false) | 264 | // will only error if the channel is not configured (i.e. ch1, ch2 are false) |
| 229 | #[cfg(dac_v2)] | 265 | #[cfg(any(dac_v2, dac_v3))] |
| 230 | dac.set_channel_mode(0).unwrap(); | 266 | dac.set_channel_mode(0).unwrap(); |
| 231 | dac.enable_channel().unwrap(); | 267 | dac.enable_channel().unwrap(); |
| 232 | dac.set_trigger_enable(true).unwrap(); | 268 | dac.set_trigger_enable(true).unwrap(); |
| @@ -252,7 +288,6 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { | |||
| 252 | /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. | 288 | /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. |
| 253 | /// | 289 | /// |
| 254 | /// **Important:** Channel 1 has to be configured for the DAC instance! | 290 | /// **Important:** Channel 1 has to be configured for the DAC instance! |
| 255 | #[cfg(all(bdma, not(dma)))] // It currently only works with BDMA-only chips (DMA should theoretically work though) | ||
| 256 | pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> | 291 | pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> |
| 257 | where | 292 | where |
| 258 | Tx: DmaCh1<T>, | 293 | Tx: DmaCh1<T>, |
| @@ -327,8 +362,9 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { | |||
| 327 | pub fn new( | 362 | pub fn new( |
| 328 | _peri: impl Peripheral<P = T> + 'd, | 363 | _peri: impl Peripheral<P = T> + 'd, |
| 329 | dma: impl Peripheral<P = Tx> + 'd, | 364 | dma: impl Peripheral<P = Tx> + 'd, |
| 330 | _pin: impl Peripheral<P = impl DacPin<T, 2>> + 'd, | 365 | pin: impl Peripheral<P = impl DacPin<T, 2>> + crate::gpio::sealed::Pin + 'd, |
| 331 | ) -> Self { | 366 | ) -> Self { |
| 367 | pin.set_as_analog(); | ||
| 332 | into_ref!(_peri, dma); | 368 | into_ref!(_peri, dma); |
| 333 | T::enable(); | 369 | T::enable(); |
| 334 | T::reset(); | 370 | T::reset(); |
| @@ -340,7 +376,7 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { | |||
| 340 | 376 | ||
| 341 | // Configure each activated channel. All results can be `unwrap`ed since they | 377 | // Configure each activated channel. All results can be `unwrap`ed since they |
| 342 | // will only error if the channel is not configured (i.e. ch1, ch2 are false) | 378 | // will only error if the channel is not configured (i.e. ch1, ch2 are false) |
| 343 | #[cfg(dac_v2)] | 379 | #[cfg(any(dac_v2, dac_v3))] |
| 344 | dac.set_channel_mode(0).unwrap(); | 380 | dac.set_channel_mode(0).unwrap(); |
| 345 | dac.enable_channel().unwrap(); | 381 | dac.enable_channel().unwrap(); |
| 346 | dac.set_trigger_enable(true).unwrap(); | 382 | dac.set_trigger_enable(true).unwrap(); |
| @@ -364,7 +400,6 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { | |||
| 364 | /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. | 400 | /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. |
| 365 | /// | 401 | /// |
| 366 | /// **Important:** Channel 2 has to be configured for the DAC instance! | 402 | /// **Important:** Channel 2 has to be configured for the DAC instance! |
| 367 | #[cfg(all(bdma, not(dma)))] // It currently only works with BDMA-only chips (DMA should theoretically work though) | ||
| 368 | pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> | 403 | pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> |
| 369 | where | 404 | where |
| 370 | Tx: DmaCh2<T>, | 405 | Tx: DmaCh2<T>, |
| @@ -442,9 +477,11 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> { | |||
| 442 | peri: impl Peripheral<P = T> + 'd, | 477 | peri: impl Peripheral<P = T> + 'd, |
| 443 | dma_ch1: impl Peripheral<P = TxCh1> + 'd, | 478 | dma_ch1: impl Peripheral<P = TxCh1> + 'd, |
| 444 | dma_ch2: impl Peripheral<P = TxCh2> + 'd, | 479 | dma_ch2: impl Peripheral<P = TxCh2> + 'd, |
| 445 | _pin_ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd, | 480 | pin_ch1: impl Peripheral<P = impl DacPin<T, 1>> + crate::gpio::sealed::Pin + 'd, |
| 446 | _pin_ch2: impl Peripheral<P = impl DacPin<T, 2>> + 'd, | 481 | pin_ch2: impl Peripheral<P = impl DacPin<T, 2>> + crate::gpio::sealed::Pin + 'd, |
| 447 | ) -> Self { | 482 | ) -> Self { |
| 483 | pin_ch1.set_as_analog(); | ||
| 484 | pin_ch2.set_as_analog(); | ||
| 448 | into_ref!(peri, dma_ch1, dma_ch2); | 485 | into_ref!(peri, dma_ch1, dma_ch2); |
| 449 | T::enable(); | 486 | T::enable(); |
| 450 | T::reset(); | 487 | T::reset(); |
| @@ -461,12 +498,12 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> { | |||
| 461 | 498 | ||
| 462 | // Configure each activated channel. All results can be `unwrap`ed since they | 499 | // Configure each activated channel. All results can be `unwrap`ed since they |
| 463 | // will only error if the channel is not configured (i.e. ch1, ch2 are false) | 500 | // will only error if the channel is not configured (i.e. ch1, ch2 are false) |
| 464 | #[cfg(dac_v2)] | 501 | #[cfg(any(dac_v2, dac_v3))] |
| 465 | dac_ch1.set_channel_mode(0).unwrap(); | 502 | dac_ch1.set_channel_mode(0).unwrap(); |
| 466 | dac_ch1.enable_channel().unwrap(); | 503 | dac_ch1.enable_channel().unwrap(); |
| 467 | dac_ch1.set_trigger_enable(true).unwrap(); | 504 | dac_ch1.set_trigger_enable(true).unwrap(); |
| 468 | 505 | ||
| 469 | #[cfg(dac_v2)] | 506 | #[cfg(any(dac_v2, dac_v3))] |
| 470 | dac_ch2.set_channel_mode(0).unwrap(); | 507 | dac_ch2.set_channel_mode(0).unwrap(); |
| 471 | dac_ch2.enable_channel().unwrap(); | 508 | dac_ch2.enable_channel().unwrap(); |
| 472 | dac_ch2.set_trigger_enable(true).unwrap(); | 509 | dac_ch2.set_trigger_enable(true).unwrap(); |
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 5a87888b7..68c78123d 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> { | |||
| 466 | self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); | 466 | self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); |
| 467 | } | 467 | } |
| 468 | 468 | ||
| 469 | /// Read bytes from the ring buffer | 469 | /// Read elements from the ring buffer |
| 470 | /// Return a tuple of the length read and the length remaining in the buffer | 470 | /// Return a tuple of the length read and the length remaining in the buffer |
| 471 | /// If not all of the bytes were read, then there will be some bytes in the buffer remaining | 471 | /// If not all of the elements were read, then there will be some elements in the buffer remaining |
| 472 | /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read | 472 | /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read |
| 473 | /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. | 473 | /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. |
| 474 | pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { | 474 | pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { |
| 475 | self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) | 475 | self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | /// Read an exact number of elements from the ringbuffer. | ||
| 479 | /// | ||
| 480 | /// Returns the remaining number of elements available for immediate reading. | ||
| 481 | /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. | ||
| 482 | /// | ||
| 483 | /// Async/Wake Behavior: | ||
| 484 | /// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point, | ||
| 485 | /// and when it wraps around. This means that when called with a buffer of length 'M', when this | ||
| 486 | /// ring buffer was created with a buffer of size 'N': | ||
| 487 | /// - 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. | ||
| 488 | /// - Otherwise, this function may need up to N/2 extra elements to arrive before returning. | ||
| 489 | pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result<usize, OverrunError> { | ||
| 490 | use core::future::poll_fn; | ||
| 491 | use core::sync::atomic::compiler_fence; | ||
| 492 | |||
| 493 | let mut read_data = 0; | ||
| 494 | let buffer_len = buffer.len(); | ||
| 495 | |||
| 496 | poll_fn(|cx| { | ||
| 497 | self.set_waker(cx.waker()); | ||
| 498 | |||
| 499 | compiler_fence(Ordering::SeqCst); | ||
| 500 | |||
| 501 | match self.read(&mut buffer[read_data..buffer_len]) { | ||
| 502 | Ok((len, remaining)) => { | ||
| 503 | read_data += len; | ||
| 504 | if read_data == buffer_len { | ||
| 505 | Poll::Ready(Ok(remaining)) | ||
| 506 | } else { | ||
| 507 | Poll::Pending | ||
| 508 | } | ||
| 509 | } | ||
| 510 | Err(e) => Poll::Ready(Err(e)), | ||
| 511 | } | ||
| 512 | }) | ||
| 513 | .await | ||
| 514 | } | ||
| 515 | |||
| 478 | /// The capacity of the ringbuffer | 516 | /// The capacity of the ringbuffer |
| 479 | pub fn cap(&self) -> usize { | 517 | pub fn cap(&self) -> usize { |
| 480 | self.ringbuf.cap() | 518 | self.ringbuf.cap() |
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 58d438af8..c27ec7bd9 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs | |||
| @@ -28,6 +28,12 @@ pub struct TransferOptions { | |||
| 28 | pub flow_ctrl: FlowControl, | 28 | pub flow_ctrl: FlowControl, |
| 29 | /// FIFO threshold for DMA FIFO mode. If none, direct mode is used. | 29 | /// FIFO threshold for DMA FIFO mode. If none, direct mode is used. |
| 30 | pub fifo_threshold: Option<FifoThreshold>, | 30 | pub fifo_threshold: Option<FifoThreshold>, |
| 31 | /// Enable circular DMA | ||
| 32 | pub circular: bool, | ||
| 33 | /// Enable half transfer interrupt | ||
| 34 | pub half_transfer_ir: bool, | ||
| 35 | /// Enable transfer complete interrupt | ||
| 36 | pub complete_transfer_ir: bool, | ||
| 31 | } | 37 | } |
| 32 | 38 | ||
| 33 | impl Default for TransferOptions { | 39 | impl Default for TransferOptions { |
| @@ -37,6 +43,9 @@ impl Default for TransferOptions { | |||
| 37 | mburst: Burst::Single, | 43 | mburst: Burst::Single, |
| 38 | flow_ctrl: FlowControl::Dma, | 44 | flow_ctrl: FlowControl::Dma, |
| 39 | fifo_threshold: None, | 45 | fifo_threshold: None, |
| 46 | circular: false, | ||
| 47 | half_transfer_ir: false, | ||
| 48 | complete_transfer_ir: true, | ||
| 40 | } | 49 | } |
| 41 | } | 50 | } |
| 42 | } | 51 | } |
| @@ -365,7 +374,13 @@ impl<'a, C: Channel> Transfer<'a, C> { | |||
| 365 | }); | 374 | }); |
| 366 | w.set_pinc(vals::Inc::FIXED); | 375 | w.set_pinc(vals::Inc::FIXED); |
| 367 | w.set_teie(true); | 376 | w.set_teie(true); |
| 368 | w.set_tcie(true); | 377 | w.set_tcie(options.complete_transfer_ir); |
| 378 | if options.circular { | ||
| 379 | w.set_circ(vals::Circ::ENABLED); | ||
| 380 | debug!("Setting circular mode"); | ||
| 381 | } else { | ||
| 382 | w.set_circ(vals::Circ::DISABLED); | ||
| 383 | } | ||
| 369 | #[cfg(dma_v1)] | 384 | #[cfg(dma_v1)] |
| 370 | w.set_trbuff(true); | 385 | w.set_trbuff(true); |
| 371 | 386 | ||
| @@ -646,7 +661,7 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> { | |||
| 646 | w.set_minc(vals::Inc::INCREMENTED); | 661 | w.set_minc(vals::Inc::INCREMENTED); |
| 647 | w.set_pinc(vals::Inc::FIXED); | 662 | w.set_pinc(vals::Inc::FIXED); |
| 648 | w.set_teie(true); | 663 | w.set_teie(true); |
| 649 | w.set_htie(true); | 664 | w.set_htie(options.half_transfer_ir); |
| 650 | w.set_tcie(true); | 665 | w.set_tcie(true); |
| 651 | w.set_circ(vals::Circ::ENABLED); | 666 | w.set_circ(vals::Circ::ENABLED); |
| 652 | #[cfg(dma_v1)] | 667 | #[cfg(dma_v1)] |
| @@ -696,15 +711,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> { | |||
| 696 | self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); | 711 | self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); |
| 697 | } | 712 | } |
| 698 | 713 | ||
| 699 | /// Read bytes from the ring buffer | 714 | /// Read elements from the ring buffer |
| 700 | /// Return a tuple of the length read and the length remaining in the buffer | 715 | /// Return a tuple of the length read and the length remaining in the buffer |
| 701 | /// If not all of the bytes were read, then there will be some bytes in the buffer remaining | 716 | /// If not all of the elements were read, then there will be some elements in the buffer remaining |
| 702 | /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read | 717 | /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read |
| 703 | /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. | 718 | /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. |
| 704 | pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { | 719 | pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { |
| 705 | self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) | 720 | self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) |
| 706 | } | 721 | } |
| 707 | 722 | ||
| 723 | /// Read an exact number of elements from the ringbuffer. | ||
| 724 | /// | ||
| 725 | /// Returns the remaining number of elements available for immediate reading. | ||
| 726 | /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. | ||
| 727 | /// | ||
| 728 | /// Async/Wake Behavior: | ||
| 729 | /// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point, | ||
| 730 | /// and when it wraps around. This means that when called with a buffer of length 'M', when this | ||
| 731 | /// ring buffer was created with a buffer of size 'N': | ||
| 732 | /// - 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. | ||
| 733 | /// - Otherwise, this function may need up to N/2 extra elements to arrive before returning. | ||
| 734 | pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result<usize, OverrunError> { | ||
| 735 | use core::future::poll_fn; | ||
| 736 | use core::sync::atomic::compiler_fence; | ||
| 737 | |||
| 738 | let mut read_data = 0; | ||
| 739 | let buffer_len = buffer.len(); | ||
| 740 | |||
| 741 | poll_fn(|cx| { | ||
| 742 | self.set_waker(cx.waker()); | ||
| 743 | |||
| 744 | compiler_fence(Ordering::SeqCst); | ||
| 745 | |||
| 746 | match self.read(&mut buffer[read_data..buffer_len]) { | ||
| 747 | Ok((len, remaining)) => { | ||
| 748 | read_data += len; | ||
| 749 | if read_data == buffer_len { | ||
| 750 | Poll::Ready(Ok(remaining)) | ||
| 751 | } else { | ||
| 752 | Poll::Pending | ||
| 753 | } | ||
| 754 | } | ||
| 755 | Err(e) => Poll::Ready(Err(e)), | ||
| 756 | } | ||
| 757 | }) | ||
| 758 | .await | ||
| 759 | } | ||
| 760 | |||
| 708 | // The capacity of the ringbuffer | 761 | // The capacity of the ringbuffer |
| 709 | pub fn cap(&self) -> usize { | 762 | pub fn cap(&self) -> usize { |
| 710 | self.ringbuf.cap() | 763 | self.ringbuf.cap() |
diff --git a/embassy-stm32/src/dma/ringbuffer.rs b/embassy-stm32/src/dma/ringbuffer.rs index a2bde986f..190793974 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> { | |||
| 72 | self.cap() - remaining_transfers | 72 | self.cap() - remaining_transfers |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | /// Read bytes from the ring buffer | 75 | /// Read elements from the ring buffer |
| 76 | /// Return a tuple of the length read and the length remaining in the buffer | 76 | /// Return a tuple of the length read and the length remaining in the buffer |
| 77 | /// If not all of the bytes were read, then there will be some bytes in the buffer remaining | 77 | /// If not all of the elements were read, then there will be some elements in the buffer remaining |
| 78 | /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read | 78 | /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read |
| 79 | /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. | 79 | /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. |
| 80 | pub fn read(&mut self, mut dma: impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { | 80 | pub fn read(&mut self, mut dma: impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { |
| 81 | /* | 81 | /* |
| @@ -95,11 +95,11 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { | |||
| 95 | */ | 95 | */ |
| 96 | let end = self.pos(dma.get_remaining_transfers()); | 96 | let end = self.pos(dma.get_remaining_transfers()); |
| 97 | if self.start == end && dma.get_complete_count() == 0 { | 97 | if self.start == end && dma.get_complete_count() == 0 { |
| 98 | // No bytes are available in the buffer | 98 | // No elements are available in the buffer |
| 99 | Ok((0, self.cap())) | 99 | Ok((0, self.cap())) |
| 100 | } else if self.start < end { | 100 | } else if self.start < end { |
| 101 | // The available, unread portion in the ring buffer DOES NOT wrap | 101 | // The available, unread portion in the ring buffer DOES NOT wrap |
| 102 | // Copy out the bytes from the dma buffer | 102 | // Copy out the elements from the dma buffer |
| 103 | let len = self.copy_to(buf, self.start..end); | 103 | let len = self.copy_to(buf, self.start..end); |
| 104 | 104 | ||
| 105 | compiler_fence(Ordering::SeqCst); | 105 | compiler_fence(Ordering::SeqCst); |
| @@ -128,7 +128,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { | |||
| 128 | // The DMA writer has wrapped since we last read and is currently | 128 | // The DMA writer has wrapped since we last read and is currently |
| 129 | // writing (or the next byte added will be) in the beginning of the ring buffer. | 129 | // writing (or the next byte added will be) in the beginning of the ring buffer. |
| 130 | 130 | ||
| 131 | // The provided read buffer is not large enough to include all bytes from the tail of the dma buffer. | 131 | // The provided read buffer is not large enough to include all elements from the tail of the dma buffer. |
| 132 | 132 | ||
| 133 | // Copy out from the dma buffer | 133 | // Copy out from the dma buffer |
| 134 | let len = self.copy_to(buf, self.start..self.cap()); | 134 | let len = self.copy_to(buf, self.start..self.cap()); |
| @@ -154,8 +154,8 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { | |||
| 154 | // The DMA writer has wrapped since we last read and is currently | 154 | // The DMA writer has wrapped since we last read and is currently |
| 155 | // writing (or the next byte added will be) in the beginning of the ring buffer. | 155 | // writing (or the next byte added will be) in the beginning of the ring buffer. |
| 156 | 156 | ||
| 157 | // The provided read buffer is large enough to include all bytes from the tail of the dma buffer, | 157 | // The provided read buffer is large enough to include all elements from the tail of the dma buffer, |
| 158 | // so the next read will not have any unread tail bytes in the ring buffer. | 158 | // so the next read will not have any unread tail elements in the ring buffer. |
| 159 | 159 | ||
| 160 | // Copy out from the dma buffer | 160 | // Copy out from the dma buffer |
| 161 | let tail = self.copy_to(buf, self.start..self.cap()); | 161 | let tail = self.copy_to(buf, self.start..self.cap()); |
| @@ -180,7 +180,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> { | |||
| 180 | } | 180 | } |
| 181 | /// Copy from the dma buffer at `data_range` into `buf` | 181 | /// Copy from the dma buffer at `data_range` into `buf` |
| 182 | fn copy_to(&mut self, buf: &mut [W], data_range: Range<usize>) -> usize { | 182 | fn copy_to(&mut self, buf: &mut [W], data_range: Range<usize>) -> usize { |
| 183 | // Limit the number of bytes that can be copied | 183 | // Limit the number of elements that can be copied |
| 184 | let length = usize::min(data_range.len(), buf.len()); | 184 | let length = usize::min(data_range.len(), buf.len()); |
| 185 | 185 | ||
| 186 | // Copy from dma buffer into read buffer | 186 | // Copy from dma buffer into read buffer |
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index a24cba9f0..e100ca5cc 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs | |||
| @@ -265,63 +265,9 @@ pub(crate) mod sealed { | |||
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | fn _configure_pwr() { | 267 | fn _configure_pwr() { |
| 268 | // TODO: move this to RCC | 268 | // TODO: move the rest of this to rcc |
| 269 | |||
| 270 | let pwr = crate::pac::PWR; | ||
| 271 | let rcc = crate::pac::RCC; | 269 | let rcc = crate::pac::RCC; |
| 272 | 270 | ||
| 273 | rcc.cfgr().modify(|w| w.set_stopwuck(true)); | ||
| 274 | |||
| 275 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 276 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 277 | |||
| 278 | // configure LSE | ||
| 279 | rcc.bdcr().modify(|w| w.set_lseon(true)); | ||
| 280 | |||
| 281 | // select system clock source = PLL | ||
| 282 | // set PLL coefficients | ||
| 283 | // m: 2, | ||
| 284 | // n: 12, | ||
| 285 | // r: 3, | ||
| 286 | // q: 4, | ||
| 287 | // p: 3, | ||
| 288 | let src_bits = 0b11; | ||
| 289 | let pllp = (3 - 1) & 0b11111; | ||
| 290 | let pllq = (4 - 1) & 0b111; | ||
| 291 | let pllr = (3 - 1) & 0b111; | ||
| 292 | let plln = 12 & 0b1111111; | ||
| 293 | let pllm = (2 - 1) & 0b111; | ||
| 294 | rcc.pllcfgr().modify(|w| { | ||
| 295 | w.set_pllsrc(src_bits); | ||
| 296 | w.set_pllm(pllm); | ||
| 297 | w.set_plln(plln); | ||
| 298 | w.set_pllr(pllr); | ||
| 299 | w.set_pllp(pllp); | ||
| 300 | w.set_pllpen(true); | ||
| 301 | w.set_pllq(pllq); | ||
| 302 | w.set_pllqen(true); | ||
| 303 | }); | ||
| 304 | // enable PLL | ||
| 305 | rcc.cr().modify(|w| w.set_pllon(true)); | ||
| 306 | rcc.cr().write(|w| w.set_hsion(false)); | ||
| 307 | // while !rcc.cr().read().pllrdy() {} | ||
| 308 | |||
| 309 | // configure SYSCLK mux to use PLL clocl | ||
| 310 | rcc.cfgr().modify(|w| w.set_sw(0b11)); | ||
| 311 | |||
| 312 | // configure CPU1 & CPU2 dividers | ||
| 313 | rcc.cfgr().modify(|w| w.set_hpre(0)); // not divided | ||
| 314 | rcc.extcfgr().modify(|w| { | ||
| 315 | w.set_c2hpre(0b1000); // div2 | ||
| 316 | w.set_shdhpre(0); // not divided | ||
| 317 | }); | ||
| 318 | |||
| 319 | // apply APB1 / APB2 values | ||
| 320 | rcc.cfgr().modify(|w| { | ||
| 321 | w.set_ppre1(0b000); // not divided | ||
| 322 | w.set_ppre2(0b000); // not divided | ||
| 323 | }); | ||
| 324 | |||
| 325 | // TODO: required | 271 | // TODO: required |
| 326 | // set RF wake-up clock = LSE | 272 | // set RF wake-up clock = LSE |
| 327 | rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); | 273 | 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 886fc0b93..4ae65d3e6 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -78,6 +78,14 @@ pub struct Clocks { | |||
| 78 | /// The existence of this value indicates that the clock configuration can no longer be changed | 78 | /// The existence of this value indicates that the clock configuration can no longer be changed |
| 79 | static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); | 79 | static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); |
| 80 | 80 | ||
| 81 | #[cfg(stm32wb)] | ||
| 82 | /// RCC initialization function | ||
| 83 | pub(crate) unsafe fn init(config: Config) { | ||
| 84 | set_freqs(compute_clocks(&config)); | ||
| 85 | |||
| 86 | configure_clocks(&config); | ||
| 87 | } | ||
| 88 | |||
| 81 | /// Sets the clock frequencies | 89 | /// Sets the clock frequencies |
| 82 | /// | 90 | /// |
| 83 | /// Safety: Sets a mutable global. | 91 | /// Safety: Sets a mutable global. |
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index e6123821a..4322b950a 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | use crate::pac::RCC; | 1 | use crate::rcc::Clocks; |
| 2 | use crate::rcc::{set_freqs, Clocks}; | 2 | use crate::time::{khz, mhz, Hertz}; |
| 3 | use crate::time::Hertz; | ||
| 4 | 3 | ||
| 5 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | 4 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, |
| 6 | /// and with the addition of the init function to configure a system clock. | 5 | /// 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); | |||
| 13 | /// LSI speed | 12 | /// LSI speed |
| 14 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 13 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 15 | 14 | ||
| 16 | /// System clock mux source | ||
| 17 | #[derive(Clone, Copy)] | 15 | #[derive(Clone, Copy)] |
| 18 | pub enum ClockSrc { | 16 | pub enum HsePrescaler { |
| 19 | HSE(Hertz), | 17 | NotDivided, |
| 20 | HSI16, | 18 | Div2, |
| 19 | } | ||
| 20 | |||
| 21 | impl From<HsePrescaler> for bool { | ||
| 22 | fn from(value: HsePrescaler) -> Self { | ||
| 23 | match value { | ||
| 24 | HsePrescaler::NotDivided => false, | ||
| 25 | HsePrescaler::Div2 => true, | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | pub struct Hse { | ||
| 31 | pub prediv: HsePrescaler, | ||
| 32 | |||
| 33 | pub frequency: Hertz, | ||
| 34 | } | ||
| 35 | |||
| 36 | /// System clock mux source | ||
| 37 | #[derive(Clone, Copy, PartialEq)] | ||
| 38 | pub enum Sysclk { | ||
| 39 | /// MSI selected as sysclk | ||
| 40 | MSI, | ||
| 41 | /// HSI selected as sysclk | ||
| 42 | HSI, | ||
| 43 | /// HSE selected as sysclk | ||
| 44 | HSE, | ||
| 45 | /// PLL selected as sysclk | ||
| 46 | Pll, | ||
| 47 | } | ||
| 48 | |||
| 49 | impl From<Sysclk> for u8 { | ||
| 50 | fn from(value: Sysclk) -> Self { | ||
| 51 | match value { | ||
| 52 | Sysclk::MSI => 0b00, | ||
| 53 | Sysclk::HSI => 0b01, | ||
| 54 | Sysclk::HSE => 0b10, | ||
| 55 | Sysclk::Pll => 0b11, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | #[derive(Clone, Copy, PartialEq)] | ||
| 61 | pub enum PllSource { | ||
| 62 | Hsi, | ||
| 63 | Msi, | ||
| 64 | Hse, | ||
| 65 | } | ||
| 66 | |||
| 67 | impl From<PllSource> for u8 { | ||
| 68 | fn from(value: PllSource) -> Self { | ||
| 69 | match value { | ||
| 70 | PllSource::Msi => 0b01, | ||
| 71 | PllSource::Hsi => 0b10, | ||
| 72 | PllSource::Hse => 0b11, | ||
| 73 | } | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | pub enum Pll48Source { | ||
| 78 | PllSai, | ||
| 79 | Pll, | ||
| 80 | Msi, | ||
| 81 | Hsi48, | ||
| 82 | } | ||
| 83 | |||
| 84 | pub struct PllMux { | ||
| 85 | /// Source clock selection. | ||
| 86 | pub source: PllSource, | ||
| 87 | |||
| 88 | /// PLL pre-divider (DIVM). Must be between 1 and 63. | ||
| 89 | pub prediv: u8, | ||
| 90 | } | ||
| 91 | |||
| 92 | pub struct Pll { | ||
| 93 | /// PLL multiplication factor. Must be between 4 and 512. | ||
| 94 | pub mul: u16, | ||
| 95 | |||
| 96 | /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128. | ||
| 97 | /// On PLL1, it must be even (in particular, it cannot be 1.) | ||
| 98 | pub divp: Option<u16>, | ||
| 99 | /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128. | ||
| 100 | pub divq: Option<u16>, | ||
| 101 | /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128. | ||
| 102 | pub divr: Option<u16>, | ||
| 21 | } | 103 | } |
| 22 | 104 | ||
| 23 | /// AHB prescaler | 105 | /// AHB prescaler |
| @@ -84,86 +166,250 @@ impl Into<u8> for AHBPrescaler { | |||
| 84 | 166 | ||
| 85 | /// Clocks configutation | 167 | /// Clocks configutation |
| 86 | pub struct Config { | 168 | pub struct Config { |
| 87 | pub mux: ClockSrc, | 169 | pub hse: Option<Hse>, |
| 88 | pub ahb_pre: AHBPrescaler, | 170 | pub lse: Option<Hertz>, |
| 171 | pub sys: Sysclk, | ||
| 172 | pub mux: Option<PllMux>, | ||
| 173 | pub pll48: Option<Pll48Source>, | ||
| 174 | |||
| 175 | pub pll: Option<Pll>, | ||
| 176 | pub pllsai: Option<Pll>, | ||
| 177 | |||
| 178 | pub ahb1_pre: AHBPrescaler, | ||
| 179 | pub ahb2_pre: AHBPrescaler, | ||
| 180 | pub ahb3_pre: AHBPrescaler, | ||
| 89 | pub apb1_pre: APBPrescaler, | 181 | pub apb1_pre: APBPrescaler, |
| 90 | pub apb2_pre: APBPrescaler, | 182 | pub apb2_pre: APBPrescaler, |
| 91 | } | 183 | } |
| 92 | 184 | ||
| 185 | pub const WPAN_DEFAULT: Config = Config { | ||
| 186 | hse: Some(Hse { | ||
| 187 | frequency: mhz(32), | ||
| 188 | prediv: HsePrescaler::NotDivided, | ||
| 189 | }), | ||
| 190 | lse: Some(khz(32)), | ||
| 191 | sys: Sysclk::Pll, | ||
| 192 | mux: Some(PllMux { | ||
| 193 | source: PllSource::Hse, | ||
| 194 | prediv: 2, | ||
| 195 | }), | ||
| 196 | pll48: None, | ||
| 197 | |||
| 198 | pll: Some(Pll { | ||
| 199 | mul: 12, | ||
| 200 | divp: Some(3), | ||
| 201 | divq: Some(4), | ||
| 202 | divr: Some(3), | ||
| 203 | }), | ||
| 204 | pllsai: None, | ||
| 205 | |||
| 206 | ahb1_pre: AHBPrescaler::NotDivided, | ||
| 207 | ahb2_pre: AHBPrescaler::Div2, | ||
| 208 | ahb3_pre: AHBPrescaler::NotDivided, | ||
| 209 | apb1_pre: APBPrescaler::NotDivided, | ||
| 210 | apb2_pre: APBPrescaler::NotDivided, | ||
| 211 | }; | ||
| 212 | |||
| 93 | impl Default for Config { | 213 | impl Default for Config { |
| 94 | #[inline] | 214 | #[inline] |
| 95 | fn default() -> Config { | 215 | fn default() -> Config { |
| 96 | Config { | 216 | Config { |
| 97 | mux: ClockSrc::HSI16, | 217 | hse: None, |
| 98 | ahb_pre: AHBPrescaler::NotDivided, | 218 | lse: None, |
| 219 | sys: Sysclk::HSI, | ||
| 220 | mux: None, | ||
| 221 | pll48: None, | ||
| 222 | pll: None, | ||
| 223 | pllsai: None, | ||
| 224 | |||
| 225 | ahb1_pre: AHBPrescaler::NotDivided, | ||
| 226 | ahb2_pre: AHBPrescaler::NotDivided, | ||
| 227 | ahb3_pre: AHBPrescaler::NotDivided, | ||
| 99 | apb1_pre: APBPrescaler::NotDivided, | 228 | apb1_pre: APBPrescaler::NotDivided, |
| 100 | apb2_pre: APBPrescaler::NotDivided, | 229 | apb2_pre: APBPrescaler::NotDivided, |
| 101 | } | 230 | } |
| 102 | } | 231 | } |
| 103 | } | 232 | } |
| 104 | 233 | ||
| 105 | pub(crate) unsafe fn init(config: Config) { | 234 | pub(crate) fn compute_clocks(config: &Config) -> Clocks { |
| 106 | let (sys_clk, sw) = match config.mux { | 235 | let hse_clk = config.hse.as_ref().map(|hse| match hse.prediv { |
| 107 | ClockSrc::HSI16 => { | 236 | HsePrescaler::NotDivided => hse.frequency, |
| 108 | // Enable HSI16 | 237 | HsePrescaler::Div2 => hse.frequency / 2u32, |
| 109 | RCC.cr().write(|w| w.set_hsion(true)); | 238 | }); |
| 110 | while !RCC.cr().read().hsirdy() {} | ||
| 111 | 239 | ||
| 112 | (HSI_FREQ.0, 0x01) | 240 | let mux_clk = config.mux.as_ref().map(|pll_mux| { |
| 241 | (match pll_mux.source { | ||
| 242 | PllSource::Hse => hse_clk.unwrap(), | ||
| 243 | PllSource::Hsi => HSI_FREQ, | ||
| 244 | _ => unreachable!(), | ||
| 245 | } / pll_mux.prediv) | ||
| 246 | }); | ||
| 247 | |||
| 248 | let (pll_r, _pll_q, _pll_p) = match &config.pll { | ||
| 249 | Some(pll) => { | ||
| 250 | let pll_vco = mux_clk.unwrap() * pll.mul as u32; | ||
| 251 | |||
| 252 | ( | ||
| 253 | pll.divr.map(|divr| pll_vco / divr), | ||
| 254 | pll.divq.map(|divq| pll_vco / divq), | ||
| 255 | pll.divp.map(|divp| pll_vco / divp), | ||
| 256 | ) | ||
| 113 | } | 257 | } |
| 114 | ClockSrc::HSE(freq) => { | 258 | None => (None, None, None), |
| 115 | // Enable HSE | 259 | }; |
| 116 | RCC.cr().write(|w| w.set_hseon(true)); | ||
| 117 | while !RCC.cr().read().hserdy() {} | ||
| 118 | 260 | ||
| 119 | (freq.0, 0x02) | 261 | let sys_clk = match config.sys { |
| 262 | Sysclk::HSE => hse_clk.unwrap(), | ||
| 263 | Sysclk::HSI => HSI_FREQ, | ||
| 264 | Sysclk::Pll => pll_r.unwrap(), | ||
| 265 | _ => unreachable!(), | ||
| 266 | }; | ||
| 267 | |||
| 268 | let ahb1_clk = match config.ahb1_pre { | ||
| 269 | AHBPrescaler::NotDivided => sys_clk, | ||
| 270 | pre => { | ||
| 271 | let pre: u8 = pre.into(); | ||
| 272 | let pre = 1u32 << (pre as u32 - 7); | ||
| 273 | sys_clk / pre | ||
| 120 | } | 274 | } |
| 121 | }; | 275 | }; |
| 122 | 276 | ||
| 123 | RCC.cfgr().modify(|w| { | 277 | let ahb2_clk = match config.ahb2_pre { |
| 124 | w.set_sw(sw.into()); | 278 | AHBPrescaler::NotDivided => sys_clk, |
| 125 | w.set_hpre(config.ahb_pre.into()); | 279 | pre => { |
| 126 | w.set_ppre1(config.apb1_pre.into()); | 280 | let pre: u8 = pre.into(); |
| 127 | w.set_ppre2(config.apb2_pre.into()); | 281 | let pre = 1u32 << (pre as u32 - 7); |
| 128 | }); | 282 | sys_clk / pre |
| 283 | } | ||
| 284 | }; | ||
| 129 | 285 | ||
| 130 | let ahb_freq: u32 = match config.ahb_pre { | 286 | let ahb3_clk = match config.ahb3_pre { |
| 131 | AHBPrescaler::NotDivided => sys_clk, | 287 | AHBPrescaler::NotDivided => sys_clk, |
| 132 | pre => { | 288 | pre => { |
| 133 | let pre: u8 = pre.into(); | 289 | let pre: u8 = pre.into(); |
| 134 | let pre = 1 << (pre as u32 - 7); | 290 | let pre = 1u32 << (pre as u32 - 7); |
| 135 | sys_clk / pre | 291 | sys_clk / pre |
| 136 | } | 292 | } |
| 137 | }; | 293 | }; |
| 138 | 294 | ||
| 139 | let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | 295 | let (apb1_clk, apb1_tim_clk) = match config.apb1_pre { |
| 140 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | 296 | APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk), |
| 141 | pre => { | 297 | pre => { |
| 142 | let pre: u8 = pre.into(); | 298 | let pre: u8 = pre.into(); |
| 143 | let pre: u8 = 1 << (pre - 3); | 299 | let pre: u8 = 1 << (pre - 3); |
| 144 | let freq = ahb_freq / pre as u32; | 300 | let freq = ahb1_clk / pre as u32; |
| 145 | (freq, freq * 2) | 301 | (freq, freq * 2u32) |
| 146 | } | 302 | } |
| 147 | }; | 303 | }; |
| 148 | 304 | ||
| 149 | let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { | 305 | let (apb2_clk, apb2_tim_clk) = match config.apb2_pre { |
| 150 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | 306 | APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk), |
| 151 | pre => { | 307 | pre => { |
| 152 | let pre: u8 = pre.into(); | 308 | let pre: u8 = pre.into(); |
| 153 | let pre: u8 = 1 << (pre - 3); | 309 | let pre: u8 = 1 << (pre - 3); |
| 154 | let freq = ahb_freq / pre as u32; | 310 | let freq = ahb1_clk / pre as u32; |
| 155 | (freq, freq * 2) | 311 | (freq, freq * 2u32) |
| 312 | } | ||
| 313 | }; | ||
| 314 | |||
| 315 | Clocks { | ||
| 316 | sys: sys_clk, | ||
| 317 | ahb1: ahb1_clk, | ||
| 318 | ahb2: ahb2_clk, | ||
| 319 | ahb3: ahb3_clk, | ||
| 320 | apb1: apb1_clk, | ||
| 321 | apb2: apb2_clk, | ||
| 322 | apb1_tim: apb1_tim_clk, | ||
| 323 | apb2_tim: apb2_tim_clk, | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | pub(crate) fn configure_clocks(config: &Config) { | ||
| 328 | let pwr = crate::pac::PWR; | ||
| 329 | let rcc = crate::pac::RCC; | ||
| 330 | |||
| 331 | let needs_hsi = if let Some(pll_mux) = &config.mux { | ||
| 332 | pll_mux.source == PllSource::Hsi | ||
| 333 | } else { | ||
| 334 | false | ||
| 335 | }; | ||
| 336 | |||
| 337 | if needs_hsi || config.sys == Sysclk::HSI { | ||
| 338 | rcc.cr().modify(|w| { | ||
| 339 | w.set_hsion(true); | ||
| 340 | }); | ||
| 341 | |||
| 342 | while !rcc.cr().read().hsirdy() {} | ||
| 343 | } | ||
| 344 | |||
| 345 | match &config.lse { | ||
| 346 | Some(_) => { | ||
| 347 | rcc.cfgr().modify(|w| w.set_stopwuck(true)); | ||
| 348 | |||
| 349 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 350 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 351 | |||
| 352 | rcc.bdcr().modify(|w| w.set_lseon(true)); | ||
| 353 | } | ||
| 354 | _ => {} | ||
| 355 | } | ||
| 356 | |||
| 357 | match &config.hse { | ||
| 358 | Some(hse) => { | ||
| 359 | rcc.cr().modify(|w| { | ||
| 360 | w.set_hsepre(hse.prediv.into()); | ||
| 361 | w.set_hseon(true); | ||
| 362 | }); | ||
| 363 | |||
| 364 | while !rcc.cr().read().hserdy() {} | ||
| 365 | } | ||
| 366 | _ => {} | ||
| 367 | } | ||
| 368 | |||
| 369 | match &config.mux { | ||
| 370 | Some(pll_mux) => { | ||
| 371 | rcc.pllcfgr().modify(|w| { | ||
| 372 | w.set_pllm(pll_mux.prediv); | ||
| 373 | w.set_pllsrc(pll_mux.source.into()); | ||
| 374 | }); | ||
| 156 | } | 375 | } |
| 376 | _ => {} | ||
| 157 | }; | 377 | }; |
| 158 | 378 | ||
| 159 | set_freqs(Clocks { | 379 | match &config.pll { |
| 160 | sys: Hertz(sys_clk), | 380 | Some(pll) => { |
| 161 | ahb1: Hertz(ahb_freq), | 381 | rcc.pllcfgr().modify(|w| { |
| 162 | ahb2: Hertz(ahb_freq), | 382 | w.set_plln(pll.mul as u8); |
| 163 | ahb3: Hertz(ahb_freq), | 383 | pll.divp.map(|divp| { |
| 164 | apb1: Hertz(apb1_freq), | 384 | w.set_pllpen(true); |
| 165 | apb2: Hertz(apb2_freq), | 385 | w.set_pllp((divp - 1) as u8) |
| 166 | apb1_tim: Hertz(apb1_tim_freq), | 386 | }); |
| 167 | apb2_tim: Hertz(apb2_tim_freq), | 387 | pll.divq.map(|divq| { |
| 388 | w.set_pllqen(true); | ||
| 389 | w.set_pllq((divq - 1) as u8) | ||
| 390 | }); | ||
| 391 | pll.divr.map(|divr| { | ||
| 392 | // w.set_pllren(true); | ||
| 393 | w.set_pllr((divr - 1) as u8); | ||
| 394 | }); | ||
| 395 | }); | ||
| 396 | |||
| 397 | rcc.cr().modify(|w| w.set_pllon(true)); | ||
| 398 | |||
| 399 | while !rcc.cr().read().pllrdy() {} | ||
| 400 | } | ||
| 401 | _ => {} | ||
| 402 | } | ||
| 403 | |||
| 404 | rcc.cfgr().modify(|w| { | ||
| 405 | w.set_sw(config.sys.into()); | ||
| 406 | w.set_hpre(config.ahb1_pre.into()); | ||
| 407 | w.set_ppre1(config.apb1_pre.into()); | ||
| 408 | w.set_ppre2(config.apb2_pre.into()); | ||
| 409 | }); | ||
| 410 | |||
| 411 | rcc.extcfgr().modify(|w| { | ||
| 412 | w.set_c2hpre(config.ahb2_pre.into()); | ||
| 413 | w.set_shdhpre(config.ahb3_pre.into()); | ||
| 168 | }); | 414 | }); |
| 169 | } | 415 | } |
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 698292bff..434c56a48 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 | |||
| 225 | mburst: crate::dma::Burst::Incr4, | 225 | mburst: crate::dma::Burst::Incr4, |
| 226 | flow_ctrl: crate::dma::FlowControl::Peripheral, | 226 | flow_ctrl: crate::dma::FlowControl::Peripheral, |
| 227 | fifo_threshold: Some(crate::dma::FifoThreshold::Full), | 227 | fifo_threshold: Some(crate::dma::FifoThreshold::Full), |
| 228 | circular: false, | ||
| 229 | half_transfer_ir: false, | ||
| 230 | complete_transfer_ir: true, | ||
| 228 | }; | 231 | }; |
| 229 | #[cfg(all(sdmmc_v1, not(dma)))] | 232 | #[cfg(all(sdmmc_v1, not(dma)))] |
| 230 | const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions { | 233 | 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 30b67b7b2..068474e7a 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 } | |||
| 34 | [[bin]] | 34 | [[bin]] |
| 35 | name = "rtos_trace" | 35 | name = "rtos_trace" |
| 36 | required-features = ["nightly"] | 36 | required-features = ["nightly"] |
| 37 | |||
| 38 | [profile.release] | ||
| 39 | debug = 2 | ||
diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index ded3b7db8..715f1ecfe 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 | |||
| 19 | cortex-m-rt = "0.7.0" | 19 | cortex-m-rt = "0.7.0" |
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 22 | |||
| 23 | [profile.release] | ||
| 24 | debug = 2 | ||
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 9b41ec5ab..780aaeac2 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 } | |||
| 57 | num-integer = { version = "0.1.45", default-features = false } | 57 | num-integer = { version = "0.1.45", default-features = false } |
| 58 | microfft = "0.5.0" | 58 | microfft = "0.5.0" |
| 59 | 59 | ||
| 60 | [patch.crates-io] | 60 | [profile.release] |
| 61 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | 61 | debug = 2 |
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index f1d45f336..b0e51dcf4 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml | |||
| @@ -53,3 +53,6 @@ rand = { version = "0.8.4", default-features = false } | |||
| 53 | embedded-storage = "0.3.0" | 53 | embedded-storage = "0.3.0" |
| 54 | usbd-hid = "0.6.0" | 54 | usbd-hid = "0.6.0" |
| 55 | serde = { version = "1.0.136", default-features = false } | 55 | serde = { version = "1.0.136", default-features = false } |
| 56 | |||
| 57 | [profile.release] | ||
| 58 | debug = 2 | ||
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 2a018ad04..9b6468f9c 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml | |||
| @@ -54,7 +54,4 @@ pio = "0.2.1" | |||
| 54 | rand = { version = "0.8.5", default-features = false } | 54 | rand = { version = "0.8.5", default-features = false } |
| 55 | 55 | ||
| 56 | [profile.release] | 56 | [profile.release] |
| 57 | debug = true | 57 | debug = 2 |
| 58 | |||
| 59 | [patch.crates-io] | ||
| 60 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | ||
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 92933ab50..42adede10 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml | |||
| @@ -23,3 +23,6 @@ clap = { version = "3.0.0-beta.5", features = ["derive"] } | |||
| 23 | rand_core = { version = "0.6.3", features = ["std"] } | 23 | rand_core = { version = "0.6.3", features = ["std"] } |
| 24 | heapless = { version = "0.7.5", default-features = false } | 24 | heapless = { version = "0.7.5", default-features = false } |
| 25 | static_cell = { version = "1.1", features = ["nightly"]} | 25 | static_cell = { version = "1.1", features = ["nightly"]} |
| 26 | |||
| 27 | [profile.release] | ||
| 28 | debug = 2 | ||
diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index e74c5357b..8534921ab 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml | |||
| @@ -20,3 +20,6 @@ embedded-hal = "0.2.6" | |||
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 22 | heapless = { version = "0.7.5", default-features = false } | 22 | heapless = { version = "0.7.5", default-features = false } |
| 23 | |||
| 24 | [profile.release] | ||
| 25 | debug = 2 | ||
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 620a139ae..46b6db45c 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 | |||
| 18 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 18 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 19 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 19 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 20 | static_cell = { version = "1.1", features = ["nightly"]} | 20 | static_cell = { version = "1.1", features = ["nightly"]} |
| 21 | |||
| 22 | [profile.release] | ||
| 23 | debug = 2 | ||
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 8450c541f..5d32992cd 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml | |||
| @@ -26,3 +26,6 @@ nb = "1.0.0" | |||
| 26 | 26 | ||
| 27 | [profile.dev] | 27 | [profile.dev] |
| 28 | opt-level = "s" | 28 | opt-level = "s" |
| 29 | |||
| 30 | [profile.release] | ||
| 31 | debug = 2 | ||
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index 147e2ecbf..9857fb631 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml | |||
| @@ -21,3 +21,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } | |||
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 22 | heapless = { version = "0.7.5", default-features = false } | 22 | heapless = { version = "0.7.5", default-features = false } |
| 23 | nb = "1.0.0" | 23 | nb = "1.0.0" |
| 24 | |||
| 25 | [profile.release] | ||
| 26 | debug = 2 | ||
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 6ac5d57e9..bd594d16a 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml | |||
| @@ -25,3 +25,6 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 25 | nb = "1.0.0" | 25 | nb = "1.0.0" |
| 26 | embedded-storage = "0.3.0" | 26 | embedded-storage = "0.3.0" |
| 27 | static_cell = { version = "1.1", features = ["nightly"]} | 27 | static_cell = { version = "1.1", features = ["nightly"]} |
| 28 | |||
| 29 | [profile.release] | ||
| 30 | debug = 2 | ||
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index e1ef40f92..fdd3b7d4f 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml | |||
| @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" | |||
| 8 | # Change stm32f429zi to your chip name, if necessary. | 8 | # Change stm32f429zi to your chip name, if necessary. |
| 9 | 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"] } | 9 | 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"] } |
| 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | 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"] } | 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
| 14 | embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } | 14 | 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 08bed88db..f84f74d30 100644 --- a/examples/stm32f4/src/bin/can.rs +++ b/examples/stm32f4/src/bin/can.rs | |||
| @@ -40,10 +40,13 @@ async fn main(_spawner: Spawner) { | |||
| 40 | 40 | ||
| 41 | can.as_mut() | 41 | can.as_mut() |
| 42 | .modify_config() | 42 | .modify_config() |
| 43 | .set_bit_timing(0x001c0003) // http://www.bittiming.can-wiki.info/ | ||
| 44 | .set_loopback(true) // Receive own frames | 43 | .set_loopback(true) // Receive own frames |
| 45 | .set_silent(true) | 44 | .set_silent(true) |
| 46 | .enable(); | 45 | .leave_disabled(); |
| 46 | |||
| 47 | can.set_bitrate(1_000_000); | ||
| 48 | |||
| 49 | can.enable().await; | ||
| 47 | 50 | ||
| 48 | let mut i: u8 = 0; | 51 | let mut i: u8 = 0; |
| 49 | loop { | 52 | loop { |
diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs index 3a6216712..aaedcfecc 100644 --- a/examples/stm32f4/src/bin/dac.rs +++ b/examples/stm32f4/src/bin/dac.rs | |||
| @@ -14,11 +14,11 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 14 | info!("Hello World, dude!"); | 14 | info!("Hello World, dude!"); |
| 15 | 15 | ||
| 16 | let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4); | 16 | let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4); |
| 17 | unwrap!(dac.set_trigger_enable(false)); | ||
| 17 | 18 | ||
| 18 | loop { | 19 | loop { |
| 19 | for v in 0..=255 { | 20 | for v in 0..=255 { |
| 20 | unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); | 21 | unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); |
| 21 | dac.trigger(); | ||
| 22 | } | 22 | } |
| 23 | } | 23 | } |
| 24 | } | 24 | } |
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index bbc99fee0..a6964c7bc 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml | |||
| @@ -28,3 +28,6 @@ rand_core = "0.6.3" | |||
| 28 | critical-section = "1.1" | 28 | critical-section = "1.1" |
| 29 | embedded-storage = "0.3.0" | 29 | embedded-storage = "0.3.0" |
| 30 | static_cell = { version = "1.1", features = ["nightly"]} | 30 | static_cell = { version = "1.1", features = ["nightly"]} |
| 31 | |||
| 32 | [profile.release] | ||
| 33 | debug = 2 | ||
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 4a14568ac..b4dfe3c6b 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml | |||
| @@ -20,3 +20,6 @@ embedded-hal = "0.2.6" | |||
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 22 | heapless = { version = "0.7.5", default-features = false } | 22 | heapless = { version = "0.7.5", default-features = false } |
| 23 | |||
| 24 | [profile.release] | ||
| 25 | debug = 2 | ||
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 935997a74..ce8838605 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml | |||
| @@ -22,3 +22,6 @@ embedded-hal = "0.2.6" | |||
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 24 | heapless = { version = "0.7.5", default-features = false } | 24 | heapless = { version = "0.7.5", default-features = false } |
| 25 | |||
| 26 | [profile.release] | ||
| 27 | debug = 2 | ||
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index 586b4154b..ee078286b 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs | |||
| @@ -21,11 +21,11 @@ fn main() -> ! { | |||
| 21 | let p = embassy_stm32::init(config); | 21 | let p = embassy_stm32::init(config); |
| 22 | 22 | ||
| 23 | let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); | 23 | let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); |
| 24 | unwrap!(dac.set_trigger_enable(false)); | ||
| 24 | 25 | ||
| 25 | loop { | 26 | loop { |
| 26 | for v in 0..=255 { | 27 | for v in 0..=255 { |
| 27 | unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); | 28 | unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); |
| 28 | dac.trigger(); | ||
| 29 | } | 29 | } |
| 30 | } | 30 | } |
| 31 | } | 31 | } |
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index e6a5a4c14..c325751c6 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml | |||
| @@ -34,5 +34,5 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 34 | embedded-hal = "0.2.6" | 34 | embedded-hal = "0.2.6" |
| 35 | static_cell = "1.1" | 35 | static_cell = "1.1" |
| 36 | 36 | ||
| 37 | [patch.crates-io] | 37 | [profile.release] |
| 38 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | 38 | debug = 2 |
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index dcca1cc3d..329d44cac 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml | |||
| @@ -20,3 +20,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } | |||
| 20 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 20 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 21 | heapless = { version = "0.7.5", default-features = false } | 21 | heapless = { version = "0.7.5", default-features = false } |
| 22 | embedded-storage = "0.3.0" | 22 | embedded-storage = "0.3.0" |
| 23 | |||
| 24 | [profile.release] | ||
| 25 | debug = 2 | ||
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 41c9869bf..0f770e2f0 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml | |||
| @@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 27 | chrono = { version = "^0.4", default-features = false } | 27 | chrono = { version = "^0.4", default-features = false } |
| 28 | 28 | ||
| 29 | micromath = "2.0.0" | 29 | micromath = "2.0.0" |
| 30 | |||
| 31 | [profile.release] | ||
| 32 | debug = 2 | ||
diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs index ade43eb35..0193a248e 100644 --- a/examples/stm32l4/src/bin/dac.rs +++ b/examples/stm32l4/src/bin/dac.rs | |||
| @@ -13,11 +13,11 @@ fn main() -> ! { | |||
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); | 15 | let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); |
| 16 | unwrap!(dac.set_trigger_enable(false)); | ||
| 16 | 17 | ||
| 17 | loop { | 18 | loop { |
| 18 | for v in 0..=255 { | 19 | for v in 0..=255 { |
| 19 | unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); | 20 | unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); |
| 20 | dac.trigger(); | ||
| 21 | } | 21 | } |
| 22 | } | 22 | } |
| 23 | } | 23 | } |
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 5d66c59c3..1afd00398 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml | |||
| @@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 27 | rand_core = { version = "0.6.3", default-features = false } | 27 | rand_core = { version = "0.6.3", default-features = false } |
| 28 | embedded-io = { version = "0.4.0", features = ["async"] } | 28 | embedded-io = { version = "0.4.0", features = ["async"] } |
| 29 | static_cell = { version = "1.1", features = ["nightly"]} | 29 | static_cell = { version = "1.1", features = ["nightly"]} |
| 30 | |||
| 31 | [profile.release] | ||
| 32 | debug = 2 | ||
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index a43a55909..db251eafe 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 | |||
| 23 | heapless = { version = "0.7.5", default-features = false } | 23 | heapless = { version = "0.7.5", default-features = false } |
| 24 | 24 | ||
| 25 | micromath = "2.0.0" | 25 | micromath = "2.0.0" |
| 26 | |||
| 27 | [profile.release] | ||
| 28 | debug = 2 | ||
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 48e340264..1a5aff352 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml | |||
| @@ -52,3 +52,6 @@ required-features = ["ble"] | |||
| 52 | [[bin]] | 52 | [[bin]] |
| 53 | name = "gatt_server" | 53 | name = "gatt_server" |
| 54 | required-features = ["ble"] | 54 | required-features = ["ble"] |
| 55 | |||
| 56 | [profile.release] | ||
| 57 | debug = 2 | ||
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 6e6f269aa..48b69c8d0 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 | |||
| 28 | heapless = { version = "0.7.5", default-features = false } | 28 | heapless = { version = "0.7.5", default-features = false } |
| 29 | chrono = { version = "^0.4", default-features = false } | 29 | chrono = { version = "^0.4", default-features = false } |
| 30 | 30 | ||
| 31 | [patch.crates-io] | 31 | [profile.release] |
| 32 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | 32 | debug = 2 |
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index 3679e3857..2791cc341 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml | |||
| @@ -17,3 +17,6 @@ wasm-bindgen = "0.2" | |||
| 17 | web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] } | 17 | web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] } |
| 18 | log = "0.4.11" | 18 | log = "0.4.11" |
| 19 | critical-section = { version = "1.1", features = ["std"] } | 19 | critical-section = { version = "1.1", features = ["std"] } |
| 20 | |||
| 21 | [profile.release] | ||
| 22 | debug = 2 | ||
diff --git a/tests/stm32/src/bin/wpan_ble.rs b/tests/stm32/src/bin/wpan_ble.rs index 3ad8aca4e..452da77a4 100644 --- a/tests/stm32/src/bin/wpan_ble.rs +++ b/tests/stm32/src/bin/wpan_ble.rs | |||
| @@ -12,6 +12,7 @@ use common::*; | |||
| 12 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 13 | use embassy_stm32::bind_interrupts; | 13 | use embassy_stm32::bind_interrupts; |
| 14 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 14 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 15 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 15 | use embassy_stm32_wpan::hci::host::uart::UartHci; | 16 | use embassy_stm32_wpan::hci::host::uart::UartHci; |
| 16 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; | 17 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; |
| 17 | use embassy_stm32_wpan::hci::types::AdvertisingType; | 18 | use embassy_stm32_wpan::hci::types::AdvertisingType; |
| @@ -40,7 +41,10 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) { | |||
| 40 | 41 | ||
| 41 | #[embassy_executor::main] | 42 | #[embassy_executor::main] |
| 42 | async fn main(spawner: Spawner) { | 43 | async fn main(spawner: Spawner) { |
| 43 | let p = embassy_stm32::init(config()); | 44 | let mut config = config(); |
| 45 | config.rcc = WPAN_DEFAULT; | ||
| 46 | |||
| 47 | let p = embassy_stm32::init(config); | ||
| 44 | info!("Hello World!"); | 48 | info!("Hello World!"); |
| 45 | 49 | ||
| 46 | let config = Config::default(); | 50 | let config = Config::default(); |
diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs index b04a19ee9..7eab2fd38 100644 --- a/tests/stm32/src/bin/wpan_mac.rs +++ b/tests/stm32/src/bin/wpan_mac.rs | |||
| @@ -10,6 +10,7 @@ use common::*; | |||
| 10 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 11 | use embassy_stm32::bind_interrupts; | 11 | use embassy_stm32::bind_interrupts; |
| 12 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 12 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 13 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 13 | use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest}; | 14 | use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest}; |
| 14 | use embassy_stm32_wpan::mac::event::MacEvent; | 15 | use embassy_stm32_wpan::mac::event::MacEvent; |
| 15 | use embassy_stm32_wpan::mac::typedefs::{ | 16 | use embassy_stm32_wpan::mac::typedefs::{ |
| @@ -31,7 +32,10 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) { | |||
| 31 | 32 | ||
| 32 | #[embassy_executor::main] | 33 | #[embassy_executor::main] |
| 33 | async fn main(spawner: Spawner) { | 34 | async fn main(spawner: Spawner) { |
| 34 | let p = embassy_stm32::init(config()); | 35 | let mut config = config(); |
| 36 | config.rcc = WPAN_DEFAULT; | ||
| 37 | |||
| 38 | let p = embassy_stm32::init(config); | ||
| 35 | info!("Hello World!"); | 39 | info!("Hello World!"); |
| 36 | 40 | ||
| 37 | let config = Config::default(); | 41 | let config = Config::default(); |
