summaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorBob McWhirter <bmcwhirt@redhat.com>2021-07-08 14:55:27 -0400
committerBob McWhirter <bmcwhirt@redhat.com>2021-07-13 10:09:35 -0400
commitf01ddd5f5c2ec9505037663db8b1d54d7c153b0f (patch)
treef379fb7dccd2530dca2c0b613358ff3ec042ca3a /embassy-stm32
parent6ec725309580b86889cf3d10070a1f18046182a0 (diff)
downloadembassy-f01ddd5f5c2ec9505037663db8b1d54d7c153b0f.zip
Mix dmamux into bdma_v1.
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/bdma/mod.rs22
-rw-r--r--embassy-stm32/src/bdma/v1.rs90
-rw-r--r--embassy-stm32/src/dma/mod.rs23
-rw-r--r--embassy-stm32/src/dma/v2.rs1
-rw-r--r--embassy-stm32/src/dma_traits.rs21
-rw-r--r--embassy-stm32/src/dmamux/mod.rs216
-rw-r--r--embassy-stm32/src/lib.rs5
-rw-r--r--embassy-stm32/src/usart/mod.rs7
8 files changed, 138 insertions, 247 deletions
diff --git a/embassy-stm32/src/bdma/mod.rs b/embassy-stm32/src/bdma/mod.rs
index 1a49f4e1..ae7e9d23 100644
--- a/embassy-stm32/src/bdma/mod.rs
+++ b/embassy-stm32/src/bdma/mod.rs
@@ -6,25 +6,3 @@ mod _version;
#[allow(unused)]
pub use _version::*;
-
-use core::future::Future;
-
-pub trait WriteDma<T> {
- type WriteDmaFuture<'a>: Future<Output = ()> + 'a
- where
- Self: 'a;
-
- fn transfer<'a>(&'a mut self, buf: &'a [u8], dst: *mut u8) -> Self::WriteDmaFuture<'a>
- where
- T: 'a;
-}
-
-pub trait ReadDma<T> {
- type ReadDmaFuture<'a>: Future<Output = ()> + 'a
- where
- Self: 'a;
-
- fn transfer<'a>(&'a mut self, src: *const u8, buf: &'a mut [u8]) -> Self::ReadDmaFuture<'a>
- where
- T: 'a;
-}
diff --git a/embassy-stm32/src/bdma/v1.rs b/embassy-stm32/src/bdma/v1.rs
index f81a0876..fd3bf699 100644
--- a/embassy-stm32/src/bdma/v1.rs
+++ b/embassy-stm32/src/bdma/v1.rs
@@ -6,10 +6,11 @@ use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::util::{AtomicWaker, OnDrop};
use futures::future::poll_fn;
-use super::{ReadDma, WriteDma};
+use crate::dma_traits::{ReadDma, WriteDma};
use crate::interrupt;
use crate::pac;
use crate::pac::bdma::vals;
+use crate::rcc::sealed::RccPeripheral;
const CH_COUNT: usize = pac::peripheral_count!(DMA) * 8;
const CH_STATUS_NONE: u8 = 0;
@@ -57,6 +58,9 @@ pub(crate) async unsafe fn transfer_p2m(
while regs.cr().read().en() {}
});
+ #[cfg(dmamux)]
+ crate::dmamux::configure_channel(1, 2);
+
regs.par().write_value(src as u32);
regs.mar().write_value(dst.as_mut_ptr() as u32);
regs.ndtr().write(|w| w.set_ndt(dst.len() as u16));
@@ -88,6 +92,9 @@ pub(crate) async unsafe fn transfer_m2p(
state_number: usize,
src: &[u8],
dst: *mut u8,
+ #[cfg(dmamux)] dmamux_regs: &'static pac::dmamux::Dmamux,
+ #[cfg(dmamux)] dmamux_ch_num: u8,
+ #[cfg(dmamux)] request: u8,
) {
// ndtr is max 16 bits.
assert!(src.len() <= 0xFFFF);
@@ -105,6 +112,9 @@ pub(crate) async unsafe fn transfer_m2p(
while regs.cr().read().en() {}
});
+ #[cfg(dmamux)]
+ crate::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request);
+
regs.par().write_value(dst as u32);
regs.mar().write_value(src.as_ptr() as u32);
regs.ndtr().write(|w| w.set_ndt(src.len() as u16));
@@ -161,9 +171,10 @@ pub(crate) unsafe fn init() {
}
pac::peripherals! {
(bdma, DMA1) => {
- critical_section::with(|_| {
- pac::RCC.ahbenr().modify(|w| w.set_dmaen(true));
- });
+ //critical_section::with(|_| {
+ //pac::RCC.ahbenr().modify(|w| w.set_dmaen(true));
+ //});
+ crate::peripherals::DMA1::enable();
};
}
}
@@ -220,8 +231,10 @@ macro_rules! impl_dma_channel {
}
}
+ #[cfg(not(dmamux))]
impl<T> WriteDma<T> for crate::peripherals::$channel_peri
where
+ Self: crate::dmamux::sealed::PeripheralChannel<T, crate::dmamux::M2P>,
T: 'static,
{
type WriteDmaFuture<'a> = impl Future<Output = ()>;
@@ -234,10 +247,47 @@ macro_rules! impl_dma_channel {
let state_num = self.state_num();
let regs = self.regs();
+
unsafe { transfer_m2p(regs, state_num, buf, dst) }
}
}
+ #[cfg(dmamux)]
+ impl<T> WriteDma<T> for crate::peripherals::$channel_peri
+ where
+ Self: crate::dmamux::sealed::PeripheralChannel<T, crate::dmamux::M2P>,
+ T: 'static,
+ {
+ type WriteDmaFuture<'a> = impl Future<Output = ()>;
+
+ fn transfer<'a>(&'a mut self, buf: &'a [u8], dst: *mut u8) -> Self::WriteDmaFuture<'a>
+ where
+ T: 'a,
+ {
+ use sealed::Channel as _Channel;
+
+ let state_num = self.state_num();
+ let regs = self.regs();
+
+ use crate::dmamux::sealed::Channel as _MuxChannel;
+ use crate::dmamux::sealed::PeripheralChannel;
+ let dmamux_regs = self.dmamux_regs();
+ let dmamux_ch_num = self.dma_ch_num();
+ let request = PeripheralChannel::<T, crate::dmamux::M2P>::request(self);
+ unsafe {
+ transfer_m2p(
+ regs,
+ state_num,
+ buf,
+ dst,
+ dmamux_regs,
+ dmamux_ch_num,
+ request,
+ )
+ }
+ }
+ }
+
impl<T> ReadDma<T> for crate::peripherals::$channel_peri
where
T: 'static,
@@ -292,6 +342,8 @@ pac::interrupts! {
#[cfg(usart)]
use crate::usart;
+
+#[cfg(not(dmamux))]
pac::peripheral_dma_channels! {
($peri:ident, usart, $kind:ident, RX, $channel_peri:ident, $dma_peri:ident, $channel_num:expr) => {
impl usart::RxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
@@ -302,4 +354,34 @@ pac::peripheral_dma_channels! {
impl usart::TxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
impl usart::sealed::TxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
};
+
+ ($peri:ident, uart, $kind:ident, RX, $channel_peri:ident, $dma_peri:ident, $channel_num:expr) => {
+ impl usart::RxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
+ impl usart::sealed::RxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
+ };
+
+ ($peri:ident, uart, $kind:ident, TX, $channel_peri:ident, $dma_peri:ident, $channel_num:expr) => {
+ impl usart::TxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
+ impl usart::sealed::TxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
+ };
+}
+
+#[cfg(dmamux)]
+pac::peripherals! {
+ (usart, $peri:ident) => {
+ pac::dma_channels! {
+ ($channel_peri:ident, $dma_peri:ident, $channel_num:expr) => {
+ impl usart::TxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
+ impl usart::sealed::TxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
+ };
+ }
+ };
+ (uart, $peri:ident) => {
+ pac::dma_channels! {
+ ($channel_peri:ident, $dma_peri:ident, $channel_num:expr) => {
+ impl usart::TxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
+ impl usart::sealed::TxDma<crate::peripherals::$peri> for crate::peripherals::$channel_peri { }
+ };
+ }
+ };
}
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 466cfa03..ed080cd1 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -1,6 +1,5 @@
#![macro_use]
-#[cfg(dma)]
#[cfg_attr(dma_v1, path = "v1.rs")]
#[cfg_attr(dma_v2, path = "v2.rs")]
mod _version;
@@ -8,25 +7,3 @@ mod _version;
#[cfg(dma)]
#[allow(unused)]
pub use _version::*;
-
-use core::future::Future;
-
-pub trait WriteDma<T> {
- type WriteDmaFuture<'a>: Future<Output = ()> + 'a
- where
- Self: 'a;
-
- fn transfer<'a>(&'a mut self, buf: &'a [u8], dst: *mut u8) -> Self::WriteDmaFuture<'a>
- where
- T: 'a;
-}
-
-pub trait ReadDma<T> {
- type ReadDmaFuture<'a>: Future<Output = ()> + 'a
- where
- Self: 'a;
-
- fn transfer<'a>(&'a mut self, src: *const u8, buf: &'a mut [u8]) -> Self::ReadDmaFuture<'a>
- where
- T: 'a;
-}
diff --git a/embassy-stm32/src/dma/v2.rs b/embassy-stm32/src/dma/v2.rs
index e7cd2471..5080776f 100644
--- a/embassy-stm32/src/dma/v2.rs
+++ b/embassy-stm32/src/dma/v2.rs
@@ -1,5 +1,6 @@
use core::task::Poll;
+use crate::dma_traits::{ReadDma, WriteDma};
use atomic_polyfill::{AtomicU8, Ordering};
use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::util::AtomicWaker;
diff --git a/embassy-stm32/src/dma_traits.rs b/embassy-stm32/src/dma_traits.rs
new file mode 100644
index 00000000..8f1a9f40
--- /dev/null
+++ b/embassy-stm32/src/dma_traits.rs
@@ -0,0 +1,21 @@
+use core::future::Future;
+
+pub trait WriteDma<T> {
+ type WriteDmaFuture<'a>: Future<Output = ()> + 'a
+ where
+ Self: 'a;
+
+ fn transfer<'a>(&'a mut self, buf: &'a [u8], dst: *mut u8) -> Self::WriteDmaFuture<'a>
+ where
+ T: 'a;
+}
+
+pub trait ReadDma<T> {
+ type ReadDmaFuture<'a>: Future<Output = ()> + 'a
+ where
+ Self: 'a;
+
+ fn transfer<'a>(&'a mut self, src: *const u8, buf: &'a mut [u8]) -> Self::ReadDmaFuture<'a>
+ where
+ T: 'a;
+}
diff --git a/embassy-stm32/src/dmamux/mod.rs b/embassy-stm32/src/dmamux/mod.rs
index b4d5b983..745906cd 100644
--- a/embassy-stm32/src/dmamux/mod.rs
+++ b/embassy-stm32/src/dmamux/mod.rs
@@ -20,41 +20,11 @@ use crate::peripherals;
use core::future::Future;
-use crate::dma::{ReadDma, WriteDma};
+use crate::dma_traits::{ReadDma, WriteDma};
-const CH_COUNT: usize = peripheral_count!(DMA) * 8;
-const CH_STATUS_NONE: u8 = 0;
-const CH_STATUS_COMPLETED: u8 = 1;
-const CH_STATUS_ERROR: u8 = 2;
-
-struct State {
- ch_wakers: [AtomicWaker; CH_COUNT],
- ch_status: [AtomicU8; CH_COUNT],
-}
-
-impl State {
- const fn new() -> Self {
- const AW: AtomicWaker = AtomicWaker::new();
- const AU: AtomicU8 = AtomicU8::new(CH_STATUS_NONE);
- Self {
- ch_wakers: [AW; CH_COUNT],
- ch_status: [AU; CH_COUNT],
- }
- }
-}
-
-static STATE: State = State::new();
-
-#[allow(unused)]
-pub(crate) async unsafe fn transfer_p2m(
- ch: &mut impl Channel,
- ch_func: u8,
- src: *const u8,
- dst: &mut [u8],
-) {
- unimplemented!()
-}
+pub(crate) fn configure_channel(ch_num: u8, request_num: u8) {}
+/*
#[allow(unused)]
pub(crate) async unsafe fn transfer_m2p(
ch: &mut impl Channel,
@@ -128,22 +98,36 @@ pub(crate) async unsafe fn transfer_m2p(
// TODO handle error
assert!(res == CH_STATUS_COMPLETED);
}
+ */
+
+pub(crate) unsafe fn configure_dmamux(
+ dmamux_regs: &pac::dmamux::Dmamux,
+ dmamux_ch_num: u8,
+ request: u8,
+) {
+ let ch_mux_regs = dmamux_regs.ccr(dmamux_ch_num as _);
+ ch_mux_regs.write(|reg| {
+ // one request?
+ reg.set_nbreq(0);
+ reg.set_dmareq_id(request);
+ });
+
+ ch_mux_regs.modify(|reg| {
+ reg.set_ege(true);
+ //reg.set_se(true);
+ //reg.set_soie(true);
+ });
+}
pub(crate) mod sealed {
use super::*;
- pub trait Bdma {
- fn regs() -> &'static pac::bdma::Dma;
- fn num() -> u8;
- }
-
pub trait DmaMux {
fn regs() -> &'static pac::dmamux::Dmamux;
}
pub trait Channel {
fn num(&self) -> usize;
- fn regs(&self) -> pac::bdma::Ch;
fn dma_regs() -> &'static pac::bdma::Dma;
fn dma_ch_num(&self) -> u8;
@@ -156,7 +140,6 @@ pub(crate) mod sealed {
}
}
-pub trait Bdma: sealed::Bdma {}
pub trait DmaMux: sealed::DmaMux {}
pub trait Channel: sealed::Channel {}
pub trait PeripheralChannel<PERI, OP>: sealed::Channel {}
@@ -172,10 +155,6 @@ macro_rules! impl_dma_channel {
($dma_num * 8) + $channel_num
}
- fn regs(&self) -> pac::bdma::Ch {
- Self::dma_regs().ch(self.dma_ch_num() as _)
- }
-
fn dma_regs() -> &'static pac::bdma::Dma {
&crate::pac::$dma_peri
}
@@ -192,42 +171,6 @@ macro_rules! impl_dma_channel {
($dma_num * 8) + $channel_num
}
}
-
- impl<T> WriteDma<T> for peripherals::$channel_peri
- where
- Self: sealed::PeripheralChannel<T, M2P>,
- T: 'static,
- {
- type WriteDmaFuture<'a> = impl Future<Output = ()>;
-
- fn transfer<'a>(&'a mut self, buf: &'a [u8], dst: *mut u8) -> Self::WriteDmaFuture<'a>
- where
- T: 'a,
- {
- let request = sealed::PeripheralChannel::<T, M2P>::request(self);
- unsafe { transfer_m2p(self, request, buf, dst) }
- }
- }
-
- impl<T> ReadDma<T> for peripherals::$channel_peri
- where
- Self: sealed::PeripheralChannel<T, P2M>,
- T: 'static,
- {
- type ReadDmaFuture<'a> = impl Future<Output = ()>;
-
- fn transfer<'a>(
- &'a mut self,
- src: *const u8,
- buf: &'a mut [u8],
- ) -> Self::ReadDmaFuture<'a>
- where
- T: 'a,
- {
- let request = sealed::PeripheralChannel::<T, P2M>::request(self);
- unsafe { transfer_p2m(self, request, src, buf) }
- }
- }
};
}
@@ -242,25 +185,8 @@ macro_rules! impl_dmamux {
};
}
-macro_rules! impl_bdma {
- ($peri:ident, $dma_num:expr) => {
- impl sealed::Bdma for peripherals::$peri {
- fn num() -> u8 {
- $dma_num
- }
-
- fn regs() -> &'static pac::bdma::Dma {
- &pac::$peri
- }
- }
-
- impl Bdma for peripherals::$peri {}
- };
-}
-
peripherals! {
(bdma, DMA1) => {
- impl_bdma!(DMA1, 0);
dma_channels! {
($channel_peri:ident, DMA1, $channel_num:expr) => {
impl_dma_channel!($channel_peri, DMAMUX1, $channel_num, DMA1, 0);
@@ -268,7 +194,6 @@ peripherals! {
}
};
(bdma, DMA2) => {
- impl_bdma!(DMA2, 1);
dma_channels! {
($channel_peri:ident, DMA2, $channel_num:expr) => {
impl_dma_channel!($channel_peri, DMAMUX1, $channel_num, DMA2, 1);
@@ -285,9 +210,6 @@ macro_rules! impl_usart_dma_requests {
dma_requests! {
// TODO: DRY this up.
(usart, $peri:ident, RX, $request:expr) => {
- impl usart::RxDma<peripherals::$peri> for peripherals::$channel_peri { }
- impl usart::sealed::RxDma<peripherals::$peri> for peripherals::$channel_peri { }
-
impl sealed::PeripheralChannel<peripherals::$peri, P2M> for peripherals::$channel_peri {
fn request(&self) -> u8 {
$request
@@ -299,9 +221,6 @@ macro_rules! impl_usart_dma_requests {
};
(usart, $peri:ident, TX, $request:expr) => {
- impl usart::TxDma<peripherals::$peri> for peripherals::$channel_peri { }
- impl usart::sealed::TxDma<peripherals::$peri> for peripherals::$channel_peri { }
-
impl sealed::PeripheralChannel<peripherals::$peri, M2P> for peripherals::$channel_peri {
fn request(&self) -> u8 {
$request
@@ -313,9 +232,6 @@ macro_rules! impl_usart_dma_requests {
};
(uart, $peri:ident, TX, $request:expr) => {
- impl usart::RxDma<peripherals::$peri> for peripherals::$channel_peri { }
- impl usart::sealed::RxDma<peripherals::$peri> for peripherals::$channel_peri { }
-
impl sealed::PeripheralChannel<peripherals::$peri, P2M> for peripherals::$channel_peri {
fn request(&self) -> u8 {
$request
@@ -326,9 +242,6 @@ macro_rules! impl_usart_dma_requests {
};
(uart, $peri:ident, RX, $request:expr) => {
- impl usart::TxDma<peripherals::$peri> for peripherals::$channel_peri { }
- impl usart::sealed::TxDma<peripherals::$peri> for peripherals::$channel_peri { }
-
impl sealed::PeripheralChannel<peripherals::$peri, M2P> for peripherals::$channel_peri {
fn request(&self) -> u8 {
$request
@@ -351,86 +264,5 @@ dma_channels! {
};
}
-unsafe fn on_irq() {
- defmt::info!("irq fire");
- peripherals! {
- //(bdma, $dma:ident) => {
- (bdma, DMA1) => {
- defmt::info!("---> dma DMA1");
- //for isrn in 0..2 {
- //let isr = pac::$dma.isr(isrn).read();
- let isr = pac::DMA1.isr().read();
- pac::DMA1.ifcr().write_value(isr);
- let dman = <peripherals::DMA1 as sealed::Bdma>::num() as usize;
-
- for chn in 0..8 {
- let n = dman * 8 + chn;
- defmt::info!("n={}", n);
- if isr.teif(chn) {
- defmt::info!("transfer error");
- STATE.ch_status[n].store(CH_STATUS_ERROR, Ordering::Release);
- STATE.ch_wakers[n].wake();
- } else if isr.tcif(chn) {
- defmt::info!("transfer complete");
- STATE.ch_status[n].store(CH_STATUS_COMPLETED, Ordering::Release);
- STATE.ch_wakers[n].wake();
- } else if isr.htif(chn) {
- defmt::info!("half transfer");
- } else if isr.gif(chn) {
- defmt::info!("half transfer");
- }
- }
- //}
- };
-
- (bdma, DMA2) => {
- defmt::info!("---> dma DMA2");
- //for isrn in 0..2 {
- //let isr = pac::$dma.isr(isrn).read();
- let isr = pac::DMA2.isr().read();
- pac::DMA2.ifcr().write_value(isr);
- let dman = <peripherals::DMA2 as sealed::Bdma>::num() as usize;
-
- for chn in 0..8 {
- let n = dman * 8 + chn;
- defmt::info!("n={}", n);
- if isr.teif(chn) {
- defmt::info!("transfer error");
- STATE.ch_status[n].store(CH_STATUS_ERROR, Ordering::Release);
- STATE.ch_wakers[n].wake();
- } else if isr.tcif(chn) {
- defmt::info!("transfer complete");
- STATE.ch_status[n].store(CH_STATUS_COMPLETED, Ordering::Release);
- STATE.ch_wakers[n].wake();
- } else if isr.htif(chn) {
- defmt::info!("half transfer");
- } else if isr.gif(chn) {
- defmt::info!("half transfer");
- }
- }
- //}
- };
-
- }
- defmt::info!("irq fire complete");
-}
-
/// safety: must be called only once
-pub(crate) unsafe fn init() {
- interrupts! {
- (DMA, $irq:ident) => {
- defmt::info!("enable irq {}", stringify!($irq));
- interrupt::$irq::steal().enable();
- };
- }
-}
-
-interrupts! {
- (DMA, $irq:ident) => {
- #[crate::interrupt]
- unsafe fn $irq () {
- defmt::info!("irq firing {}", stringify!($irq));
- on_irq()
- }
- };
-}
+pub(crate) unsafe fn init() {}
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index f750c989..4b2826ae 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -20,6 +20,9 @@ pub mod gpio;
pub mod rcc;
// Sometimes-present hardware
+#[cfg(any(dma, bdma, dmamux))]
+pub mod dma_traits;
+
#[cfg(adc)]
pub mod adc;
#[cfg(bdma)]
@@ -28,7 +31,7 @@ pub mod bdma;
pub mod clock;
#[cfg(dac)]
pub mod dac;
-#[cfg(any(dma, dmamux))]
+#[cfg(dma)]
pub mod dma;
#[cfg(dmamux)]
pub mod dmamux;
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 2bab4016..ddaed5bb 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -73,11 +73,8 @@ pub enum Error {
pub(crate) mod sealed {
use super::*;
- #[cfg(any(dma, dmamux))]
- use crate::dma::WriteDma;
-
- #[cfg(bdma)]
- use crate::bdma::WriteDma;
+ #[cfg(any(dma, bdma, dmamux))]
+ use crate::dma_traits::WriteDma;
pub trait Instance {
fn regs(&self) -> crate::pac::usart::Usart;