aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob McWhirter <[email protected]>2021-07-02 09:54:31 -0400
committerBob McWhirter <[email protected]>2021-07-13 10:08:43 -0400
commit043f0ea5088e02f509b3e1f013192c44c7854540 (patch)
treebc6caf1eb0e217a20e7ca70425a7675c1e81d48a
parent91521a86a0b273a8f375eff205963df14fa93f4f (diff)
Checkpoint DMAMUX channel setup.
-rw-r--r--embassy-stm32/src/dmamux/mod.rs187
-rw-r--r--embassy-stm32/src/lib.rs2
-rw-r--r--embassy-stm32/src/usart/v3.rs2
-rw-r--r--examples/stm32l4/src/bin/usart.rs4
4 files changed, 190 insertions, 5 deletions
diff --git a/embassy-stm32/src/dmamux/mod.rs b/embassy-stm32/src/dmamux/mod.rs
new file mode 100644
index 000000000..4939d26a6
--- /dev/null
+++ b/embassy-stm32/src/dmamux/mod.rs
@@ -0,0 +1,187 @@
1#![macro_use]
2
3use crate::pac::dma_channels;
4use crate::pac::dma_requests;
5use crate::pac::peripherals;
6use crate::peripherals;
7
8use core::future::Future;
9
10use crate::dma::{ReadDma, WriteDma};
11
12#[allow(unused)]
13pub(crate) async unsafe fn transfer_p2m(
14 ch: &mut impl Channel,
15 ch_func: u8,
16 src: *const u8,
17 dst: &mut [u8],
18) {
19 unimplemented!()
20}
21
22#[allow(unused)]
23pub(crate) async unsafe fn transfer_m2p(
24 ch: &mut impl Channel,
25 ch_func: u8,
26 src: &[u8],
27 dst: *mut u8,
28) {
29 unimplemented!()
30}
31
32pub(crate) mod sealed {
33 use super::*;
34
35 pub trait DmaMux {}
36
37 pub trait Channel {
38 fn dmamux_ch_num(&self) -> u8;
39 }
40
41 pub trait PeripheralChannel<PERI, OP>: Channel {
42 fn request(&self) -> u8;
43 }
44}
45
46pub trait DmaMux: sealed::DmaMux {}
47pub trait Channel: sealed::Channel {}
48pub trait PeripheralChannel<PERI, OP>: sealed::Channel {}
49
50pub struct P2M;
51pub struct M2P;
52
53macro_rules! impl_dma_channel {
54 ($channel_peri:ident, $dmamux_peri:ident, $channel_num:expr, $dma_num:expr) => {
55 impl Channel for peripherals::$channel_peri {}
56 impl sealed::Channel for peripherals::$channel_peri {
57 fn dmamux_ch_num(&self) -> u8 {
58 ($dma_num * 8) + $channel_num
59 }
60 }
61
62 impl<T> WriteDma<T> for peripherals::$channel_peri
63 where
64 Self: sealed::PeripheralChannel<T, M2P>,
65 T: 'static,
66 {
67 type WriteDmaFuture<'a> = impl Future<Output = ()>;
68
69 fn transfer<'a>(&'a mut self, buf: &'a [u8], dst: *mut u8) -> Self::WriteDmaFuture<'a>
70 where
71 T: 'a,
72 {
73 let request = sealed::PeripheralChannel::<T, M2P>::request(self);
74 unsafe { transfer_m2p(self, request, buf, dst) }
75 }
76 }
77
78 impl<T> ReadDma<T> for peripherals::$channel_peri
79 where
80 Self: sealed::PeripheralChannel<T, P2M>,
81 T: 'static,
82 {
83 type ReadDmaFuture<'a> = impl Future<Output = ()>;
84
85 fn transfer<'a>(
86 &'a mut self,
87 src: *const u8,
88 buf: &'a mut [u8],
89 ) -> Self::ReadDmaFuture<'a>
90 where
91 T: 'a,
92 {
93 let request = sealed::PeripheralChannel::<T, P2M>::request(self);
94 unsafe { transfer_p2m(self, request, src, buf) }
95 }
96 }
97 };
98}
99
100peripherals! {
101 (bdma, DMA1) => {
102 //impl_dma!(DMA1, 0);
103 dma_channels! {
104 ($channel_peri:ident, DMA1, $channel_num:expr) => {
105 impl_dma_channel!($channel_peri, DMAMUX1, $channel_num, 0);
106 };
107 }
108 };
109 (bdma, DMA2) => {
110 //impl_dma!(DMA2, 1);
111 dma_channels! {
112 ($channel_peri:ident, DMA2, $channel_num:expr) => {
113 impl_dma_channel!($channel_peri, DMAMUX1, $channel_num, 1);
114 };
115 }
116 };
117}
118
119macro_rules! impl_usart_dma_requests {
120 ($channel_peri:ident, $dma_peri:ident, $channel_num:expr) => {
121 dma_requests! {
122 (usart, $peri:ident, RX, $request:expr) => {
123 impl usart::RxDma<peripherals::$peri> for peripherals::$channel_peri { }
124 impl usart::sealed::RxDma<peripherals::$peri> for peripherals::$channel_peri { }
125
126 impl sealed::PeripheralChannel<peripherals::$peri, P2M> for peripherals::$channel_peri {
127 fn request(&self) -> u8 {
128 $request
129 }
130 }
131
132 impl PeripheralChannel<peripherals::$peri, P2M> for peripherals::$channel_peri { }
133
134 };
135
136 (usart, $peri:ident, TX, $request:expr) => {
137 impl usart::TxDma<peripherals::$peri> for peripherals::$channel_peri { }
138 impl usart::sealed::TxDma<peripherals::$peri> for peripherals::$channel_peri { }
139
140 impl sealed::PeripheralChannel<peripherals::$peri, M2P> for peripherals::$channel_peri {
141 fn request(&self) -> u8 {
142 $request
143 }
144 }
145
146 impl PeripheralChannel<peripherals::$peri, M2P> for peripherals::$channel_peri { }
147
148 };
149
150 (uart, $peri:ident, TX, $request:expr) => {
151 impl usart::RxDma<peripherals::$peri> for peripherals::$channel_peri { }
152 impl usart::sealed::RxDma<peripherals::$peri> for peripherals::$channel_peri { }
153
154 impl sealed::PeripheralChannel<peripherals::$peri, P2M> for peripherals::$channel_peri {
155 fn request(&self) -> u8 {
156 $request
157 }
158 }
159
160 impl PeripheralChannel<peripherals::$peri, P2M> for peripherals::$channel_peri { }
161 };
162
163 (uart, $peri:ident, RX, $request:expr) => {
164 impl usart::TxDma<peripherals::$peri> for peripherals::$channel_peri { }
165 impl usart::sealed::TxDma<peripherals::$peri> for peripherals::$channel_peri { }
166
167 impl sealed::PeripheralChannel<peripherals::$peri, M2P> for peripherals::$channel_peri {
168 fn request(&self) -> u8 {
169 $request
170 }
171 }
172
173 impl PeripheralChannel<peripherals::$peri, M2P> for peripherals::$channel_peri { }
174 };
175 }
176
177 };
178}
179
180#[cfg(usart)]
181use crate::usart;
182
183dma_channels! {
184 ($channel_peri:ident, $dma_peri:ident, $channel_num:expr) => {
185 impl_usart_dma_requests!($channel_peri, $dma_peri, $channel_num);
186 };
187}
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 35a8d3baf..67962fdde 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -30,6 +30,8 @@ pub mod clock;
30pub mod dac; 30pub mod dac;
31#[cfg(any(dma, dmamux))] 31#[cfg(any(dma, dmamux))]
32pub mod dma; 32pub mod dma;
33#[cfg(dmamux)]
34pub mod dmamux;
33#[cfg(all(eth, feature = "net"))] 35#[cfg(all(eth, feature = "net"))]
34pub mod eth; 36pub mod eth;
35#[cfg(exti)] 37#[cfg(exti)]
diff --git a/embassy-stm32/src/usart/v3.rs b/embassy-stm32/src/usart/v3.rs
index 1e9051443..0071c597a 100644
--- a/embassy-stm32/src/usart/v3.rs
+++ b/embassy-stm32/src/usart/v3.rs
@@ -57,7 +57,7 @@ impl<'d, T: Instance> Uart<'d, T> {
57 } 57 }
58 } 58 }
59 59
60 #[cfg(dma)] 60 #[cfg(any(dma, dmamux))]
61 pub async fn write_dma(&mut self, ch: &mut impl TxDma<T>, buffer: &[u8]) -> Result<(), Error> { 61 pub async fn write_dma(&mut self, ch: &mut impl TxDma<T>, buffer: &[u8]) -> Result<(), Error> {
62 unsafe { 62 unsafe {
63 self.inner.regs().cr3().modify(|reg| { 63 self.inner.regs().cr3().modify(|reg| {
diff --git a/examples/stm32l4/src/bin/usart.rs b/examples/stm32l4/src/bin/usart.rs
index 5b6d9eaa1..0b14eeb59 100644
--- a/examples/stm32l4/src/bin/usart.rs
+++ b/examples/stm32l4/src/bin/usart.rs
@@ -82,10 +82,6 @@ fn main() -> ! {
82 w.syscfgen().set_bit(); 82 w.syscfgen().set_bit();
83 w 83 w
84 }); 84 });
85 //pp.RCC.apb1enr.modify(|_, w| {
86 //w.usart3en().enabled();
87 //w
88 //});
89 85
90 unsafe { embassy::time::set_clock(&ZeroClock) }; 86 unsafe { embassy::time::set_clock(&ZeroClock) };
91 87