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 as DMA , DMAMUX } ;
77
88/// Extension trait to split a DMA peripheral into independent channels
99pub trait DmaExt {
@@ -243,6 +243,57 @@ pub trait Channel: private::Channel {
243243 }
244244}
245245
246+ /// Singleton that represents a DMA channel
247+ pub struct C < const N : u8 > {
248+ mux : dmamux:: Channel < N > ,
249+ }
250+
251+ impl < const N : u8 > private:: Channel for C < N > {
252+ fn ch ( & self ) -> & stm32:: dma1:: CH {
253+ // NOTE(unsafe) $Ci grants exclusive access to this register
254+ unsafe { & ( * DMA :: ptr ( ) ) . ch ( N as usize ) }
255+ }
256+ }
257+
258+ impl < const N : u8 > C < N > {
259+ pub fn mux ( & mut self ) -> & mut dyn dmamux:: DmaMuxChannel {
260+ & mut self . mux
261+ }
262+ }
263+
264+ impl < const N : u8 > Channel for C < N > {
265+ fn select_peripheral ( & mut self , index : DmaMuxIndex ) {
266+ self . mux ( ) . select_peripheral ( index) ;
267+ }
268+
269+ fn event_occurred ( & self , event : Event ) -> bool {
270+ use Event :: * ;
271+
272+ // NOTE(unsafe) atomic read
273+ let flags = unsafe { ( * DMA :: ptr ( ) ) . isr ( ) . read ( ) } ;
274+ match event {
275+ HalfTransfer => flags. htif ( N ) . bit_is_set ( ) ,
276+ TransferComplete => flags. tcif ( N ) . bit_is_set ( ) ,
277+ TransferError => flags. teif ( N ) . bit_is_set ( ) ,
278+ Any => flags. gif ( N ) . bit_is_set ( ) ,
279+ }
280+ }
281+
282+ fn clear_event ( & mut self , event : Event ) {
283+ use Event :: * ;
284+
285+ // NOTE(unsafe) atomic write to a stateless register
286+ unsafe {
287+ let _ = & ( * DMA :: ptr ( ) ) . ifcr ( ) . write ( |w| match event {
288+ HalfTransfer => w. chtif ( N ) . set_bit ( ) ,
289+ TransferComplete => w. ctcif ( N ) . set_bit ( ) ,
290+ TransferError => w. cteif ( N ) . set_bit ( ) ,
291+ Any => w. cgif ( N ) . set_bit ( ) ,
292+ } ) ;
293+ }
294+ }
295+ }
296+
246297macro_rules! dma {
247298 (
248299 channels: {
@@ -251,11 +302,6 @@ macro_rules! dma {
251302 ) +
252303 } ,
253304 ) => {
254- use crate :: dmamux;
255- use crate :: rcc:: { Enable , Reset } ;
256- use crate :: stm32:: { self , DMA1 as DMA } ;
257- use crate :: dmamux:: DmaMuxExt ;
258-
259305 /// DMA channels
260306 pub struct Channels {
261307 $( pub $chi: $Ci, ) +
@@ -269,60 +315,8 @@ macro_rules! dma {
269315 }
270316 }
271317
272-
273318 $(
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- }
319+ pub type $Ci = C <$i>;
326320 ) +
327321 }
328322}
0 commit comments