1#![macro_use]
3
4#[cfg(any(bdma, dma))]
5mod dma_bdma;
6#[cfg(any(bdma, dma))]
7pub use dma_bdma::*;
8
9#[cfg(gpdma)]
10pub(crate) mod gpdma;
11#[cfg(gpdma)]
12pub use gpdma::*;
13
14#[cfg(dmamux)]
15mod dmamux;
16#[cfg(dmamux)]
17pub(crate) use dmamux::*;
18
19mod util;
20pub(crate) use util::*;
21
22pub(crate) mod ringbuffer;
23pub mod word;
24
25use embassy_hal_internal::{impl_peripheral, PeripheralType};
26
27use crate::interrupt;
28
29#[derive(Debug, Copy, Clone, PartialEq, Eq)]
30#[cfg_attr(feature = "defmt", derive(defmt::Format))]
31enum Dir {
32 MemoryToPeripheral,
33 PeripheralToMemory,
34}
35
36#[cfg(any(dma_v2, bdma_v2, gpdma, dmamux))]
38pub type Request = u8;
39#[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))]
41pub type Request = ();
42
43pub(crate) trait SealedChannel {
44 fn id(&self) -> u8;
45}
46
47pub(crate) trait ChannelInterrupt {
48 #[cfg_attr(not(feature = "rt"), allow(unused))]
49 unsafe fn on_irq();
50}
51
52#[allow(private_bounds)]
54pub trait Channel: SealedChannel + PeripheralType + Into<AnyChannel> + 'static {}
55
56macro_rules! dma_channel_impl {
57 ($channel_peri:ident, $index:expr) => {
58 impl crate::dma::SealedChannel for crate::peripherals::$channel_peri {
59 fn id(&self) -> u8 {
60 $index
61 }
62 }
63 impl crate::dma::ChannelInterrupt for crate::peripherals::$channel_peri {
64 unsafe fn on_irq() {
65 crate::dma::AnyChannel { id: $index }.on_irq();
66 }
67 }
68
69 impl crate::dma::Channel for crate::peripherals::$channel_peri {}
70
71 impl From<crate::peripherals::$channel_peri> for crate::dma::AnyChannel {
72 fn from(val: crate::peripherals::$channel_peri) -> Self {
73 Self {
74 id: crate::dma::SealedChannel::id(&val),
75 }
76 }
77 }
78 };
79}
80
81pub struct AnyChannel {
83 pub(crate) id: u8,
84}
85impl_peripheral!(AnyChannel);
86
87impl AnyChannel {
88 fn info(&self) -> &ChannelInfo {
89 &crate::_generated::DMA_CHANNELS[self.id as usize]
90 }
91}
92
93impl SealedChannel for AnyChannel {
94 fn id(&self) -> u8 {
95 self.id
96 }
97}
98impl Channel for AnyChannel {}
99
100const CHANNEL_COUNT: usize = crate::_generated::DMA_CHANNELS.len();
101static STATE: [ChannelState; CHANNEL_COUNT] = [ChannelState::NEW; CHANNEL_COUNT];
102
103pub(crate) unsafe fn init(
105 cs: critical_section::CriticalSection,
106 #[cfg(bdma)] bdma_priority: interrupt::Priority,
107 #[cfg(dma)] dma_priority: interrupt::Priority,
108 #[cfg(gpdma)] gpdma_priority: interrupt::Priority,
109) {
110 #[cfg(any(dma, bdma))]
111 dma_bdma::init(
112 cs,
113 #[cfg(dma)]
114 dma_priority,
115 #[cfg(bdma)]
116 bdma_priority,
117 );
118 #[cfg(gpdma)]
119 gpdma::init(cs, gpdma_priority);
120 #[cfg(dmamux)]
121 dmamux::init(cs);
122}