11//! Direct Memory Access Engine
22
33// 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 } ;
77
88/// Extension trait to split a DMA peripheral into independent channels
99pub trait DmaExt {
@@ -18,6 +18,8 @@ pub trait DmaExt {
1818}
1919
2020/// Channel priority level
21+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
22+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
2123pub enum Priority {
2224 /// Low
2325 Low = 0b00 ,
@@ -41,6 +43,8 @@ impl From<Priority> for u8 {
4143}
4244
4345/// DMA transfer direction
46+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
47+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
4448pub enum Direction {
4549 /// From memory to peripheral
4650 FromMemory ,
@@ -57,8 +61,9 @@ impl From<Direction> for bool {
5761 }
5862}
5963
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 ) ]
6267#[ repr( u8 ) ]
6368pub enum WordSize {
6469 #[ doc = "0: 8-bit size" ]
@@ -76,6 +81,8 @@ impl From<WordSize> for u8 {
7681}
7782
7883/// DMA events
84+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
85+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
7986pub enum Event {
8087 /// First half of a transfer is done
8188 HalfTransfer ,
@@ -243,6 +250,57 @@ pub trait Channel: private::Channel {
243250 }
244251}
245252
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+
246304macro_rules! dma {
247305 (
248306 channels: {
@@ -251,11 +309,6 @@ macro_rules! dma {
251309 ) +
252310 } ,
253311 ) => {
254- use crate :: dmamux;
255- use crate :: rcc:: { Enable , Reset } ;
256- use crate :: stm32:: { self , DMA1 as DMA } ;
257- use crate :: dmamux:: DmaMuxExt ;
258-
259312 /// DMA channels
260313 pub struct Channels {
261314 $( pub $chi: $Ci, ) +
@@ -269,60 +322,8 @@ macro_rules! dma {
269322 }
270323 }
271324
272-
273325 $(
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>;
326327 ) +
327328 }
328329}
@@ -357,19 +358,19 @@ dma!(
357358 } ,
358359) ;
359360
360- impl DmaExt for DMA {
361+ impl DmaExt for DMA1 {
361362 type Channels = Channels ;
362363
363364 fn reset ( self , rcc : & mut Rcc ) -> Self {
364365 // reset DMA
365- <DMA as Reset >:: reset ( rcc) ;
366+ <DMA1 as Reset >:: reset ( rcc) ;
366367 self
367368 }
368369
369370 fn split ( self , rcc : & mut Rcc , dmamux : DMAMUX ) -> Self :: Channels {
370371 let muxchannels = dmamux. split ( ) ;
371372 // enable DMA clock
372- DMA :: enable ( rcc) ;
373+ DMA1 :: enable ( rcc) ;
373374
374375 let mut channels = Channels {
375376 ch1 : C1 {
0 commit comments