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(any(chip = "imxrt1010", chip = "imxrt1020", chip = "imxrt1060"))]
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 pub(super) const SAI_DMA_RX_MAPPING: [u32; 3] = [19, 21, 83];
72 pub(super) const SAI_DMA_TX_MAPPING: [u32; 3] = [20, 22, 84];
73}
74#[cfg(chip = "imxrt1170")]
75mod mappings {
76 pub(super) const LPUART_DMA_RX_MAPPING: [u32; 12] =
77 [9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31];
78 pub(super) const LPUART_DMA_TX_MAPPING: [u32; 12] =
79 [8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30];
80
81 pub(super) const LPSPI_DMA_RX_MAPPING: [u32; 6] = [36, 38, 40, 42, 44, 46];
82 pub(super) const LPSPI_DMA_TX_MAPPING: [u32; 6] = [37, 39, 41, 43, 45, 47];
83
84 pub(super) const SAI_DMA_RX_MAPPING: [u32; 4] = [54, 56, 58, 60];
85 pub(super) const SAI_DMA_TX_MAPPING: [u32; 4] = [55, 57, 59, 61];
86}
87use mappings::*;
88
89use crate::lpuart;
91
92unsafe impl peripheral::Destination<u8> for lpuart::Lpuart {
95 fn destination_signal(&self) -> u32 {
96 LPUART_DMA_TX_MAPPING[self.instance() as usize - 1]
97 }
98 fn destination_address(&self) -> *const u8 {
99 self.data().cast()
100 }
101 fn enable_destination(&mut self) {
102 self.enable_dma_transmit();
103 }
104 fn disable_destination(&mut self) {
105 self.disable_dma_transmit();
106 }
107}
108
109unsafe impl peripheral::Source<u8> for lpuart::Lpuart {
112 fn source_signal(&self) -> u32 {
113 LPUART_DMA_RX_MAPPING[self.instance() as usize - 1]
114 }
115 fn source_address(&self) -> *const u8 {
116 self.data().cast()
117 }
118 fn enable_source(&mut self) {
119 self.enable_dma_receive();
120 }
121 fn disable_source(&mut self) {
122 self.disable_dma_receive();
123 }
124}
125
126impl lpuart::Lpuart {
127 fn instance(&self) -> u8 {
131 ral::lpuart::number(&*self.lpuart).unwrap()
132 }
133
134 pub fn dma_write<'a>(
139 &'a mut self,
140 channel: &'a mut Channel,
141 buffer: &'a [u8],
142 ) -> peripheral::Write<'a, Self, u8> {
143 peripheral::write(channel, buffer, self)
144 }
145
146 pub fn dma_read<'a>(
150 &'a mut self,
151 channel: &'a mut Channel,
152 buffer: &'a mut [u8],
153 ) -> peripheral::Read<'a, Self, u8> {
154 peripheral::read(channel, self, buffer)
155 }
156}
157
158use crate::lpspi;
160
161unsafe impl peripheral::Source<u32> for lpspi::Lpspi {
164 fn source_signal(&self) -> u32 {
165 LPSPI_DMA_RX_MAPPING[self.instance() as usize - 1]
166 }
167 fn source_address(&self) -> *const u32 {
168 self.rdr().cast()
169 }
170 fn enable_source(&mut self) {
171 self.enable_dma_receive()
172 }
173 fn disable_source(&mut self) {
174 self.disable_dma_receive();
175 }
176}
177
178unsafe impl peripheral::Destination<u32> for lpspi::Lpspi {
181 fn destination_signal(&self) -> u32 {
182 LPSPI_DMA_TX_MAPPING[self.instance() as usize - 1]
183 }
184 fn destination_address(&self) -> *const u32 {
185 self.tdr().cast()
186 }
187 fn enable_destination(&mut self) {
188 self.enable_dma_transmit();
189 }
190 fn disable_destination(&mut self) {
191 self.disable_dma_transmit();
192 }
193}
194
195unsafe impl peripheral::Bidirectional<u32> for lpspi::Lpspi {}
198
199impl lpspi::Lpspi {
200 fn instance(&self) -> u8 {
204 ral::lpspi::number(&*self.lpspi).unwrap()
205 }
206 pub fn dma_write<'a>(
214 &'a mut self,
215 channel: &'a mut Channel,
216 buffer: &'a [u32],
217 ) -> Result<peripheral::Write<'a, Self, u32>, lpspi::LpspiError> {
218 let mut transaction = self.bus_transaction(buffer)?;
219 transaction.set_receive_data_mask(true);
220
221 self.wait_for_transmit_fifo_space()?;
222 self.enqueue_transaction(transaction);
223 Ok(peripheral::write(channel, buffer, self))
224 }
225
226 pub fn dma_read<'a>(
233 &'a mut self,
234 channel: &'a mut Channel,
235 buffer: &'a mut [u32],
236 ) -> Result<peripheral::Read<'a, Self, u32>, lpspi::LpspiError> {
237 let mut transaction = self.bus_transaction(buffer)?;
238 transaction.set_transmit_data_mask(true);
239
240 self.wait_for_transmit_fifo_space()?;
241 self.enqueue_transaction(transaction);
242 Ok(peripheral::read(channel, self, buffer))
243 }
244
245 pub fn dma_full_duplex<'a>(
253 &'a mut self,
254 rx: &'a mut Channel,
255 tx: &'a mut Channel,
256 buffer: &'a mut [u32],
257 ) -> Result<peripheral::FullDuplex<'a, Self, u32>, lpspi::LpspiError> {
258 let transaction = self.bus_transaction(buffer)?;
259
260 self.wait_for_transmit_fifo_space()?;
261 self.enqueue_transaction(transaction);
262 Ok(peripheral::full_duplex(rx, tx, self, buffer))
263 }
264}
265
266#[cfg(any(chip = "imxrt1010", chip = "imxrt1020", chip = "imxrt1060"))]
268use crate::adc;
269
270#[cfg(any(chip = "imxrt1010", chip = "imxrt1020", chip = "imxrt1060"))]
271unsafe impl peripheral::Source<u16> for adc::DmaSource {
274 fn source_signal(&self) -> u32 {
275 let n = self.instance();
276 ADC_DMA_RX_MAPPING[if n == ral::SOLE_INSTANCE {
277 n as usize
278 } else {
279 n as usize - 1
280 }]
281 }
282 fn source_address(&self) -> *const u16 {
283 self.r0().cast()
284 }
285 fn enable_source(&mut self) {
286 self.enable_dma();
287 }
288 fn disable_source(&mut self) {
289 self.disable_dma();
290 }
291}
292
293#[cfg(any(
295 chip = "imxrt1010",
296 chip = "imxrt1020",
297 chip = "imxrt1060",
298 chip = "imxrt1170"
299))]
300use crate::sai;
301
302#[cfg(any(
303 chip = "imxrt1010",
304 chip = "imxrt1020",
305 chip = "imxrt1060",
306 chip = "imxrt1170"
307))]
308unsafe impl peripheral::Destination<u32> for sai::Tx {
311 fn destination_signal(&self) -> u32 {
312 let instance = ral::sai::number(&*self.sai).unwrap();
313 SAI_DMA_TX_MAPPING[instance as usize - 1]
314 }
315 fn destination_address(&self) -> *const u32 {
316 self.tdr(self.channel())
317 }
318 fn enable_destination(&mut self) {
319 self.enable_dma_transmit();
320 }
321 fn disable_destination(&mut self) {
322 self.disable_dma_transmit();
323 }
324}
325
326#[cfg(any(
327 chip = "imxrt1010",
328 chip = "imxrt1020",
329 chip = "imxrt1060",
330 chip = "imxrt1170"
331))]
332unsafe impl peripheral::Source<u32> for sai::Rx {
335 fn source_signal(&self) -> u32 {
336 let instance = ral::sai::number(&*self.sai).unwrap();
337 SAI_DMA_RX_MAPPING[instance as usize - 1]
338 }
339 fn source_address(&self) -> *const u32 {
340 self.rdr(self.channel())
341 }
342 fn enable_source(&mut self) {
343 self.enable_dma_receive();
344 }
345 fn disable_source(&mut self) {
346 self.disable_dma_receive();
347 }
348}