1use crate::ral;
4
5use crate::common::dma::channel::Channel;
6
7pub const CHANNEL_COUNT: usize = crate::chip::config::DMA_CHANNEL_COUNT;
14
15pub static DMA: crate::common::dma::Dma<{ CHANNEL_COUNT }> = unsafe {
27 crate::common::dma::Dma::new(
28 crate::ral::dma::DMA.cast(),
29 crate::ral::dmamux::DMAMUX.cast(),
30 )
31};
32
33pub fn channels(_: ral::dma::DMA, _: ral::dmamux::DMAMUX) -> [Option<Channel>; CHANNEL_COUNT] {
41 const NO_CHANNEL: Option<Channel> = None;
42 let mut channels: [Option<Channel>; CHANNEL_COUNT] = [NO_CHANNEL; CHANNEL_COUNT];
43
44 for (idx, channel) in channels.iter_mut().enumerate() {
45 let mut chan = unsafe { DMA.channel(idx) };
48 chan.reset();
49 *channel = Some(chan);
50 }
51 channels
52}
53
54use crate::dma::peripheral;
60
61#[cfg(family = "imxrt10xx")]
62mod mappings {
63 pub(super) const LPUART_DMA_RX_MAPPING: [u32; 8] = [3, 67, 5, 69, 7, 71, 9, 73];
64 pub(super) const LPUART_DMA_TX_MAPPING: [u32; 8] = [2, 66, 4, 68, 6, 70, 8, 72];
65
66 pub(super) const LPSPI_DMA_RX_MAPPING: [u32; 4] = [13, 77, 15, 79];
67 pub(super) const LPSPI_DMA_TX_MAPPING: [u32; 4] = [14, 78, 16, 80];
68
69 pub(super) const ADC_DMA_RX_MAPPING: [u32; 2] = [24, 88];
70}
71#[cfg(family = "imxrt11xx")]
72mod mappings {
73 pub(super) const LPUART_DMA_RX_MAPPING: [u32; 12] =
74 [9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31];
75 pub(super) const LPUART_DMA_TX_MAPPING: [u32; 12] =
76 [8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30];
77
78 pub(super) const LPSPI_DMA_RX_MAPPING: [u32; 6] = [36, 38, 40, 42, 44, 46];
79 pub(super) const LPSPI_DMA_TX_MAPPING: [u32; 6] = [37, 39, 41, 43, 45, 47];
80}
81use mappings::*;
82
83use crate::lpuart;
85
86unsafe impl<P, const N: u8> peripheral::Destination<u8> for lpuart::Lpuart<P, N> {
89 fn destination_signal(&self) -> u32 {
90 LPUART_DMA_TX_MAPPING[N as usize - 1]
91 }
92 fn destination_address(&self) -> *const u8 {
93 self.data().cast()
94 }
95 fn enable_destination(&mut self) {
96 self.enable_dma_transmit();
97 }
98 fn disable_destination(&mut self) {
99 self.disable_dma_transmit();
100 }
101}
102
103unsafe impl<P, const N: u8> peripheral::Source<u8> for lpuart::Lpuart<P, N> {
106 fn source_signal(&self) -> u32 {
107 LPUART_DMA_RX_MAPPING[N as usize - 1]
108 }
109 fn source_address(&self) -> *const u8 {
110 self.data().cast()
111 }
112 fn enable_source(&mut self) {
113 self.enable_dma_receive();
114 }
115 fn disable_source(&mut self) {
116 self.disable_dma_receive();
117 }
118}
119
120impl<P, const N: u8> lpuart::Lpuart<P, N> {
121 pub fn dma_write<'a>(
126 &'a mut self,
127 channel: &'a mut Channel,
128 buffer: &'a [u8],
129 ) -> peripheral::Write<'a, Self, u8> {
130 peripheral::write(channel, buffer, self)
131 }
132
133 pub fn dma_read<'a>(
137 &'a mut self,
138 channel: &'a mut Channel,
139 buffer: &'a mut [u8],
140 ) -> peripheral::Read<'a, Self, u8> {
141 peripheral::read(channel, self, buffer)
142 }
143}
144
145use crate::lpspi;
147
148unsafe impl<P, const N: u8> peripheral::Source<u32> for lpspi::Lpspi<P, N> {
151 fn source_signal(&self) -> u32 {
152 LPSPI_DMA_RX_MAPPING[N as usize - 1]
153 }
154 fn source_address(&self) -> *const u32 {
155 self.rdr().cast()
156 }
157 fn enable_source(&mut self) {
158 self.enable_dma_receive()
159 }
160 fn disable_source(&mut self) {
161 self.disable_dma_receive();
162 }
163}
164
165unsafe impl<P, const N: u8> peripheral::Destination<u32> for lpspi::Lpspi<P, N> {
168 fn destination_signal(&self) -> u32 {
169 LPSPI_DMA_TX_MAPPING[N as usize - 1]
170 }
171 fn destination_address(&self) -> *const u32 {
172 self.tdr().cast()
173 }
174 fn enable_destination(&mut self) {
175 self.enable_dma_transmit();
176 }
177 fn disable_destination(&mut self) {
178 self.disable_dma_transmit();
179 }
180}
181
182unsafe impl<P, const N: u8> peripheral::Bidirectional<u32> for lpspi::Lpspi<P, N> {}
185
186impl<P, const N: u8> lpspi::Lpspi<P, N> {
187 pub fn dma_write<'a>(
195 &'a mut self,
196 channel: &'a mut Channel,
197 buffer: &'a [u32],
198 ) -> Result<peripheral::Write<'a, Self, u32>, lpspi::LpspiError> {
199 let mut transaction = lpspi::Transaction::new_u32s(buffer)?;
200 transaction.bit_order = self.bit_order();
201
202 transaction.receive_data_mask = true;
203 self.wait_for_transmit_fifo_space()?;
204 self.enqueue_transaction(&transaction);
205 Ok(peripheral::write(channel, buffer, self))
206 }
207
208 pub fn dma_read<'a>(
215 &'a mut self,
216 channel: &'a mut Channel,
217 buffer: &'a mut [u32],
218 ) -> Result<peripheral::Read<'a, Self, u32>, lpspi::LpspiError> {
219 let mut transaction = lpspi::Transaction::new_u32s(buffer)?;
220 transaction.bit_order = self.bit_order();
221
222 transaction.transmit_data_mask = true;
223 self.wait_for_transmit_fifo_space()?;
224 self.enqueue_transaction(&transaction);
225 Ok(peripheral::read(channel, self, buffer))
226 }
227
228 pub fn dma_full_duplex<'a>(
236 &'a mut self,
237 rx: &'a mut Channel,
238 tx: &'a mut Channel,
239 buffer: &'a mut [u32],
240 ) -> Result<peripheral::FullDuplex<'a, Self, u32>, lpspi::LpspiError> {
241 let mut transaction = lpspi::Transaction::new_u32s(buffer)?;
242 transaction.bit_order = self.bit_order();
243
244 self.wait_for_transmit_fifo_space()?;
245 self.enqueue_transaction(&transaction);
246 Ok(peripheral::full_duplex(rx, tx, self, buffer))
247 }
248}
249
250#[cfg(family = "imxrt10xx")]
252use crate::adc;
253
254#[cfg(family = "imxrt10xx")]
255unsafe impl<P, const N: u8> peripheral::Source<u16> for adc::DmaSource<P, N> {
258 fn source_signal(&self) -> u32 {
259 ADC_DMA_RX_MAPPING[if N == ral::SOLE_INSTANCE {
260 N as usize
261 } else {
262 N as usize - 1
263 }]
264 }
265 fn source_address(&self) -> *const u16 {
266 self.r0().cast()
267 }
268 fn enable_source(&mut self) {
269 self.enable_dma();
270 }
271 fn disable_source(&mut self) {
272 self.disable_dma();
273 }
274}