summaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorVincent Stakenburg <v.stakenburg@cosinuss.nl>2022-06-09 15:17:03 +0200
committerVincent Stakenburg <v.stakenburg@cosinuss.nl>2022-08-19 12:05:19 +0200
commita833e02363dac8ba5b9a421804acc8b2b6bd751c (patch)
tree429ebb6f152311d23a5ffd828a0c1273cdff0d7a /embassy-stm32
parentaefa5275a2ab2cac6caef599e7adb76ce1beeddd (diff)
downloadembassy-a833e02363dac8ba5b9a421804acc8b2b6bd751c.zip
implement support for LPUART
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/build.rs12
-rw-r--r--embassy-stm32/src/usart/buffered.rs28
-rw-r--r--embassy-stm32/src/usart/mod.rs119
3 files changed, 97 insertions, 62 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index c892007a..a4709f4c 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 0e8d0d68..ec2231e4 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<StateInner<'d, T>>);
-impl<'d, T: Instance> State<'d, T> {
+pub struct State<'d, T: BasicInstance>(StateStorage<StateInner<'d, T>>);
+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<Output = Result<usize, Self::Error>>
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<Output = Result<&'a [u8], Self::Error>>
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<Output = Result<usize, Self::Error>>
where
Self: 'a;
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index ca75bab4..51185097 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<P = T> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + '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<u8> for UartRx<'d, T, RxDma> {
+ impl<'d, T: BasicInstance, RxDma> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, RxDma> {
type Error = Error;
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
let r = T::regs();
@@ -302,7 +302,7 @@ mod eh02 {
}
}
- impl<'d, T: Instance, TxDma> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, TxDma> {
+ impl<'d, T: BasicInstance, TxDma> embedded_hal_02::blocking::serial::Write<u8> 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<u8> for Uart<'d, T, TxDma, RxDma> {
+ impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::serial::Read<u8> for Uart<'d, T, TxDma, RxDma> {
type Error = Error;
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
embedded_hal_02::serial::Read::read(&mut self.rx)
}
}
- impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, TxDma, RxDma> {
+ impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write<u8> 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<T>,
{
@@ -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<T>,
{
@@ -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<T>,
{
@@ -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<T>,
{
@@ -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<regs::Ixr, crate::pac::common::R> {
+fn sr(r: crate::pac::lpuart::Lpuart) -> crate::pac::common::Reg<regs::Isr, crate::pac::common::R> {
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 Instance: sealed::Instance + RccPeripheral {
- type Interrupt: Interrupt;
+ pub trait FullInstance: BasicInstance {
+ fn regs_uart() -> crate::pac::usart::Usart;
+ }
}
-pin_trait!(RxPin, Instance);
-pin_trait!(TxPin, Instance);
-pin_trait!(CtsPin, Instance);
-pin_trait!(RtsPin, Instance);
-pin_trait!(CkPin, Instance);
+pub trait BasicInstance: sealed::BasicInstance {}
-dma_trait!(TxDma, Instance);
-dma_trait!(RxDma, Instance);
+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)
+ }
+ }
+ };
+}
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 {
}
};
);