@@ -7,12 +7,52 @@ mod utilities;
77use cortex_m:: singleton;
88use cortex_m_rt:: entry;
99use cortex_m_semihosting:: debug;
10+ use embedded_dma:: { ReadBuffer , WriteBuffer } ;
1011use stm32h5xx_hal:: {
11- gpdma:: { config:: transform:: * , DmaConfig , DmaTransfer } ,
12+ gpdma:: { config:: transform:: * , DmaConfig , DmaTransfer , Word } ,
1213 pac,
1314 prelude:: * ,
1415} ;
1516
17+ // Buffer is used to manage a reference to a static buffer returned by the cortex_m::singleton!
18+ // macro and which can be with the DmaTransfer API (which requires passing ReadBuffer and
19+ // WriteBuffer implementations by value) and then used to access the buffer after the transfer has
20+ // completed.
21+ struct Buffer < T : Word + ' static , const N : usize > {
22+ data : & ' static mut [ T ; N ] ,
23+ }
24+
25+ impl < T , const N : usize > Buffer < T , N >
26+ where
27+ T : Word + ' static ,
28+ {
29+ fn new ( data : & ' static mut [ T ; N ] ) -> Self {
30+ Self { data }
31+ }
32+ }
33+
34+ unsafe impl < T , const N : usize > ReadBuffer for & Buffer < T , N >
35+ where
36+ T : Word + ' static ,
37+ {
38+ type Word = T ;
39+
40+ unsafe fn read_buffer ( & self ) -> ( * const Self :: Word , usize ) {
41+ ( self . data . as_ptr ( ) , N )
42+ }
43+ }
44+
45+ unsafe impl < T , const N : usize > WriteBuffer for & mut Buffer < T , N >
46+ where
47+ T : Word + ' static ,
48+ {
49+ type Word = T ;
50+
51+ unsafe fn write_buffer ( & mut self ) -> ( * mut Self :: Word , usize ) {
52+ ( self . data . as_mut_ptr ( ) , N )
53+ }
54+ }
55+
1656#[ entry]
1757fn main ( ) -> ! {
1858 utilities:: logger:: init ( ) ;
@@ -31,90 +71,109 @@ fn main() -> ! {
3171 log:: info!( "u8 to u8" ) ;
3272 let src =
3373 singleton ! ( : [ u8 ; 40 ] = core:: array:: from_fn( |i| i as u8 ) ) . unwrap ( ) ;
74+
75+ let src_buffer = Buffer :: new ( src) ;
3476 let dest = singleton ! ( : [ u8 ; 40 ] = [ 0u8 ; 40 ] ) . unwrap ( ) ;
35- let source_copy = unsafe { & * ( src. as_ptr ( ) as * const [ u8 ; 40 ] ) } ;
36- let dest_copy = unsafe { & * ( dest. as_ptr ( ) as * const [ u8 ; 40 ] ) } ;
77+ let mut dest_buffer = Buffer :: new ( dest) ;
3778
3879 let mut channel = channels. 0 ;
3980 let config = DmaConfig :: new ( ) ;
40- let mut transfer =
41- DmaTransfer :: memory_to_memory ( config, & mut channel, src, dest) ;
81+ let mut transfer = DmaTransfer :: memory_to_memory (
82+ config,
83+ & mut channel,
84+ & src_buffer,
85+ & mut dest_buffer,
86+ ) ;
4287 transfer. start ( ) . unwrap ( ) ;
4388 transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
44- assert_eq ! ( source_copy , dest_copy ) ;
89+ assert_eq ! ( src_buffer . data , dest_buffer . data ) ;
4590
4691 log:: info!( "u32 to u32 with data transform" ) ;
4792 let src = singleton ! ( : [ u32 ; 10 ] = [ 0x12345678u32 ; 10 ] ) . unwrap ( ) ;
4893 let dest = singleton ! ( : [ u32 ; 10 ] = [ 0u32 ; 10 ] ) . unwrap ( ) ;
49-
50- let dest_copy = unsafe { & * ( dest. as_ptr ( ) as * const [ u32 ; 10 ] ) } ;
94+ let mut dest_buffer = Buffer :: new ( dest) ;
5195
5296 let config = DmaConfig :: new ( ) . with_data_transform (
5397 DataTransform :: builder ( )
5498 . swap_destination_half_words ( )
5599 . swap_destination_half_word_byte_order ( ) ,
56100 ) ;
57101
58- let mut transfer =
59- DmaTransfer :: memory_to_memory ( config, & mut channel, src, dest) ;
102+ let mut transfer = DmaTransfer :: memory_to_memory (
103+ config,
104+ & mut channel,
105+ src,
106+ & mut dest_buffer,
107+ ) ;
60108
61109 transfer. start ( ) . unwrap ( ) ;
62110 transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
63111 let expected = [ 0x78563412 ; 10 ] ;
64- assert_eq ! ( expected, * dest_copy ) ;
112+ assert_eq ! ( expected, * dest_buffer . data ) ;
65113
66114 log:: info!( "u32 to u16 with truncate" ) ;
67115 let src = singleton ! ( : [ u32 ; 10 ] = [ 0x12345678u32 ; 10 ] ) . unwrap ( ) ;
68116 let dest = singleton ! ( : [ u16 ; 20 ] = [ 0u16 ; 20 ] ) . unwrap ( ) ;
69- let dest_copy = unsafe { & * ( dest. as_ptr ( ) as * const [ u16 ; 20 ] ) } ;
117+ let mut dest_buffer = Buffer :: new ( dest) ;
118+
70119 let config = DmaConfig :: new ( ) . with_data_transform (
71120 DataTransform :: builder ( ) . left_align_right_truncate ( ) ,
72121 ) ;
73- let mut transfer =
74- DmaTransfer :: memory_to_memory ( config, & mut channel, src, dest) ;
122+ let mut transfer = DmaTransfer :: memory_to_memory (
123+ config,
124+ & mut channel,
125+ src,
126+ & mut dest_buffer,
127+ ) ;
75128
76129 transfer. start ( ) . unwrap ( ) ;
77130 transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
78131 let expected = [ 0x1234 ; 10 ] ;
79- assert_eq ! ( expected, ( * dest_copy ) [ 0 ..10 ] ) ;
132+ assert_eq ! ( expected, ( * dest_buffer . data ) [ 0 ..10 ] ) ;
80133
81134 log:: info!( "u32 to u8 with unpack" ) ;
82135 let src = singleton ! ( : [ u32 ; 10 ] = [ 0x12345678u32 ; 10 ] ) . unwrap ( ) ;
83136 let dest = singleton ! ( : [ u8 ; 40 ] = [ 0u8 ; 40 ] ) . unwrap ( ) ;
84-
85- let dest_copy = unsafe { & * ( dest. as_ptr ( ) as * const [ u8 ; 40 ] ) } ;
137+ let mut dest_buffer = Buffer :: new ( dest) ;
86138
87139 let config =
88140 DmaConfig :: new ( ) . with_data_transform ( DataTransform :: builder ( ) . unpack ( ) ) ;
89- let mut transfer =
90- DmaTransfer :: memory_to_memory ( config, & mut channel, src, dest) ;
141+ let mut transfer = DmaTransfer :: memory_to_memory (
142+ config,
143+ & mut channel,
144+ src,
145+ & mut dest_buffer,
146+ ) ;
91147
92148 transfer. start ( ) . unwrap ( ) ;
93149 transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
94150 let expected = [ 0x78 , 0x56 , 0x34 , 0x12 ] ;
95- assert_eq ! ( expected, ( * dest_copy ) [ 0 ..4 ] ) ;
96- assert_eq ! ( expected, ( * dest_copy ) [ 36 ..40 ] ) ;
151+ assert_eq ! ( expected, ( * dest_buffer . data ) [ 0 ..4 ] ) ;
152+ assert_eq ! ( expected, ( * dest_buffer . data ) [ 36 ..40 ] ) ;
97153
98154 log:: info!( "u8 to u32 with pack" ) ;
99155 let src = singleton ! ( : [ u8 ; 40 ] = [ 0u8 ; 40 ] ) . unwrap ( ) ;
100156 let dest = singleton ! ( : [ u32 ; 10 ] = [ 0u32 ; 10 ] ) . unwrap ( ) ;
157+ let mut dest_buffer = Buffer :: new ( dest) ;
101158
102159 for chunk in src. chunks_mut ( 4 ) {
103160 chunk. copy_from_slice ( & [ 0x78 , 0x56 , 0x34 , 0x12 ] ) ;
104161 }
105162
106- let dest_copy = unsafe { & * ( dest. as_ptr ( ) as * const [ u32 ; 10 ] ) } ;
107-
108163 let config =
109164 DmaConfig :: new ( ) . with_data_transform ( DataTransform :: builder ( ) . pack ( ) ) ;
110- let mut transfer =
111- DmaTransfer :: memory_to_memory ( config, & mut channel, src, dest) ;
165+ let mut transfer = DmaTransfer :: memory_to_memory (
166+ config,
167+ & mut channel,
168+ src,
169+ & mut dest_buffer,
170+ ) ;
112171
113172 transfer. start ( ) . unwrap ( ) ;
114173 transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
115174 let expected = [ 0x12345678 ; 10 ] ;
116- assert_eq ! ( expected, ( * dest_copy ) ) ;
117- assert_eq ! ( expected, ( * dest_copy ) ) ;
175+ assert_eq ! ( expected, ( * dest_buffer . data ) ) ;
176+ assert_eq ! ( expected, ( * dest_buffer . data ) ) ;
118177
119178 log:: info!( "All tests passed!" ) ;
120179 loop {
0 commit comments