Skip to content

Commit 0444a36

Browse files
Added an additional SPI API function dmaSendAsync which will start the a DMA send of a buffer and return immediately. The next time dmaSendAsync is called it waits if the previous transfer is not complete. Note the buffer is not copied, so ddouble buffering is needed to use this function
1 parent 3c4307e commit 0444a36

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

STM32F1/libraries/SPI/src/SPI.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,48 @@ uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc)
469469
return b;
470470
}
471471

472+
473+
uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc)
474+
{
475+
static bool isRunning=false;
476+
uint8 b = 0;
477+
478+
if (isRunning)
479+
{
480+
481+
uint32_t m = millis();
482+
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
483+
//delayMicroseconds(10);
484+
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
485+
}
486+
487+
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
488+
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
489+
spi_tx_dma_disable(_currentSetting->spi_d);
490+
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
491+
isRunning=false;
492+
}
493+
494+
495+
if (length == 0) return 0;
496+
uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
497+
498+
dma_init(_currentSetting->spiDmaDev);
499+
// TX
500+
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
501+
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
502+
transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
503+
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
504+
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
505+
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
506+
spi_tx_dma_enable(_currentSetting->spi_d);
507+
508+
isRunning=true;
509+
510+
return b;
511+
}
512+
513+
472514
void SPIClass::attachInterrupt(void) {
473515
// Should be enableInterrupt()
474516
}

STM32F1/libraries/SPI/src/SPI.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ class SPIClass {
291291
* @param length Number of bytes in buffer to transmit.
292292
*/
293293
uint8 dmaSend(void * transmitBuf, uint16 length, bool minc = 1);
294-
294+
uint8 dmaSendAsync(void * transmitBuf, uint16 length, bool minc = 1);
295295
/*
296296
* Pin accessors
297297
*/

0 commit comments

Comments
 (0)