1#![macro_use]
8
9mod dma;
10pub use dma::*;
11
12mod util;
13pub(crate) use util::*;
14
15pub(crate) mod ringbuffer;
16pub mod word;
17
18use embassy_hal_internal::{impl_peripheral, Peripheral};
19
20use crate::interrupt;
21
22#[derive(Debug, Copy, Clone, PartialEq, Eq)]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24enum Dir {
25 MemoryToPeripheral,
26 PeripheralToMemory,
27}
28
29pub type Request = u8;
31pub(crate) trait SealedChannel {
34 fn id(&self) -> u8;
35}
36
37pub(crate) trait ChannelInterrupt {
38 #[cfg_attr(not(feature = "rt"), allow(unused))]
39 unsafe fn on_irq();
40}
41
42#[allow(private_bounds)]
44pub trait Channel: SealedChannel + Peripheral<P = Self> + Into<AnyChannel> + 'static {
45 #[inline]
51 fn degrade(self) -> AnyChannel {
52 AnyChannel { id: self.id() }
53 }
54}
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(x: crate::peripherals::$channel_peri) -> Self {
73 crate::dma::Channel::degrade(x)
74 }
75 }
76 };
77}
78
79pub struct AnyChannel {
81 pub(crate) id: u8,
82}
83impl_peripheral!(AnyChannel);
84
85impl AnyChannel {
86 fn info(&self) -> &ChannelInfo {
87 &crate::_generated::DMA_CHANNELS[self.id as usize]
88 }
89}
90
91impl SealedChannel for AnyChannel {
92 fn id(&self) -> u8 {
93 self.id
94 }
95}
96impl Channel for AnyChannel {}
97
98const CHANNEL_COUNT: usize = crate::_generated::DMA_CHANNELS.len();
99static STATE: [ChannelState; CHANNEL_COUNT] = [ChannelState::NEW; CHANNEL_COUNT];
100
101pub struct NoDma;
109
110impl_peripheral!(NoDma);
111
112pub(crate) unsafe fn init(
114 cs: critical_section::CriticalSection,
115 dma_priority: interrupt::Priority,
116) {
117 dma::init(cs, dma_priority);
118}