summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobert-hh <robert@hammelrath.com>2022-03-20 13:20:10 +0100
committerDamien George <damien@micropython.org>2022-04-11 12:27:49 +1000
commit752fe759104172af2e8cbd7a3713b29134bd5a7f (patch)
treeade4187c5796a4590212549bfe2c1c3725315a24
parentb70b8ce3e4f213e297b4438dbfca7412525a3785 (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.c28
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);
+ }
}
}