1
1
//! Direct Memory Access Engine
2
2
3
3
// TODO: add DMA2 for B1, C1
4
- use crate :: dmamux:: DmaMuxIndex ;
5
- use crate :: rcc:: Rcc ;
6
- use crate :: stm32:: DMAMUX ;
4
+ use crate :: dmamux:: { self , DmaMuxExt , DmaMuxIndex } ;
5
+ use crate :: rcc:: { Enable , Rcc , Reset } ;
6
+ use crate :: stm32:: { self , DMA1 , DMAMUX } ;
7
7
8
8
/// Extension trait to split a DMA peripheral into independent channels
9
9
pub trait DmaExt {
@@ -18,6 +18,8 @@ pub trait DmaExt {
18
18
}
19
19
20
20
/// Channel priority level
21
+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
22
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
21
23
pub enum Priority {
22
24
/// Low
23
25
Low = 0b00 ,
@@ -41,6 +43,8 @@ impl From<Priority> for u8 {
41
43
}
42
44
43
45
/// DMA transfer direction
46
+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
47
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
44
48
pub enum Direction {
45
49
/// From memory to peripheral
46
50
FromMemory ,
@@ -57,8 +61,9 @@ impl From<Direction> for bool {
57
61
}
58
62
}
59
63
60
- #[ doc = "Peripheral size" ]
61
- #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
64
+ /// Peripheral size
65
+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
66
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
62
67
#[ repr( u8 ) ]
63
68
pub enum WordSize {
64
69
#[ doc = "0: 8-bit size" ]
@@ -76,6 +81,8 @@ impl From<WordSize> for u8 {
76
81
}
77
82
78
83
/// DMA events
84
+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
85
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
79
86
pub enum Event {
80
87
/// First half of a transfer is done
81
88
HalfTransfer ,
@@ -243,6 +250,57 @@ pub trait Channel: private::Channel {
243
250
}
244
251
}
245
252
253
+ /// Singleton that represents a DMA channel
254
+ pub struct C < const N : u8 > {
255
+ mux : dmamux:: Channel < N > ,
256
+ }
257
+
258
+ impl < const N : u8 > private:: Channel for C < N > {
259
+ fn ch ( & self ) -> & stm32:: dma1:: CH {
260
+ // NOTE(unsafe) $Ci grants exclusive access to this register
261
+ unsafe { ( * DMA1 :: ptr ( ) ) . ch ( N as usize ) }
262
+ }
263
+ }
264
+
265
+ impl < const N : u8 > C < N > {
266
+ pub fn mux ( & mut self ) -> & mut dyn dmamux:: DmaMuxChannel {
267
+ & mut self . mux
268
+ }
269
+ }
270
+
271
+ impl < const N : u8 > Channel for C < N > {
272
+ fn select_peripheral ( & mut self , index : DmaMuxIndex ) {
273
+ self . mux ( ) . select_peripheral ( index) ;
274
+ }
275
+
276
+ fn event_occurred ( & self , event : Event ) -> bool {
277
+ use Event :: * ;
278
+
279
+ // NOTE(unsafe) atomic read
280
+ let flags = unsafe { ( * DMA1 :: ptr ( ) ) . isr ( ) . read ( ) } ;
281
+ match event {
282
+ HalfTransfer => flags. htif ( N ) . bit_is_set ( ) ,
283
+ TransferComplete => flags. tcif ( N ) . bit_is_set ( ) ,
284
+ TransferError => flags. teif ( N ) . bit_is_set ( ) ,
285
+ Any => flags. gif ( N ) . bit_is_set ( ) ,
286
+ }
287
+ }
288
+
289
+ fn clear_event ( & mut self , event : Event ) {
290
+ use Event :: * ;
291
+
292
+ // NOTE(unsafe) atomic write to a stateless register
293
+ unsafe {
294
+ let _ = & ( * DMA1 :: ptr ( ) ) . ifcr ( ) . write ( |w| match event {
295
+ HalfTransfer => w. chtif ( N ) . set_bit ( ) ,
296
+ TransferComplete => w. ctcif ( N ) . set_bit ( ) ,
297
+ TransferError => w. cteif ( N ) . set_bit ( ) ,
298
+ Any => w. cgif ( N ) . set_bit ( ) ,
299
+ } ) ;
300
+ }
301
+ }
302
+ }
303
+
246
304
macro_rules! dma {
247
305
(
248
306
channels: {
@@ -251,11 +309,6 @@ macro_rules! dma {
251
309
) +
252
310
} ,
253
311
) => {
254
- use crate :: dmamux;
255
- use crate :: rcc:: { Enable , Reset } ;
256
- use crate :: stm32:: { self , DMA1 as DMA } ;
257
- use crate :: dmamux:: DmaMuxExt ;
258
-
259
312
/// DMA channels
260
313
pub struct Channels {
261
314
$( pub $chi: $Ci, ) +
@@ -269,60 +322,8 @@ macro_rules! dma {
269
322
}
270
323
}
271
324
272
-
273
325
$(
274
- /// Singleton that represents a DMA channel
275
- pub struct $Ci {
276
- mux: dmamux:: Channel <$i>,
277
- }
278
-
279
- impl private:: Channel for $Ci {
280
- fn ch( & self ) -> & stm32:: dma1:: CH {
281
- // NOTE(unsafe) $Ci grants exclusive access to this register
282
- unsafe { & ( * DMA :: ptr( ) ) . ch( $i) }
283
- }
284
- }
285
-
286
- impl $Ci {
287
- pub fn mux( & mut self ) -> & mut dyn dmamux:: DmaMuxChannel {
288
- & mut self . mux
289
- }
290
- }
291
-
292
- impl Channel for $Ci {
293
-
294
- fn select_peripheral( & mut self , index: DmaMuxIndex ) {
295
- self . mux( ) . select_peripheral( index) ;
296
- }
297
-
298
- fn event_occurred( & self , event: Event ) -> bool {
299
- use Event :: * ;
300
-
301
- // NOTE(unsafe) atomic read
302
- let flags = unsafe { ( * DMA :: ptr( ) ) . isr( ) . read( ) } ;
303
- match event {
304
- HalfTransfer => flags. htif( $i) . bit_is_set( ) ,
305
- TransferComplete => flags. tcif( $i) . bit_is_set( ) ,
306
- TransferError => flags. teif( $i) . bit_is_set( ) ,
307
- Any => flags. gif( $i) . bit_is_set( ) ,
308
- }
309
- }
310
-
311
- fn clear_event( & mut self , event: Event ) {
312
- use Event :: * ;
313
-
314
- // NOTE(unsafe) atomic write to a stateless register
315
- unsafe {
316
- let _ = & ( * DMA :: ptr( ) ) . ifcr( ) . write( |w| match event {
317
- HalfTransfer => w. chtif( $i) . set_bit( ) ,
318
- TransferComplete => w. ctcif( $i) . set_bit( ) ,
319
- TransferError => w. cteif( $i) . set_bit( ) ,
320
- Any => w. cgif( $i) . set_bit( ) ,
321
- } ) ;
322
- }
323
- }
324
-
325
- }
326
+ pub type $Ci = C <$i>;
326
327
) +
327
328
}
328
329
}
@@ -357,19 +358,19 @@ dma!(
357
358
} ,
358
359
) ;
359
360
360
- impl DmaExt for DMA {
361
+ impl DmaExt for DMA1 {
361
362
type Channels = Channels ;
362
363
363
364
fn reset ( self , rcc : & mut Rcc ) -> Self {
364
365
// reset DMA
365
- <DMA as Reset >:: reset ( rcc) ;
366
+ <DMA1 as Reset >:: reset ( rcc) ;
366
367
self
367
368
}
368
369
369
370
fn split ( self , rcc : & mut Rcc , dmamux : DMAMUX ) -> Self :: Channels {
370
371
let muxchannels = dmamux. split ( ) ;
371
372
// enable DMA clock
372
- DMA :: enable ( rcc) ;
373
+ DMA1 :: enable ( rcc) ;
373
374
374
375
let mut channels = Channels {
375
376
ch1 : C1 {
0 commit comments