diff options
| author | robert-hh <robert@hammelrath.com> | 2022-03-20 13:20:10 +0100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2022-04-11 12:27:49 +1000 |
| commit | 752fe759104172af2e8cbd7a3713b29134bd5a7f (patch) | |
| tree | ade4187c5796a4590212549bfe2c1c3725315a24 | |
| parent | b70b8ce3e4f213e297b4438dbfca7412525a3785 (diff) | |
mimxrt/machine_spi: Improve handling of busy SPI peripheral.
This commit changes the method of waiting for SPI being not busy. Instead
of the FIFO size, the TransferBusyFlag is probed.
Also, raise an error if the transfer failed.
| -rw-r--r-- | ports/mimxrt/machine_spi.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/ports/mimxrt/machine_spi.c b/ports/mimxrt/machine_spi.c index b8b5a4d5b..223573279 100644 --- a/ports/mimxrt/machine_spi.c +++ b/ports/mimxrt/machine_spi.c @@ -277,6 +277,10 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8 LPSPI_MasterTransferCreateHandleEDMA(self->spi_inst, &g_master_edma_handle, LPSPI_EDMAMasterCallback, self, &lpspiEdmaMasterRxRegToRxDataHandle, &lpspiEdmaMasterTxDataToTxRegHandle); + + // Wait a short while for a previous transfer to finish, but not forever + for (volatile int j = 0; (j < 5000) && ((LPSPI_GetStatusFlags(self->spi_inst) & kLPSPI_ModuleBusyFlag) != 0); j++) {} + // Start master transfer lpspi_transfer_t masterXfer; masterXfer.txData = (uint8_t *)src; @@ -297,12 +301,15 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8 } else if (src) { DCACHE_CleanByRange((uint32_t)src, len); } - LPSPI_MasterTransferEDMA(self->spi_inst, &g_master_edma_handle, &masterXfer); - - while (self->transfer_busy) { - MICROPY_EVENT_POLL_HOOK + if (LPSPI_MasterTransferEDMA(self->spi_inst, &g_master_edma_handle, &masterXfer) != kStatus_Success) { + L1CACHE_EnableDCache(); + mp_raise_OSError(EIO); + } else { + while (self->transfer_busy) { + MICROPY_EVENT_POLL_HOOK + } + L1CACHE_EnableDCache(); } - L1CACHE_EnableDCache(); } // Release DMA channels, even if never allocated. if (chan_rx >= 0) { @@ -313,10 +320,9 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8 } if (!use_dma) { - // Wait until a previous Transfer is finished - while (LPSPI_GetTxFifoCount(self->spi_inst) > 0) { - MICROPY_EVENT_POLL_HOOK - } + // Wait a short while for a previous transfer to finish, but not forever + for (volatile int j = 0; (j < 5000) && ((LPSPI_GetStatusFlags(self->spi_inst) & kLPSPI_ModuleBusyFlag) != 0); j++) {} + // Reconfigure the TCR, required after switch between DMA vs. non-DMA LPSPI_Enable(self->spi_inst, false); // Disable first before new settings are applied self->spi_inst->TCR = LPSPI_TCR_CPOL(self->master_config->cpol) | LPSPI_TCR_CPHA(self->master_config->cpha) | @@ -330,7 +336,9 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8 masterXfer.dataSize = len; masterXfer.configFlags = (self->master_config->whichPcs << LPSPI_MASTER_PCS_SHIFT) | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap; - LPSPI_MasterTransferBlocking(self->spi_inst, &masterXfer); + if (LPSPI_MasterTransferBlocking(self->spi_inst, &masterXfer) != kStatus_Success) { + mp_raise_OSError(EIO); + } } } |
