Merge pull request #2821 from embassy-rs/usart-nodma

stm32/usart: remove DMA generic params.
This commit is contained in:
Dario Nieuwenhuis 2024-04-16 00:05:43 +00:00 committed by GitHub
commit e38f1011d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 574 additions and 411 deletions

View File

@ -82,12 +82,12 @@ macro_rules! new_dma {
} }
macro_rules! new_pin { macro_rules! new_pin {
($name:ident, $aftype:expr, $speed:expr) => {{ ($name:ident, $aftype:expr) => {{
let pin = $name.into_ref(); new_pin!($name, $aftype, crate::gpio::Speed::Medium, crate::gpio::Pull::None)
pin.set_as_af(pin.af_num(), $aftype);
pin.set_speed($speed);
Some(pin.map_into())
}}; }};
($name:ident, $aftype:expr, $speed:expr) => {
new_pin!($name, $aftype, $speed, crate::gpio::Pull::None)
};
($name:ident, $aftype:expr, $speed:expr, $pull:expr) => {{ ($name:ident, $aftype:expr, $speed:expr, $pull:expr) => {{
let pin = $name.into_ref(); let pin = $name.into_ref();
pin.set_as_af_pull(pin.af_num(), $aftype, $pull); pin.set_as_af_pull(pin.af_num(), $aftype, $pull);

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,22 @@
use core::future::poll_fn; use core::future::poll_fn;
use core::marker::PhantomData;
use core::mem; use core::mem;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_internal::PeripheralRef;
use futures::future::{select, Either}; use futures::future::{select, Either};
use super::{clear_interrupt_flags, rdr, reconfigure, sr, BasicInstance, Config, ConfigError, Error, UartRx}; use super::{clear_interrupt_flags, rdr, reconfigure, sr, BasicInstance, Config, ConfigError, Error, UartRx};
use crate::dma::ReadableRingBuffer; use crate::dma::ReadableRingBuffer;
use crate::mode::Async;
use crate::usart::{Regs, Sr}; use crate::usart::{Regs, Sr};
/// Rx-only Ring-buffered UART Driver /// Rx-only Ring-buffered UART Driver
/// ///
/// Created with [UartRx::into_ring_buffered] /// Created with [UartRx::into_ring_buffered]
pub struct RingBufferedUartRx<'d, T: BasicInstance> { pub struct RingBufferedUartRx<'d, T: BasicInstance> {
_peri: PeripheralRef<'d, T>, _phantom: PhantomData<T>,
ring_buf: ReadableRingBuffer<'d, u8>, ring_buf: ReadableRingBuffer<'d, u8>,
} }
@ -28,26 +29,29 @@ impl<'d, T: BasicInstance> SetConfig for RingBufferedUartRx<'d, T> {
} }
} }
impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> { impl<'d, T: BasicInstance> UartRx<'d, T, Async> {
/// Turn the `UartRx` into a buffered uart which can continously receive in the background /// Turn the `UartRx` into a buffered uart which can continously receive in the background
/// without the possibility of losing bytes. The `dma_buf` is a buffer registered to the /// without the possibility of losing bytes. The `dma_buf` is a buffer registered to the
/// DMA controller, and must be large enough to prevent overflows. /// DMA controller, and must be large enough to prevent overflows.
pub fn into_ring_buffered(self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d, T> { pub fn into_ring_buffered(mut self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d, T> {
assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
let request = self.rx_dma.request();
let opts = Default::default(); let opts = Default::default();
// Safety: we forget the struct before this function returns. // Safety: we forget the struct before this function returns.
let rx_dma = unsafe { self.rx_dma.clone_unchecked() }; let rx_dma = self.rx_dma.as_mut().unwrap();
let _peri = unsafe { self._peri.clone_unchecked() }; let request = rx_dma.request;
let rx_dma = unsafe { rx_dma.channel.clone_unchecked() };
let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(T::regs()), dma_buf, opts) }; let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(T::regs()), dma_buf, opts) };
// Don't disable the clock // Don't disable the clock
mem::forget(self); mem::forget(self);
RingBufferedUartRx { _peri, ring_buf } RingBufferedUartRx {
_phantom: PhantomData,
ring_buf,
}
} }
} }

View File

