We are using the MUSKA SPI interface to communicate with an external Wifi module.
We are running the SPI interface at 12.5 Mbits/sec.
WE understand from the Wifi module vendor that it is critical that we maintain a steady SCLK signal once a transaction has been started (there should not be any stall in between bytes in the SCLK signal) or it can cause the Wifi module to hang.
It seems like the interrupt based transfer on Muska cannot keep up with updating the TX/RX buffers and causes the SCLK signal to stall. That is understandable since Muska only runs at 26 MHz. Even with Continuous Transfer enabled we see stalling in between bytes after 8 bytes have been transferred.
To solve the problem, I am trying to use DMA based SPI transfer. So far that works well when we know ahead of time exactly how many bytes we want to include in a transaction. With a DMA based transfer, the SCLK stalls disappear.
But, when we receive data over Wifi, we do not ahead of time know how much data we will be receiving. There is a separate Data Ready flow control data HW signal from the Wifi module which indicates when there is no more data to receive as SPI transaction is going on. We have to monitor that signal to see when to end the SPI transacation.
So my plan is the following for receiving Wifi data.
There does not seem to be much documentation in the HRM as to how we abort an SPI transaction. I wrote a function which tries to do that:
ADI_SPI_RESULT adi_spi_HaltTransaction(ADI_SPI_HANDLE const hDevice)
//hDevice->pSpi->CTL &= (uint16_t)~((uint16_t) BITM_SPI_CTL_SPIEN); //disable SPI
/* Clear possible interrupt sources: XFRDONE and underflow and overflow */
hDevice->pSpi->IEN &= ~(BITM_SPI_IEN_XFRDONE|BITM_SPI_IEN_RXOVR|BITM_SPI_IEN_TXUNDR);
hDevice->bTransferComplete = true;
hDevice->pSpi->CNT = 0; //reset SPI transaction byte count.
if( hDevice->bDmaMode==true )
//disable SPI DMA
hDevice->pSpi->DMA &= (uint16_t)~(BITM_SPI_DMA_EN | BITM_SPI_DMA_RXEN | BITM_SPI_DMA_TXEN);
hDevice->pSpi->CTL |= (BITM_SPI_CTL_RFLUSH|BITM_SPI_CTL_TFLUSH); //flush fifos
//hDevice->pSpi->CTL &= (uint16_t)~(BITM_SPI_CTL_RFLUSH|BITM_SPI_CTL_TFLUSH);
hDevice->pSpi->CTL &= (uint16_t)~BITM_SPI_CTL_CON; //reset continuous mode
//hDevice->pSpi->CTL |= BITM_SPI_CTL_SPIEN; //re-enable SPI
/* Everything done, now just clear the STAT register */
uint16_t nErrorStatus = hDevice->pSpi->STAT;
hDevice->pSpi->STAT = nErrorStatus;
hDevice->RxRemaining = 0u;
hDevice->TxRemaining = 0u;
This seems to stop the current transaction. But when I start the next DMA based SPI transaction, it appears that the data being sent out on MOSI may still be data from the previous cancelled transaction. And I am getting CLK stalls in between bytes.
Is there any guidance on how to abort a DMA based SPI transaction and restart a new fresh one. That would be much appreciated.