diff options
| author | Bob McWhirter <[email protected]> | 2021-07-02 09:54:31 -0400 |
|---|---|---|
| committer | Bob McWhirter <[email protected]> | 2021-07-13 10:08:43 -0400 |
| commit | 043f0ea5088e02f509b3e1f013192c44c7854540 (patch) | |
| tree | bc6caf1eb0e217a20e7ca70425a7675c1e81d48a | |
| parent | 91521a86a0b273a8f375eff205963df14fa93f4f (diff) | |
Checkpoint DMAMUX channel setup.
| -rw-r--r-- | embassy-stm32/src/dmamux/mod.rs | 187 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/v3.rs | 2 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/usart.rs | 4 |
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 | |||
| 3 | use crate::pac::dma_channels; | ||
| 4 | use crate::pac::dma_requests; | ||
| 5 | use crate::pac::peripherals; | ||
| 6 | use crate::peripherals; | ||
| 7 | |||
| 8 | use core::future::Future; | ||
| 9 | |||
| 10 | use crate::dma::{ReadDma, WriteDma}; | ||
| 11 | |||
| 12 | #[allow(unused)] | ||
| 13 | pub(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)] | ||
| 23 | pub(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 | |||
| 32 | pub(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 | |||
| 46 | pub trait DmaMux: sealed::DmaMux {} | ||
| 47 | pub trait Channel: sealed::Channel {} | ||
| 48 | pub trait PeripheralChannel<PERI, OP>: sealed::Channel {} | ||
| 49 | |||
| 50 | pub struct P2M; | ||
| 51 | pub struct M2P; | ||
| 52 | |||
| 53 | macro_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 | |||
| 100 | peripherals! { | ||
| 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 | |||
| 119 | macro_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)] | ||
| 181 | use crate::usart; | ||
| 182 | |||
| 183 | dma_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; | |||
| 30 | pub mod dac; | 30 | pub mod dac; |
| 31 | #[cfg(any(dma, dmamux))] | 31 | #[cfg(any(dma, dmamux))] |
| 32 | pub mod dma; | 32 | pub mod dma; |
| 33 | #[cfg(dmamux)] | ||
| 34 | pub mod dmamux; | ||
| 33 | #[cfg(all(eth, feature = "net"))] | 35 | #[cfg(all(eth, feature = "net"))] |
| 34 | pub mod eth; | 36 | pub 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 | ||
