1use core::{
11 fmt::{self, Debug, Formatter},
12 marker::PhantomData,
13 mem,
14 ops::Not,
15 ptr,
16 sync::atomic::{compiler_fence, Ordering},
17};
18use embedded_dma::{ReadBuffer, WriteBuffer};
19use enumflags2::BitFlags;
20
21use crate::pac::RCC;
22use crate::{pac, rcc};
23
24pub mod traits;
25use crate::serial::RxISR;
26use traits::{
27 sealed::Bits, Channel, DMASet, Direction, DmaEventExt, DmaFlagExt, Instance, PeriAddress,
28 SafePeripheralRead, Stream, StreamISR,
29};
30
31#[derive(PartialEq, Eq)]
33pub enum DMAError<T> {
34 NotReady(T),
36 SmallBuffer(T),
38 Overrun(T),
40}
41
42impl<T> Debug for DMAError<T> {
46 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
47 match self {
48 DMAError::NotReady(_) => f.debug_tuple("NotReady").finish(),
49 DMAError::SmallBuffer(_) => f.debug_tuple("SmallBuffer").finish(),
50 DMAError::Overrun(_) => f.debug_tuple("Overrun").finish(),
51 }
52 }
53}
54
55#[cfg(not(feature = "gpio-f413"))]
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub enum DmaChannel {
60 Channel0 = 0,
61 Channel1 = 1,
62 Channel2 = 2,
63 Channel3 = 3,
64 Channel4 = 4,
65 Channel5 = 5,
66 Channel6 = 6,
67 Channel7 = 7,
68}
69
70#[cfg(feature = "gpio-f413")]
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
74pub enum DmaChannel {
75 Channel0 = 0,
76 Channel1 = 1,
77 Channel2 = 2,
78 Channel3 = 3,
79 Channel4 = 4,
80 Channel5 = 5,
81 Channel6 = 6,
82 Channel7 = 7,
83 Channel8 = 8,
84 Channel9 = 9,
85 Channel10 = 10,
86 Channel11 = 11,
87 Channel12 = 12,
88 Channel13 = 13,
89 Channel14 = 14,
90 Channel15 = 15,
91}
92
93impl Bits<u8> for DmaChannel {
94 fn bits(self) -> u8 {
95 self as u8
96 }
97}
98
99#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub enum PeripheralIncrementOffset {
102 PeripheralDataSize = 0,
104 FixedSize = 1,
106}
107
108impl Bits<bool> for PeripheralIncrementOffset {
109 fn bits(self) -> bool {
110 match self {
111 PeripheralIncrementOffset::PeripheralDataSize => false,
112 PeripheralIncrementOffset::FixedSize => true,
113 }
114 }
115}
116
117#[derive(Debug, Clone, Copy, PartialEq, Eq)]
119pub enum DmaDataSize {
120 Byte = 0,
121 HalfWord = 1,
122 Word = 2,
123}
124
125impl Bits<u8> for DmaDataSize {
126 fn bits(self) -> u8 {
127 self as u8
128 }
129}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
133pub enum DmaDirection {
134 MemoryToMemory = 2,
136 PeripheralToMemory = 0,
138 MemoryToPeripheral = 1,
140}
141
142impl Bits<u8> for DmaDirection {
143 fn bits(self) -> u8 {
144 self as u8
145 }
146}
147
148#[derive(Debug, Clone, Copy, PartialEq, Eq)]
150pub enum DmaFlowController {
151 Dma = 0,
152 Peripheral = 1,
153}
154
155impl Bits<bool> for DmaFlowController {
156 fn bits(self) -> bool {
157 match self {
158 DmaFlowController::Dma => false,
159 DmaFlowController::Peripheral => true,
160 }
161 }
162}
163
164#[derive(Debug, Clone, Copy)]
166pub struct PeripheralToMemory;
167
168impl Bits<u8> for PeripheralToMemory {
169 #[inline(always)]
170 fn bits(self) -> u8 {
171 0
172 }
173}
174
175impl Direction for PeripheralToMemory {
176 fn new() -> Self {
177 PeripheralToMemory
178 }
179 #[inline(always)]
180 fn direction() -> DmaDirection {
181 DmaDirection::PeripheralToMemory
182 }
183}
184
185#[derive(Debug, Clone, Copy)]
187pub struct MemoryToMemory<T> {
188 _data: PhantomData<T>,
189}
190
191impl<T> Bits<u8> for MemoryToMemory<T> {
192 #[inline(always)]
193 fn bits(self) -> u8 {
194 2
195 }
196}
197
198impl<T> Direction for MemoryToMemory<T> {
199 fn new() -> Self {
200 Self { _data: PhantomData }
201 }
202 #[inline(always)]
203 fn direction() -> DmaDirection {
204 DmaDirection::MemoryToMemory
205 }
206}
207
208#[derive(Debug, Clone, Copy)]
210pub struct MemoryToPeripheral;
211
212impl Bits<u8> for MemoryToPeripheral {
213 #[inline(always)]
214 fn bits(self) -> u8 {
215 1
216 }
217}
218
219impl Direction for MemoryToPeripheral {
220 fn new() -> Self {
221 MemoryToPeripheral
222 }
223 fn direction() -> DmaDirection {
224 DmaDirection::MemoryToPeripheral
225 }
226}
227
228unsafe impl PeriAddress for MemoryToMemory<u8> {
229 fn address(&self) -> u32 {
230 unimplemented!()
231 }
232 type MemSize = u8;
233}
234
235unsafe impl PeriAddress for MemoryToMemory<u16> {
236 fn address(&self) -> u32 {
237 unimplemented!()
238 }
239 type MemSize = u16;
240}
241
242unsafe impl PeriAddress for MemoryToMemory<u32> {
243 fn address(&self) -> u32 {
244 unimplemented!()
245 }
246 type MemSize = u32;
247}
248
249#[derive(Debug, Clone, Copy)]
251pub enum FifoLevel {
252 GtZeroLtQuarter,
254 GteQuarterLtHalf,
256 GteHalfLtThreeQuarter,
258 GteThreeQuarterLtFull,
260 Empty,
262 Full,
264 Invalid,
266}
267
268impl From<u8> for FifoLevel {
269 fn from(value: u8) -> Self {
270 match value {
271 0 => FifoLevel::GtZeroLtQuarter,
272 1 => FifoLevel::GteQuarterLtHalf,
273 2 => FifoLevel::GteHalfLtThreeQuarter,
274 3 => FifoLevel::GteThreeQuarterLtFull,
275 4 => FifoLevel::Empty,
276 5 => FifoLevel::Full,
277 _ => FifoLevel::Invalid,
278 }
279 }
280}
281
282#[derive(Debug, Clone, Copy, PartialEq, Eq)]
284pub enum CurrentBuffer {
285 FirstBuffer,
287 SecondBuffer,
289}
290
291impl Not for CurrentBuffer {
292 type Output = CurrentBuffer;
293
294 fn not(self) -> Self::Output {
295 if self == CurrentBuffer::FirstBuffer {
296 CurrentBuffer::SecondBuffer
297 } else {
298 CurrentBuffer::FirstBuffer
299 }
300 }
301}
302
303#[enumflags2::bitflags]
305#[repr(u32)]
306#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
307pub enum DmaEvent {
308 DirectModeError = 1 << 1,
309 TransferError = 1 << 2,
310 HalfTransfer = 1 << 3,
311 TransferComplete = 1 << 4,
312}
313
314impl DmaEventExt for BitFlags<DmaEvent> {
315 #[inline(always)]
316 fn is_listen_transfer_complete(&self) -> bool {
317 self.contains(DmaEvent::TransferComplete)
318 }
319 #[inline(always)]
320 fn is_listen_half_transfer(&self) -> bool {
321 self.contains(DmaEvent::HalfTransfer)
322 }
323 #[inline(always)]
324 fn is_listen_transfer_error(&self) -> bool {
325 self.contains(DmaEvent::TransferError)
326 }
327 #[inline(always)]
328 fn is_listen_direct_mode_error(&self) -> bool {
329 self.contains(DmaEvent::DirectModeError)
330 }
331}
332
333#[enumflags2::bitflags]
335#[repr(u32)]
336#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
337pub enum DmaFlag {
338 FifoError = 1 << 0,
339 DirectModeError = 1 << 2,
340 TransferError = 1 << 3,
341 HalfTransfer = 1 << 4,
342 TransferComplete = 1 << 5,
343}
344
345impl DmaFlagExt for BitFlags<DmaFlag> {
346 #[inline(always)]
347 fn is_transfer_complete(&self) -> bool {
348 self.contains(DmaFlag::TransferComplete)
349 }
350
351 #[inline(always)]
352 fn is_half_transfer(&self) -> bool {
353 self.contains(DmaFlag::HalfTransfer)
354 }
355
356 #[inline(always)]
357 fn is_transfer_error(&self) -> bool {
358 self.contains(DmaFlag::TransferError)
359 }
360
361 #[inline(always)]
362 fn is_direct_mode_error(&self) -> bool {
363 self.contains(DmaFlag::DirectModeError)
364 }
365
366 #[inline(always)]
367 fn is_fifo_error(&self) -> bool {
368 self.contains(DmaFlag::FifoError)
369 }
370}
371
372pub struct StreamX<DMA, const S: u8> {
374 _dma: PhantomData<DMA>,
375}
376
377impl<DMA, const S: u8> StreamX<DMA, S> {
378 fn new() -> Self {
379 Self { _dma: PhantomData }
380 }
381}
382
383impl<DMA: Instance, const S: u8> StreamX<DMA, S> {
384 #[cfg(not(any(feature = "gpio-f411", feature = "gpio-f413", feature = "gpio-f410")))]
385 #[inline(always)]
386 unsafe fn st() -> &'static pac::dma2::ST {
387 (*DMA::ptr()).st(S as usize)
388 }
389 #[cfg(any(feature = "gpio-f411", feature = "gpio-f413", feature = "gpio-f410"))]
390 #[inline(always)]
391 unsafe fn st() -> &'static pac::dma1::ST {
392 (*DMA::ptr()).st(S as usize)
393 }
394}
395
396pub type Stream0<DMA> = StreamX<DMA, 0>;
398pub type Stream1<DMA> = StreamX<DMA, 1>;
400pub type Stream2<DMA> = StreamX<DMA, 2>;
402pub type Stream3<DMA> = StreamX<DMA, 3>;
404pub type Stream4<DMA> = StreamX<DMA, 4>;
406pub type Stream5<DMA> = StreamX<DMA, 5>;
408pub type Stream6<DMA> = StreamX<DMA, 6>;
410pub type Stream7<DMA> = StreamX<DMA, 7>;
412
413impl<DMA> crate::Sealed for StreamX<DMA, 0> {}
414impl<DMA> crate::Sealed for StreamX<DMA, 1> {}
415impl<DMA> crate::Sealed for StreamX<DMA, 2> {}
416impl<DMA> crate::Sealed for StreamX<DMA, 3> {}
417impl<DMA> crate::Sealed for StreamX<DMA, 4> {}
418impl<DMA> crate::Sealed for StreamX<DMA, 5> {}
419impl<DMA> crate::Sealed for StreamX<DMA, 6> {}
420impl<DMA> crate::Sealed for StreamX<DMA, 7> {}
421
422pub struct StreamsTuple<DMA>(
424 pub StreamX<DMA, 0>,
425 pub StreamX<DMA, 1>,
426 pub StreamX<DMA, 2>,
427 pub StreamX<DMA, 3>,
428 pub StreamX<DMA, 4>,
429 pub StreamX<DMA, 5>,
430 pub StreamX<DMA, 6>,
431 pub StreamX<DMA, 7>,
432);
433
434impl<DMA: rcc::Enable + rcc::Reset> StreamsTuple<DMA> {
435 pub fn new(_regs: DMA, rcc: &mut RCC) -> Self {
437 DMA::enable(rcc);
438 DMA::reset(rcc);
439 Self(
440 StreamX::new(),
441 StreamX::new(),
442 StreamX::new(),
443 StreamX::new(),
444 StreamX::new(),
445 StreamX::new(),
446 StreamX::new(),
447 StreamX::new(),
448 )
449 }
450}
451
452impl<I: Instance, const S: u8> crate::Listen for StreamX<I, S>
453where
454 Self: crate::Sealed + StreamISR,
455{
456 type Event = DmaEvent;
457
458 #[inline(always)]
459 fn listen(&mut self, interrupts: impl Into<BitFlags<DmaEvent>>) {
460 self.listen_event(None, Some(interrupts.into()));
461 }
462
463 #[inline(always)]
464 fn listen_only(&mut self, interrupts: impl Into<BitFlags<DmaEvent>>) {
465 self.listen_event(Some(BitFlags::ALL), Some(interrupts.into()));
466 }
467
468 #[inline(always)]
469 fn unlisten(&mut self, interrupts: impl Into<BitFlags<DmaEvent>>) {
470 self.listen_event(Some(interrupts.into()), None);
471 }
472}
473
474impl<I: Instance, const S: u8> Stream for StreamX<I, S>
475where
476 Self: crate::Sealed + StreamISR,
477{
478 const NUMBER: usize = S as usize;
479
480 #[inline(always)]
481 fn set_peripheral_address(&mut self, value: u32) {
482 unsafe { Self::st() }
483 .par()
484 .write(|w| unsafe { w.pa().bits(value) });
485 }
486
487 #[inline(always)]
488 fn set_memory_address(&mut self, value: u32) {
489 unsafe { Self::st() }
490 .m0ar()
491 .write(|w| unsafe { w.m0a().bits(value) });
492 }
493
494 #[inline(always)]
495 fn memory_address(&self) -> u32 {
496 unsafe { Self::st() }.m0ar().read().m0a().bits()
497 }
498
499 #[inline(always)]
500 fn set_alternate_memory_address(&mut self, value: u32) {
501 unsafe { Self::st() }
502 .m1ar()
503 .write(|w| unsafe { w.m1a().bits(value) });
504 }
505
506 #[inline(always)]
507 fn alternate_memory_address(&self) -> u32 {
508 unsafe { Self::st() }.m1ar().read().m1a().bits()
509 }
510
511 #[inline(always)]
512 fn set_number_of_transfers(&mut self, value: u16) {
513 unsafe { Self::st() }.ndtr().write(|w| w.ndt().set(value));
514 }
515
516 #[inline(always)]
517 fn number_of_transfers(&self) -> u16 {
518 unsafe { Self::st() }.ndtr().read().ndt().bits()
519 }
520
521 #[inline(always)]
522 unsafe fn enable(&mut self) {
523 Self::st().cr().modify(|_, w| w.en().set_bit());
524 }
525
526 #[inline(always)]
527 fn is_enabled(&self) -> bool {
528 unsafe { Self::st() }.cr().read().en().bit_is_set()
529 }
530
531 #[inline(always)]
532 unsafe fn disable(&mut self) {
533 unsafe { Self::st() }.cr().modify(|_, w| w.en().clear_bit());
534 }
535
536 #[inline(always)]
537 fn set_channel(&mut self, channel: DmaChannel) {
538 unsafe { Self::st() }
539 .cr()
540 .modify(|_, w| w.chsel().set(channel.bits()));
541 }
542
543 #[inline(always)]
544 fn set_priority(&mut self, priority: config::Priority) {
545 unsafe { Self::st() }
546 .cr()
547 .modify(|_, w| w.pl().set(priority.bits()));
548 }
549
550 #[inline(always)]
551 fn set_peripheral_increment_offset(&mut self, value: PeripheralIncrementOffset) {
552 unsafe { Self::st() }
553 .cr()
554 .modify(|_, w| w.pincos().bit(value.bits()));
555 }
556
557 #[inline(always)]
558 unsafe fn set_memory_size(&mut self, size: DmaDataSize) {
559 Self::st().cr().modify(|_, w| w.msize().bits(size.bits()));
560 }
561
562 #[inline(always)]
563 unsafe fn set_peripheral_size(&mut self, size: DmaDataSize) {
564 Self::st().cr().modify(|_, w| w.psize().bits(size.bits()));
565 }
566
567 #[inline(always)]
568 fn set_memory_increment(&mut self, increment: bool) {
569 unsafe { Self::st() }
570 .cr()
571 .modify(|_, w| w.minc().bit(increment));
572 }
573
574 #[inline(always)]
575 fn set_peripheral_increment(&mut self, increment: bool) {
576 unsafe { Self::st() }
577 .cr()
578 .modify(|_, w| w.pinc().bit(increment));
579 }
580
581 #[inline(always)]
582 fn set_circular_mode(&mut self, value: bool) {
583 unsafe { Self::st() }
584 .cr()
585 .modify(|_, w| w.circ().bit(value));
586 }
587
588 #[inline(always)]
589 fn set_direction(&mut self, direction: DmaDirection) {
590 unsafe { Self::st() }
591 .cr()
592 .modify(|_, w| unsafe { w.dir().bits(direction.bits()) });
593 }
594
595 #[inline(always)]
596 fn set_flow_controller(&mut self, value: DmaFlowController) {
597 unsafe { Self::st() }
598 .cr()
599 .modify(|_, w| w.pfctrl().bit(value.bits()));
600 }
601
602 #[inline(always)]
603 fn events(&self) -> BitFlags<DmaEvent> {
604 BitFlags::from_bits_truncate(unsafe { Self::st() }.cr().read().bits())
605 }
606
607 #[inline(always)]
608 fn listen_fifo_error(&mut self) {
609 unsafe { Self::st() }
610 .fcr()
611 .modify(|_, w| w.feie().set_bit());
612 }
613
614 #[inline(always)]
615 fn unlisten_fifo_error(&mut self) {
616 unsafe { Self::st() }
617 .fcr()
618 .modify(|_, w| w.feie().clear_bit());
619 }
620
621 #[inline(always)]
622 fn set_double_buffer(&mut self, double_buffer: bool) {
623 unsafe { Self::st() }
624 .cr()
625 .modify(|_, w| w.dbm().bit(double_buffer));
626 }
627
628 #[inline(always)]
629 fn set_fifo_threshold(&mut self, fifo_threshold: config::FifoThreshold) {
630 unsafe { Self::st() }
631 .fcr()
632 .modify(|_, w| w.fth().set(fifo_threshold.bits()));
633 }
634
635 #[inline(always)]
636 fn set_fifo_enable(&mut self, fifo_enable: bool) {
637 unsafe { Self::st() }
639 .fcr()
640 .modify(|_, w| w.dmdis().bit(fifo_enable));
641 }
642
643 #[inline(always)]
644 fn set_memory_burst(&mut self, memory_burst: config::BurstMode) {
645 unsafe { Self::st() }
646 .cr()
647 .modify(|_, w| w.mburst().set(memory_burst.bits()));
648 }
649
650 #[inline(always)]
651 fn set_peripheral_burst(&mut self, peripheral_burst: config::BurstMode) {
652 unsafe { Self::st() }
653 .cr()
654 .modify(|_, w| w.pburst().set(peripheral_burst.bits()));
655 }
656
657 #[inline(always)]
658 fn fifo_level(&self) -> FifoLevel {
659 unsafe { Self::st() }.fcr().read().fs().bits().into()
660 }
661
662 fn current_buffer(&self) -> CurrentBuffer {
663 if unsafe { Self::st() }.cr().read().ct().bit_is_set() {
664 CurrentBuffer::SecondBuffer
665 } else {
666 CurrentBuffer::FirstBuffer
667 }
668 }
669}
670
671impl<I: Instance, const S: u8> StreamX<I, S>
672where
673 Self: crate::Sealed + StreamISR,
674{
675 fn listen_event(
676 &mut self,
677 disable: Option<BitFlags<DmaEvent>>,
678 enable: Option<BitFlags<DmaEvent>>,
679 ) {
680 unsafe {
681 Self::st().cr().modify(|r, w| {
682 w.bits({
683 let mut bits = r.bits();
684 if let Some(d) = disable {
685 bits &= !d.bits()
686 }
687 if let Some(e) = enable {
688 bits |= e.bits();
689 }
690 bits
691 })
692 });
693 }
694 }
695}
696
697macro_rules! dma_stream {
700 ($(($number:literal, $isr_shift:literal, $ifcr:ident, $isr:ident)),+
701 $(,)*) => {
702 $(
703 impl<I: Instance> crate::ClearFlags for StreamX<I, $number> {
704 type Flag = DmaFlag;
705
706
707 #[inline(always)]
708 fn clear_flags(&mut self, flags: impl Into<BitFlags<DmaFlag>>) {
709 let dma = unsafe { &*I::ptr() };
710 dma.$ifcr().write(|w| unsafe { w.bits(flags.into().bits() << $isr_shift) });
711 }
712 }
713
714 impl<I: Instance> crate::ReadFlags for StreamX<I, $number> {
715 type Flag = DmaFlag;
716
717 #[inline(always)]
718 fn flags(&self) -> BitFlags<DmaFlag>
719 {
720 let dma = unsafe { &*I::ptr() };
722 BitFlags::from_bits_truncate(
723 ((dma.$isr().read().bits() >> $isr_shift))
724 )
725 }
726 }
727
728 impl<I: Instance> StreamISR for StreamX<I, $number> { }
729 )+
730 };
731}
732
733dma_stream!(
734 (0, 0, lifcr, lisr),
735 (1, 6, lifcr, lisr),
736 (2, 16, lifcr, lisr),
737 (3, 22, lifcr, lisr),
738 (4, 0, hifcr, hisr),
739 (5, 6, hifcr, hisr),
740 (6, 16, hifcr, hisr),
741 (7, 22, hifcr, hisr),
742);
743
744#[derive(Debug, Clone, Copy)]
746pub struct ChannelX<const C: u8>;
747
748macro_rules! dma_channel {
749 ($(($name:ident, $num:literal)),+ $(,)*) => {
750 $(
751 impl Channel for ChannelX<$num> {
752 const VALUE: DmaChannel = DmaChannel::$name ;
753 }
754 pub type $name = ChannelX<$num>;
755 )+
756 };
757}
758
759dma_channel!(
760 (Channel0, 0),
761 (Channel1, 1),
762 (Channel2, 2),
763 (Channel3, 3),
764 (Channel4, 4),
765 (Channel5, 5),
766 (Channel6, 6),
767 (Channel7, 7),
768);
769
770#[cfg(feature = "gpio-f413")]
771dma_channel!((Channel8, 8), (Channel9, 9),);
772
773pub mod config {
775 use super::Bits;
776
777 #[derive(Debug, Clone, Copy)]
781 pub enum Priority {
782 Low,
784 Medium,
786 High,
788 VeryHigh,
790 }
791
792 impl Bits<u8> for Priority {
793 fn bits(self) -> u8 {
794 match self {
795 Priority::Low => 0,
796 Priority::Medium => 1,
797 Priority::High => 2,
798 Priority::VeryHigh => 3,
799 }
800 }
801 }
802
803 #[derive(Debug, Clone, Copy)]
805 pub enum FifoThreshold {
806 QuarterFull,
808 HalfFull,
810 ThreeQuarterFull,
812 Full,
814 }
815
816 impl Bits<u8> for FifoThreshold {
817 fn bits(self) -> u8 {
818 match self {
819 FifoThreshold::QuarterFull => 0,
820 FifoThreshold::HalfFull => 1,
821 FifoThreshold::ThreeQuarterFull => 2,
822 FifoThreshold::Full => 3,
823 }
824 }
825 }
826
827 #[derive(Debug, Clone, Copy)]
829 pub enum BurstMode {
830 NoBurst,
832 Burst4,
834 Burst8,
836 Burst16,
838 }
839
840 impl Bits<u8> for BurstMode {
841 fn bits(self) -> u8 {
842 match self {
843 BurstMode::NoBurst => 0,
844 BurstMode::Burst4 => 1,
845 BurstMode::Burst8 => 2,
846 BurstMode::Burst16 => 3,
847 }
848 }
849 }
850
851 #[derive(Debug, Clone, Copy)]
853 pub struct DmaConfig {
854 pub(crate) priority: Priority,
855 pub(crate) memory_increment: bool,
856 pub(crate) peripheral_increment: bool,
857 pub(crate) transfer_complete_interrupt: bool,
858 pub(crate) half_transfer_interrupt: bool,
859 pub(crate) transfer_error_interrupt: bool,
860 pub(crate) direct_mode_error_interrupt: bool,
861 pub(crate) fifo_error_interrupt: bool,
862 pub(crate) double_buffer: bool,
863 pub(crate) fifo_threshold: FifoThreshold,
864 pub(crate) fifo_enable: bool,
865 pub(crate) memory_burst: BurstMode,
866 pub(crate) peripheral_burst: BurstMode,
867 }
868
869 impl Default for DmaConfig {
870 fn default() -> Self {
871 Self {
872 priority: Priority::Medium,
873 memory_increment: false,
874 peripheral_increment: false,
875 transfer_complete_interrupt: false,
876 half_transfer_interrupt: false,
877 transfer_error_interrupt: false,
878 direct_mode_error_interrupt: false,
879 fifo_error_interrupt: false,
880 double_buffer: false,
881 fifo_threshold: FifoThreshold::QuarterFull,
882 fifo_enable: false,
883 memory_burst: BurstMode::NoBurst,
884 peripheral_burst: BurstMode::NoBurst,
885 }
886 }
887 }
888
889 impl DmaConfig {
890 #[inline(always)]
892 pub fn priority(mut self, priority: Priority) -> Self {
893 self.priority = priority;
894 self
895 }
896
897 #[inline(always)]
899 pub fn memory_increment(mut self, memory_increment: bool) -> Self {
900 self.memory_increment = memory_increment;
901 self
902 }
903 #[inline(always)]
905 pub fn peripheral_increment(mut self, peripheral_increment: bool) -> Self {
906 self.peripheral_increment = peripheral_increment;
907 self
908 }
909 #[inline(always)]
911 pub fn transfer_complete_interrupt(mut self, transfer_complete_interrupt: bool) -> Self {
912 self.transfer_complete_interrupt = transfer_complete_interrupt;
913 self
914 }
915 #[inline(always)]
917 pub fn half_transfer_interrupt(mut self, half_transfer_interrupt: bool) -> Self {
918 self.half_transfer_interrupt = half_transfer_interrupt;
919 self
920 }
921 #[inline(always)]
923 pub fn transfer_error_interrupt(mut self, transfer_error_interrupt: bool) -> Self {
924 self.transfer_error_interrupt = transfer_error_interrupt;
925 self
926 }
927 #[inline(always)]
929 pub fn direct_mode_error_interrupt(mut self, direct_mode_error_interrupt: bool) -> Self {
930 self.direct_mode_error_interrupt = direct_mode_error_interrupt;
931 self
932 }
933 #[inline(always)]
935 pub fn fifo_error_interrupt(mut self, fifo_error_interrupt: bool) -> Self {
936 self.fifo_error_interrupt = fifo_error_interrupt;
937 self
938 }
939 #[inline(always)]
941 pub fn double_buffer(mut self, double_buffer: bool) -> Self {
942 self.double_buffer = double_buffer;
943 self
944 }
945 #[inline(always)]
947 pub fn fifo_threshold(mut self, fifo_threshold: FifoThreshold) -> Self {
948 self.fifo_threshold = fifo_threshold;
949 self
950 }
951 #[inline(always)]
953 pub fn fifo_enable(mut self, fifo_enable: bool) -> Self {
954 self.fifo_enable = fifo_enable;
955 self
956 }
957 #[inline(always)]
959 pub fn memory_burst(mut self, memory_burst: BurstMode) -> Self {
960 self.memory_burst = memory_burst;
961 self
962 }
963 #[inline(always)]
965 pub fn peripheral_burst(mut self, peripheral_burst: BurstMode) -> Self {
966 self.peripheral_burst = peripheral_burst;
967 self
968 }
969 }
970}
971
972pub struct Transfer<STREAM, const CHANNEL: u8, PERIPHERAL, DIRECTION, BUF>
974where
975 STREAM: Stream,
976 PERIPHERAL: PeriAddress,
977{
978 stream: STREAM,
979 peripheral: PERIPHERAL,
980 _direction: PhantomData<DIRECTION>,
981 buf: Option<BUF>,
982 double_buf: Option<BUF>,
983 transfer_length: u16,
985}
986
987fn stream_disable<T: Stream>(stream: &mut T) {
990 if stream.is_enabled() {
991 let interrupts = stream.events();
993 stream.unlisten(BitFlags::ALL);
994 unsafe { stream.disable() };
995 while stream.is_enabled() {}
996
997 stream.clear_all_flags();
998 stream.listen(interrupts);
999 }
1000}
1001
1002impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF>
1003 Transfer<STREAM, CHANNEL, PERIPHERAL, MemoryToPeripheral, BUF>
1004where
1005 STREAM: Stream,
1006 ChannelX<CHANNEL>: Channel,
1007 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, MemoryToPeripheral>,
1008 BUF: ReadBuffer<Word = <PERIPHERAL as PeriAddress>::MemSize>,
1009{
1010 pub fn init_memory_to_peripheral(
1018 mut stream: STREAM,
1019 peripheral: PERIPHERAL,
1020 buf: BUF,
1021 double_buf: Option<BUF>,
1022 config: config::DmaConfig,
1023 ) -> Self {
1024 let first_buf = {
1025 let (buf_ptr, buf_len) = unsafe { buf.read_buffer() };
1028 (buf_ptr as u32, buf_len as u16)
1029 };
1030
1031 let db = double_buf.as_ref().map(|db| {
1032 let (db_ptr, db_len) = unsafe { db.read_buffer() };
1033 (db_ptr as u32, db_len as u16)
1034 });
1035 let n_transfers = Self::init_common(&mut stream, &peripheral, config, first_buf, db);
1036
1037 Self {
1038 stream,
1039 peripheral,
1040 _direction: PhantomData,
1041 buf: Some(buf),
1042 double_buf,
1043 transfer_length: n_transfers,
1044 }
1045 }
1046
1047 pub fn next_transfer(&mut self, new_buf: BUF) -> Result<(BUF, CurrentBuffer), DMAError<BUF>> {
1059 let ptr_and_len = {
1060 let (buf_ptr, buf_len) = unsafe { new_buf.read_buffer() };
1063 (buf_ptr as u32, buf_len as u16)
1064 };
1065 self.next_transfer_common(new_buf, ptr_and_len, self.double_buf.is_some())
1066 }
1067
1068 pub unsafe fn next_transfer_with<F, T>(&mut self, f: F) -> Result<T, DMAError<()>>
1088 where
1089 F: FnOnce(BUF, CurrentBuffer) -> (BUF, T),
1090 {
1091 if self.double_buf.is_some() {
1092 if !self.stream.is_transfer_complete() {
1093 return Err(DMAError::NotReady(()));
1094 }
1095 self.stream.clear_transfer_complete();
1096
1097 let current_buffer = self.stream.current_buffer();
1098 let db = if current_buffer == CurrentBuffer::SecondBuffer {
1100 self.buf.take().unwrap()
1101 } else {
1102 self.double_buf.take().unwrap()
1103 };
1104 let r = f(db, !current_buffer);
1105 let new_buf = r.0;
1106 let ptr_and_len = {
1107 let (new_buf_ptr, new_buf_len) = new_buf.read_buffer();
1108 (new_buf_ptr as u32, new_buf_len as u16)
1109 };
1110 self.next_transfer_with_common(new_buf, ptr_and_len, true, current_buffer);
1111 return Ok(r.1);
1112 }
1113 stream_disable(&mut self.stream);
1114 self.stream.clear_transfer_complete();
1115
1116 compiler_fence(Ordering::SeqCst);
1118
1119 let old_buf = self.buf.take().unwrap();
1121 let r = f(old_buf, CurrentBuffer::FirstBuffer);
1122 let new_buf = r.0;
1123
1124 let ptr_and_len = {
1125 let (new_buf_ptr, new_buf_len) = new_buf.read_buffer();
1126 (new_buf_ptr as u32, new_buf_len as u16)
1127 };
1128 self.next_transfer_with_common(new_buf, ptr_and_len, false, CurrentBuffer::FirstBuffer);
1129 Ok(r.1)
1130 }
1131}
1132
1133impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF> RxISR
1134 for Transfer<STREAM, CHANNEL, PERIPHERAL, PeripheralToMemory, BUF>
1135where
1136 STREAM: Stream,
1137 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, PeripheralToMemory> + RxISR,
1138{
1139 fn is_idle(&self) -> bool {
1141 self.peripheral.is_idle()
1142 }
1143
1144 fn is_rx_not_empty(&self) -> bool {
1146 self.peripheral.is_rx_not_empty()
1147 }
1148
1149 fn clear_idle_interrupt(&self) {
1151 self.peripheral.clear_idle_interrupt();
1152 }
1153}
1154
1155impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF>
1156 Transfer<STREAM, CHANNEL, PERIPHERAL, PeripheralToMemory, BUF>
1157where
1158 STREAM: Stream,
1159 ChannelX<CHANNEL>: Channel,
1160 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, PeripheralToMemory> + SafePeripheralRead,
1161 BUF: WriteBuffer<Word = <PERIPHERAL as PeriAddress>::MemSize>,
1162{
1163 pub fn peripheral(&self) -> &PERIPHERAL {
1165 &self.peripheral
1166 }
1167}
1168
1169impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF>
1170 Transfer<STREAM, CHANNEL, PERIPHERAL, PeripheralToMemory, BUF>
1171where
1172 STREAM: Stream,
1173 ChannelX<CHANNEL>: Channel,
1174 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, PeripheralToMemory>,
1175 BUF: WriteBuffer<Word = <PERIPHERAL as PeriAddress>::MemSize>,
1176{
1177 pub fn init_peripheral_to_memory(
1185 mut stream: STREAM,
1186 peripheral: PERIPHERAL,
1187 mut buf: BUF,
1188 mut double_buf: Option<BUF>,
1189 config: config::DmaConfig,
1190 ) -> Self {
1191 let first_buf = {
1192 let (buf_ptr, buf_len) = unsafe { buf.write_buffer() };
1195 (buf_ptr as u32, buf_len as u16)
1196 };
1197
1198 let db = double_buf.as_mut().map(|db| {
1199 let (db_ptr, db_len) = unsafe { db.write_buffer() };
1200 (db_ptr as u32, db_len as u16)
1201 });
1202 let n_transfers = Self::init_common(&mut stream, &peripheral, config, first_buf, db);
1203
1204 Self {
1205 stream,
1206 peripheral,
1207 _direction: PhantomData,
1208 buf: Some(buf),
1209 double_buf,
1210 transfer_length: n_transfers,
1211 }
1212 }
1213
1214 pub fn next_transfer(
1226 &mut self,
1227 mut new_buf: BUF,
1228 ) -> Result<(BUF, CurrentBuffer), DMAError<BUF>> {
1229 let ptr_and_len = {
1230 let (buf_ptr, buf_len) = unsafe { new_buf.write_buffer() };
1233 (buf_ptr as u32, buf_len as u16)
1234 };
1235 self.next_transfer_common(new_buf, ptr_and_len, self.double_buf.is_some())
1236 }
1237
1238 pub unsafe fn next_transfer_with<F, T>(&mut self, f: F) -> Result<T, DMAError<()>>
1258 where
1259 F: FnOnce(BUF, CurrentBuffer) -> (BUF, T),
1260 {
1261 if self.double_buf.is_some() {
1262 if !self.stream.is_transfer_complete() {
1263 return Err(DMAError::NotReady(()));
1264 }
1265 self.stream.clear_transfer_complete();
1266
1267 let current_buffer = self.stream.current_buffer();
1268 let db = if current_buffer == CurrentBuffer::SecondBuffer {
1270 self.buf.take().unwrap()
1271 } else {
1272 self.double_buf.take().unwrap()
1273 };
1274 let r = f(db, !current_buffer);
1275 let mut new_buf = r.0;
1276 let ptr_and_len = {
1277 let (new_buf_ptr, new_buf_len) = new_buf.write_buffer();
1278 (new_buf_ptr as u32, new_buf_len as u16)
1279 };
1280 self.next_transfer_with_common(new_buf, ptr_and_len, true, current_buffer);
1281 return Ok(r.1);
1282 }
1283 stream_disable(&mut self.stream);
1284 self.stream.clear_transfer_complete();
1285
1286 compiler_fence(Ordering::SeqCst);
1288
1289 let old_buf = self.buf.take().unwrap();
1291 let r = f(old_buf, CurrentBuffer::FirstBuffer);
1292 let mut new_buf = r.0;
1293
1294 let ptr_and_len = {
1295 let (new_buf_ptr, new_buf_len) = new_buf.write_buffer();
1296 (new_buf_ptr as u32, new_buf_len as u16)
1297 };
1298 self.next_transfer_with_common(new_buf, ptr_and_len, false, CurrentBuffer::FirstBuffer);
1299 Ok(r.1)
1300 }
1301}
1302
1303impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF, S>
1304 Transfer<STREAM, CHANNEL, PERIPHERAL, MemoryToMemory<S>, BUF>
1305where
1306 STREAM: Stream,
1307 ChannelX<CHANNEL>: Channel,
1308 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, MemoryToMemory<S>>,
1309 MemoryToMemory<S>: PeriAddress,
1310 BUF: WriteBuffer<Word = <PERIPHERAL as PeriAddress>::MemSize>,
1311{
1312 pub fn init_memory_to_memory(
1322 mut stream: STREAM,
1323 peripheral: PERIPHERAL,
1324 mut buf: BUF,
1325 mut double_buf: BUF,
1326 config: config::DmaConfig,
1327 ) -> Self {
1328 let first_buf = {
1329 let (buf_ptr, buf_len) = unsafe { buf.write_buffer() };
1332 (buf_ptr as u32, buf_len as u16)
1333 };
1334
1335 let db = {
1336 let (db_ptr, db_len) = unsafe { double_buf.write_buffer() };
1337 (db_ptr as u32, db_len as u16)
1338 };
1339 let n_transfers = Self::init_common(&mut stream, &peripheral, config, first_buf, Some(db));
1340
1341 Self {
1342 stream,
1343 peripheral,
1344 _direction: PhantomData,
1345 buf: Some(buf),
1346 double_buf: Some(double_buf),
1347 transfer_length: n_transfers,
1348 }
1349 }
1350
1351 pub fn next_transfer(
1358 &mut self,
1359 mut new_buf: BUF,
1360 ) -> Result<(BUF, CurrentBuffer), DMAError<BUF>> {
1361 let ptr_and_len = {
1362 let (buf_ptr, buf_len) = unsafe { new_buf.write_buffer() };
1365 (buf_ptr as u32, buf_len as u16)
1366 };
1367 self.next_transfer_common(new_buf, ptr_and_len, false)
1368 }
1369
1370 pub fn next_transfer_with<F, T>(&mut self, f: F) -> T
1376 where
1377 F: FnOnce(BUF, CurrentBuffer) -> (BUF, T),
1378 {
1379 stream_disable(&mut self.stream);
1380 self.stream.clear_transfer_complete();
1381
1382 compiler_fence(Ordering::SeqCst);
1384
1385 let old_buf = self.buf.take().unwrap();
1387 let r = f(old_buf, CurrentBuffer::FirstBuffer);
1388 let mut new_buf = r.0;
1389
1390 let ptr_and_len = {
1391 let (new_buf_ptr, new_buf_len) = unsafe { new_buf.write_buffer() };
1392 (new_buf_ptr as u32, new_buf_len as u16)
1393 };
1394 unsafe {
1396 self.next_transfer_with_common(new_buf, ptr_and_len, false, CurrentBuffer::FirstBuffer);
1397 }
1398 r.1
1399 }
1400}
1401
1402impl<STREAM, const CHANNEL: u8, PERIPHERAL, DIR, BUF>
1403 Transfer<STREAM, CHANNEL, PERIPHERAL, DIR, BUF>
1404where
1405 STREAM: Stream,
1406 ChannelX<CHANNEL>: Channel,
1407 DIR: Direction,
1408 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, DIR>,
1409{
1410 pub fn start<F>(&mut self, f: F)
1412 where
1413 F: FnOnce(&mut PERIPHERAL),
1414 {
1415 compiler_fence(Ordering::Release);
1417
1418 unsafe {
1419 self.stream.enable();
1420 }
1421 f(&mut self.peripheral);
1422 }
1423
1424 pub fn pause<F>(&mut self, f: F)
1426 where
1427 F: FnOnce(&mut PERIPHERAL),
1428 {
1429 f(&mut self.peripheral);
1430 stream_disable(&mut self.stream)
1431 }
1432
1433 pub fn release(mut self) -> (STREAM, PERIPHERAL, BUF, Option<BUF>) {
1435 stream_disable(&mut self.stream);
1436 compiler_fence(Ordering::SeqCst);
1437 self.stream.clear_all_flags();
1438
1439 unsafe {
1440 let stream = ptr::read(&self.stream);
1441 let peripheral = ptr::read(&self.peripheral);
1442 let buf = ptr::read(&self.buf);
1443 let double_buf = ptr::read(&self.double_buf);
1444 mem::forget(self);
1445 (stream, peripheral, buf.unwrap(), double_buf)
1446 }
1447 }
1448
1449 pub fn number_of_transfers(&self) -> u16 {
1451 self.stream.number_of_transfers()
1452 }
1453
1454 pub unsafe fn stream(&mut self) -> &mut STREAM {
1462 &mut self.stream
1463 }
1464
1465 #[inline(always)]
1467 pub fn wait(&self) {
1468 while !self.stream.is_transfer_complete() {}
1469 }
1470
1471 fn apply_config(stream: &mut STREAM, config: config::DmaConfig) {
1473 let msize = match mem::size_of::<<PERIPHERAL as PeriAddress>::MemSize>() {
1474 1 => DmaDataSize::Byte,
1475 2 => DmaDataSize::HalfWord,
1476 4 => DmaDataSize::Word,
1477 _ => DmaDataSize::Word,
1479 };
1480
1481 stream.clear_all_flags();
1482 stream.set_priority(config.priority);
1483 unsafe {
1485 stream.set_memory_size(msize);
1486 stream.set_peripheral_size(msize);
1487 }
1488 stream.set_memory_increment(config.memory_increment);
1489 stream.set_peripheral_increment(config.peripheral_increment);
1490 let mut interrupts = BitFlags::default();
1491 if config.transfer_complete_interrupt {
1492 interrupts |= DmaEvent::TransferComplete;
1493 }
1494 if config.half_transfer_interrupt {
1495 interrupts |= DmaEvent::HalfTransfer;
1496 }
1497 if config.transfer_error_interrupt {
1498 interrupts |= DmaEvent::TransferError;
1499 }
1500 if config.direct_mode_error_interrupt {
1501 interrupts |= DmaEvent::DirectModeError;
1502 }
1503 stream.listen_only(interrupts);
1504 if config.fifo_error_interrupt {
1505 stream.listen_fifo_error();
1506 } else {
1507 stream.unlisten_fifo_error();
1508 }
1509 stream.set_double_buffer(config.double_buffer);
1510 stream.set_fifo_threshold(config.fifo_threshold);
1511 stream.set_fifo_enable(config.fifo_enable);
1512 stream.set_memory_burst(config.memory_burst);
1513 stream.set_peripheral_burst(config.peripheral_burst);
1514 }
1515
1516 fn init_common(
1517 stream: &mut STREAM,
1518 peripheral: &PERIPHERAL,
1519 config: config::DmaConfig,
1520 buf: (u32, u16),
1522 db: Option<(u32, u16)>,
1523 ) -> u16 {
1524 stream_disable(stream);
1525
1526 stream.set_channel(ChannelX::<CHANNEL>::VALUE);
1528
1529 stream.set_direction(DIR::direction());
1531 let (buf_ptr, buf_len) = buf;
1532
1533 stream.set_memory_address(buf_ptr);
1535
1536 let is_mem2mem = DIR::direction() == DmaDirection::MemoryToMemory;
1537 if is_mem2mem {
1538 if !config.fifo_enable {
1540 panic!("Fifo disabled.");
1541 } else if config.double_buffer {
1542 panic!("Double buffering enabled.");
1543 }
1544 } else {
1545 stream.set_peripheral_address(peripheral.address());
1547 }
1548
1549 let db_len = if let Some((db_ptr, db_len)) = db {
1550 if is_mem2mem {
1551 stream.set_peripheral_address(db_ptr);
1553 } else {
1554 stream.set_alternate_memory_address(db_ptr);
1555 }
1556 Some(db_len)
1557 } else {
1558 if config.double_buffer {
1560 panic!("No second buffer.");
1561 }
1562 None
1563 };
1564
1565 let n_transfers = if let Some(db) = db_len {
1566 buf_len.min(db)
1567 } else {
1568 buf_len
1569 };
1570 stream.set_number_of_transfers(n_transfers);
1571
1572 Self::apply_config(stream, config);
1573 n_transfers
1574 }
1575
1576 #[allow(clippy::branches_sharing_code)]
1577 fn next_transfer_common(
1578 &mut self,
1579 new_buf: BUF,
1580 ptr_and_len: (u32, u16),
1581 double_buffering: bool,
1582 ) -> Result<(BUF, CurrentBuffer), DMAError<BUF>> {
1583 if double_buffering {
1584 if !self.stream.is_transfer_complete() {
1585 return Err(DMAError::NotReady(new_buf));
1586 }
1587 self.stream.clear_transfer_complete();
1588 let (new_buf_ptr, new_buf_len) = ptr_and_len;
1589
1590 if new_buf_len < self.transfer_length {
1592 return Err(DMAError::SmallBuffer(new_buf));
1593 }
1594
1595 if self.stream.current_buffer() == CurrentBuffer::SecondBuffer {
1596 compiler_fence(Ordering::Release);
1598 self.stream.set_memory_address(new_buf_ptr);
1599
1600 if self.stream.memory_address() != new_buf_ptr {
1602 self.stream.clear_transfer_complete();
1603 return Err(DMAError::Overrun(new_buf));
1604 }
1605
1606 compiler_fence(Ordering::Acquire);
1608
1609 let old_buf = self.buf.replace(new_buf);
1610
1611 return Ok((old_buf.unwrap(), CurrentBuffer::FirstBuffer));
1613 } else {
1614 compiler_fence(Ordering::Release);
1616 self.stream.set_alternate_memory_address(new_buf_ptr);
1617
1618 if self.stream.alternate_memory_address() != new_buf_ptr {
1620 self.stream.clear_transfer_complete();
1621 return Err(DMAError::Overrun(new_buf));
1622 }
1623
1624 compiler_fence(Ordering::Acquire);
1626
1627 let old_buf = self.double_buf.replace(new_buf);
1628
1629 return Ok((old_buf.unwrap(), CurrentBuffer::SecondBuffer));
1631 }
1632 }
1633 stream_disable(&mut self.stream);
1634 self.stream.clear_transfer_complete();
1635
1636 compiler_fence(Ordering::SeqCst);
1638
1639 let (buf_ptr, buf_len) = ptr_and_len;
1640 self.stream.set_memory_address(buf_ptr);
1641 self.stream.set_number_of_transfers(buf_len);
1642 let old_buf = self.buf.replace(new_buf);
1643
1644 unsafe {
1645 self.stream.enable();
1646 }
1647
1648 Ok((old_buf.unwrap(), CurrentBuffer::FirstBuffer))
1649 }
1650
1651 #[allow(clippy::branches_sharing_code)]
1656 unsafe fn next_transfer_with_common(
1657 &mut self,
1658 new_buf: BUF,
1659 ptr_and_len: (u32, u16),
1660 double_buffering: bool,
1661 current_buffer: CurrentBuffer,
1662 ) {
1663 if double_buffering {
1664 let (new_buf_ptr, new_buf_len) = ptr_and_len;
1665
1666 assert!(
1668 new_buf_len >= self.transfer_length,
1669 "Second Buffer not big enough"
1670 );
1671
1672 if self.stream.is_transfer_complete() {
1676 panic!("Overrun");
1681 }
1682
1683 if current_buffer == CurrentBuffer::SecondBuffer {
1684 compiler_fence(Ordering::Release);
1686 self.stream.set_memory_address(new_buf_ptr);
1687
1688 if self.stream.memory_address() != new_buf_ptr {
1691 panic!("Overrun");
1692 }
1693
1694 compiler_fence(Ordering::Acquire);
1696
1697 self.buf.replace(new_buf);
1698 } else {
1699 compiler_fence(Ordering::Release);
1701 self.stream.set_alternate_memory_address(new_buf_ptr);
1702
1703 if self.stream.alternate_memory_address() != new_buf_ptr {
1704 panic!("Overrun");
1705 }
1706
1707 compiler_fence(Ordering::Acquire);
1709
1710 self.double_buf.replace(new_buf);
1711 }
1712 return;
1713 }
1714 let (buf_ptr, buf_len) = ptr_and_len;
1715 self.stream.set_memory_address(buf_ptr);
1716 self.stream.set_number_of_transfers(buf_len);
1717 self.buf.replace(new_buf);
1718
1719 self.stream.enable();
1720 }
1721}
1722
1723impl<STREAM, const CHANNEL: u8, PERIPHERAL, DIR, BUF> crate::Sealed
1724 for Transfer<STREAM, CHANNEL, PERIPHERAL, DIR, BUF>
1725where
1726 STREAM: Stream,
1727 PERIPHERAL: PeriAddress,
1728{
1729}
1730
1731impl<STREAM, const CHANNEL: u8, PERIPHERAL, DIR, BUF> crate::ClearFlags
1732 for Transfer<STREAM, CHANNEL, PERIPHERAL, DIR, BUF>
1733where
1734 STREAM: Stream,
1735 ChannelX<CHANNEL>: Channel,
1736 DIR: Direction,
1737 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, DIR>,
1738{
1739 type Flag = DmaFlag;
1740
1741 #[inline(always)]
1742 fn clear_flags(&mut self, flags: impl Into<BitFlags<DmaFlag>>) {
1743 self.stream.clear_flags(flags)
1744 }
1745}
1746
1747impl<STREAM, const CHANNEL: u8, PERIPHERAL, DIR, BUF> crate::ReadFlags
1748 for Transfer<STREAM, CHANNEL, PERIPHERAL, DIR, BUF>
1749where
1750 STREAM: Stream,
1751 ChannelX<CHANNEL>: Channel,
1752 DIR: Direction,
1753 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, DIR>,
1754{
1755 type Flag = DmaFlag;
1756
1757 #[inline(always)]
1758 fn flags(&self) -> BitFlags<DmaFlag> {
1759 self.stream.flags()
1760 }
1761}
1762
1763impl<STREAM, const CHANNEL: u8, PERIPHERAL, DIR, BUF> StreamISR
1764 for Transfer<STREAM, CHANNEL, PERIPHERAL, DIR, BUF>
1765where
1766 STREAM: Stream,
1767 ChannelX<CHANNEL>: Channel,
1768 DIR: Direction,
1769 PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, DIR>,
1770{
1771}
1772
1773impl<STREAM, const CHANNEL: u8, PERIPHERAL, DIR, BUF> Drop
1774 for Transfer<STREAM, CHANNEL, PERIPHERAL, DIR, BUF>
1775where
1776 STREAM: Stream,
1777 PERIPHERAL: PeriAddress,
1778{
1779 fn drop(&mut self) {
1780 stream_disable(&mut self.stream);
1781 compiler_fence(Ordering::SeqCst);
1782 }
1783}