diff options
| -rw-r--r-- | embassy-stm32/src/dmamux/mod.rs | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/embassy-stm32/src/dmamux/mod.rs b/embassy-stm32/src/dmamux/mod.rs index 4939d26a6..fc043a3f8 100644 --- a/embassy-stm32/src/dmamux/mod.rs +++ b/embassy-stm32/src/dmamux/mod.rs | |||
| @@ -1,7 +1,15 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | use core::task::Poll; | ||
| 2 | 3 | ||
| 4 | use atomic_polyfill::{AtomicU8, Ordering}; | ||
| 5 | use embassy::interrupt::{Interrupt, InterruptExt}; | ||
| 6 | use embassy::util::AtomicWaker; | ||
| 7 | use futures::future::poll_fn; | ||
| 8 | |||
| 9 | use crate::pac; | ||
| 3 | use crate::pac::dma_channels; | 10 | use crate::pac::dma_channels; |
| 4 | use crate::pac::dma_requests; | 11 | use crate::pac::dma_requests; |
| 12 | use crate::pac::peripheral_count; | ||
| 5 | use crate::pac::peripherals; | 13 | use crate::pac::peripherals; |
| 6 | use crate::peripherals; | 14 | use crate::peripherals; |
| 7 | 15 | ||
| @@ -9,6 +17,29 @@ use core::future::Future; | |||
| 9 | 17 | ||
| 10 | use crate::dma::{ReadDma, WriteDma}; | 18 | use crate::dma::{ReadDma, WriteDma}; |
| 11 | 19 | ||
| 20 | const CH_COUNT: usize = peripheral_count!(DMA) * 8; | ||
| 21 | const CH_STATUS_NONE: u8 = 0; | ||
| 22 | const CH_STATUS_COMPLETED: u8 = 1; | ||
| 23 | const CH_STATUS_ERROR: u8 = 2; | ||
| 24 | |||
| 25 | struct State { | ||
| 26 | ch_wakers: [AtomicWaker; CH_COUNT], | ||
| 27 | ch_status: [AtomicU8; CH_COUNT], | ||
| 28 | } | ||
| 29 | |||
| 30 | impl State { | ||
| 31 | const fn new() -> Self { | ||
| 32 | const AW: AtomicWaker = AtomicWaker::new(); | ||
| 33 | const AU: AtomicU8 = AtomicU8::new(CH_STATUS_NONE); | ||
| 34 | Self { | ||
| 35 | ch_wakers: [AW; CH_COUNT], | ||
| 36 | ch_status: [AU; CH_COUNT], | ||
| 37 | } | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | static STATE: State = State::new(); | ||
| 42 | |||
| 12 | #[allow(unused)] | 43 | #[allow(unused)] |
| 13 | pub(crate) async unsafe fn transfer_p2m( | 44 | pub(crate) async unsafe fn transfer_p2m( |
| 14 | ch: &mut impl Channel, | 45 | ch: &mut impl Channel, |
| @@ -32,9 +63,12 @@ pub(crate) async unsafe fn transfer_m2p( | |||
| 32 | pub(crate) mod sealed { | 63 | pub(crate) mod sealed { |
| 33 | use super::*; | 64 | use super::*; |
| 34 | 65 | ||
| 35 | pub trait DmaMux {} | 66 | pub trait DmaMux { |
| 67 | fn regs() -> &'static pac::dmamux::Dmamux; | ||
| 68 | } | ||
| 36 | 69 | ||
| 37 | pub trait Channel { | 70 | pub trait Channel { |
| 71 | fn dmamux_regs() -> &'static pac::dmamux::Dmamux; | ||
| 38 | fn dmamux_ch_num(&self) -> u8; | 72 | fn dmamux_ch_num(&self) -> u8; |
| 39 | } | 73 | } |
| 40 | 74 | ||
| @@ -54,6 +88,10 @@ macro_rules! impl_dma_channel { | |||
| 54 | ($channel_peri:ident, $dmamux_peri:ident, $channel_num:expr, $dma_num:expr) => { | 88 | ($channel_peri:ident, $dmamux_peri:ident, $channel_num:expr, $dma_num:expr) => { |
| 55 | impl Channel for peripherals::$channel_peri {} | 89 | impl Channel for peripherals::$channel_peri {} |
| 56 | impl sealed::Channel for peripherals::$channel_peri { | 90 | impl sealed::Channel for peripherals::$channel_peri { |
| 91 | fn dmamux_regs() -> &'static pac::dmamux::Dmamux { | ||
| 92 | &crate::pac::$dmamux_peri | ||
| 93 | } | ||
| 94 | |||
| 57 | fn dmamux_ch_num(&self) -> u8 { | 95 | fn dmamux_ch_num(&self) -> u8 { |
| 58 | ($dma_num * 8) + $channel_num | 96 | ($dma_num * 8) + $channel_num |
| 59 | } | 97 | } |
| @@ -97,9 +135,19 @@ macro_rules! impl_dma_channel { | |||
| 97 | }; | 135 | }; |
| 98 | } | 136 | } |
| 99 | 137 | ||
| 138 | macro_rules! impl_dmamux { | ||
| 139 | ($peri:ident) => { | ||
| 140 | impl sealed::DmaMux for peripherals::$peri { | ||
| 141 | fn regs() -> &'static pac::dmamux::Dmamux { | ||
| 142 | &pac::$peri | ||
| 143 | } | ||
| 144 | } | ||
| 145 | impl DmaMux for peripherals::$peri {} | ||
| 146 | }; | ||
| 147 | } | ||
| 148 | |||
| 100 | peripherals! { | 149 | peripherals! { |
| 101 | (bdma, DMA1) => { | 150 | (bdma, DMA1) => { |
| 102 | //impl_dma!(DMA1, 0); | ||
| 103 | dma_channels! { | 151 | dma_channels! { |
| 104 | ($channel_peri:ident, DMA1, $channel_num:expr) => { | 152 | ($channel_peri:ident, DMA1, $channel_num:expr) => { |
| 105 | impl_dma_channel!($channel_peri, DMAMUX1, $channel_num, 0); | 153 | impl_dma_channel!($channel_peri, DMAMUX1, $channel_num, 0); |
| @@ -107,18 +155,21 @@ peripherals! { | |||
| 107 | } | 155 | } |
| 108 | }; | 156 | }; |
| 109 | (bdma, DMA2) => { | 157 | (bdma, DMA2) => { |
| 110 | //impl_dma!(DMA2, 1); | ||
| 111 | dma_channels! { | 158 | dma_channels! { |
| 112 | ($channel_peri:ident, DMA2, $channel_num:expr) => { | 159 | ($channel_peri:ident, DMA2, $channel_num:expr) => { |
| 113 | impl_dma_channel!($channel_peri, DMAMUX1, $channel_num, 1); | 160 | impl_dma_channel!($channel_peri, DMAMUX1, $channel_num, 1); |
| 114 | }; | 161 | }; |
| 115 | } | 162 | } |
| 116 | }; | 163 | }; |
| 164 | (dmamux, DMAMUX1) => { | ||
| 165 | impl_dmamux!(DMAMUX1); | ||
| 166 | }; | ||
| 117 | } | 167 | } |
| 118 | 168 | ||
| 119 | macro_rules! impl_usart_dma_requests { | 169 | macro_rules! impl_usart_dma_requests { |
| 120 | ($channel_peri:ident, $dma_peri:ident, $channel_num:expr) => { | 170 | ($channel_peri:ident, $dma_peri:ident, $channel_num:expr) => { |
| 121 | dma_requests! { | 171 | dma_requests! { |
| 172 | // TODO: DRY this up. | ||
| 122 | (usart, $peri:ident, RX, $request:expr) => { | 173 | (usart, $peri:ident, RX, $request:expr) => { |
| 123 | impl usart::RxDma<peripherals::$peri> for peripherals::$channel_peri { } | 174 | impl usart::RxDma<peripherals::$peri> for peripherals::$channel_peri { } |
| 124 | impl usart::sealed::RxDma<peripherals::$peri> for peripherals::$channel_peri { } | 175 | impl usart::sealed::RxDma<peripherals::$peri> for peripherals::$channel_peri { } |
