11//! Audio module. Handles audio startup and I/O.
22//! As well as converting between the S24 input and f32 for processing.
3+ use core:: ops:: { Deref , DerefMut } ;
4+
35use log:: info;
46
57use stm32h7xx_hal:: {
68 dma,
79 gpio:: { gpioe, Analog } ,
8- pac, rcc,
9- rcc:: rec,
10- sai,
11- sai:: * ,
12- stm32,
13- stm32:: rcc:: d2ccip1r:: SAI1SEL_A ,
10+ pac:: { self } ,
11+ rcc:: { self , rec} ,
12+ sai:: { self , * } ,
13+ stm32:: { self , rcc:: d2ccip1r:: SAI1SEL_A } ,
1414 traits:: i2s:: FullDuplex ,
1515} ;
1616
@@ -41,19 +41,44 @@ pub const MAX_TRANSFER_SIZE: usize = BLOCK_SIZE_MAX * 2;
4141
4242pub type AudioBuffer = [ ( f32 , f32 ) ; BLOCK_SIZE_MAX ] ;
4343
44+ /// Raw pointer backed reference to the DMA buffers. It exists to avoid storing multiple aliasing
45+ /// `&mut` references to `TX_BUFFER` and `RX_BUFFER`, which is UB.
46+ /// # Safety
47+ /// References are created whenever the underlying buffer is accessed, but since the access is single
48+ /// threaded and the references are short lived this should be fine.
49+ /// This wrapper is only, and may only be, pointing to memory with a 'static lifetime.
50+ struct DmaBufferRawRef {
51+ ptr : * mut DmaBuffer ,
52+ }
53+ impl Deref for DmaBufferRawRef {
54+ type Target = DmaBuffer ;
55+
56+ fn deref ( & self ) -> & Self :: Target {
57+ unsafe { & * self . ptr }
58+ }
59+ }
60+ impl DerefMut for DmaBufferRawRef {
61+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
62+ unsafe { & mut * self . ptr }
63+ }
64+ }
65+ unsafe impl stable_deref_trait:: StableDeref for DmaBufferRawRef { }
66+ // Required for using the buffer in practice. No more dangerous than sending a `&mut DmaBuffer`
67+ unsafe impl Send for DmaBufferRawRef { }
68+
4469type DmaInputStream = dma:: Transfer <
4570 dma:: dma:: Stream1 < stm32:: DMA1 > ,
4671 stm32:: SAI1 ,
4772 dma:: PeripheralToMemory ,
48- & ' static mut [ u32 ; DMA_BUFFER_SIZE ] ,
73+ DmaBufferRawRef ,
4974 dma:: DBTransfer ,
5075> ;
5176
5277type DmaOutputStream = dma:: Transfer <
5378 dma:: dma:: Stream0 < stm32:: DMA1 > ,
5479 stm32:: SAI1 ,
5580 dma:: MemoryToPeripheral ,
56- & ' static mut [ u32 ; DMA_BUFFER_SIZE ] ,
81+ DmaBufferRawRef ,
5782 dma:: DBTransfer ,
5883> ;
5984
@@ -138,7 +163,9 @@ impl Audio {
138163 let dma1_streams = dma:: dma:: StreamsTuple :: new ( dma1_d, dma1_p) ;
139164
140165 // dma1 stream 0
141- let tx_buffer: & ' static mut [ u32 ; DMA_BUFFER_SIZE ] = unsafe { & mut TX_BUFFER } ;
166+ let tx_buffer = DmaBufferRawRef {
167+ ptr : & raw mut TX_BUFFER ,
168+ } ;
142169 let dma_config = dma:: dma:: DmaConfig :: default ( )
143170 . priority ( dma:: config:: Priority :: High )
144171 . memory_increment ( true )
@@ -155,7 +182,9 @@ impl Audio {
155182 ) ;
156183
157184 // dma1 stream 1
158- let rx_buffer: & ' static mut [ u32 ; DMA_BUFFER_SIZE ] = unsafe { & mut RX_BUFFER } ;
185+ let rx_buffer = DmaBufferRawRef {
186+ ptr : & raw mut RX_BUFFER ,
187+ } ;
159188 let dma_config = dma_config
160189 . transfer_complete_interrupt ( true )
161190 . half_transfer_interrupt ( true ) ;
@@ -207,8 +236,12 @@ impl Audio {
207236 sai. enable ( ) ;
208237 sai. try_send ( 0 , 0 ) . unwrap ( ) ;
209238 } ) ;
210- let input = Input :: new ( unsafe { & mut RX_BUFFER } ) ;
211- let output = Output :: new ( unsafe { & mut TX_BUFFER } ) ;
239+ let input = Input :: new ( DmaBufferRawRef {
240+ ptr : & raw mut RX_BUFFER ,
241+ } ) ;
242+ let output = Output :: new ( DmaBufferRawRef {
243+ ptr : & raw mut TX_BUFFER ,
244+ } ) ;
212245 info ! (
213246 "{:?}, {:?}" ,
214247 & input. buffer[ 0 ] as * const u32 , & output. buffer[ 0 ] as * const u32
@@ -289,12 +322,12 @@ impl Audio {
289322
290323struct Input {
291324 index : usize ,
292- buffer : & ' static DmaBuffer ,
325+ buffer : DmaBufferRawRef ,
293326}
294327
295328impl Input {
296329 /// Create a new Input from a DmaBuffer
297- fn new ( buffer : & ' static DmaBuffer ) -> Self {
330+ fn new ( buffer : DmaBufferRawRef ) -> Self {
298331 Self { index : 0 , buffer }
299332 }
300333
@@ -310,12 +343,12 @@ impl Input {
310343
311344struct Output {
312345 index : usize ,
313- buffer : & ' static mut DmaBuffer ,
346+ buffer : DmaBufferRawRef ,
314347}
315348
316349impl Output {
317350 /// Create a new Input from a DmaBuffer
318- fn new ( buffer : & ' static mut DmaBuffer ) -> Self {
351+ fn new ( buffer : DmaBufferRawRef ) -> Self {
319352 Self { index : 0 , buffer }
320353 }
321354
0 commit comments