@@ -7,12 +7,52 @@ mod utilities;
7
7
use cortex_m:: singleton;
8
8
use cortex_m_rt:: entry;
9
9
use cortex_m_semihosting:: debug;
10
+ use embedded_dma:: { ReadBuffer , WriteBuffer } ;
10
11
use stm32h5xx_hal:: {
11
- gpdma:: { config:: transform:: * , DmaConfig , DmaTransfer } ,
12
+ gpdma:: { config:: transform:: * , DmaConfig , DmaTransfer , Word } ,
12
13
pac,
13
14
prelude:: * ,
14
15
} ;
15
16
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
+
16
56
#[ entry]
17
57
fn main ( ) -> ! {
18
58
utilities:: logger:: init ( ) ;
@@ -31,90 +71,109 @@ fn main() -> ! {
31
71
log:: info!( "u8 to u8" ) ;
32
72
let src =
33
73
singleton ! ( : [ u8 ; 40 ] = core:: array:: from_fn( |i| i as u8 ) ) . unwrap ( ) ;
74
+
75
+ let src_buffer = Buffer :: new ( src) ;
34
76
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) ;
37
78
38
79
let mut channel = channels. 0 ;
39
80
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
+ ) ;
42
87
transfer. start ( ) . unwrap ( ) ;
43
88
transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
44
- assert_eq ! ( source_copy , dest_copy ) ;
89
+ assert_eq ! ( src_buffer . data , dest_buffer . data ) ;
45
90
46
91
log:: info!( "u32 to u32 with data transform" ) ;
47
92
let src = singleton ! ( : [ u32 ; 10 ] = [ 0x12345678u32 ; 10 ] ) . unwrap ( ) ;
48
93
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) ;
51
95
52
96
let config = DmaConfig :: new ( ) . with_data_transform (
53
97
DataTransform :: builder ( )
54
98
. swap_destination_half_words ( )
55
99
. swap_destination_half_word_byte_order ( ) ,
56
100
) ;
57
101
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
+ ) ;
60
108
61
109
transfer. start ( ) . unwrap ( ) ;
62
110
transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
63
111
let expected = [ 0x78563412 ; 10 ] ;
64
- assert_eq ! ( expected, * dest_copy ) ;
112
+ assert_eq ! ( expected, * dest_buffer . data ) ;
65
113
66
114
log:: info!( "u32 to u16 with truncate" ) ;
67
115
let src = singleton ! ( : [ u32 ; 10 ] = [ 0x12345678u32 ; 10 ] ) . unwrap ( ) ;
68
116
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
+
70
119
let config = DmaConfig :: new ( ) . with_data_transform (
71
120
DataTransform :: builder ( ) . left_align_right_truncate ( ) ,
72
121
) ;
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
+ ) ;
75
128
76
129
transfer. start ( ) . unwrap ( ) ;
77
130
transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
78
131
let expected = [ 0x1234 ; 10 ] ;
79
- assert_eq ! ( expected, ( * dest_copy ) [ 0 ..10 ] ) ;
132
+ assert_eq ! ( expected, ( * dest_buffer . data ) [ 0 ..10 ] ) ;
80
133
81
134
log:: info!( "u32 to u8 with unpack" ) ;
82
135
let src = singleton ! ( : [ u32 ; 10 ] = [ 0x12345678u32 ; 10 ] ) . unwrap ( ) ;
83
136
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) ;
86
138
87
139
let config =
88
140
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
+ ) ;
91
147
92
148
transfer. start ( ) . unwrap ( ) ;
93
149
transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
94
150
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 ] ) ;
97
153
98
154
log:: info!( "u8 to u32 with pack" ) ;
99
155
let src = singleton ! ( : [ u8 ; 40 ] = [ 0u8 ; 40 ] ) . unwrap ( ) ;
100
156
let dest = singleton ! ( : [ u32 ; 10 ] = [ 0u32 ; 10 ] ) . unwrap ( ) ;
157
+ let mut dest_buffer = Buffer :: new ( dest) ;
101
158
102
159
for chunk in src. chunks_mut ( 4 ) {
103
160
chunk. copy_from_slice ( & [ 0x78 , 0x56 , 0x34 , 0x12 ] ) ;
104
161
}
105
162
106
- let dest_copy = unsafe { & * ( dest. as_ptr ( ) as * const [ u32 ; 10 ] ) } ;
107
-
108
163
let config =
109
164
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
+ ) ;
112
171
113
172
transfer. start ( ) . unwrap ( ) ;
114
173
transfer. wait_for_transfer_complete ( ) . unwrap ( ) ;
115
174
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 ) ) ;
118
177
119
178
log:: info!( "All tests passed!" ) ;
120
179
loop {
0 commit comments