diff --git a/targets/TARGET_NUVOTON/TARGET_M251/objects.h b/targets/TARGET_NUVOTON/TARGET_M251/objects.h index 50c0b95a8b..aca28833f1 100644 --- a/targets/TARGET_NUVOTON/TARGET_M251/objects.h +++ b/targets/TARGET_NUVOTON/TARGET_M251/objects.h @@ -86,7 +86,7 @@ struct spi_s { int dma_chn_id_tx; int dma_chn_id_rx; uint32_t event; - uint32_t hdlr_async; + uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way }; struct i2c_s { diff --git a/targets/TARGET_NUVOTON/TARGET_M251/spi_api.c b/targets/TARGET_NUVOTON/TARGET_M251/spi_api.c index a72ae85a82..3004a64986 100644 --- a/targets/TARGET_NUVOTON/TARGET_M251/spi_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M251/spi_api.c @@ -367,6 +367,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, SPI_ENABLE_SYNC(spi_base); + // Initialize total SPI transfer frames + obj->spi.txrx_rmn = NU_MAX(tx_length, rx_length); + if (obj->spi.dma_usage == DMA_USAGE_NEVER) { // Interrupt way spi_master_write_asynch(obj, spi_fifo_depth(obj) / 2); @@ -637,16 +640,12 @@ static uint32_t spi_event_check(spi_t *obj) static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit) { uint32_t n_words = 0; - uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos; - uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos; - uint32_t max_tx = NU_MAX(tx_rmn, rx_rmn); - max_tx = NU_MIN(max_tx, tx_limit); uint8_t data_width = spi_get_data_width(obj); uint8_t bytes_per_word = (data_width + 7) / 8; uint8_t *tx = (uint8_t *)(obj->tx_buff.buffer) + bytes_per_word * obj->tx_buff.pos; SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi); - while ((n_words < max_tx) && spi_writeable(obj)) { + while (obj->spi.txrx_rmn && spi_writeable(obj)) { if (spi_is_tx_complete(obj)) { // Transmit dummy as transmit buffer is empty SPI_WRITE_TX(spi_base, 0); @@ -669,6 +668,7 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit) obj->tx_buff.pos ++; } n_words ++; + obj->spi.txrx_rmn --; } //Return the number of words that have been sent @@ -689,15 +689,12 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit) static uint32_t spi_master_read_asynch(spi_t *obj) { uint32_t n_words = 0; - uint32_t tx_rmn = obj->tx_buff.length - obj->tx_buff.pos; - uint32_t rx_rmn = obj->rx_buff.length - obj->rx_buff.pos; - uint32_t max_rx = NU_MAX(tx_rmn, rx_rmn); uint8_t data_width = spi_get_data_width(obj); uint8_t bytes_per_word = (data_width + 7) / 8; uint8_t *rx = (uint8_t *)(obj->rx_buff.buffer) + bytes_per_word * obj->rx_buff.pos; SPI_T *spi_base = (SPI_T *) NU_MODBASE(obj->spi.spi); - while ((n_words < max_rx) && spi_readable(obj)) { + while (spi_readable(obj)) { if (spi_is_rx_complete(obj)) { // Disregard as receive buffer is full SPI_READ_RX(spi_base);