@ -5,7 +5,6 @@ use core::fmt::Write;
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use heapless::String; use heapless::String;
@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!"); info!("Hello World!");
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.USART1, p.PE1, p.PE0, Irqs, p.DMA1_CH4, NoDma, config).unwrap(); let mut usart = Uart::new(p.USART1, p.PE1, p.PE0, Irqs, p.DMA1_CH4, p.DMA1_CH5, config).unwrap();
for n in 0u32.. { for n in 0u32.. {
let mut s: String<128> = String::new(); let mut s: String<128> = String::new();

View File

@ -3,7 +3,6 @@
use cortex_m_rt::entry; use cortex_m_rt::entry;
use defmt::*; use defmt::*;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
@ -19,7 +18,7 @@ fn main() -> ! {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, NoDma, NoDma, config).unwrap(); let mut usart = Uart::new_blocking(p.USART3, p.PD9, p.PD8, config).unwrap();
unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n"));
info!("wrote Hello, starting echo"); info!("wrote Hello, starting echo");

View File

@ -5,7 +5,6 @@ use core::fmt::Write;
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use heapless::String; use heapless::String;
@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!"); info!("Hello World!");
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, p.DMA1_CH3, NoDma, config).unwrap(); let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, p.DMA1_CH3, p.DMA1_CH1, config).unwrap();
for n in 0u32.. { for n in 0u32.. {
let mut s: String<128> = String::new(); let mut s: String<128> = String::new();

View File

@ -5,7 +5,6 @@ use core::fmt::Write;
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use heapless::String; use heapless::String;
@ -19,7 +18,7 @@ bind_interrupts!(struct Irqs {
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.UART7, p.PA8, p.PA15, Irqs, p.DMA1_CH1, NoDma, config).unwrap(); let mut usart = Uart::new(p.UART7, p.PA8, p.PA15, Irqs, p.DMA1_CH1, p.DMA1_CH3, config).unwrap();
for n in 0u32.. { for n in 0u32.. {
let mut s: String<128> = String::new(); let mut s: String<128> = String::new();

View File

@ -4,22 +4,16 @@
use cortex_m_rt::entry; use cortex_m_rt::entry;
use defmt::*; use defmt::*;
use embassy_executor::Executor; use embassy_executor::Executor;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart};
use static_cell::StaticCell; use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
UART7 => usart::InterruptHandler<peripherals::UART7>;
});
#[embassy_executor::task] #[embassy_executor::task]
async fn main_task() { async fn main_task() {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, NoDma, NoDma, config).unwrap(); let mut usart = Uart::new_blocking(p.UART7, p.PF6, p.PF7, config).unwrap();
unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n"));
info!("wrote Hello, starting echo"); info!("wrote Hello, starting echo");

View File

@ -6,7 +6,6 @@ use core::fmt::Write;
use cortex_m_rt::entry; use cortex_m_rt::entry;
use defmt::*; use defmt::*;
use embassy_executor::Executor; use embassy_executor::Executor;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use heapless::String; use heapless::String;
@ -22,7 +21,7 @@ async fn main_task() {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, NoDma, config).unwrap(); let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1, config).unwrap();
for n in 0u32.. { for n in 0u32.. {
let mut s: String<128> = String::new(); let mut s: String<128> = String::new();

View File

@ -3,8 +3,8 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::dma::NoDma; use embassy_stm32::mode::Async;
use embassy_stm32::peripherals::{GPDMA1_CH1, UART7}; use embassy_stm32::peripherals::UART7;
use embassy_stm32::usart::{Config, Uart, UartRx}; use embassy_stm32::usart::{Config, Uart, UartRx};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
@ -15,18 +15,6 @@ bind_interrupts!(struct Irqs {
UART7 => usart::InterruptHandler<peripherals::UART7>; UART7 => usart::InterruptHandler<peripherals::UART7>;
}); });
#[embassy_executor::task]
async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) {
unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n"));
info!("wrote Hello, starting echo");
let mut buf = [0u8; 1];
loop {
unwrap!(usart.blocking_read(&mut buf));
unwrap!(usart.blocking_write(&buf));
}
}
static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
#[embassy_executor::main] #[embassy_executor::main]
@ -50,7 +38,7 @@ async fn main(spawner: Spawner) -> ! {
} }
#[embassy_executor::task] #[embassy_executor::task]
async fn reader(mut rx: UartRx<'static, UART7, GPDMA1_CH1>) { async fn reader(mut rx: UartRx<'static, UART7, Async>) {
let mut buf = [0; 8]; let mut buf = [0; 8];
loop { loop {
info!("reading..."); info!("reading...");

View File

@ -4,22 +4,16 @@
use cortex_m_rt::entry; use cortex_m_rt::entry;
use defmt::*; use defmt::*;
use embassy_executor::Executor; use embassy_executor::Executor;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart};
use static_cell::StaticCell; use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
UART7 => usart::InterruptHandler<peripherals::UART7>;
});
#[embassy_executor::task] #[embassy_executor::task]
async fn main_task() { async fn main_task() {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, NoDma, NoDma, config).unwrap(); let mut usart = Uart::new_blocking(p.UART7, p.PF6, p.PF7, config).unwrap();
unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n"));
info!("wrote Hello, starting echo"); info!("wrote Hello, starting echo");

View File

@ -6,7 +6,6 @@ use core::fmt::Write;
use cortex_m_rt::entry; use cortex_m_rt::entry;
use defmt::*; use defmt::*;
use embassy_executor::Executor; use embassy_executor::Executor;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use heapless::String; use heapless::String;
@ -22,7 +21,7 @@ async fn main_task() {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.DMA1_CH0, NoDma, config).unwrap(); let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.DMA1_CH0, p.DMA1_CH1, config).unwrap();
for n in 0u32.. { for n in 0u32.. {
let mut s: String<128> = String::new(); let mut s: String<128> = String::new();

View File

@ -3,8 +3,8 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::dma::NoDma; use embassy_stm32::mode::Async;
use embassy_stm32::peripherals::{DMA1_CH1, UART7}; use embassy_stm32::peripherals::UART7;
use embassy_stm32::usart::{Config, Uart, UartRx}; use embassy_stm32::usart::{Config, Uart, UartRx};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
@ -15,18 +15,6 @@ bind_interrupts!(struct Irqs {
UART7 => usart::InterruptHandler<peripherals::UART7>; UART7 => usart::InterruptHandler<peripherals::UART7>;
}); });
#[embassy_executor::task]
async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) {
unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n"));
info!("wrote Hello, starting echo");
let mut buf = [0u8; 1];
loop {
unwrap!(usart.blocking_read(&mut buf));
unwrap!(usart.blocking_write(&buf));
}
}
static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
#[embassy_executor::main] #[embassy_executor::main]
@ -50,7 +38,7 @@ async fn main(spawner: Spawner) -> ! {
} }
#[embassy_executor::task] #[embassy_executor::task]
async fn reader(mut rx: UartRx<'static, UART7, DMA1_CH1>) { async fn reader(mut rx: UartRx<'static, UART7, Async>) {
let mut buf = [0; 8]; let mut buf = [0; 8];
loop { loop {
info!("reading..."); info!("reading...");

View File

@ -2,7 +2,6 @@
#![no_main] #![no_main]
use defmt::*; use defmt::*;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
@ -18,7 +17,7 @@ fn main() -> ! {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, NoDma, NoDma, config).unwrap(); let mut usart = Uart::new_blocking(p.UART4, p.PA1, p.PA0, config).unwrap();
unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n"));
info!("wrote Hello, starting echo"); info!("wrote Hello, starting echo");

View File

@ -5,7 +5,6 @@ use core::fmt::Write;
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, Uart}; use embassy_stm32::usart::{Config, Uart};
use embassy_stm32::{bind_interrupts, peripherals, usart}; use embassy_stm32::{bind_interrupts, peripherals, usart};
use heapless::String; use heapless::String;
@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!"); info!("Hello World!");
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, p.DMA1_CH3, NoDma, config).unwrap(); let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, p.DMA1_CH3, p.DMA1_CH4, config).unwrap();
for n in 0u32.. { for n in 0u32.. {
let mut s: String<128> = String::new(); let mut s: String<128> = String::new();

View File

@ -6,7 +6,6 @@ mod common;
use common::*; use common::*;
use defmt::{assert, assert_eq, unreachable}; use defmt::{assert, assert_eq, unreachable};
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; use embassy_stm32::usart::{Config, ConfigError, Error, Uart};
use embassy_time::{block_for, Duration, Instant}; use embassy_time::{block_for, Duration, Instant};
@ -20,11 +19,10 @@ async fn main(_spawner: Spawner) {
let mut usart = peri!(p, UART); let mut usart = peri!(p, UART);
let mut rx = peri!(p, UART_RX); let mut rx = peri!(p, UART_RX);
let mut tx = peri!(p, UART_TX); let mut tx = peri!(p, UART_TX);
let irq = irqs!(UART);
{ {
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config).unwrap(); let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap();
// We can't send too many bytes, they have to fit in the FIFO. // We can't send too many bytes, they have to fit in the FIFO.
// This is because we aren't sending+receiving at the same time. // This is because we aren't sending+receiving at the same time.
@ -40,7 +38,7 @@ async fn main(_spawner: Spawner) {
// Test error handling with with an overflow error // Test error handling with with an overflow error
{ {
let config = Config::default(); let config = Config::default();
let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config).unwrap(); let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap();
// Send enough bytes to fill the RX FIFOs off all USART versions. // Send enough bytes to fill the RX FIFOs off all USART versions.
let data = [0; 64]; let data = [0; 64];
@ -70,7 +68,7 @@ async fn main(_spawner: Spawner) {
let mut config = Config::default(); let mut config = Config::default();
config.baudrate = baudrate; config.baudrate = baudrate;
let mut usart = match Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config) { let mut usart = match Uart::new_blocking(&mut usart, &mut rx, &mut tx, config) {
Ok(x) => x, Ok(x) => x,
Err(ConfigError::BaudrateTooHigh) => { Err(ConfigError::BaudrateTooHigh) => {
info!("baudrate too high"); info!("baudrate too high");

View File

@ -8,6 +8,7 @@ mod common;
use common::*; use common::*;
use defmt::{assert_eq, panic}; use defmt::{assert_eq, panic};
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::mode::Async;
use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx}; use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx};
use embassy_time::Timer; use embassy_time::Timer;
use rand_chacha::ChaCha8Rng; use rand_chacha::ChaCha8Rng;
@ -51,7 +52,7 @@ async fn main(spawner: Spawner) {
} }
#[embassy_executor::task] #[embassy_executor::task]
async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) { async fn transmit_task(mut tx: UartTx<'static, peris::UART, Async>) {
// workaround https://github.com/embassy-rs/embassy/issues/1426 // workaround https://github.com/embassy-rs/embassy/issues/1426
Timer::after_millis(100).await; Timer::after_millis(100).await;