diff options
| author | xoviat <[email protected]> | 2023-07-28 17:18:22 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-07-28 17:18:22 -0500 |
| commit | c7c701b3e312c14ca00eabfa8b6d422cec869cbf (patch) | |
| tree | df9388eca3a45127eb36a670396d3a2c91517fa0 /embassy-stm32/src | |
| parent | e495d606ec62ccfd72eaf9fc868455da217e2d5c (diff) | |
| parent | cc414e63d3b7aec7da07d9097cf8a78b5d55a73a (diff) | |
Merge branch 'main' of https://github.com/embassy-rs/embassy into hrtim
Diffstat (limited to 'embassy-stm32/src')
49 files changed, 890 insertions, 525 deletions
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index 2322204d5..e577ec289 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 3 | 3 | ||
| 4 | use crate::adc::{Adc, AdcPin, Instance, SampleTime}; | 4 | use crate::adc::{Adc, AdcPin, Instance, SampleTime}; |
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index d9af0c55e..e8245884e 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 3 | 3 | ||
| 4 | use crate::adc::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; | 4 | use crate::adc::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; |
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index 091c1d447..9a7acea53 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 3 | 3 | ||
| 4 | use super::InternalChannel; | 4 | use super::InternalChannel; |
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 3a6e58cf6..821cc7f6a 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 3 | 3 | ||
| 4 | use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; | 4 | use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; |
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index c51c6840f..64d0f0c75 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs | |||
| @@ -226,7 +226,7 @@ impl Prescaler { | |||
| 226 | 226 | ||
| 227 | impl<'d, T: Instance> Adc<'d, T> { | 227 | impl<'d, T: Instance> Adc<'d, T> { |
| 228 | pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self { | 228 | pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self { |
| 229 | embassy_hal_common::into_ref!(adc); | 229 | embassy_hal_internal::into_ref!(adc); |
| 230 | T::enable(); | 230 | T::enable(); |
| 231 | T::reset(); | 231 | T::reset(); |
| 232 | 232 | ||
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 5a0153464..1d0fdd532 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs | |||
| @@ -6,7 +6,7 @@ use core::task::Poll; | |||
| 6 | 6 | ||
| 7 | pub use bxcan; | 7 | pub use bxcan; |
| 8 | use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; | 8 | use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; |
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | use futures::FutureExt; | 10 | use futures::FutureExt; |
| 11 | 11 | ||
| 12 | use crate::gpio::sealed::AFType; | 12 | use crate::gpio::sealed::AFType; |
| @@ -77,6 +77,7 @@ pub struct Can<'d, T: Instance> { | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | #[derive(Debug)] | 79 | #[derive(Debug)] |
| 80 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 80 | pub enum BusError { | 81 | pub enum BusError { |
| 81 | Stuff, | 82 | Stuff, |
| 82 | Form, | 83 | Form, |
| @@ -90,6 +91,22 @@ pub enum BusError { | |||
| 90 | BusWarning, | 91 | BusWarning, |
| 91 | } | 92 | } |
| 92 | 93 | ||
| 94 | #[derive(Debug)] | ||
| 95 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 96 | pub enum TryReadError { | ||
| 97 | /// Bus error | ||
| 98 | BusError(BusError), | ||
| 99 | /// Receive buffer is empty | ||
| 100 | Empty, | ||
| 101 | } | ||
| 102 | |||
| 103 | #[derive(Debug)] | ||
| 104 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 105 | pub enum TryWriteError { | ||
| 106 | /// All transmit mailboxes are full | ||
| 107 | Full, | ||
| 108 | } | ||
| 109 | |||
| 93 | impl<'d, T: Instance> Can<'d, T> { | 110 | impl<'d, T: Instance> Can<'d, T> { |
| 94 | /// Creates a new Bxcan instance, keeping the peripheral in sleep mode. | 111 | /// Creates a new Bxcan instance, keeping the peripheral in sleep mode. |
| 95 | /// You must call [Can::enable_non_blocking] to use the peripheral. | 112 | /// You must call [Can::enable_non_blocking] to use the peripheral. |
| @@ -161,58 +178,60 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 161 | .leave_disabled(); | 178 | .leave_disabled(); |
| 162 | } | 179 | } |
| 163 | 180 | ||
| 181 | /// Enables the peripheral and synchronizes with the bus. | ||
| 182 | /// | ||
| 183 | /// This will wait for 11 consecutive recessive bits (bus idle state). | ||
| 184 | /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting. | ||
| 185 | pub async fn enable(&mut self) { | ||
| 186 | while self.borrow_mut().enable_non_blocking().is_err() { | ||
| 187 | // SCE interrupt is only generated for entering sleep mode, but not leaving. | ||
| 188 | // Yield to allow other tasks to execute while can bus is initializing. | ||
| 189 | embassy_futures::yield_now().await; | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 164 | /// Queues the message to be sent but exerts backpressure | 193 | /// Queues the message to be sent but exerts backpressure |
| 165 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { | 194 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { |
| 166 | poll_fn(|cx| { | 195 | CanTx { can: &self.can }.write(frame).await |
| 167 | T::state().tx_waker.register(cx.waker()); | 196 | } |
| 168 | if let Ok(status) = self.can.borrow_mut().transmit(frame) { | ||
| 169 | return Poll::Ready(status); | ||
| 170 | } | ||
| 171 | 197 | ||
| 172 | Poll::Pending | 198 | /// Attempts to transmit a frame without blocking. |
| 173 | }) | 199 | /// |
| 174 | .await | 200 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. |
| 201 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { | ||
| 202 | CanTx { can: &self.can }.try_write(frame) | ||
| 175 | } | 203 | } |
| 176 | 204 | ||
| 205 | /// Waits for a specific transmit mailbox to become empty | ||
| 177 | pub async fn flush(&self, mb: bxcan::Mailbox) { | 206 | pub async fn flush(&self, mb: bxcan::Mailbox) { |
| 178 | poll_fn(|cx| { | 207 | CanTx { can: &self.can }.flush(mb).await |
| 179 | T::state().tx_waker.register(cx.waker()); | 208 | } |
| 180 | if T::regs().tsr().read().tme(mb.index()) { | ||
| 181 | return Poll::Ready(()); | ||
| 182 | } | ||
| 183 | 209 | ||
| 184 | Poll::Pending | 210 | /// Waits until any of the transmit mailboxes become empty |
| 185 | }) | 211 | pub async fn flush_any(&self) { |
| 186 | .await; | 212 | CanTx { can: &self.can }.flush_any().await |
| 213 | } | ||
| 214 | |||
| 215 | /// Waits until all of the transmit mailboxes become empty | ||
| 216 | pub async fn flush_all(&self) { | ||
| 217 | CanTx { can: &self.can }.flush_all().await | ||
| 187 | } | 218 | } |
| 188 | 219 | ||
| 189 | /// Returns a tuple of the time the message was received and the message frame | 220 | /// Returns a tuple of the time the message was received and the message frame |
| 190 | pub async fn read(&mut self) -> Result<(u16, bxcan::Frame), BusError> { | 221 | pub async fn read(&mut self) -> Result<(u16, bxcan::Frame), BusError> { |
| 191 | poll_fn(|cx| { | 222 | CanRx { can: &self.can }.read().await |
| 192 | T::state().err_waker.register(cx.waker()); | 223 | } |
| 193 | if let Poll::Ready((time, frame)) = T::state().rx_queue.recv().poll_unpin(cx) { | ||
| 194 | return Poll::Ready(Ok((time, frame))); | ||
| 195 | } else if let Some(err) = self.curr_error() { | ||
| 196 | return Poll::Ready(Err(err)); | ||
| 197 | } | ||
| 198 | 224 | ||
| 199 | Poll::Pending | 225 | /// Attempts to read a can frame without blocking. |
| 200 | }) | 226 | /// |
| 201 | .await | 227 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. |
| 228 | pub fn try_read(&mut self) -> Result<(u16, bxcan::Frame), TryReadError> { | ||
| 229 | CanRx { can: &self.can }.try_read() | ||
| 202 | } | 230 | } |
| 203 | 231 | ||
| 204 | fn curr_error(&self) -> Option<BusError> { | 232 | /// Waits while receive queue is empty. |
| 205 | let err = { T::regs().esr().read() }; | 233 | pub async fn wait_not_empty(&mut self) { |
| 206 | if err.boff() { | 234 | CanRx { can: &self.can }.wait_not_empty().await |
| 207 | return Some(BusError::BusOff); | ||
| 208 | } else if err.epvf() { | ||
| 209 | return Some(BusError::BusPassive); | ||
| 210 | } else if err.ewgf() { | ||
| 211 | return Some(BusError::BusWarning); | ||
| 212 | } else if let Some(err) = err.lec().into_bus_err() { | ||
| 213 | return Some(err); | ||
| 214 | } | ||
| 215 | None | ||
| 216 | } | 235 | } |
| 217 | 236 | ||
| 218 | unsafe fn receive_fifo(fifo: RxFifo) { | 237 | unsafe fn receive_fifo(fifo: RxFifo) { |
| @@ -374,6 +393,14 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 374 | .await | 393 | .await |
| 375 | } | 394 | } |
| 376 | 395 | ||
| 396 | /// Attempts to transmit a frame without blocking. | ||
| 397 | /// | ||
| 398 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. | ||
| 399 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { | ||
| 400 | self.can.borrow_mut().transmit(frame).map_err(|_| TryWriteError::Full) | ||
| 401 | } | ||
| 402 | |||
| 403 | /// Waits for a specific transmit mailbox to become empty | ||
| 377 | pub async fn flush(&self, mb: bxcan::Mailbox) { | 404 | pub async fn flush(&self, mb: bxcan::Mailbox) { |
| 378 | poll_fn(|cx| { | 405 | poll_fn(|cx| { |
| 379 | T::state().tx_waker.register(cx.waker()); | 406 | T::state().tx_waker.register(cx.waker()); |
| @@ -385,6 +412,42 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 385 | }) | 412 | }) |
| 386 | .await; | 413 | .await; |
| 387 | } | 414 | } |
| 415 | |||
| 416 | /// Waits until any of the transmit mailboxes become empty | ||
| 417 | pub async fn flush_any(&self) { | ||
| 418 | poll_fn(|cx| { | ||
| 419 | T::state().tx_waker.register(cx.waker()); | ||
| 420 | |||
| 421 | let tsr = T::regs().tsr().read(); | ||
| 422 | if tsr.tme(bxcan::Mailbox::Mailbox0.index()) | ||
| 423 | || tsr.tme(bxcan::Mailbox::Mailbox1.index()) | ||
| 424 | || tsr.tme(bxcan::Mailbox::Mailbox2.index()) | ||
| 425 | { | ||
| 426 | return Poll::Ready(()); | ||
| 427 | } | ||
| 428 | |||
| 429 | Poll::Pending | ||
| 430 | }) | ||
| 431 | .await; | ||
| 432 | } | ||
| 433 | |||
| 434 | /// Waits until all of the transmit mailboxes become empty | ||
| 435 | pub async fn flush_all(&self) { | ||
| 436 | poll_fn(|cx| { | ||
| 437 | T::state().tx_waker.register(cx.waker()); | ||
| 438 | |||
| 439 | let tsr = T::regs().tsr().read(); | ||
| 440 | if tsr.tme(bxcan::Mailbox::Mailbox0.index()) | ||
| 441 | && tsr.tme(bxcan::Mailbox::Mailbox1.index()) | ||
| 442 | && tsr.tme(bxcan::Mailbox::Mailbox2.index()) | ||
| 443 | { | ||
| 444 | return Poll::Ready(()); | ||
| 445 | } | ||
| 446 | |||
| 447 | Poll::Pending | ||
| 448 | }) | ||
| 449 | .await; | ||
| 450 | } | ||
| 388 | } | 451 | } |
| 389 | 452 | ||
| 390 | #[allow(dead_code)] | 453 | #[allow(dead_code)] |
| @@ -407,6 +470,33 @@ impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { | |||
| 407 | .await | 470 | .await |
| 408 | } | 471 | } |
| 409 | 472 | ||
| 473 | /// Attempts to read a CAN frame without blocking. | ||
| 474 | /// | ||
| 475 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. | ||
| 476 | pub fn try_read(&mut self) -> Result<(u16, bxcan::Frame), TryReadError> { | ||
| 477 | if let Ok(envelope) = T::state().rx_queue.try_recv() { | ||
| 478 | return Ok(envelope); | ||
| 479 | } | ||
| 480 | |||
| 481 | if let Some(err) = self.curr_error() { | ||
| 482 | return Err(TryReadError::BusError(err)); | ||
| 483 | } | ||
| 484 | |||
| 485 | Err(TryReadError::Empty) | ||
| 486 | } | ||
| 487 | |||
| 488 | /// Waits while receive queue is empty. | ||
| 489 | pub async fn wait_not_empty(&mut self) { | ||
| 490 | poll_fn(|cx| { | ||
| 491 | if T::state().rx_queue.poll_ready_to_receive(cx) { | ||
| 492 | Poll::Ready(()) | ||
| 493 | } else { | ||
| 494 | Poll::Pending | ||
| 495 | } | ||
| 496 | }) | ||
| 497 | .await | ||
| 498 | } | ||
| 499 | |||
| 410 | fn curr_error(&self) -> Option<BusError> { | 500 | fn curr_error(&self) -> Option<BusError> { |
| 411 | let err = { T::regs().esr().read() }; | 501 | let err = { T::regs().esr().read() }; |
| 412 | if err.boff() { | 502 | if err.boff() { |
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index c31a7fc63..f77788db3 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | pub use bxcan; | 1 | pub use bxcan; |
| 2 | use embassy_hal_common::PeripheralRef; | 2 | use embassy_hal_internal::PeripheralRef; |
| 3 | 3 | ||
| 4 | use crate::peripherals; | 4 | use crate::peripherals; |
| 5 | 5 | ||
diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs index 3946a2d47..154f2eb91 100644 --- a/embassy-stm32/src/crc/v1.rs +++ b/embassy-stm32/src/crc/v1.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use embassy_hal_common::{into_ref, PeripheralRef}; | 1 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 2 | 2 | ||
| 3 | use crate::pac::CRC as PAC_CRC; | 3 | use crate::pac::CRC as PAC_CRC; |
| 4 | use crate::peripherals::CRC; | 4 | use crate::peripherals::CRC; |
diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs index f337055a7..de0c08755 100644 --- a/embassy-stm32/src/crc/v2v3.rs +++ b/embassy-stm32/src/crc/v2v3.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use embassy_hal_common::{into_ref, PeripheralRef}; | 1 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 2 | 2 | ||
| 3 | use crate::pac::crc::vals; | 3 | use crate::pac::crc::vals; |
| 4 | use crate::pac::CRC as PAC_CRC; | 4 | use crate::pac::CRC as PAC_CRC; |
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 3d58914b3..a2040b857 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | //! Provide access to the STM32 digital-to-analog converter (DAC). | 3 | //! Provide access to the STM32 digital-to-analog converter (DAC). |
| 4 | use core::marker::PhantomData; | 4 | use core::marker::PhantomData; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | 7 | ||
| 8 | use crate::pac::dac; | 8 | use crate::pac::dac; |
| 9 | use crate::rcc::RccPeripheral; | 9 | use crate::rcc::RccPeripheral; |
| @@ -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/dcmi.rs b/embassy-stm32/src/dcmi.rs index 78b026cb6..7497f4aaa 100644 --- a/embassy-stm32/src/dcmi.rs +++ b/embassy-stm32/src/dcmi.rs | |||
| @@ -2,7 +2,7 @@ use core::future::poll_fn; | |||
| 2 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use embassy_sync::waitqueue::AtomicWaker; | 6 | use embassy_sync::waitqueue::AtomicWaker; |
| 7 | 7 | ||
| 8 | use crate::dma::Transfer; | 8 | use crate::dma::Transfer; |
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 5a87888b7..d956047d5 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs | |||
| @@ -6,7 +6,7 @@ use core::sync::atomic::{fence, Ordering}; | |||
| 6 | use core::task::{Context, Poll, Waker}; | 6 | use core::task::{Context, Poll, Waker}; |
| 7 | 7 | ||
| 8 | use atomic_polyfill::AtomicUsize; | 8 | use atomic_polyfill::AtomicUsize; |
| 9 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 10 | use embassy_sync::waitqueue::AtomicWaker; | 10 | use embassy_sync::waitqueue::AtomicWaker; |
| 11 | 11 | ||
| 12 | use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; | 12 | use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; |
| @@ -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..219ef2eb0 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs | |||
| @@ -4,7 +4,7 @@ use core::pin::Pin; | |||
| 4 | use core::sync::atomic::{fence, AtomicUsize, Ordering}; | 4 | use core::sync::atomic::{fence, AtomicUsize, Ordering}; |
| 5 | use core::task::{Context, Poll, Waker}; | 5 | use core::task::{Context, Poll, Waker}; |
| 6 | 6 | ||
| 7 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | 9 | ||
| 10 | use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; | 10 | use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; |
| @@ -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/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index b7bcf7795..97cc200d7 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs | |||
| @@ -5,7 +5,7 @@ use core::pin::Pin; | |||
| 5 | use core::sync::atomic::{fence, Ordering}; | 5 | use core::sync::atomic::{fence, Ordering}; |
| 6 | use core::task::{Context, Poll}; | 6 | use core::task::{Context, Poll}; |
| 7 | 7 | ||
| 8 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 8 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | 10 | ||
| 11 | use super::word::{Word, WordSize}; | 11 | use super::word::{Word, WordSize}; |
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 0858587bd..4f1a58ae2 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs | |||
| @@ -26,7 +26,7 @@ pub mod word; | |||
| 26 | 26 | ||
| 27 | use core::mem; | 27 | use core::mem; |
| 28 | 28 | ||
| 29 | use embassy_hal_common::impl_peripheral; | 29 | use embassy_hal_internal::impl_peripheral; |
| 30 | 30 | ||
| 31 | #[cfg(dmamux)] | 31 | #[cfg(dmamux)] |
| 32 | pub use self::dmamux::*; | 32 | pub use self::dmamux::*; |
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/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index 2a6ea35ff..a1e0240c8 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs | |||
| @@ -6,7 +6,7 @@ mod tx_desc; | |||
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::sync::atomic::{fence, Ordering}; | 7 | use core::sync::atomic::{fence, Ordering}; |
| 8 | 8 | ||
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; | 10 | use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; |
| 11 | 11 | ||
| 12 | pub(crate) use self::rx_desc::{RDes, RDesRing}; | 12 | pub(crate) use self::rx_desc::{RDes, RDesRing}; |
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index bb681c42b..ada495fdb 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs | |||
| @@ -3,7 +3,7 @@ mod descriptors; | |||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use core::sync::atomic::{fence, Ordering}; | 4 | use core::sync::atomic::{fence, Ordering}; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | 7 | ||
| 8 | pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; | 8 | pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; |
| 9 | use super::*; | 9 | use super::*; |
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 3ff92c9e6..925cf39be 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs | |||
| @@ -3,7 +3,7 @@ use core::marker::PhantomData; | |||
| 3 | use core::pin::Pin; | 3 | use core::pin::Pin; |
| 4 | use core::task::{Context, Poll}; | 4 | use core::task::{Context, Poll}; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::impl_peripheral; | 6 | use embassy_hal_internal::impl_peripheral; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | 8 | ||
| 9 | use crate::gpio::{AnyPin, Input, Pin as GpioPin}; | 9 | use crate::gpio::{AnyPin, Input, Pin as GpioPin}; |
diff --git a/embassy-stm32/src/flash/asynch.rs b/embassy-stm32/src/flash/asynch.rs index f175349cd..e966e2a77 100644 --- a/embassy-stm32/src/flash/asynch.rs +++ b/embassy-stm32/src/flash/asynch.rs | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 3 | 3 | ||
| 4 | use embassy_hal_common::drop::OnDrop; | 4 | use embassy_hal_internal::drop::OnDrop; |
| 5 | use embassy_hal_common::into_ref; | 5 | use embassy_hal_internal::into_ref; |
| 6 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 6 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 7 | use embassy_sync::mutex::Mutex; | 7 | use embassy_sync::mutex::Mutex; |
| 8 | 8 | ||
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs index 2a374733d..16c511295 100644 --- a/embassy-stm32/src/flash/common.rs +++ b/embassy-stm32/src/flash/common.rs | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 3 | 3 | ||
| 4 | use embassy_hal_common::drop::OnDrop; | 4 | use embassy_hal_internal::drop::OnDrop; |
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use stm32_metapac::FLASH_BASE; | 6 | use stm32_metapac::FLASH_BASE; |
| 7 | 7 | ||
| 8 | use super::{ | 8 | use super::{ |
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 4cb39e033..728f6d604 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs | |||
| @@ -14,7 +14,7 @@ use crate::pac; | |||
| 14 | mod alt_regions { | 14 | mod alt_regions { |
| 15 | use core::marker::PhantomData; | 15 | use core::marker::PhantomData; |
| 16 | 16 | ||
| 17 | use embassy_hal_common::PeripheralRef; | 17 | use embassy_hal_internal::PeripheralRef; |
| 18 | use stm32_metapac::FLASH_SIZE; | 18 | use stm32_metapac::FLASH_SIZE; |
| 19 | 19 | ||
| 20 | use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION}; | 20 | use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION}; |
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs index 60d7a00ee..177e66a91 100644 --- a/embassy-stm32/src/fmc.rs +++ b/embassy-stm32/src/fmc.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | 4 | ||
| 5 | use crate::gpio::sealed::AFType; | 5 | use crate::gpio::sealed::AFType; |
| 6 | use crate::gpio::{Pull, Speed}; | 6 | use crate::gpio::{Pull, Speed}; |
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index af3a8eaca..cda597145 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | use core::convert::Infallible; | 2 | use core::convert::Infallible; |
| 3 | 3 | ||
| 4 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; | 4 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 5 | 5 | ||
| 6 | use crate::pac::gpio::{self, vals}; | 6 | use crate::pac::gpio::{self, vals}; |
| 7 | use crate::{pac, peripherals, Peripheral}; | 7 | use crate::{pac, peripherals, Peripheral}; |
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index aa485cd86..e5254a8cd 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_embedded_hal::SetConfig; | 3 | use embassy_embedded_hal::SetConfig; |
| 4 | use embassy_hal_common::{into_ref, PeripheralRef}; | 4 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 5 | 5 | ||
| 6 | use crate::dma::NoDma; | 6 | use crate::dma::NoDma; |
| 7 | use crate::gpio::sealed::AFType; | 7 | use crate::gpio::sealed::AFType; |
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 208d1527d..eaf980a4d 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -4,8 +4,8 @@ use core::marker::PhantomData; | |||
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_embedded_hal::SetConfig; | 6 | use embassy_embedded_hal::SetConfig; |
| 7 | use embassy_hal_common::drop::OnDrop; | 7 | use embassy_hal_internal::drop::OnDrop; |
| 8 | use embassy_hal_common::{into_ref, PeripheralRef}; | 8 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | 10 | ||
| 11 | use crate::dma::{NoDma, Transfer}; | 11 | use crate::dma::{NoDma, Transfer}; |
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index 62dda69b4..1ccad7328 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | 2 | ||
| 3 | use crate::gpio::sealed::{AFType, Pin as _}; | 3 | use crate::gpio::sealed::{AFType, Pin as _}; |
| 4 | use crate::gpio::AnyPin; | 4 | use crate::gpio::AnyPin; |
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/lib.rs b/embassy-stm32/src/lib.rs index 8c005bfed..34220fbf5 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #![cfg_attr(not(test), no_std)] | 1 | #![cfg_attr(not(test), no_std)] |
| 2 | #![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] | 2 | #![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] |
| 3 | 3 | ||
| 4 | //! ## Feature flags | ||
| 5 | #![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)] | ||
| 6 | |||
| 4 | // This must go FIRST so that all the other modules see its macros. | 7 | // This must go FIRST so that all the other modules see its macros. |
| 5 | pub mod fmt; | 8 | pub mod fmt; |
| 6 | include!(concat!(env!("OUT_DIR"), "/_macros.rs")); | 9 | include!(concat!(env!("OUT_DIR"), "/_macros.rs")); |
| @@ -44,7 +47,6 @@ pub mod i2c; | |||
| 44 | pub mod i2s; | 47 | pub mod i2s; |
| 45 | #[cfg(stm32wb)] | 48 | #[cfg(stm32wb)] |
| 46 | pub mod ipcc; | 49 | pub mod ipcc; |
| 47 | pub mod pwm; | ||
| 48 | #[cfg(quadspi)] | 50 | #[cfg(quadspi)] |
| 49 | pub mod qspi; | 51 | pub mod qspi; |
| 50 | #[cfg(rng)] | 52 | #[cfg(rng)] |
| @@ -80,7 +82,7 @@ pub use crate::_generated::interrupt; | |||
| 80 | /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) | 82 | /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) |
| 81 | /// and implements the right [`Binding`]s for it. You can pass this struct to drivers to | 83 | /// and implements the right [`Binding`]s for it. You can pass this struct to drivers to |
| 82 | /// prove at compile-time that the right interrupts have been bound. | 84 | /// prove at compile-time that the right interrupts have been bound. |
| 83 | // developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`. | 85 | // developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. |
| 84 | #[macro_export] | 86 | #[macro_export] |
| 85 | macro_rules! bind_interrupts { | 87 | macro_rules! bind_interrupts { |
| 86 | ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { | 88 | ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { |
| @@ -104,7 +106,7 @@ macro_rules! bind_interrupts { | |||
| 104 | 106 | ||
| 105 | // Reexports | 107 | // Reexports |
| 106 | pub use _generated::{peripherals, Peripherals}; | 108 | pub use _generated::{peripherals, Peripherals}; |
| 107 | pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 109 | pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 108 | #[cfg(feature = "unstable-pac")] | 110 | #[cfg(feature = "unstable-pac")] |
| 109 | pub use stm32_metapac as pac; | 111 | pub use stm32_metapac as pac; |
| 110 | #[cfg(not(feature = "unstable-pac"))] | 112 | #[cfg(not(feature = "unstable-pac"))] |
diff --git a/embassy-stm32/src/pwm/mod.rs b/embassy-stm32/src/pwm/mod.rs deleted file mode 100644 index 5aba2663e..000000000 --- a/embassy-stm32/src/pwm/mod.rs +++ /dev/null | |||
| @@ -1,269 +0,0 @@ | |||
| 1 | pub mod complementary_pwm; | ||
| 2 | pub mod simple_pwm; | ||
| 3 | |||
| 4 | use stm32_metapac::timer::vals::Ckd; | ||
| 5 | |||
| 6 | #[cfg(feature = "unstable-pac")] | ||
| 7 | pub mod low_level { | ||
| 8 | pub use super::sealed::*; | ||
| 9 | } | ||
| 10 | |||
| 11 | #[derive(Clone, Copy)] | ||
| 12 | pub enum Channel { | ||
| 13 | Ch1, | ||
| 14 | Ch2, | ||
| 15 | Ch3, | ||
| 16 | Ch4, | ||
| 17 | } | ||
| 18 | |||
| 19 | impl Channel { | ||
| 20 | pub fn raw(&self) -> usize { | ||
| 21 | match self { | ||
| 22 | Channel::Ch1 => 0, | ||
| 23 | Channel::Ch2 => 1, | ||
| 24 | Channel::Ch3 => 2, | ||
| 25 | Channel::Ch4 => 3, | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | #[derive(Clone, Copy)] | ||
| 31 | pub enum OutputCompareMode { | ||
| 32 | Frozen, | ||
| 33 | ActiveOnMatch, | ||
| 34 | InactiveOnMatch, | ||
| 35 | Toggle, | ||
| 36 | ForceInactive, | ||
| 37 | ForceActive, | ||
| 38 | PwmMode1, | ||
| 39 | PwmMode2, | ||
| 40 | } | ||
| 41 | |||
| 42 | impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm { | ||
| 43 | fn from(mode: OutputCompareMode) -> Self { | ||
| 44 | match mode { | ||
| 45 | OutputCompareMode::Frozen => stm32_metapac::timer::vals::Ocm::FROZEN, | ||
| 46 | OutputCompareMode::ActiveOnMatch => stm32_metapac::timer::vals::Ocm::ACTIVEONMATCH, | ||
| 47 | OutputCompareMode::InactiveOnMatch => stm32_metapac::timer::vals::Ocm::INACTIVEONMATCH, | ||
| 48 | OutputCompareMode::Toggle => stm32_metapac::timer::vals::Ocm::TOGGLE, | ||
| 49 | OutputCompareMode::ForceInactive => stm32_metapac::timer::vals::Ocm::FORCEINACTIVE, | ||
| 50 | OutputCompareMode::ForceActive => stm32_metapac::timer::vals::Ocm::FORCEACTIVE, | ||
| 51 | OutputCompareMode::PwmMode1 => stm32_metapac::timer::vals::Ocm::PWMMODE1, | ||
| 52 | OutputCompareMode::PwmMode2 => stm32_metapac::timer::vals::Ocm::PWMMODE2, | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | pub(crate) mod sealed { | ||
| 58 | use super::*; | ||
| 59 | |||
| 60 | pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance { | ||
| 61 | /// Global output enable. Does not do anything on non-advanced timers. | ||
| 62 | fn enable_outputs(&mut self, enable: bool); | ||
| 63 | |||
| 64 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); | ||
| 65 | |||
| 66 | fn enable_channel(&mut self, channel: Channel, enable: bool); | ||
| 67 | |||
| 68 | fn set_compare_value(&mut self, channel: Channel, value: u16); | ||
| 69 | |||
| 70 | fn get_max_compare_value(&self) -> u16; | ||
| 71 | } | ||
| 72 | |||
| 73 | pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance { | ||
| 74 | fn set_dead_time_clock_division(&mut self, value: Ckd); | ||
| 75 | |||
| 76 | fn set_dead_time_value(&mut self, value: u8); | ||
| 77 | |||
| 78 | fn enable_complementary_channel(&mut self, channel: Channel, enable: bool); | ||
| 79 | } | ||
| 80 | |||
| 81 | pub trait CaptureCompare32bitInstance: crate::timer::sealed::GeneralPurpose32bitInstance { | ||
| 82 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); | ||
| 83 | |||
| 84 | fn enable_channel(&mut self, channel: Channel, enable: bool); | ||
| 85 | |||
| 86 | fn set_compare_value(&mut self, channel: Channel, value: u32); | ||
| 87 | |||
| 88 | fn get_max_compare_value(&self) -> u32; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | pub trait CaptureCompare16bitInstance: | ||
| 93 | sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static | ||
| 94 | { | ||
| 95 | } | ||
| 96 | |||
| 97 | pub trait ComplementaryCaptureCompare16bitInstance: | ||
| 98 | sealed::ComplementaryCaptureCompare16bitInstance + crate::timer::AdvancedControlInstance + 'static | ||
| 99 | { | ||
| 100 | } | ||
| 101 | |||
| 102 | pub trait CaptureCompare32bitInstance: | ||
| 103 | sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + crate::timer::GeneralPurpose32bitInstance + 'static | ||
| 104 | { | ||
| 105 | } | ||
| 106 | |||
| 107 | #[allow(unused)] | ||
| 108 | macro_rules! impl_compare_capable_16bit { | ||
| 109 | ($inst:ident) => { | ||
| 110 | impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 111 | fn enable_outputs(&mut self, _enable: bool) {} | ||
| 112 | |||
| 113 | fn set_output_compare_mode(&mut self, channel: crate::pwm::Channel, mode: OutputCompareMode) { | ||
| 114 | use crate::timer::sealed::GeneralPurpose16bitInstance; | ||
| 115 | let r = Self::regs_gp16(); | ||
| 116 | let raw_channel: usize = channel.raw(); | ||
| 117 | r.ccmr_output(raw_channel / 2) | ||
| 118 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | ||
| 119 | } | ||
| 120 | |||
| 121 | fn enable_channel(&mut self, channel: Channel, enable: bool) { | ||
| 122 | use crate::timer::sealed::GeneralPurpose16bitInstance; | ||
| 123 | Self::regs_gp16() | ||
| 124 | .ccer() | ||
| 125 | .modify(|w| w.set_cce(channel.raw(), enable)); | ||
| 126 | } | ||
| 127 | |||
| 128 | fn set_compare_value(&mut self, channel: Channel, value: u16) { | ||
| 129 | use crate::timer::sealed::GeneralPurpose16bitInstance; | ||
| 130 | Self::regs_gp16().ccr(channel.raw()).modify(|w| w.set_ccr(value)); | ||
| 131 | } | ||
| 132 | |||
| 133 | fn get_max_compare_value(&self) -> u16 { | ||
| 134 | use crate::timer::sealed::GeneralPurpose16bitInstance; | ||
| 135 | Self::regs_gp16().arr().read().arr() | ||
| 136 | } | ||
| 137 | } | ||
| 138 | }; | ||
| 139 | } | ||
| 140 | |||
| 141 | foreach_interrupt! { | ||
| 142 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { | ||
| 143 | impl_compare_capable_16bit!($inst); | ||
| 144 | |||
| 145 | impl CaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 146 | |||
| 147 | } | ||
| 148 | }; | ||
| 149 | |||
| 150 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { | ||
| 151 | impl_compare_capable_16bit!($inst); | ||
| 152 | impl crate::pwm::sealed::CaptureCompare32bitInstance for crate::peripherals::$inst { | ||
| 153 | fn set_output_compare_mode( | ||
| 154 | &mut self, | ||
| 155 | channel: crate::pwm::Channel, | ||
| 156 | mode: OutputCompareMode, | ||
| 157 | ) { | ||
| 158 | use crate::timer::sealed::GeneralPurpose32bitInstance; | ||
| 159 | let raw_channel = channel.raw(); | ||
| 160 | Self::regs_gp32().ccmr_output(raw_channel / 2).modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | ||
| 161 | } | ||
| 162 | |||
| 163 | fn enable_channel(&mut self, channel: Channel, enable: bool) { | ||
| 164 | use crate::timer::sealed::GeneralPurpose32bitInstance; | ||
| 165 | Self::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), enable)); | ||
| 166 | } | ||
| 167 | |||
| 168 | fn set_compare_value(&mut self, channel: Channel, value: u32) { | ||
| 169 | use crate::timer::sealed::GeneralPurpose32bitInstance; | ||
| 170 | Self::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(value)); | ||
| 171 | } | ||
| 172 | |||
| 173 | fn get_max_compare_value(&self) -> u32 { | ||
| 174 | use crate::timer::sealed::GeneralPurpose32bitInstance; | ||
| 175 | Self::regs_gp32().arr().read().arr() as u32 | ||
| 176 | } | ||
| 177 | } | ||
| 178 | impl CaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 179 | |||
| 180 | } | ||
| 181 | impl CaptureCompare32bitInstance for crate::peripherals::$inst { | ||
| 182 | |||
| 183 | } | ||
| 184 | }; | ||
| 185 | |||
| 186 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { | ||
| 187 | impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 188 | fn enable_outputs(&mut self, enable: bool) { | ||
| 189 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 190 | let r = Self::regs_advanced(); | ||
| 191 | r.bdtr().modify(|w| w.set_moe(enable)); | ||
| 192 | } | ||
| 193 | |||
| 194 | fn set_output_compare_mode( | ||
| 195 | &mut self, | ||
| 196 | channel: crate::pwm::Channel, | ||
| 197 | mode: OutputCompareMode, | ||
| 198 | ) { | ||
| 199 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 200 | let r = Self::regs_advanced(); | ||
| 201 | let raw_channel: usize = channel.raw(); | ||
| 202 | r.ccmr_output(raw_channel / 2) | ||
| 203 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | ||
| 204 | } | ||
| 205 | |||
| 206 | fn enable_channel(&mut self, channel: Channel, enable: bool) { | ||
| 207 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 208 | Self::regs_advanced() | ||
| 209 | .ccer() | ||
| 210 | .modify(|w| w.set_cce(channel.raw(), enable)); | ||
| 211 | } | ||
| 212 | |||
| 213 | fn set_compare_value(&mut self, channel: Channel, value: u16) { | ||
| 214 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 215 | Self::regs_advanced() | ||
| 216 | .ccr(channel.raw()) | ||
| 217 | .modify(|w| w.set_ccr(value)); | ||
| 218 | } | ||
| 219 | |||
| 220 | fn get_max_compare_value(&self) -> u16 { | ||
| 221 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 222 | Self::regs_advanced().arr().read().arr() | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | impl CaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 227 | |||
| 228 | } | ||
| 229 | |||
| 230 | impl crate::pwm::sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 231 | fn set_dead_time_clock_division(&mut self, value: Ckd) { | ||
| 232 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 233 | Self::regs_advanced().cr1().modify(|w| w.set_ckd(value)); | ||
| 234 | } | ||
| 235 | |||
| 236 | fn set_dead_time_value(&mut self, value: u8) { | ||
| 237 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 238 | Self::regs_advanced().bdtr().modify(|w| w.set_dtg(value)); | ||
| 239 | } | ||
| 240 | |||
| 241 | fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { | ||
| 242 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 243 | Self::regs_advanced() | ||
| 244 | .ccer() | ||
| 245 | .modify(|w| w.set_ccne(channel.raw(), enable)); | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 250 | |||
| 251 | } | ||
| 252 | }; | ||
| 253 | } | ||
| 254 | |||
| 255 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); | ||
| 256 | pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance); | ||
| 257 | pin_trait!(Channel2Pin, CaptureCompare16bitInstance); | ||
| 258 | pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance); | ||
| 259 | pin_trait!(Channel3Pin, CaptureCompare16bitInstance); | ||
| 260 | pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance); | ||
| 261 | pin_trait!(Channel4Pin, CaptureCompare16bitInstance); | ||
| 262 | pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance); | ||
| 263 | pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); | ||
| 264 | pin_trait!(BreakInputPin, CaptureCompare16bitInstance); | ||
| 265 | pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance); | ||
| 266 | pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance); | ||
| 267 | pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance); | ||
| 268 | pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); | ||
| 269 | pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); | ||
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 31b676088..32382fb28 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | pub mod enums; | 3 | pub mod enums; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use enums::*; | 6 | use enums::*; |
| 7 | 7 | ||
| 8 | use crate::dma::Transfer; | 8 | use crate::dma::Transfer; |
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index b84470440..7aa9f0fd2 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | use stm32_metapac::rcc::vals::{Mco1, Mco2, Mcopre}; | 4 | use stm32_metapac::rcc::vals::{Mco1, Mco2, Mcopre}; |
| 5 | 5 | ||
| 6 | use super::sealed::RccPeripheral; | 6 | use super::sealed::RccPeripheral; |
diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs index 7e5cd0d1a..bbc0e0831 100644 --- a/embassy-stm32/src/rcc/h7.rs +++ b/embassy-stm32/src/rcc/h7.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | pub use pll::PllConfig; | 4 | pub use pll::PllConfig; |
| 5 | use stm32_metapac::rcc::vals::{Mco1, Mco2}; | 5 | use stm32_metapac::rcc::vals::{Mco1, Mco2}; |
| 6 | 6 | ||
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 8a9b4adbf..dc5f55d0c 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | use stm32_metapac::rcc::regs::Cfgr; | 4 | use stm32_metapac::rcc::regs::Cfgr; |
| 5 | use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; | 5 | use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; |
| 6 | 6 | ||
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/rng.rs b/embassy-stm32/src/rng.rs index b2faec53d..27415c2d7 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | use core::future::poll_fn; | 3 | use core::future::poll_fn; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | use rand_core::{CryptoRng, RngCore}; | 8 | use rand_core::{CryptoRng, RngCore}; |
| 9 | 9 | ||
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 12a2ac795..323be3187 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -15,7 +15,7 @@ pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; | |||
| 15 | #[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")] | 15 | #[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")] |
| 16 | mod _version; | 16 | mod _version; |
| 17 | pub use _version::*; | 17 | pub use _version::*; |
| 18 | use embassy_hal_common::Peripheral; | 18 | use embassy_hal_internal::Peripheral; |
| 19 | 19 | ||
| 20 | /// Errors that can occur on methods on [RtcClock] | 20 | /// Errors that can occur on methods on [RtcClock] |
| 21 | #[derive(Clone, Debug, PartialEq, Eq)] | 21 | #[derive(Clone, Debug, PartialEq, Eq)] |
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 698292bff..6b532363c 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs | |||
| @@ -6,8 +6,8 @@ use core::marker::PhantomData; | |||
| 6 | use core::ops::{Deref, DerefMut}; | 6 | use core::ops::{Deref, DerefMut}; |
| 7 | use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | use embassy_hal_common::drop::OnDrop; | 9 | use embassy_hal_internal::drop::OnDrop; |
| 10 | use embassy_hal_common::{into_ref, PeripheralRef}; | 10 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 11 | use embassy_sync::waitqueue::AtomicWaker; | 11 | use embassy_sync::waitqueue::AtomicWaker; |
| 12 | use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; | 12 | use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; |
| 13 | 13 | ||
| @@ -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/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index d5f63f84e..bdf3c85b0 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -4,7 +4,7 @@ use core::ptr; | |||
| 4 | 4 | ||
| 5 | use embassy_embedded_hal::SetConfig; | 5 | use embassy_embedded_hal::SetConfig; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_hal_common::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 8 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 9 | 9 | ||
| 10 | use crate::dma::{slice_ptr_parts, word, Transfer}; | 10 | use crate::dma::{slice_ptr_parts, word, Transfer}; |
diff --git a/embassy-stm32/src/pwm/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 4d64d005c..64bb32c39 100644 --- a/embassy-stm32/src/pwm/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::{into_ref, PeripheralRef}; | 3 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 4 | use stm32_metapac::timer::vals::Ckd; | 4 | use stm32_metapac::timer::vals::Ckd; |
| 5 | 5 | ||
| 6 | use super::simple_pwm::*; | 6 | use super::simple_pwm::*; |
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index a92f854ec..286ab556f 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -1,3 +1,6 @@ | |||
| 1 | pub mod complementary_pwm; | ||
| 2 | pub mod simple_pwm; | ||
| 3 | |||
| 1 | use stm32_metapac::timer::vals; | 4 | use stm32_metapac::timer::vals; |
| 2 | 5 | ||
| 3 | use crate::interrupt; | 6 | use crate::interrupt; |
| @@ -44,24 +47,122 @@ pub(crate) mod sealed { | |||
| 44 | fn regs_advanced() -> crate::pac::timer::TimAdv; | 47 | fn regs_advanced() -> crate::pac::timer::TimAdv; |
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | #[cfg(hrtim_v1)] | 50 | pub trait CaptureCompare16bitInstance: GeneralPurpose16bitInstance { |
| 48 | pub trait HighResolutionControlInstance: RccPeripheral { | 51 | /// Global output enable. Does not do anything on non-advanced timers. |
| 49 | type Interrupt: interrupt::typelevel::Interrupt; | 52 | fn enable_outputs(&mut self, enable: bool); |
| 53 | |||
| 54 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); | ||
| 55 | |||
| 56 | fn enable_channel(&mut self, channel: Channel, enable: bool); | ||
| 57 | |||
| 58 | fn set_compare_value(&mut self, channel: Channel, value: u16); | ||
| 59 | |||
| 60 | fn get_max_compare_value(&self) -> u16; | ||
| 61 | } | ||
| 62 | |||
| 63 | pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance { | ||
| 64 | fn set_dead_time_clock_division(&mut self, value: vals::Ckd); | ||
| 65 | |||
| 66 | fn set_dead_time_value(&mut self, value: u8); | ||
| 67 | |||
| 68 | fn enable_complementary_channel(&mut self, channel: Channel, enable: bool); | ||
| 69 | } | ||
| 70 | |||
| 71 | pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance { | ||
| 72 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); | ||
| 73 | |||
| 74 | fn enable_channel(&mut self, channel: Channel, enable: bool); | ||
| 75 | |||
| 76 | fn set_compare_value(&mut self, channel: Channel, value: u32); | ||
| 77 | |||
| 78 | fn get_max_compare_value(&self) -> u32; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | #[derive(Clone, Copy)] | ||
| 83 | pub enum Channel { | ||
| 84 | Ch1, | ||
| 85 | Ch2, | ||
| 86 | Ch3, | ||
| 87 | Ch4, | ||
| 88 | } | ||
| 89 | |||
| 90 | impl Channel { | ||
| 91 | pub fn raw(&self) -> usize { | ||
| 92 | match self { | ||
| 93 | Channel::Ch1 => 0, | ||
| 94 | Channel::Ch2 => 1, | ||
| 95 | Channel::Ch3 => 2, | ||
| 96 | Channel::Ch4 => 3, | ||
| 97 | } | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | #[derive(Clone, Copy)] | ||
| 102 | pub enum OutputCompareMode { | ||
| 103 | Frozen, | ||
| 104 | ActiveOnMatch, | ||
| 105 | InactiveOnMatch, | ||
| 106 | Toggle, | ||
| 107 | ForceInactive, | ||
| 108 | ForceActive, | ||
| 109 | PwmMode1, | ||
| 110 | PwmMode2, | ||
| 111 | } | ||
| 50 | 112 | ||
| 51 | fn regs() -> crate::pac::hrtim::Hrtim; | 113 | impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm { |
| 114 | fn from(mode: OutputCompareMode) -> Self { | ||
| 115 | match mode { | ||
| 116 | OutputCompareMode::Frozen => stm32_metapac::timer::vals::Ocm::FROZEN, | ||
| 117 | OutputCompareMode::ActiveOnMatch => stm32_metapac::timer::vals::Ocm::ACTIVEONMATCH, | ||
| 118 | OutputCompareMode::InactiveOnMatch => stm32_metapac::timer::vals::Ocm::INACTIVEONMATCH, | ||
| 119 | OutputCompareMode::Toggle => stm32_metapac::timer::vals::Ocm::TOGGLE, | ||
| 120 | OutputCompareMode::ForceInactive => stm32_metapac::timer::vals::Ocm::FORCEINACTIVE, | ||
| 121 | OutputCompareMode::ForceActive => stm32_metapac::timer::vals::Ocm::FORCEACTIVE, | ||
| 122 | OutputCompareMode::PwmMode1 => stm32_metapac::timer::vals::Ocm::PWMMODE1, | ||
| 123 | OutputCompareMode::PwmMode2 => stm32_metapac::timer::vals::Ocm::PWMMODE2, | ||
| 124 | } | ||
| 52 | } | 125 | } |
| 53 | } | 126 | } |
| 54 | 127 | ||
| 128 | pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} | ||
| 129 | |||
| 55 | pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {} | 130 | pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {} |
| 56 | 131 | ||
| 57 | pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + 'static {} | 132 | pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + 'static {} |
| 58 | 133 | ||
| 59 | pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {} | 134 | pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {} |
| 60 | 135 | ||
| 61 | #[cfg(hrtim_v1)] | 136 | pub trait CaptureCompare16bitInstance: |
| 62 | pub trait HighResolutionControlInstance: sealed::HighResolutionControlInstance + 'static {} | 137 | sealed::CaptureCompare16bitInstance + GeneralPurpose16bitInstance + 'static |
| 138 | { | ||
| 139 | } | ||
| 63 | 140 | ||
| 64 | pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} | 141 | pub trait ComplementaryCaptureCompare16bitInstance: |
| 142 | sealed::ComplementaryCaptureCompare16bitInstance + AdvancedControlInstance + 'static | ||
| 143 | { | ||
| 144 | } | ||
| 145 | |||
| 146 | pub trait CaptureCompare32bitInstance: | ||
| 147 | sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + GeneralPurpose32bitInstance + 'static | ||
| 148 | { | ||
| 149 | } | ||
| 150 | |||
| 151 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); | ||
| 152 | pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance); | ||
| 153 | pin_trait!(Channel2Pin, CaptureCompare16bitInstance); | ||
| 154 | pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance); | ||
| 155 | pin_trait!(Channel3Pin, CaptureCompare16bitInstance); | ||
| 156 | pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance); | ||
| 157 | pin_trait!(Channel4Pin, CaptureCompare16bitInstance); | ||
| 158 | pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance); | ||
| 159 | pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); | ||
| 160 | pin_trait!(BreakInputPin, CaptureCompare16bitInstance); | ||
| 161 | pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance); | ||
| 162 | pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance); | ||
| 163 | pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance); | ||
| 164 | pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); | ||
| 165 | pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); | ||
| 65 | 166 | ||
| 66 | #[allow(unused)] | 167 | #[allow(unused)] |
| 67 | macro_rules! impl_basic_16bit_timer { | 168 | macro_rules! impl_basic_16bit_timer { |
| @@ -150,33 +251,94 @@ macro_rules! impl_32bit_timer { | |||
| 150 | }; | 251 | }; |
| 151 | } | 252 | } |
| 152 | 253 | ||
| 254 | #[allow(unused)] | ||
| 255 | macro_rules! impl_compare_capable_16bit { | ||
| 256 | ($inst:ident) => { | ||
| 257 | impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 258 | fn enable_outputs(&mut self, _enable: bool) {} | ||
| 259 | |||
| 260 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { | ||
| 261 | use sealed::GeneralPurpose16bitInstance; | ||
| 262 | let r = Self::regs_gp16(); | ||
| 263 | let raw_channel: usize = channel.raw(); | ||
| 264 | r.ccmr_output(raw_channel / 2) | ||
| 265 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | ||
| 266 | } | ||
| 267 | |||
| 268 | fn enable_channel(&mut self, channel: Channel, enable: bool) { | ||
| 269 | use sealed::GeneralPurpose16bitInstance; | ||
| 270 | Self::regs_gp16() | ||
| 271 | .ccer() | ||
| 272 | .modify(|w| w.set_cce(channel.raw(), enable)); | ||
| 273 | } | ||
| 274 | |||
| 275 | fn set_compare_value(&mut self, channel: Channel, value: u16) { | ||
| 276 | use sealed::GeneralPurpose16bitInstance; | ||
| 277 | Self::regs_gp16().ccr(channel.raw()).modify(|w| w.set_ccr(value)); | ||
| 278 | } | ||
| 279 | |||
| 280 | fn get_max_compare_value(&self) -> u16 { | ||
| 281 | use sealed::GeneralPurpose16bitInstance; | ||
| 282 | Self::regs_gp16().arr().read().arr() | ||
| 283 | } | ||
| 284 | } | ||
| 285 | }; | ||
| 286 | } | ||
| 287 | |||
| 153 | foreach_interrupt! { | 288 | foreach_interrupt! { |
| 154 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { | 289 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { |
| 155 | impl_basic_16bit_timer!($inst, $irq); | 290 | impl_basic_16bit_timer!($inst, $irq); |
| 156 | 291 | impl Basic16bitInstance for crate::peripherals::$inst {} | |
| 157 | impl Basic16bitInstance for crate::peripherals::$inst { | ||
| 158 | } | ||
| 159 | }; | 292 | }; |
| 160 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { | 293 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { |
| 161 | impl_basic_16bit_timer!($inst, $irq); | 294 | impl_basic_16bit_timer!($inst, $irq); |
| 162 | 295 | impl_compare_capable_16bit!($inst); | |
| 163 | impl Basic16bitInstance for crate::peripherals::$inst { | 296 | impl Basic16bitInstance for crate::peripherals::$inst {} |
| 164 | } | 297 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} |
| 298 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 165 | 299 | ||
| 166 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 300 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { |
| 167 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 301 | fn regs_gp16() -> crate::pac::timer::TimGp16 { |
| 168 | crate::pac::$inst | 302 | crate::pac::$inst |
| 169 | } | 303 | } |
| 170 | } | 304 | } |
| 171 | |||
| 172 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 173 | } | ||
| 174 | }; | 305 | }; |
| 175 | 306 | ||
| 176 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { | 307 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { |
| 177 | impl_basic_16bit_timer!($inst, $irq); | 308 | impl_basic_16bit_timer!($inst, $irq); |
| 309 | impl_32bit_timer!($inst); | ||
| 310 | impl_compare_capable_16bit!($inst); | ||
| 311 | impl Basic16bitInstance for crate::peripherals::$inst {} | ||
| 312 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 313 | impl CaptureCompare32bitInstance for crate::peripherals::$inst {} | ||
| 314 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} | ||
| 315 | impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} | ||
| 316 | |||
| 317 | impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst { | ||
| 318 | fn set_output_compare_mode( | ||
| 319 | &mut self, | ||
| 320 | channel: Channel, | ||
| 321 | mode: OutputCompareMode, | ||
| 322 | ) { | ||
| 323 | use crate::timer::sealed::GeneralPurpose32bitInstance; | ||
| 324 | let raw_channel = channel.raw(); | ||
| 325 | Self::regs_gp32().ccmr_output(raw_channel / 2).modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | ||
| 326 | } | ||
| 178 | 327 | ||
| 179 | impl Basic16bitInstance for crate::peripherals::$inst { | 328 | fn enable_channel(&mut self, channel: Channel, enable: bool) { |
| 329 | use crate::timer::sealed::GeneralPurpose32bitInstance; | ||
| 330 | Self::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), enable)); | ||
| 331 | } | ||
| 332 | |||
| 333 | fn set_compare_value(&mut self, channel: Channel, value: u32) { | ||
| 334 | use crate::timer::sealed::GeneralPurpose32bitInstance; | ||
| 335 | Self::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(value)); | ||
| 336 | } | ||
| 337 | |||
| 338 | fn get_max_compare_value(&self) -> u32 { | ||
| 339 | use crate::timer::sealed::GeneralPurpose32bitInstance; | ||
| 340 | Self::regs_gp32().arr().read().arr() as u32 | ||
| 341 | } | ||
| 180 | } | 342 | } |
| 181 | 343 | ||
| 182 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 344 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { |
| @@ -184,21 +346,16 @@ foreach_interrupt! { | |||
| 184 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } | 346 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } |
| 185 | } | 347 | } |
| 186 | } | 348 | } |
| 187 | |||
| 188 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 189 | } | ||
| 190 | |||
| 191 | impl_32bit_timer!($inst); | ||
| 192 | |||
| 193 | impl GeneralPurpose32bitInstance for crate::peripherals::$inst { | ||
| 194 | } | ||
| 195 | }; | 349 | }; |
| 196 | 350 | ||
| 197 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { | 351 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { |
| 198 | impl_basic_16bit_timer!($inst, $irq); | 352 | impl_basic_16bit_timer!($inst, $irq); |
| 199 | 353 | ||
| 200 | impl Basic16bitInstance for crate::peripherals::$inst { | 354 | impl Basic16bitInstance for crate::peripherals::$inst {} |
| 201 | } | 355 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} |
| 356 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 357 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 358 | impl AdvancedControlInstance for crate::peripherals::$inst {} | ||
| 202 | 359 | ||
| 203 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 360 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { |
| 204 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 361 | fn regs_gp16() -> crate::pac::timer::TimGp16 { |
| @@ -206,17 +363,71 @@ foreach_interrupt! { | |||
| 206 | } | 363 | } |
| 207 | } | 364 | } |
| 208 | 365 | ||
| 209 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 210 | } | ||
| 211 | |||
| 212 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { | 366 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { |
| 213 | fn regs_advanced() -> crate::pac::timer::TimAdv { | 367 | fn regs_advanced() -> crate::pac::timer::TimAdv { |
| 214 | crate::pac::$inst | 368 | crate::pac::$inst |
| 215 | } | 369 | } |
| 216 | } | 370 | } |
| 217 | 371 | ||
| 218 | impl AdvancedControlInstance for crate::peripherals::$inst { | 372 | impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { |
| 373 | fn enable_outputs(&mut self, enable: bool) { | ||
| 374 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 375 | let r = Self::regs_advanced(); | ||
| 376 | r.bdtr().modify(|w| w.set_moe(enable)); | ||
| 377 | } | ||
| 378 | |||
| 379 | fn set_output_compare_mode( | ||
| 380 | &mut self, | ||
| 381 | channel: Channel, | ||
| 382 | mode: OutputCompareMode, | ||
| 383 | ) { | ||
| 384 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 385 | let r = Self::regs_advanced(); | ||
| 386 | let raw_channel: usize = channel.raw(); | ||
| 387 | r.ccmr_output(raw_channel / 2) | ||
| 388 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | ||
| 389 | } | ||
| 390 | |||
| 391 | fn enable_channel(&mut self, channel: Channel, enable: bool) { | ||
| 392 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 393 | Self::regs_advanced() | ||
| 394 | .ccer() | ||
| 395 | .modify(|w| w.set_cce(channel.raw(), enable)); | ||
| 396 | } | ||
| 397 | |||
| 398 | fn set_compare_value(&mut self, channel: Channel, value: u16) { | ||
| 399 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 400 | Self::regs_advanced() | ||
| 401 | .ccr(channel.raw()) | ||
| 402 | .modify(|w| w.set_ccr(value)); | ||
| 403 | } | ||
| 404 | |||
| 405 | fn get_max_compare_value(&self) -> u16 { | ||
| 406 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 407 | Self::regs_advanced().arr().read().arr() | ||
| 408 | } | ||
| 409 | } | ||
| 410 | |||
| 411 | impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 412 | fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { | ||
| 413 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 414 | Self::regs_advanced().cr1().modify(|w| w.set_ckd(value)); | ||
| 415 | } | ||
| 416 | |||
| 417 | fn set_dead_time_value(&mut self, value: u8) { | ||
| 418 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 419 | Self::regs_advanced().bdtr().modify(|w| w.set_dtg(value)); | ||
| 420 | } | ||
| 421 | |||
| 422 | fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { | ||
| 423 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 424 | Self::regs_advanced() | ||
| 425 | .ccer() | ||
| 426 | .modify(|w| w.set_ccne(channel.raw(), enable)); | ||
| 427 | } | ||
| 219 | } | 428 | } |
| 429 | |||
| 430 | |||
| 220 | }; | 431 | }; |
| 221 | 432 | ||
| 222 | ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { | 433 | ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { |
diff --git a/embassy-stm32/src/pwm/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 995f59c23..514796930 100644 --- a/embassy-stm32/src/pwm/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::{into_ref, PeripheralRef}; | 3 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 4 | 4 | ||
| 5 | use super::*; | 5 | use super::*; |
| 6 | #[allow(unused_imports)] | 6 | #[allow(unused_imports)] |
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 433ad299c..ca117da82 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs | |||
| @@ -2,7 +2,7 @@ use core::future::poll_fn; | |||
| 2 | use core::slice; | 2 | use core::slice; |
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::atomic_ring_buffer::RingBuffer; | 5 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; |
| 6 | use embassy_sync::waitqueue::AtomicWaker; | 6 | use embassy_sync::waitqueue::AtomicWaker; |
| 7 | 7 | ||
| 8 | use super::*; | 8 | use super::*; |
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index ea8e525ea..d99034bca 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -5,8 +5,8 @@ use core::marker::PhantomData; | |||
| 5 | use core::sync::atomic::{compiler_fence, Ordering}; | 5 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | 7 | ||
| 8 | use embassy_hal_common::drop::OnDrop; | 8 | use embassy_hal_internal::drop::OnDrop; |
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | use futures::future::{select, Either}; | 10 | use futures::future::{select, Either}; |
| 11 | 11 | ||
| 12 | use crate::dma::{NoDma, Transfer}; | 12 | use crate::dma::{NoDma, Transfer}; |
| @@ -857,7 +857,7 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: | |||
| 857 | "Using {} oversampling, desired baudrate: {}, actual baudrate: {}", | 857 | "Using {} oversampling, desired baudrate: {}, actual baudrate: {}", |
| 858 | oversampling, | 858 | oversampling, |
| 859 | config.baudrate, | 859 | config.baudrate, |
| 860 | pclk_freq.0 / div | 860 | (pclk_freq.0 * mul as u32) / div |
| 861 | ); | 861 | ); |
| 862 | 862 | ||
| 863 | r.cr2().write(|w| { | 863 | r.cr2().write(|w| { |
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index c74d7e092..80261d048 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs | |||
| @@ -2,7 +2,7 @@ use core::future::poll_fn; | |||
| 2 | use core::sync::atomic::{compiler_fence, Ordering}; | 2 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::PeripheralRef; | 5 | use embassy_hal_internal::PeripheralRef; |
| 6 | use futures::future::{select, Either}; | 6 | use futures::future::{select, Either}; |
| 7 | 7 | ||
| 8 | use super::{clear_interrupt_flags, rdr, sr, BasicInstance, Error, UartRx}; | 8 | use super::{clear_interrupt_flags, rdr, sr, BasicInstance, Error, UartRx}; |
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index ecdd1d0b8..cef196355 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs | |||
| @@ -5,7 +5,7 @@ use core::marker::PhantomData; | |||
| 5 | use core::sync::atomic::{AtomicBool, Ordering}; | 5 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | 7 | ||
| 8 | use embassy_hal_common::into_ref; | 8 | use embassy_hal_internal::into_ref; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | use embassy_usb_driver as driver; | 10 | use embassy_usb_driver as driver; |
| 11 | use embassy_usb_driver::{ | 11 | use embassy_usb_driver::{ |
diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs index fd0e22adf..348f0f79d 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb_otg/usb.rs | |||
| @@ -3,7 +3,7 @@ use core::marker::PhantomData; | |||
| 3 | use core::sync::atomic::{AtomicBool, AtomicU16, Ordering}; | 3 | use core::sync::atomic::{AtomicBool, AtomicU16, Ordering}; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{into_ref, Peripheral}; | 6 | use embassy_hal_internal::{into_ref, Peripheral}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | use embassy_usb_driver::{ | 8 | use embassy_usb_driver::{ |
| 9 | self, Bus as _, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointIn, EndpointInfo, | 9 | self, Bus as _, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointIn, EndpointInfo, |
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs index b03e81d6e..eafd03364 100644 --- a/embassy-stm32/src/wdg/mod.rs +++ b/embassy-stm32/src/wdg/mod.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::{into_ref, Peripheral}; | 3 | use embassy_hal_internal::{into_ref, Peripheral}; |
| 4 | use stm32_metapac::iwdg::vals::{Key, Pr}; | 4 | use stm32_metapac::iwdg::vals::{Key, Pr}; |
| 5 | 5 | ||
| 6 | use crate::rcc::LSI_FREQ; | 6 | use crate::rcc::LSI_FREQ; |
