@@ -5,8 +5,8 @@ use core::{
5
5
task:: { Context , Poll } ,
6
6
} ;
7
7
8
+ use embedded_dma:: { ReadBuffer , WriteBuffer } ;
8
9
use embedded_hal:: spi:: ErrorType ;
9
- use embedded_hal_async:: spi:: SpiBus ;
10
10
use futures_util:: join;
11
11
use futures_util:: task:: AtomicWaker ;
12
12
@@ -228,18 +228,22 @@ where
228
228
W : Word + DmaWord ,
229
229
MODE : Rx < W > ,
230
230
{
231
- pub fn start_dma_read < ' a > (
231
+ pub fn start_dma_read < ' a , D > (
232
232
& ' a mut self ,
233
- words : & ' a mut [ W ] ,
234
- ) -> Result < DmaTransfer < ' a , <MODE as Rx < W > >:: CH > , Error > {
233
+ mut destination : D ,
234
+ ) -> Result < DmaTransfer < ' a , <MODE as Rx < W > >:: CH > , Error >
235
+ where
236
+ D : WriteBuffer < Word = W > ,
237
+ {
235
238
let config = DmaConfig :: new ( ) . with_request ( SPI :: rx_dma_request ( ) ) ;
239
+ let ( _, len) = unsafe { destination. write_buffer ( ) } ;
236
240
237
- self . spi . inner . set_transfer_word_count ( words . len ( ) as u16 ) ;
241
+ self . spi . inner . set_transfer_word_count ( len as u16 ) ;
238
242
// Make sure to handle any errors before initializing a transfer
239
243
self . setup_read_mode ( ) ?;
240
244
241
245
let spi = & mut self . spi ;
242
- let transfer = self . mode . init_rx_transfer ( config, words ) ;
246
+ let transfer = self . mode . init_rx_transfer ( config, destination ) ;
243
247
244
248
spi. inner . enable_rx_dma ( ) ;
245
249
@@ -250,8 +254,11 @@ where
250
254
Ok ( transfer)
251
255
}
252
256
253
- async fn read_dma ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Error > {
254
- let result = self . start_dma_read ( words) ?. await ;
257
+ pub async fn read_dma < D > ( & mut self , destination : D ) -> Result < ( ) , Error >
258
+ where
259
+ D : WriteBuffer < Word = W > ,
260
+ {
261
+ let result = self . start_dma_read ( destination) ?. await ;
255
262
self . finish_transfer_async ( result) . await
256
263
}
257
264
}
@@ -263,19 +270,24 @@ where
263
270
W : Word + DmaWord ,
264
271
MODE : Tx < W > ,
265
272
{
266
- pub fn start_dma_write < ' a > (
273
+ pub fn start_dma_write < ' a , S > (
267
274
& ' a mut self ,
268
- words : & ' a [ W ] ,
269
- ) -> Result < DmaTransfer < ' a , <MODE as Tx < W > >:: CH > , Error > {
275
+ source : S ,
276
+ ) -> Result < DmaTransfer < ' a , <MODE as Tx < W > >:: CH > , Error >
277
+ where
278
+ S : ReadBuffer < Word = W > ,
279
+ {
270
280
let config = DmaConfig :: new ( ) . with_request ( SPI :: tx_dma_request ( ) ) ;
271
281
272
- self . inner . set_transfer_word_count ( words. len ( ) as u16 ) ;
282
+ let ( _, len) = unsafe { source. read_buffer ( ) } ;
283
+
284
+ self . inner . set_transfer_word_count ( len as u16 ) ;
273
285
274
286
// Make sure to handle any errors before initializing a transfer
275
287
self . setup_write_mode ( ) ?;
276
288
277
289
let spi = & mut self . spi ;
278
- let transfer = self . mode . init_tx_transfer ( config, words ) ;
290
+ let transfer = self . mode . init_tx_transfer ( config, source ) ;
279
291
280
292
transfer. start_nonblocking ( ) ;
281
293
spi. inner . enable_tx_dma ( ) ;
@@ -284,8 +296,11 @@ where
284
296
Ok ( transfer)
285
297
}
286
298
287
- async fn write_dma ( & mut self , words : & [ W ] ) -> Result < ( ) , Error > {
288
- let result = self . start_dma_write ( words) ?. await ;
299
+ pub async fn write_dma < S > ( & mut self , source : S ) -> Result < ( ) , Error >
300
+ where
301
+ S : ReadBuffer < Word = W > ,
302
+ {
303
+ let result = self . start_dma_write ( source) ?. await ;
289
304
self . finish_transfer_async ( result) . await
290
305
}
291
306
}
@@ -298,27 +313,33 @@ where
298
313
TX : DmaChannel ,
299
314
RX : DmaChannel ,
300
315
{
301
- pub fn start_dma_duplex_transfer < ' a > (
316
+ pub fn start_dma_duplex_transfer < ' a , S , D > (
302
317
& ' a mut self ,
303
- read : & ' a mut [ W ] ,
304
- write : & ' a [ W ] ,
305
- ) -> Result < ( DmaTransfer < ' a , TX > , DmaTransfer < ' a , RX > ) , Error > {
318
+ source : S ,
319
+ mut destination : D ,
320
+ ) -> Result < ( DmaTransfer < ' a , TX > , DmaTransfer < ' a , RX > ) , Error >
321
+ where
322
+ S : ReadBuffer < Word = W > ,
323
+ D : WriteBuffer < Word = W > ,
324
+ {
325
+ let ( _, read_len) = unsafe { source. read_buffer ( ) } ;
326
+ let ( _, write_len) = unsafe { destination. write_buffer ( ) } ;
327
+
306
328
assert_eq ! (
307
- read. len( ) ,
308
- write. len( ) ,
329
+ read_len, write_len,
309
330
"Read and write buffers must have the same length"
310
331
) ;
311
332
312
333
let tx_config = DmaConfig :: new ( ) . with_request ( SPI :: tx_dma_request ( ) ) ;
313
334
let rx_config = DmaConfig :: new ( ) . with_request ( SPI :: rx_dma_request ( ) ) ;
314
335
315
- self . inner . set_transfer_word_count ( read . len ( ) as u16 ) ;
336
+ self . inner . set_transfer_word_count ( read_len as u16 ) ;
316
337
317
338
self . check_transfer_mode ( ) ?;
318
339
319
340
let spi = & mut self . spi ;
320
- let tx_transfer = self . mode . init_tx_transfer ( tx_config, write ) ;
321
- let rx_transfer = self . mode . init_rx_transfer ( rx_config, read ) ;
341
+ let tx_transfer = self . mode . init_tx_transfer ( tx_config, source ) ;
342
+ let rx_transfer = self . mode . init_rx_transfer ( rx_config, destination ) ;
322
343
323
344
spi. inner . enable_rx_dma ( ) ;
324
345
rx_transfer. start_nonblocking ( ) ;
@@ -329,27 +350,38 @@ where
329
350
Ok ( ( tx_transfer, rx_transfer) )
330
351
}
331
352
332
- async fn transfer_dma (
353
+ pub async fn transfer_dma < S , D > (
333
354
& mut self ,
334
- read : & mut [ W ] ,
335
- write : & [ W ] ,
336
- ) -> Result < ( ) , Error > {
337
- let ( tx, rx) = self . start_dma_duplex_transfer ( read, write) ?;
355
+ source : S ,
356
+ destination : D ,
357
+ ) -> Result < ( ) , Error >
358
+ where
359
+ S : ReadBuffer < Word = W > ,
360
+ D : WriteBuffer < Word = W > ,
361
+ {
362
+ let ( tx, rx) = self . start_dma_duplex_transfer ( source, destination) ?;
338
363
let ( tx, rx) = ( tx. into_future ( ) , rx. into_future ( ) ) ;
339
364
let results = join ! ( tx, rx) ;
340
365
let result = results. 0 . and ( results. 1 ) ;
341
366
342
367
self . finish_transfer_async ( result) . await
343
368
}
344
369
345
- async fn transfer_inplace_dma (
370
+ pub async fn transfer_inplace_dma < B > (
346
371
& mut self ,
347
- words : & mut [ W ] ,
348
- ) -> Result < ( ) , Error > {
372
+ mut buffer : B ,
373
+ ) -> Result < ( ) , Error >
374
+ where
375
+ B : WriteBuffer < Word = W > ,
376
+ {
377
+ let ( ptr, len) = unsafe { buffer. write_buffer ( ) } ;
378
+
349
379
// Note (unsafe): Data will be read from the start of the buffer before data is written
350
- // to those locations just like for blocking non-DMA in-place transfers
351
- let write: & [ W ] = unsafe { * ( words. as_ptr ( ) as * const & [ W ] ) } ;
352
- self . transfer_dma ( words, write) . await
380
+ // to those locations just like for blocking non-DMA in-place transfers, and the location
381
+ // is already guaranteed to be 'static
382
+ let source = unsafe { core:: slice:: from_raw_parts ( ptr, len) } ;
383
+
384
+ self . transfer_dma ( source, buffer) . await
353
385
}
354
386
}
355
387
@@ -361,112 +393,6 @@ where
361
393
type Error = Error ;
362
394
}
363
395
364
- impl < SPI , CH , W > SpiBus < W > for SpiDma < SPI , DmaTx < SPI , W , CH > , W >
365
- where
366
- SPI : Instance + Waker ,
367
- W : Word + DmaWord ,
368
- CH : DmaChannel ,
369
- {
370
- async fn read ( & mut self , _words : & mut [ W ] ) -> Result < ( ) , Self :: Error > {
371
- unimplemented ! ( "Not supported for simplex transmitter" )
372
- }
373
-
374
- async fn write ( & mut self , words : & [ W ] ) -> Result < ( ) , Self :: Error > {
375
- self . write_dma ( words) . await
376
- }
377
-
378
- async fn transfer (
379
- & mut self ,
380
- _read : & mut [ W ] ,
381
- _write : & [ W ] ,
382
- ) -> Result < ( ) , Self :: Error > {
383
- unimplemented ! ( "Not supported for simplex transmitter" )
384
- }
385
-
386
- async fn transfer_in_place (
387
- & mut self ,
388
- _words : & mut [ W ] ,
389
- ) -> Result < ( ) , Self :: Error > {
390
- unimplemented ! ( "Not supported for simplex transmitter" )
391
- }
392
-
393
- async fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
394
- // This is handled within each of the above functions
395
- Ok ( ( ) )
396
- }
397
- }
398
-
399
- impl < SPI , CH , W > SpiBus < W > for SpiDma < SPI , DmaRx < SPI , W , CH > , W >
400
- where
401
- SPI : Instance + Waker ,
402
- W : Word + DmaWord ,
403
- CH : DmaChannel ,
404
- {
405
- async fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Self :: Error > {
406
- self . read_dma ( words) . await
407
- }
408
-
409
- async fn write ( & mut self , _words : & [ W ] ) -> Result < ( ) , Self :: Error > {
410
- unimplemented ! ( "Not supported for simplex receiver" )
411
- }
412
-
413
- async fn transfer (
414
- & mut self ,
415
- _read : & mut [ W ] ,
416
- _write : & [ W ] ,
417
- ) -> Result < ( ) , Self :: Error > {
418
- unimplemented ! ( "Not supported for simplex receiver" )
419
- }
420
-
421
- async fn transfer_in_place (
422
- & mut self ,
423
- _words : & mut [ W ] ,
424
- ) -> Result < ( ) , Self :: Error > {
425
- unimplemented ! ( "Not supported for simplex receiver" )
426
- }
427
-
428
- async fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
429
- // This is handled within each of the above functions
430
- Ok ( ( ) )
431
- }
432
- }
433
-
434
- impl < SPI , TX , RX , W > SpiBus < W > for SpiDma < SPI , DmaDuplex < SPI , W , TX , RX > , W >
435
- where
436
- SPI : Instance + Waker ,
437
- W : Word + DmaWord ,
438
- TX : DmaChannel ,
439
- RX : DmaChannel ,
440
- {
441
- async fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Self :: Error > {
442
- self . read_dma ( words) . await
443
- }
444
-
445
- async fn write ( & mut self , words : & [ W ] ) -> Result < ( ) , Self :: Error > {
446
- self . write_dma ( words) . await
447
- }
448
-
449
- async fn transfer (
450
- & mut self ,
451
- read : & mut [ W ] ,
452
- write : & [ W ] ,
453
- ) -> Result < ( ) , Self :: Error > {
454
- self . transfer_dma ( read, write) . await
455
- }
456
-
457
- async fn transfer_in_place (
458
- & mut self ,
459
- words : & mut [ W ] ,
460
- ) -> Result < ( ) , Self :: Error > {
461
- self . transfer_inplace_dma ( words) . await
462
- }
463
-
464
- async fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
465
- // This is handled within each of the above functions
466
- Ok ( ( ) )
467
- }
468
- }
469
-
470
396
struct SpiDmaFuture < ' a , SPI : Instance , MODE , W : Word > {
471
397
spi : & ' a mut SpiDma < SPI , MODE , W > ,
472
398
}
0 commit comments