Skip to content

Commit e6b6bba

Browse files
Fix spi_abort_async leaving flags set that will cause the next transfer to fail
1 parent 2f6ac06 commit e6b6bba

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

targets/TARGET_NUVOTON/TARGET_M480/objects.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ struct spi_s {
9494
DMAUsage dma_usage;
9595
int dma_chn_id_tx;
9696
int dma_chn_id_rx;
97-
uint32_t event;
97+
uint32_t event_mask;
9898
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
9999
};
100100

targets/TARGET_NUVOTON/TARGET_M480/spi_api.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ static uint32_t spi_master_read_asynch(spi_t *obj);
193193
static uint32_t spi_event_check(spi_t *obj);
194194
static void spi_enable_event(spi_t *obj, uint32_t event, uint8_t enable);
195195
static void spi_buffer_set(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length);
196-
static void spi_check_dma_usage(DMAUsage *dma_usage, int *dma_ch_tx, int *dma_ch_rx);
196+
static void nu_spi_set_dma_usage(struct spi_s * const spi, DMAUsage new_dma_usage);
197197
static int spi_is_tx_complete(spi_t *obj);
198198
static int spi_is_rx_complete(spi_t *obj);
199199
static int spi_writeable(spi_t * obj);
@@ -578,7 +578,12 @@ bool spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
578578
// Set DMA usage, allocating or releasing DMA channels
579579
nu_spi_set_dma_usage(&obj->spi, hint);
580580

581-
// SPI IRQ is necessary for both interrupt way and DMA way
581+
// SPI IRQ is necessary for both interrupt way and DMA way.
582+
// However, if we are using DMA then overflows can happen if Tx length > Rx length, so ignore them
583+
if(obj->spi.dma_usage != DMA_USAGE_NEVER)
584+
{
585+
event &= ~(SPI_EVENT_RX_OVERFLOW);
586+
}
582587
spi_enable_event(obj, event, 1);
583588
spi_buffer_set(obj, tx, tx_length, rx, rx_length);
584589

@@ -737,6 +742,21 @@ void spi_abort_asynch(spi_t *obj)
737742

738743
SPI_ClearRxFIFO(spi_base);
739744
SPI_ClearTxFIFO(spi_base);
745+
746+
// Clear any events which may have been triggered by the transfer or the abort
747+
if (spi_base->STATUS & SPI_STATUS_RXOVIF_Msk) {
748+
spi_base->STATUS = SPI_STATUS_RXOVIF_Msk;
749+
}
750+
751+
// Receive Time-Out
752+
if (spi_base->STATUS & SPI_STATUS_RXTOIF_Msk) {
753+
spi_base->STATUS = SPI_STATUS_RXTOIF_Msk;
754+
}
755+
756+
// Transmit FIFO Under-Run
757+
if (spi_base->STATUS & SPI_STATUS_TXUFIF_Msk) {
758+
spi_base->STATUS = SPI_STATUS_TXUFIF_Msk;
759+
}
740760
}
741761

742762
/**
@@ -754,7 +774,7 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
754774
spi_abort_asynch(obj);
755775
}
756776

757-
return (obj->spi.event & event) | ((event & SPI_EVENT_COMPLETE) ? SPI_EVENT_INTERNAL_TRANSFER_COMPLETE : 0);
777+
return (obj->spi.event_mask & event) | ((event & SPI_EVENT_COMPLETE) ? SPI_EVENT_INTERNAL_TRANSFER_COMPLETE : 0);
758778
}
759779

760780
uint8_t spi_active(spi_t *obj)
@@ -789,8 +809,8 @@ static int spi_readable(spi_t * obj)
789809

790810
static void spi_enable_event(spi_t *obj, uint32_t event, uint8_t enable)
791811
{
792-
obj->spi.event &= ~SPI_EVENT_ALL;
793-
obj->spi.event |= (event & SPI_EVENT_ALL);
812+
obj->spi.event_mask &= ~SPI_EVENT_ALL;
813+
obj->spi.event_mask |= (event & SPI_EVENT_ALL);
794814
if (event & SPI_EVENT_RX_OVERFLOW) {
795815
SPI_EnableInt((SPI_T *) NU_MODBASE(obj->spi.spi), SPI_FIFO_RXOV_INT_MASK);
796816
}
@@ -841,21 +861,11 @@ static uint32_t spi_event_check(spi_t *obj)
841861

842862
// Receive FIFO Overrun
843863
if (spi_base->STATUS & SPI_STATUS_RXOVIF_Msk) {
844-
spi_base->STATUS = SPI_STATUS_RXOVIF_Msk;
845-
// In case of tx length > rx length on DMA way
846-
if (obj->spi.dma_usage == DMA_USAGE_NEVER) {
847-
event |= SPI_EVENT_RX_OVERFLOW;
848-
}
864+
event |= SPI_EVENT_RX_OVERFLOW;
849865
}
850866

851-
// Receive Time-Out
852-
if (spi_base->STATUS & SPI_STATUS_RXTOIF_Msk) {
853-
spi_base->STATUS = SPI_STATUS_RXTOIF_Msk;
854-
// Not using this IF. Just clear it.
855-
}
856867
// Transmit FIFO Under-Run
857868
if (spi_base->STATUS & SPI_STATUS_TXUFIF_Msk) {
858-
spi_base->STATUS = SPI_STATUS_TXUFIF_Msk;
859869
event |= SPI_EVENT_ERROR;
860870
}
861871

0 commit comments

Comments
 (0)