@@ -27,13 +27,21 @@ pub trait DmaExt {
27
27
fn split ( self , ahb : & mut AHB ) -> Self :: Channels ;
28
28
}
29
29
30
+ /// Trait implemented by DMA targets.
31
+ pub trait Target {
32
+ /// Enable DMA on the target
33
+ fn enable_dma ( & mut self ) { }
34
+ /// Disable DMA on the target
35
+ fn disable_dma ( & mut self ) { }
36
+ }
37
+
30
38
/// An in-progress one-shot DMA transfer
31
- pub struct Transfer < B , C : Channel , T > {
39
+ pub struct Transfer < B , C : Channel , T : Target > {
32
40
// This is always a `Some` outside of `drop`.
33
41
inner : Option < TransferInner < B , C , T > > ,
34
42
}
35
43
36
- impl < B , C : Channel , T > Transfer < B , C , T > {
44
+ impl < B , C : Channel , T : Target > Transfer < B , C , T > {
37
45
/// Start a DMA write transfer.
38
46
///
39
47
/// # Panics
@@ -42,7 +50,7 @@ impl<B, C: Channel, T> Transfer<B, C, T> {
42
50
pub fn start_write ( mut buffer : B , mut channel : C , target : T ) -> Self
43
51
where
44
52
B : WriteBuffer + ' static ,
45
- T : Target < C > ,
53
+ T : OnChannel < C > ,
46
54
{
47
55
// NOTE(unsafe) cannot call `&mut self` methods on `buffer` because its
48
56
// concrete type is unknown here
@@ -65,7 +73,7 @@ impl<B, C: Channel, T> Transfer<B, C, T> {
65
73
pub fn start_read ( buffer : B , mut channel : C , target : T ) -> Self
66
74
where
67
75
B : ReadBuffer + ' static ,
68
- T : Target < C > ,
76
+ T : OnChannel < C > ,
69
77
{
70
78
// NOTE(unsafe) cannot call `&mut self` methods on `buffer` because its
71
79
// concrete type is unknown here
@@ -86,14 +94,15 @@ impl<B, C: Channel, T> Transfer<B, C, T> {
86
94
///
87
95
/// - the given buffer will be valid for the duration of the transfer
88
96
/// - the DMA channel is configured correctly for the given target and buffer
89
- unsafe fn start ( buffer : B , mut channel : C , target : T ) -> Self
97
+ unsafe fn start ( buffer : B , mut channel : C , mut target : T ) -> Self
90
98
where
91
- T : Target < C > ,
99
+ T : OnChannel < C > ,
92
100
{
93
101
assert ! ( !channel. is_enabled( ) ) ;
94
102
95
103
atomic:: compiler_fence ( Ordering :: Release ) ;
96
104
105
+ target. enable_dma ( ) ;
97
106
channel. enable ( ) ;
98
107
99
108
Self {
@@ -127,7 +136,7 @@ impl<B, C: Channel, T> Transfer<B, C, T> {
127
136
}
128
137
}
129
138
130
- impl < B , C : Channel , T > Drop for Transfer < B , C , T > {
139
+ impl < B , C : Channel , T : Target > Drop for Transfer < B , C , T > {
131
140
fn drop ( & mut self ) {
132
141
if let Some ( inner) = self . inner . as_mut ( ) {
133
142
inner. stop ( ) ;
@@ -142,10 +151,12 @@ struct TransferInner<B, C, T> {
142
151
target : T ,
143
152
}
144
153
145
- impl < B , C : Channel , T > TransferInner < B , C , T > {
154
+ impl < B , C : Channel , T : Target > TransferInner < B , C , T > {
146
155
/// Stop this transfer
147
156
fn stop ( & mut self ) {
148
157
self . channel . disable ( ) ;
158
+ self . target . disable_dma ( ) ;
159
+
149
160
atomic:: compiler_fence ( Ordering :: SeqCst ) ;
150
161
}
151
162
}
@@ -674,7 +685,6 @@ macro_rules! dma {
674
685
} ;
675
686
}
676
687
677
- #[ cfg( feature = "stm32f303" ) ]
678
688
dma ! (
679
689
DMA1 , dma1, dma1en,
680
690
channels: {
@@ -705,20 +715,25 @@ dma!(
705
715
} ,
706
716
) ;
707
717
708
- /// Marker trait for DMA targets and their channels
709
- pub unsafe trait Target < C : Channel > { }
718
+ /// Marker trait mapping DMA targets to their channels
719
+ ///
720
+ /// # Safety
721
+ ///
722
+ /// `C` must be the correct DMA channel for the peripheral implementing
723
+ /// this trait.
724
+ pub unsafe trait OnChannel < C : Channel > : Target { }
710
725
711
- macro_rules! targets {
726
+ macro_rules! on_channel {
712
727
(
713
728
$dma: ident,
714
729
$( $target: ty => $C: ident, ) +
715
730
) => {
716
- $( unsafe impl Target <$dma:: $C> for $target { } ) +
731
+ $( unsafe impl OnChannel <$dma:: $C> for $target { } ) +
717
732
} ;
718
733
}
719
734
720
735
#[ cfg( feature = "stm32f303" ) ]
721
- targets ! ( dma1,
736
+ on_channel ! ( dma1,
722
737
serial:: Rx <pac:: USART1 > => C5 ,
723
738
serial:: Tx <pac:: USART1 > => C4 ,
724
739
serial:: Rx <pac:: USART2 > => C6 ,
0 commit comments