1use core::mem::size_of;
4use core::ops::Not;
5use rcc::AHB1;
6
7pub trait DmaChannel {
9 fn channel() -> u8;
11}
12
13pub struct C0;
15impl DmaChannel for C0 {
16 fn channel() -> u8 { 0 }
17}
18pub struct C1;
20impl DmaChannel for C1 {
21 fn channel() -> u8 { 1 }
22}
23pub struct C2;
25impl DmaChannel for C2 {
26 fn channel() -> u8 { 2 }
27}
28pub struct C3;
30impl DmaChannel for C3 {
31 fn channel() -> u8 { 3 }
32}
33pub struct C4;
35impl DmaChannel for C4 {
36 fn channel() -> u8 { 4 }
37}
38pub struct C5;
40impl DmaChannel for C5 {
41 fn channel() -> u8 { 5 }
42}
43pub struct C6;
45impl DmaChannel for C6 {
46 fn channel() -> u8 { 6 }
47}
48pub struct C7;
50impl DmaChannel for C7 {
51 fn channel() -> u8 { 7 }
52}
53
54pub trait DmaExt {
56 type Streams;
58
59 fn split(self, ahb: &mut AHB1) -> Self::Streams;
61}
62
63pub enum Event {
65 HalfTransfer,
67 TransferComplete,
69}
70
71#[derive(Debug, Clone, Copy)]
72enum DoubleBuffer {
73 Memory0 = 0,
74 Memory1 = 1,
75}
76
77impl Not for DoubleBuffer {
78 type Output = Self;
79 fn not(self) -> Self::Output {
80 match self {
81 DoubleBuffer::Memory0 =>
82 DoubleBuffer::Memory1,
83 DoubleBuffer::Memory1 =>
84 DoubleBuffer::Memory0,
85 }
86 }
87}
88
89pub trait DmaStream {
91 fn listen(&mut self, event: Event);
93 fn unlisten(&mut self, event: Event);
95
96 fn is_complete(&self) -> bool;
98 fn has_error(&self) -> bool;
100 fn reset(&mut self);
102}
103
104pub trait DmaStreamTransfer<S, T, X: Transfer<Self>>: DmaStream + Sized {
106 fn start_transfer<CHANNEL: DmaChannel>(self, source: S, target: &mut T) -> X;
108}
109
110pub trait Transfer<STREAM>: Sized {
112 fn is_complete(&self) -> bool;
114 fn has_error(&self) -> bool;
116 fn reset(self) -> STREAM;
120
121 fn wait(self) -> Result<STREAM, STREAM> {
123 while !self.is_complete() && !self.has_error() {}
124 if self.is_complete() {
125 Ok(self.reset())
126 } else {
127 Err(self.reset())
128 }
129 }
130}
131
132
133macro_rules! dma {
134 ($($DMAX:ident: ($dmaX:ident, $dmaXen:ident, $dmaXrst:ident, {
135 $($SX:ident: (
136 $sx:ident,
137 $crX:ident: $CRX:ident,
138 $ndtrX:ident: $NDTRX:ident,
139 $parX:ident: $PARX:ident,
140 $m0arX:ident: $M0ARX:ident,
141 $m1arX:ident: $M1ARX:ident,
142 $isr:ident: $ISR:ident,
143 $ifcr:ident: $IFCR:ident,
144 $tcif:ident, $teif:ident,
145 $ctcif:ident, $cteif:ident,
146 ),)+
147 }),)+) => {
148 $(
149 pub mod $dmaX {
151 use stm32f429::{$DMAX, dma2};
152
153 use rcc::AHB1;
154 use dma::{DmaExt, DmaStream, DmaStreamTransfer, DmaChannel,
155 Event, data_size};
156
157 #[derive(Debug)]
160 pub struct Streams {
161 $(
162 pub $sx: $SX
164 ),+
165 }
166
167 $(
168 #[derive(Debug)]
170 pub struct $SX { _0: () }
171
172 impl $SX {
173 fn isr(&self) -> dma2::$isr::R {
174 unsafe { (*$DMAX::ptr()).$isr.read() }
176 }
177
178 fn ifcr(&self) -> &dma2::$IFCR {
179 unsafe { &(*$DMAX::ptr()).$ifcr }
180 }
181
182 fn cr(&mut self) -> &dma2::$CRX {
183 unsafe { &(*$DMAX::ptr()).$crX }
184 }
185
186 fn ndtr(&mut self) -> &dma2::$NDTRX {
187 unsafe { &(*$DMAX::ptr()).$ndtrX }
188 }
189
190 fn par(&mut self) -> &dma2::$PARX {
196 unsafe { &(*$DMAX::ptr()).$parX }
197 }
198
199 fn m0ar(&mut self) -> &dma2::$M0ARX {
200 unsafe { &(*$DMAX::ptr()).$m0arX }
201 }
202
203 fn m1ar(&mut self) -> &dma2::$M1ARX {
204 unsafe { &(*$DMAX::ptr()).$m1arX }
205 }
206 }
207
208 impl DmaStream for $SX {
209 fn listen(&mut self, event: Event) {
210 match event {
211 Event::HalfTransfer => self.cr().modify(|_, w| w.htie().set_bit()),
212 Event::TransferComplete => {
213 self.cr().modify(|_, w| w.tcie().set_bit())
214 }
215 }
216 }
217
218 fn unlisten(&mut self, event: Event) {
219 match event {
220 Event::HalfTransfer => {
221 self.cr().modify(|_, w| w.htie().clear_bit())
222 },
223 Event::TransferComplete => {
224 self.cr().modify(|_, w| w.tcie().clear_bit())
225 }
226 }
227 }
228
229 fn is_complete(&self) -> bool {
230 self.isr().$tcif().bit()
231 }
232
233 fn has_error(&self) -> bool {
234 self.isr().$teif().bit()
235 }
236
237 fn reset(&mut self) {
238 self.cr().modify(|_, w| w.en().clear_bit());
240
241 self.ifcr().modify(|_, w| {
243 w.$ctcif().set_bit()
244 .$cteif().set_bit()
245 });
246 }
247 }
248
249 impl<'s, S> DmaStreamTransfer<(&'s [S], &'s [S]), S, $sx::DoubleBufferedTransfer<S>> for $SX {
250 fn start_transfer<CHANNEL: DmaChannel>(mut self, (source0, source1): (&'s [S], &'s [S]), target: &mut S) -> $sx::DoubleBufferedTransfer<S> {
252 assert_eq!(source0.len(), source1.len());
253
254 self.cr().modify(|_, w| unsafe {
255 w.msize().bits(data_size::<S>())
256 .minc().set_bit()
257 .psize().bits(data_size::<S>())
258 .pinc().clear_bit()
259 .dbm().set_bit()
260 .ct().clear_bit()
261 .circ().set_bit()
262 .dir().bits(0b01)
264 .chsel().bits(CHANNEL::channel())
265 });
266
267 let source0_addr = &source0[0] as *const _ as u32;
268 self.m0ar().write(|w| unsafe { w.bits(source0_addr) });
269 let source1_addr = &source1[0] as *const _ as u32;
270 self.m1ar().write(|w| unsafe { w.bits(source1_addr) });
271 let source_len = source0.len() as u32;
272 self.ndtr().write(|w| unsafe { w.bits(source_len) });
273 let target_addr = target as *const _ as u32;
274 self.par().write(|w| unsafe { w.bits(target_addr) });
275
276 self.cr().modify(|_, w| w.en().set_bit());
278
279 $sx::DoubleBufferedTransfer::new(self)
280 }
281 }
282
283 impl<T, S: AsRef<[T]>> DmaStreamTransfer<S, T, $sx::OneShotTransfer<S>> for $SX {
284 fn start_transfer<CHANNEL: DmaChannel>(mut self, source: S, target: &mut T) -> $sx::OneShotTransfer<S> {
286 self.cr().modify(|_, w| unsafe {
287 w.msize().bits(data_size::<T>())
288 .minc().set_bit()
289 .psize().bits(data_size::<T>())
290 .pinc().clear_bit()
291 .dbm().clear_bit()
292 .ct().clear_bit()
293 .circ().clear_bit()
294 .dir().bits(0b01)
296 .chsel().bits(CHANNEL::channel())
297 });
298
299 let source_addr = source.as_ref() as *const _ as *const () as u32;
300 self.m0ar().write(|w| unsafe { w.bits(source_addr) });
301 let source_len = source.as_ref().len() as u32;
302 self.ndtr().write(|w| unsafe { w.bits(source_len) });
303 let target_addr = target as *const _ as u32;
304 self.par().write(|w| unsafe { w.bits(target_addr) });
305
306 self.cr().modify(|_, w| w.en().set_bit());
308
309 $sx::OneShotTransfer::new(self, source)
310 }
311 }
312
313 pub mod $sx {
315 use core::marker::PhantomData;
316 use dma::{DmaStream, Transfer, DoubleBuffer};
317 use super::$SX;
318
319 pub struct DoubleBufferedTransfer<S> {
321 sent: [bool; 2],
323 _source_el: PhantomData<S>,
324 stream: $SX,
325 }
326
327 impl<S> Transfer<$SX> for DoubleBufferedTransfer<S> {
328 fn is_complete(&self) -> bool {
329 self.stream.is_complete()
330 }
331
332 fn has_error(&self) -> bool {
333 self.stream.has_error()
334 }
335
336 fn reset(mut self) -> $SX {
337 self.stream.reset();
338 self.stream
339 }
340 }
341
342 impl<S> DoubleBufferedTransfer<S> {
343 pub fn new<'s>(stream: $SX) -> Self {
348 Self {
349 sent: [false; 2],
350 _source_el: PhantomData,
351 stream,
352 }
353 }
354
355 #[inline]
357 fn front_buffer(&mut self) -> DoubleBuffer {
358 if self.stream.cr().read().ct().bit() {
359 DoubleBuffer::Memory1
360 } else {
361 DoubleBuffer::Memory0
362 }
363 }
364
365 #[inline]
367 fn back_buffer(&mut self) -> DoubleBuffer {
368 ! self.front_buffer()
369 }
370
371 pub fn writable(&mut self) -> bool {
377 self.sent[self.front_buffer() as usize] = true;
379
380 self.sent[self.back_buffer() as usize]
381 }
382
383 pub fn write<'s>(&mut self, source: &'s [S]) -> Result<(), ()> {
385 if self.has_error() {
386 return Err(())
387 }
388
389 let source_addr = &source[0] as *const _ as u32;
390 let bb = self.back_buffer();
391 match bb {
392 DoubleBuffer::Memory0 =>
393 self.stream.m0ar().write(|w| unsafe { w.bits(source_addr) }),
394 DoubleBuffer::Memory1 =>
395 self.stream.m1ar().write(|w| unsafe { w.bits(source_addr) }),
396 }
397 self.sent[bb as usize] = false;
399
400 Ok(())
401 }
402 }
403
404 pub struct OneShotTransfer<S> {
406 source: S,
407 stream: $SX,
408 }
409
410 impl<S> Transfer<$SX> for OneShotTransfer<S> {
411 fn is_complete(&self) -> bool {
412 self.stream.is_complete()
413 }
414
415 fn has_error(&self) -> bool {
416 self.stream.has_error()
417 }
418
419 fn reset(mut self) -> $SX {
420 drop(self.source);
421 self.stream.reset();
422 self.stream
423 }
424 }
425
426 impl<S> OneShotTransfer<S> {
427 pub fn new<'s>(stream: $SX, source: S) -> Self {
432 Self {
433 source,
434 stream,
435 }
436 }
437
438 pub fn status(&mut self) -> u32 {
440 self.stream.cr().read().bits()
441 }
442 }
443 }
444 )+
445
446 impl DmaExt for $DMAX {
447 type Streams = Streams;
448
449 fn split(self, ahb: &mut AHB1) -> Streams {
450 ahb.enr().modify(|_, w| w.$dmaXen().set_bit());
451 ahb.rstr().modify(|_, w| w.$dmaXrst().set_bit());
452 ahb.rstr().modify(|_, w| w.$dmaXrst().clear_bit());
453
454 $(
456 self.$crX.reset();
457 )+
458
459 Streams {
460 $($sx: $SX { _0: () }),+
461 }
462 }
463 }
464 }
465 )+
466 }
467}
468
469dma! {
470 DMA1: (dma1, dma1en, dma1rst, {
471 S0: (
472 s0,
473 s0cr: S0CR,
474 s0ndtr: S0NDTR,
475 s0par: S0PAR,
476 s0m0ar: S0M0AR,
477 s0m1ar: S0M1AR,
478 lisr: LISR,
479 lifcr: LIFCR,
480 tcif0, teif0,
481 ctcif0, cteif0,
482 ),
483 S1: (
484 s1,
485 s1cr: S1CR,
486 s1ndtr: S1NDTR,
487 s1par: S1PAR,
488 s1m0ar: S1M0AR,
489 s1m1ar: S1M1AR,
490 lisr: LISR,
491 lifcr: LIFCR,
492 tcif1, teif1,
493 ctcif1, cteif1,
494 ),
495 S2: (
496 s2,
497 s2cr: S2CR,
498 s2ndtr: S2NDTR,
499 s2par: S2PAR,
500 s2m0ar: S2M0AR,
501 s2m1ar: S2M1AR,
502 lisr: LISR,
503 lifcr: LIFCR,
504 tcif2, teif2,
505 ctcif2, cteif2,
506 ),
507 S3: (
508 s3,
509 s3cr: S3CR,
510 s3ndtr: S3NDTR,
511 s3par: S3PAR,
512 s3m0ar: S3M0AR,
513 s3m1ar: S3M1AR,
514 lisr: LISR,
515 lifcr: LIFCR,
516 tcif3, teif3,
517 ctcif3, cteif3,
518 ),
519 S4: (
520 s4,
521 s4cr: S4CR,
522 s4ndtr: S4NDTR,
523 s4par: S4PAR,
524 s4m0ar: S4M0AR,
525 s4m1ar: S4M1AR,
526 hisr: HISR,
527 hifcr: HIFCR,
528 tcif4, teif4,
529 ctcif4, cteif4,
530 ),
531 S5: (
532 s5,
533 s5cr: S5CR,
534 s5ndtr: S5NDTR,
535 s5par: S5PAR,
536 s5m0ar: S5M0AR,
537 s5m1ar: S5M1AR,
538 hisr: HISR,
539 hifcr: HIFCR,
540 tcif5, teif5,
541 ctcif5, cteif5,
542 ),
543 S6: (
544 s6,
545 s6cr: S6CR,
546 s6ndtr: S6NDTR,
547 s6par: S6PAR,
548 s6m0ar: S6M0AR,
549 s6m1ar: S6M1AR,
550 hisr: HISR,
551 hifcr: HIFCR,
552 tcif6, teif6,
553 ctcif6, cteif6,
554 ),
555 S7: (
556 s7,
557 s7cr: S7CR,
558 s7ndtr: S7NDTR,
559 s7par: S7PAR,
560 s7m0ar: S7M0AR,
561 s7m1ar: S7M1AR,
562 hisr: HISR,
563 hifcr: HIFCR,
564 tcif7, teif7,
565 ctcif7, cteif7,
566 ),
567 }),
568 DMA2: (dma2, dma2en, dma2rst, {
569 S0: (
570 s0,
571 s0cr: S0CR,
572 s0ndtr: S0NDTR,
573 s0par: S0PAR,
574 s0m0ar: S0M0AR,
575 s0m1ar: S0M1AR,
576 lisr: LISR,
577 lifcr: LIFCR,
578 tcif0, teif0,
579 ctcif0, cteif0,
580 ),
581 S1: (
582 s1,
583 s1cr: S1CR,
584 s1ndtr: S1NDTR,
585 s1par: S1PAR,
586 s1m0ar: S1M0AR,
587 s1m1ar: S1M1AR,
588 lisr: LISR,
589 lifcr: LIFCR,
590 tcif1, teif1,
591 ctcif1, cteif1,
592 ),
593 S2: (
594 s2,
595 s2cr: S2CR,
596 s2ndtr: S2NDTR,
597 s2par: S2PAR,
598 s2m0ar: S2M0AR,
599 s2m1ar: S2M1AR,
600 lisr: LISR,
601 lifcr: LIFCR,
602 tcif2, teif2,
603 ctcif2, cteif2,
604 ),
605 S3: (
606 s3,
607 s3cr: S3CR,
608 s3ndtr: S3NDTR,
609 s3par: S3PAR,
610 s3m0ar: S3M0AR,
611 s3m1ar: S3M1AR,
612 lisr: LISR,
613 lifcr: LIFCR,
614 tcif3, teif3,
615 ctcif3, cteif3,
616 ),
617 S4: (
618 s4,
619 s4cr: S4CR,
620 s4ndtr: S4NDTR,
621 s4par: S4PAR,
622 s4m0ar: S4M0AR,
623 s4m1ar: S4M1AR,
624 hisr: HISR,
625 hifcr: HIFCR,
626 tcif4, teif4,
627 ctcif4, cteif4,
628 ),
629 S5: (
630 s5,
631 s5cr: S5CR,
632 s5ndtr: S5NDTR,
633 s5par: S5PAR,
634 s5m0ar: S5M0AR,
635 s5m1ar: S5M1AR,
636 hisr: HISR,
637 hifcr: HIFCR,
638 tcif5, teif5,
639 ctcif5, cteif5,
640 ),
641 S6: (
642 s6,
643 s6cr: S6CR,
644 s6ndtr: S6NDTR,
645 s6par: S6PAR,
646 s6m0ar: S6M0AR,
647 s6m1ar: S6M1AR,
648 hisr: HISR,
649 hifcr: HIFCR,
650 tcif6, teif6,
651 ctcif6, cteif6,
652 ),
653 S7: (
654 s7,
655 s7cr: S7CR,
656 s7ndtr: S7NDTR,
657 s7par: S7PAR,
658 s7m0ar: S7M0AR,
659 s7m1ar: S7M1AR,
660 hisr: HISR,
661 hifcr: HIFCR,
662 tcif7, teif7,
663 ctcif7, cteif7,
664 ),
665 }),
666}
667
668fn data_size<T>() -> u8 {
669 match size_of::<T>() {
670 1 => 0b00,
671 2 => 0b01,
672 4 => 0b10,
673 _ => panic!("No such data size"),
674 }
675}