@@ -275,16 +275,8 @@ void SPIClass::dmaCallback_read(Adafruit_ZeroDMA *dma)
275
275
// flag this part of the dma done
276
276
spiPtr[channel]->dma_read_done = true ;
277
277
278
- // read and write dmas are both done
279
- if (spiPtr[channel]->dma_read_done && spiPtr[channel]->dma_write_done )
280
- {
281
- // is a user specified callback to call on completion
282
- if (spiPtr[channel]->userDmaCallback != NULL )
283
- {
284
- // call the callback function the user specified
285
- spiPtr[channel]->userDmaCallback ();
286
- }
287
- }
278
+ // see if the entire transaction is completed
279
+ checkDmaComplete (channel);
288
280
}
289
281
290
282
// dma callback when the write part is completed
@@ -298,15 +290,43 @@ void SPIClass::dmaCallback_write(Adafruit_ZeroDMA *dma)
298
290
// flag this part of the dma done
299
291
spiPtr[channel]->dma_write_done = true ;
300
292
293
+ // see if the entire transaction is completed
294
+ checkDmaComplete (channel);
295
+
296
+ }
297
+
298
+ // see if the entire dma transaction is completed
299
+ // will automatically initiate another dma if we have bytes remaining to transfer
300
+ void SPIClass::checkDmaComplete (uint8_t channel)
301
+ {
301
302
// read and write dmas are both done
302
303
if (spiPtr[channel]->dma_read_done && spiPtr[channel]->dma_write_done )
303
304
{
304
- // is a user specified callback to call on completion
305
- if (spiPtr[channel]->userDmaCallback != NULL )
305
+ // are more bytes that need to be transfered
306
+ // fire another dma transaction
307
+ if ( (spiPtr[channel]->dma_bytes_remaining ) > 0 )
306
308
{
307
- // call the callback function the user specified
308
- spiPtr[channel]->userDmaCallback ();
309
+ // initiate another transfer for the next section of bytes
310
+ // update buffer pointers offsets
311
+ // use the same user callback as last time if any
312
+ void * txbuf = spiPtr[channel]->txbuf_last + DMA_MAX_TRANSFER_SIZE;
313
+ void * rxbuf = spiPtr[channel]->rxbuf_last + DMA_MAX_TRANSFER_SIZE;
314
+ spiPtr[channel]->transfer (txbuf, rxbuf, spiPtr[channel]->dma_bytes_remaining , spiPtr[channel]->userDmaCallback );
309
315
}
316
+ // the transfer is completed, no bytes remaining
317
+ else
318
+ {
319
+ // flag as completed for anything poling for completion
320
+ spiPtr[channel]->dma_complete = true ;
321
+
322
+ // call the callback function the user specified if any
323
+ if (spiPtr[channel]->userDmaCallback != NULL )
324
+ {
325
+ spiPtr[channel]->userDmaCallback ();
326
+ }
327
+
328
+ }
329
+
310
330
}
311
331
}
312
332
@@ -326,7 +346,7 @@ void SPIClass::transfer(const void* txbuf, void* rxbuf, uint32_t count, bool blo
326
346
// Waits for a prior in-background DMA transfer to complete.
327
347
void SPIClass::waitForTransfer (void )
328
348
{
329
- while ( !dma_read_done || !dma_write_done )
349
+ while ( !dma_complete )
330
350
{
331
351
// do nothing, wait for transfer completion
332
352
}
@@ -337,9 +357,42 @@ void SPIClass::waitForTransfer(void)
337
357
// the callback parameter should be passed in by the user, it is called when the dma is done
338
358
void SPIClass::transfer (void * txbuf, void * rxbuf, uint32_t count, void (*functionToCallWhenComplete)(void ) )
339
359
{
340
- // save this function to call when the dma is done
360
+ // remember these buffer pointers
361
+ // will reuse if we have to do multiple dma transactions and pointer math
362
+ txbuf_last = txbuf;
363
+ rxbuf_last = rxbuf;
364
+
365
+ // save this function to call when the entire dma is done
341
366
userDmaCallback = functionToCallWhenComplete;
342
367
368
+ // Maximum bytes per DMA descriptor is 65,535 (NOT 65,536).
369
+ // We could set up a descriptor chain, but that gets more
370
+ // complex. For now, instead, break up long transfers into
371
+ // chunks of 65,535 bytes max...these transfers are all
372
+ // blocking, regardless of the "block" argument, except
373
+ // for the last one which will observe the background request.
374
+ // The fractional part is done first, so for any "partially
375
+ // blocking" transfers like these at least it's the largest
376
+ // single-descriptor transfer possible that occurs in the
377
+ // background, rather than the tail end.
378
+ uint16_t bytesThisPass;
379
+
380
+ if (count > DMA_MAX_TRANSFER_SIZE)
381
+ {
382
+ // Too big for 1 descriptor
383
+ // will need to do multiple dma transfers
384
+ bytesThisPass = DMA_MAX_TRANSFER_SIZE;
385
+
386
+ // remember bytes remaining for future transfers
387
+ dma_bytes_remaining = count - DMA_MAX_TRANSFER_SIZE;
388
+ }
389
+ else
390
+ {
391
+ // can do everything in one dma transfer
392
+ bytesThisPass = count;
393
+ dma_bytes_remaining = 0 ;
394
+ }
395
+
343
396
// ******************************
344
397
// If the RX DMA channel is not yet allocated...
345
398
if (readChannel.getChannel () >= DMAC_CH_NUM)
@@ -349,7 +402,7 @@ void SPIClass::transfer(void* txbuf, void* rxbuf, uint32_t count, void (*functio
349
402
readDescriptor = readChannel.addDescriptor (
350
403
(void *)getDataRegister (), // Source address (SPI data reg)
351
404
rxbuf, // Dest address
352
- count , // Count
405
+ bytesThisPass , // bytes to transfer
353
406
DMA_BEAT_SIZE_BYTE, // Bytes/hwords/words
354
407
false , // Don't increment source address
355
408
true ); // Increment dest address
@@ -366,7 +419,7 @@ void SPIClass::transfer(void* txbuf, void* rxbuf, uint32_t count, void (*functio
366
419
readDescriptor,
367
420
(void *)getDataRegister (), // Source address (SPI data reg)
368
421
rxbuf, // Dest address
369
- count ); // Count
422
+ bytesThisPass ); // bytes to transfer
370
423
}
371
424
372
425
// If the TX DMA channel is not yet allocated...
@@ -377,7 +430,7 @@ void SPIClass::transfer(void* txbuf, void* rxbuf, uint32_t count, void (*functio
377
430
writeDescriptor = writeChannel.addDescriptor (
378
431
txbuf, // Source address
379
432
(void *)getDataRegister (), // Dest (SPI data register)
380
- count , // Count
433
+ bytesThisPass , // bytes to transfer
381
434
DMA_BEAT_SIZE_BYTE, // Bytes/hwords/words
382
435
true , // Increment source address
383
436
false ); // Don't increment dest address
@@ -394,14 +447,16 @@ void SPIClass::transfer(void* txbuf, void* rxbuf, uint32_t count, void (*functio
394
447
writeDescriptor,
395
448
txbuf, // Source address
396
449
(void *)getDataRegister (), // Dest (SPI data register)
397
- count ); // Count
450
+ bytesThisPass ); // bytes to transfer
398
451
}
399
452
400
453
// ******************************
401
454
// clear the flags
402
- // fire the dma transactions
403
455
dma_read_done = false ;
404
456
dma_write_done = false ;
457
+ dma_complete = false ;
458
+
459
+ // fire the dma transactions
405
460
readChannel.startJob ();
406
461
writeChannel.startJob ();
407
462
}
0 commit comments