M263: Fix redundant SPI clock generation

Fix SPI clocks are generated redundantly at the end of transfer.

This is also to fix FPGA CI test mbed_hal_fpga_ci_test_shield-spi/
SPI - async mode.
pull/11379/head
Chun-Chieh Li 2019-08-20 17:17:59 +08:00
parent d15abe5171
commit eb435b7da0
2 changed files with 7 additions and 10 deletions

View File

@ -85,7 +85,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 {

View File

@ -388,6 +388,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);
@ -658,16 +661,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);
@ -690,6 +689,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
@ -710,15 +710,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);