diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index c892007a3..a4709f4ca 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -244,11 +244,11 @@ fn main() { (("usart", "CTS"), quote!(crate::usart::CtsPin)), (("usart", "RTS"), quote!(crate::usart::RtsPin)), (("usart", "CK"), quote!(crate::usart::CkPin)), - (("usart", "TX"), quote!(crate::usart::TxPin)), - (("usart", "RX"), quote!(crate::usart::RxPin)), - (("usart", "CTS"), quote!(crate::usart::CtsPin)), - (("usart", "RTS"), quote!(crate::usart::RtsPin)), - (("usart", "CK"), quote!(crate::usart::CkPin)), + (("lpuart", "TX"), quote!(crate::usart::TxPin)), + (("lpuart", "RX"), quote!(crate::usart::RxPin)), + (("lpuart", "CTS"), quote!(crate::usart::CtsPin)), + (("lpuart", "RTS"), quote!(crate::usart::RtsPin)), + (("lpuart", "CK"), quote!(crate::usart::CkPin)), (("spi", "SCK"), quote!(crate::spi::SckPin)), (("spi", "MOSI"), quote!(crate::spi::MosiPin)), (("spi", "MISO"), quote!(crate::spi::MisoPin)), @@ -497,6 +497,8 @@ fn main() { // (kind, signal) => trait (("usart", "RX"), quote!(crate::usart::RxDma)), (("usart", "TX"), quote!(crate::usart::TxDma)), + (("lpuart", "RX"), quote!(crate::usart::RxDma)), + (("lpuart", "TX"), quote!(crate::usart::TxDma)), (("spi", "RX"), quote!(crate::spi::RxDma)), (("spi", "TX"), quote!(crate::spi::TxDma)), (("i2c", "RX"), quote!(crate::i2c::RxDma)), diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 0e8d0d682..ec2231e43 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -9,14 +9,14 @@ use futures::future::poll_fn; use super::*; -pub struct State<'d, T: Instance>(StateStorage>); -impl<'d, T: Instance> State<'d, T> { +pub struct State<'d, T: BasicInstance>(StateStorage>); +impl<'d, T: BasicInstance> State<'d, T> { pub fn new() -> Self { Self(StateStorage::new()) } } -struct StateInner<'d, T: Instance> { +struct StateInner<'d, T: BasicInstance> { phantom: PhantomData<&'d mut T>, rx_waker: WakerRegistration, @@ -26,16 +26,16 @@ struct StateInner<'d, T: Instance> { tx: RingBuffer<'d>, } -unsafe impl<'d, T: Instance> Send for StateInner<'d, T> {} -unsafe impl<'d, T: Instance> Sync for StateInner<'d, T> {} +unsafe impl<'d, T: BasicInstance> Send for StateInner<'d, T> {} +unsafe impl<'d, T: BasicInstance> Sync for StateInner<'d, T> {} -pub struct BufferedUart<'d, T: Instance> { +pub struct BufferedUart<'d, T: BasicInstance> { inner: PeripheralMutex<'d, StateInner<'d, T>>, } -impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {} +impl<'d, T: BasicInstance> Unpin for BufferedUart<'d, T> {} -impl<'d, T: Instance> BufferedUart<'d, T> { +impl<'d, T: BasicInstance> BufferedUart<'d, T> { pub fn new( state: &'d mut State<'d, T>, _uart: Uart<'d, T, NoDma, NoDma>, @@ -66,7 +66,7 @@ impl<'d, T: Instance> BufferedUart<'d, T> { } } -impl<'d, T: Instance> StateInner<'d, T> +impl<'d, T: BasicInstance> StateInner<'d, T> where Self: 'd, { @@ -135,7 +135,7 @@ where } } -impl<'d, T: Instance> PeripheralState for StateInner<'d, T> +impl<'d, T: BasicInstance> PeripheralState for StateInner<'d, T> where Self: 'd, { @@ -152,11 +152,11 @@ impl embedded_io::Error for Error { } } -impl<'d, T: Instance> embedded_io::Io for BufferedUart<'d, T> { +impl<'d, T: BasicInstance> embedded_io::Io for BufferedUart<'d, T> { type Error = Error; } -impl<'d, T: Instance> embedded_io::asynch::Read for BufferedUart<'d, T> { +impl<'d, T: BasicInstance> embedded_io::asynch::Read for BufferedUart<'d, T> { type ReadFuture<'a> = impl Future> where Self: 'a; @@ -194,7 +194,7 @@ impl<'d, T: Instance> embedded_io::asynch::Read for BufferedUart<'d, T> { } } -impl<'d, T: Instance> embedded_io::asynch::BufRead for BufferedUart<'d, T> { +impl<'d, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUart<'d, T> { type FillBufFuture<'a> = impl Future> where Self: 'a; @@ -231,7 +231,7 @@ impl<'d, T: Instance> embedded_io::asynch::BufRead for BufferedUart<'d, T> { } } -impl<'d, T: Instance> embedded_io::asynch::Write for BufferedUart<'d, T> { +impl<'d, T: BasicInstance> embedded_io::asynch::Write for BufferedUart<'d, T> { type WriteFuture<'a> = impl Future> where Self: 'a; diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index ca75bab41..511850971 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -6,9 +6,7 @@ use embassy_hal_common::{into_ref, PeripheralRef}; use crate::dma::NoDma; use crate::gpio::sealed::AFType; -use crate::interrupt::Interrupt; -use crate::pac::usart::{regs, vals}; -use crate::rcc::RccPeripheral; +use crate::pac::lpuart::{regs, vals}; use crate::{peripherals, Peripheral}; #[derive(Clone, Copy, PartialEq, Eq, Debug)] @@ -71,22 +69,23 @@ pub enum Error { Parity, } -pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> { +pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> { + phantom: PhantomData<&'d mut T>, tx: UartTx<'d, T, TxDma>, rx: UartRx<'d, T, RxDma>, } -pub struct UartTx<'d, T: Instance, TxDma = NoDma> { +pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> { phantom: PhantomData<&'d mut T>, tx_dma: PeripheralRef<'d, TxDma>, } -pub struct UartRx<'d, T: Instance, RxDma = NoDma> { +pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { phantom: PhantomData<&'d mut T>, rx_dma: PeripheralRef<'d, RxDma>, } -impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> { +impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { fn new(tx_dma: PeripheralRef<'d, TxDma>) -> Self { Self { tx_dma, @@ -132,7 +131,7 @@ impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> { } } -impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> { +impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { fn new(rx_dma: PeripheralRef<'d, RxDma>) -> Self { Self { rx_dma, @@ -187,7 +186,7 @@ impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> { } } -impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { +impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { pub fn new( _inner: impl Peripheral

+ 'd, rx: impl Peripheral

> + 'd, @@ -203,7 +202,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { let pclk_freq = T::frequency(); // TODO: better calculation, including error checking and OVER8 if possible. - let div = (pclk_freq.0 + (config.baudrate / 2)) / config.baudrate; + let div = (pclk_freq.0 + (config.baudrate / 2)) / config.baudrate * T::MULTIPLIER; let r = T::regs(); @@ -235,6 +234,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { Self { tx: UartTx::new(tx_dma), rx: UartRx::new(rx_dma), + phantom: PhantomData {}, } } @@ -275,7 +275,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { mod eh02 { use super::*; - impl<'d, T: Instance, RxDma> embedded_hal_02::serial::Read for UartRx<'d, T, RxDma> { + impl<'d, T: BasicInstance, RxDma> embedded_hal_02::serial::Read for UartRx<'d, T, RxDma> { type Error = Error; fn read(&mut self) -> Result> { let r = T::regs(); @@ -302,7 +302,7 @@ mod eh02 { } } - impl<'d, T: Instance, TxDma> embedded_hal_02::blocking::serial::Write for UartTx<'d, T, TxDma> { + impl<'d, T: BasicInstance, TxDma> embedded_hal_02::blocking::serial::Write for UartTx<'d, T, TxDma> { type Error = Error; fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { self.blocking_write(buffer) @@ -312,14 +312,14 @@ mod eh02 { } } - impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::serial::Read for Uart<'d, T, TxDma, RxDma> { + impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::serial::Read for Uart<'d, T, TxDma, RxDma> { type Error = Error; fn read(&mut self) -> Result> { embedded_hal_02::serial::Read::read(&mut self.rx) } } - impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write for Uart<'d, T, TxDma, RxDma> { + impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write for Uart<'d, T, TxDma, RxDma> { type Error = Error; fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { self.blocking_write(buffer) @@ -345,15 +345,15 @@ mod eh1 { } } - impl<'d, T: Instance, TxDma, RxDma> embedded_hal_1::serial::ErrorType for Uart<'d, T, TxDma, RxDma> { + impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_1::serial::ErrorType for Uart<'d, T, TxDma, RxDma> { type Error = Error; } - impl<'d, T: Instance, TxDma> embedded_hal_1::serial::ErrorType for UartTx<'d, T, TxDma> { + impl<'d, T: BasicInstance, TxDma> embedded_hal_1::serial::ErrorType for UartTx<'d, T, TxDma> { type Error = Error; } - impl<'d, T: Instance, RxDma> embedded_hal_1::serial::ErrorType for UartRx<'d, T, RxDma> { + impl<'d, T: BasicInstance, RxDma> embedded_hal_1::serial::ErrorType for UartRx<'d, T, RxDma> { type Error = Error; } } @@ -362,7 +362,7 @@ cfg_if::cfg_if! { if #[cfg(all(feature = "unstable-traits", feature = "nightly", feature = "_todo_embedded_hal_serial"))] { use core::future::Future; - impl<'d, T: Instance, TxDma> embedded_hal_async::serial::Write for UartTx<'d, T, TxDma> + impl<'d, T: UartInstance, TxDma> embedded_hal_async::serial::Write for UartTx<'d, T, TxDma> where TxDma: crate::usart::TxDma, { @@ -379,7 +379,7 @@ cfg_if::cfg_if! { } } - impl<'d, T: Instance, RxDma> embedded_hal_async::serial::Read for UartRx<'d, T, RxDma> + impl<'d, T: UartInstance, RxDma> embedded_hal_async::serial::Read for UartRx<'d, T, RxDma> where RxDma: crate::usart::RxDma, { @@ -390,7 +390,7 @@ cfg_if::cfg_if! { } } - impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma> + impl<'d, T: UartInstance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma> where TxDma: crate::usart::TxDma, { @@ -407,7 +407,7 @@ cfg_if::cfg_if! { } } - impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma> + impl<'d, T: UartInstance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma> where RxDma: crate::usart::RxDma, { @@ -447,55 +447,88 @@ unsafe fn clear_interrupt_flags(_r: crate::pac::usart::Usart, _sr: regs::Sr) { } #[cfg(usart_v2)] -fn tdr(r: crate::pac::usart::Usart) -> *mut u8 { +fn tdr(r: crate::pac::lpuart::Lpuart) -> *mut u8 { r.tdr().ptr() as _ } #[cfg(usart_v2)] -fn rdr(r: crate::pac::usart::Usart) -> *mut u8 { +fn rdr(r: crate::pac::lpuart::Lpuart) -> *mut u8 { r.rdr().ptr() as _ } #[cfg(usart_v2)] -fn sr(r: crate::pac::usart::Usart) -> crate::pac::common::Reg { +fn sr(r: crate::pac::lpuart::Lpuart) -> crate::pac::common::Reg { r.isr() } #[cfg(usart_v2)] #[allow(unused)] -unsafe fn clear_interrupt_flags(r: crate::pac::usart::Usart, sr: regs::Ixr) { - r.icr().write(|w| *w = sr); +unsafe fn clear_interrupt_flags(r: crate::pac::lpuart::Lpuart, sr: regs::Isr) { + r.icr().write(|w| *w = regs::Icr(sr.0)); } pub(crate) mod sealed { - pub trait Instance { - fn regs() -> crate::pac::usart::Usart; + + pub trait BasicInstance: crate::rcc::RccPeripheral { + const MULTIPLIER: u32; + type Interrupt: crate::interrupt::Interrupt; + + fn regs() -> crate::pac::lpuart::Lpuart; + } + + pub trait FullInstance: BasicInstance { + fn regs_uart() -> crate::pac::usart::Usart; } } -pub trait Instance: sealed::Instance + RccPeripheral { - type Interrupt: Interrupt; +pub trait BasicInstance: sealed::BasicInstance {} + +pub trait FullInstance: sealed::FullInstance {} + +pin_trait!(RxPin, BasicInstance); +pin_trait!(TxPin, BasicInstance); +pin_trait!(CtsPin, BasicInstance); +pin_trait!(RtsPin, BasicInstance); +pin_trait!(CkPin, BasicInstance); + +dma_trait!(TxDma, BasicInstance); +dma_trait!(RxDma, BasicInstance); + +macro_rules! impl_lpuart { + ($inst:ident, $irq:ident, $mul:expr) => { + impl sealed::BasicInstance for crate::peripherals::$inst { + const MULTIPLIER: u32 = $mul; + type Interrupt = crate::interrupt::$irq; + + fn regs() -> crate::pac::lpuart::Lpuart { + crate::pac::lpuart::Lpuart(crate::pac::$inst.0) + } + } + }; } -pin_trait!(RxPin, Instance); -pin_trait!(TxPin, Instance); -pin_trait!(CtsPin, Instance); -pin_trait!(RtsPin, Instance); -pin_trait!(CkPin, Instance); - -dma_trait!(TxDma, Instance); -dma_trait!(RxDma, Instance); - foreach_interrupt!( - ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { - impl sealed::Instance for peripherals::$inst { - fn regs() -> crate::pac::usart::Usart { + ($inst:ident, lpuart, LPUART, $signal_name:ident, $irq:ident) => { + impl_lpuart!($inst, $irq, 255); + + impl BasicInstance for peripherals::$inst { + } + }; + + ($inst:ident, usart, USART, $signal_name:ident, $irq:ident) => { + impl_lpuart!($inst, $irq, 1); + + impl BasicInstance for peripherals::$inst { + } + + impl sealed::FullInstance for peripherals::$inst { + + fn regs_uart() -> crate::pac::usart::Usart { crate::pac::$inst } } - impl Instance for peripherals::$inst { - type Interrupt = crate::interrupt::$irq; + impl FullInstance for peripherals::$inst { } }; ); diff --git a/stm32-data b/stm32-data index 758c9e746..f47995849 160000 --- a/stm32-data +++ b/stm32-data @@ -1 +1 @@ -Subproject commit 758c9e74625c68bc23d66ced8bfeb5643c63cec9 +Subproject commit f47995849a1a66cc92143ff94c84b11dc2701ccb