Hey all,
I'm working on SPI implementation (both master and slave) on SAM v71 and I'm having a delay between enabling TDRE interrupt, sending first byte and TDRE interrupt getting called.
I'm not using XDMAC as my frames are only 20 bytes long.
TDRE interrupt is getting called properly (as soon as data is transferred to shift register) after the delay after interrupt enable, for every other byte in same transfer, but the same thing happens for first byte in every other frame transfer (TDRE interrupt gets disabled in between frame transfers).
If I do
while (spi->instance->SPI_SR & SPI_SR_TDRE_Msk);
after sending first byte, flag in status register is actually being set after just few clock cycles, its just interrupt that is not being called right away.
Here is my code for starting Write/Read:
boolean Spi_WriteRead(SpiObject* spi, void* txBuffer, size_t txSize, void* rxBuffer, size_t rxSize) { boolean requestAccepted = FALSE; if ((((txBuffer != NULL) && (txSize > 0)) || ((rxBuffer != NULL) && (rxSize > 0))) && (spi->txIsBusy == FALSE)) { spi->txBuffer = txBuffer; spi->rxBuffer = rxBuffer; spi->txCount = 0; spi->rxCount = 0; spi->txSize = (spi->txBuffer != NULL ? txSize : 0); spi->rxSize = (spi->rxBuffer != NULL ? rxSize : 0); spi->txIsBusy = TRUE; // flush unread data uint16_t dummyData = (spi->instance->SPI_RDR & SPI_RDR_RD_Msk) >> SPI_RDR_RD_Pos; (void)dummyData; // calculate number of dummy bytes to be sent if (spi->rxSize > spi->txSize) spi->dummySize = (spi->rxSize - spi->txSize); else spi->dummySize = 0; // start the write here, rest will happen from ISR if (spi->txCount < spi->txSize) { spi->instance->SPI_TDR = *((uint8_t*)spi->txBuffer); spi->txCount++; } else { spi->instance->SPI_TDR = (uint8_t)DUMMY_VALUE; spi->dummySize--; } // enable interrupts spi->instance->SPI_IER = SPI_IER_TDRE_Msk | SPI_IER_RDRF_Msk; } return requestAccepted; }
Appreciate any info,
Dino