1313use esp_hal:: {
1414 Async ,
1515 delay:: Delay ,
16+ dma:: { DmaDescriptor , DmaTxStreamBuf } ,
1617 dma_buffers,
1718 gpio:: { AnyPin , NoPin , Pin } ,
1819 i2s:: master:: { DataFormat , I2s , I2sTx , Standard } ,
@@ -59,24 +60,28 @@ impl Iterator for SampleSource {
5960}
6061
6162#[ embassy_executor:: task]
62- async fn writer ( tx_buffer : & ' static mut [ u8 ] , i2s_tx : I2sTx < ' static , Async > ) {
63+ async fn writer (
64+ tx_buffer : & ' static mut [ u8 ] ,
65+ tx_descriptors : & ' static mut [ DmaDescriptor ] ,
66+ i2s_tx : I2sTx < ' static , Async > ,
67+ ) {
6368 let mut samples = SampleSource :: new ( ) ;
6469 for b in tx_buffer. iter_mut ( ) {
6570 * b = samples. next ( ) . unwrap ( ) ;
6671 }
6772
68- let mut tx_transfer = i2s_tx. write_dma_circular_async ( tx_buffer) . unwrap ( ) ;
73+ let mut tx_transfer = i2s_tx
74+ . write ( DmaTxStreamBuf :: new ( tx_descriptors, tx_buffer) . unwrap ( ) )
75+ . unwrap ( ) ;
6976
7077 loop {
71- tx_transfer
72- . push_with ( |buffer| {
73- for b in buffer. iter_mut ( ) {
74- * b = samples. next ( ) . unwrap ( ) ;
75- }
76- buffer. len ( )
77- } )
78- . await
79- . unwrap ( ) ;
78+ tx_transfer. wait_for_available ( ) . await . unwrap ( ) ;
79+ tx_transfer. push_with ( |buffer| {
80+ for b in buffer. iter_mut ( ) {
81+ * b = samples. next ( ) . unwrap ( ) ;
82+ }
83+ buffer. len ( )
84+ } ) ;
8085 }
8186}
8287
@@ -99,6 +104,8 @@ fn enable_loopback() {
99104#[ cfg( test) ]
100105#[ embedded_test:: tests( default_timeout = 3 , executor = hil_test:: Executor :: new( ) ) ]
101106mod tests {
107+ use esp_hal:: dma:: DmaRxStreamBuf ;
108+
102109 use super :: * ;
103110
104111 struct Context {
@@ -153,26 +160,33 @@ mod tests {
153160 . with_bclk ( NoPin )
154161 . with_ws ( NoPin )
155162 . with_dout ( dout)
156- . build ( tx_descriptors ) ;
163+ . build ( ) ;
157164
158165 let i2s_rx = i2s
159166 . i2s_rx
160167 . with_bclk ( NoPin )
161168 . with_ws ( NoPin )
162169 . with_din ( din)
163- . build ( rx_descriptors ) ;
170+ . build ( ) ;
164171
165172 enable_loopback ( ) ;
166173
167- let mut rx_transfer = i2s_rx. read_dma_circular_async ( rx_buffer) . unwrap ( ) ;
168- spawner. must_spawn ( writer ( tx_buffer, i2s_tx) ) ;
174+ let mut rx_transfer = i2s_rx
175+ . read (
176+ DmaRxStreamBuf :: new ( rx_descriptors, rx_buffer) . unwrap ( ) ,
177+ BUFFER_SIZE ,
178+ )
179+ . unwrap ( ) ;
180+ spawner. must_spawn ( writer ( tx_buffer, tx_descriptors, i2s_tx) ) ;
169181
170- let mut rcv = [ 0u8 ; BUFFER_SIZE ] ;
182+ // let mut rcv = [0u8; BUFFER_SIZE];
171183 let mut sample_idx = 0 ;
172184 let mut samples = SampleSource :: new ( ) ;
173185 for _ in 0 ..30 {
174- let len = rx_transfer. pop ( & mut rcv) . await . unwrap ( ) ;
175- for & b in & rcv[ ..len] {
186+ rx_transfer. wait_for_available ( ) . await . unwrap ( ) ;
187+ let data = rx_transfer. peek ( ) ;
188+ let len = data. len ( ) ;
189+ for & b in data {
176190 let expected = samples. next ( ) . unwrap ( ) ;
177191 assert_eq ! (
178192 b, expected,
@@ -181,6 +195,7 @@ mod tests {
181195 ) ;
182196 sample_idx += 1 ;
183197 }
198+ rx_transfer. consume ( len) ;
184199 }
185200 }
186201
@@ -198,19 +213,19 @@ mod tests {
198213
199214 let ( din, dout) = unsafe { ctx. dout . split ( ) } ;
200215
201- let mut i2s_tx = i2s
216+ let i2s_tx = i2s
202217 . i2s_tx
203218 . with_bclk ( NoPin )
204219 . with_ws ( NoPin )
205220 . with_dout ( dout)
206- . build ( tx_descriptors ) ;
221+ . build ( ) ;
207222
208- let mut i2s_rx = i2s
223+ let i2s_rx = i2s
209224 . i2s_rx
210225 . with_bclk ( NoPin )
211226 . with_ws ( NoPin )
212227 . with_din ( din)
213- . build ( rx_descriptors ) ;
228+ . build ( ) ;
214229
215230 enable_loopback ( ) ;
216231
@@ -222,51 +237,53 @@ mod tests {
222237 let mut rcv = [ 0u8 ; 11000 ] ;
223238 let mut filler = [ 0x1u8 ; 12000 ] ;
224239
225- let mut rx_transfer = i2s_rx. read_dma_circular ( rx_buffer) . unwrap ( ) ;
226- // trying to pop data before calling `available` should just do nothing
227- assert_eq ! ( 0 , rx_transfer. pop( & mut rcv[ ..100 ] ) . unwrap( ) ) ;
240+ let mut rx_transfer = i2s_rx
241+ . read (
242+ DmaRxStreamBuf :: new ( rx_descriptors, rx_buffer) . unwrap ( ) ,
243+ 4000 ,
244+ )
245+ . unwrap ( ) ;
246+ // trying to peek data before calling `available` should just do nothing
247+ assert_eq ! ( 0 , rx_transfer. peek( ) . len( ) ) ;
228248
229249 // no data available yet
230- assert_eq ! ( 0 , rx_transfer. available ( ) . unwrap ( ) ) ;
250+ assert_eq ! ( 0 , rx_transfer. available_bytes ( ) ) ;
231251
232- let mut tx_transfer = i2s_tx. write_dma_circular ( tx_buffer) . unwrap ( ) ;
252+ let mut tx_transfer = i2s_tx
253+ . write ( DmaTxStreamBuf :: new ( tx_descriptors, tx_buffer) . unwrap ( ) )
254+ . unwrap ( ) ;
233255
234256 let mut iteration = 0 ;
235257 let mut sample_idx = 0 ;
236258 let mut check_samples = SampleSource :: new ( ) ;
237259 loop {
238- let tx_avail = tx_transfer. available ( ) . unwrap ( ) ;
260+ let tx_avail = tx_transfer. available_bytes ( ) ;
239261
240262 // make sure there are more than one descriptor buffers ready to push
241263 if tx_avail > 5000 {
242264 for b in & mut filler[ 0 ..tx_avail] . iter_mut ( ) {
243265 * b = samples. next ( ) . unwrap ( ) ;
244266 }
245- tx_transfer. push ( & filler[ 0 ..tx_avail] ) . unwrap ( ) ;
267+ tx_transfer. push ( & filler[ 0 ..tx_avail] ) ;
246268 }
247269
248270 // test calling available multiple times doesn't break anything
249- rx_transfer. available ( ) . unwrap ( ) ;
250- rx_transfer. available ( ) . unwrap ( ) ;
251- rx_transfer. available ( ) . unwrap ( ) ;
252- rx_transfer. available ( ) . unwrap ( ) ;
253- rx_transfer. available ( ) . unwrap ( ) ;
254- rx_transfer. available ( ) . unwrap ( ) ;
255- let rx_avail = rx_transfer. available ( ) . unwrap ( ) ;
271+ rx_transfer. available_bytes ( ) ;
272+ rx_transfer. available_bytes ( ) ;
273+ rx_transfer. available_bytes ( ) ;
274+ rx_transfer. available_bytes ( ) ;
275+ rx_transfer. available_bytes ( ) ;
276+ rx_transfer. available_bytes ( ) ;
277+ let rx_avail = rx_transfer. available_bytes ( ) ;
256278
257279 // make sure there are more than one descriptor buffers ready to pop
258280 if rx_avail > 0 {
259- // trying to pop less data than available is an error
260- assert_eq ! (
261- Err ( esp_hal:: dma:: DmaError :: BufferTooSmall ) ,
262- rx_transfer. pop( & mut rcv[ ..rx_avail / 2 ] )
263- ) ;
264-
265281 rcv. fill ( 0xff ) ;
266- let len = rx_transfer. pop ( & mut rcv) . unwrap ( ) ;
282+ let data = rx_transfer. peek ( ) ;
283+ let len = data. len ( ) ;
267284 assert ! ( len > 0 ) ;
268285
269- for & b in & rcv [ ..len ] {
286+ for & b in data {
270287 let expected = check_samples. next ( ) . unwrap ( ) ;
271288 assert_eq ! (
272289 b, expected,
@@ -276,6 +293,8 @@ mod tests {
276293 sample_idx += 1 ;
277294 }
278295
296+ rx_transfer. consume ( len) ;
297+
279298 iteration += 1 ;
280299
281300 if iteration == 1 {
@@ -290,60 +309,4 @@ mod tests {
290309 }
291310 }
292311 }
293-
294- #[ test]
295- fn test_i2s_push_too_late ( ctx : Context ) {
296- let ( _, _, tx_buffer, tx_descriptors) = dma_buffers ! ( 0 , 16000 ) ;
297-
298- let i2s = I2s :: new (
299- ctx. i2s ,
300- Standard :: Philips ,
301- DataFormat :: Data16Channel16 ,
302- Rate :: from_hz ( 16000 ) ,
303- ctx. dma_channel ,
304- ) ;
305-
306- let mut i2s_tx = i2s
307- . i2s_tx
308- . with_bclk ( NoPin )
309- . with_ws ( NoPin )
310- . with_dout ( ctx. dout )
311- . build ( tx_descriptors) ;
312-
313- let mut tx_transfer = i2s_tx. write_dma_circular ( tx_buffer) . unwrap ( ) ;
314-
315- let delay = esp_hal:: delay:: Delay :: new ( ) ;
316- delay. delay_millis ( 300 ) ;
317-
318- assert ! ( matches!( tx_transfer. push( & [ 0 ; 128 ] ) , Err ( _) ) ) ;
319- }
320-
321- #[ test]
322- #[ timeout( 1 ) ]
323- fn test_i2s_read_too_late ( ctx : Context ) {
324- let ( rx_buffer, rx_descriptors, _, _) = dma_buffers ! ( 16000 , 0 ) ;
325-
326- let i2s = I2s :: new (
327- ctx. i2s ,
328- Standard :: Philips ,
329- DataFormat :: Data16Channel16 ,
330- Rate :: from_hz ( 16000 ) ,
331- ctx. dma_channel ,
332- ) ;
333-
334- let mut i2s_rx = i2s
335- . i2s_rx
336- . with_bclk ( NoPin )
337- . with_ws ( NoPin )
338- . with_din ( ctx. dout ) // not a typo
339- . build ( rx_descriptors) ;
340-
341- let mut buffer = [ 0u8 ; 1024 ] ;
342- let mut rx_transfer = i2s_rx. read_dma_circular ( rx_buffer) . unwrap ( ) ;
343-
344- let delay = esp_hal:: delay:: Delay :: new ( ) ;
345- delay. delay_millis ( 300 ) ;
346-
347- assert ! ( matches!( rx_transfer. pop( & mut buffer) , Err ( _) ) ) ;
348- }
349312}
0 commit comments