drivers: spi: pl022: fix dropping RX bytes

If the thread that submits data over spi is interrupted by a higher
priority thread while pushing data to the tx fifo the hardware pushes
data to spi and frees up space in the fifo. In this case more than
8 Bytes are written to the tx fifo and bytes in the rx fifo get lost
before they are collected in the rx while loop.
To avoid this, the tx loop is exited after a maximum of 8 bytes and the
rx loop will run until it collected all bytes from the rx fifo.

Signed-off-by: Gerhard Jörges <joerges@metratec.com>
This commit is contained in:
Gerhard Jörges 2022-09-14 11:09:56 +02:00 committed by Carles Cufí
commit 1e87837f2a

View file

@ -470,6 +470,7 @@ static void spi_pl022_xfer(const struct device *dev)
const void *txbuf = data->ctx.tx_buf; const void *txbuf = data->ctx.tx_buf;
void *rxbuf = data->ctx.rx_buf; void *rxbuf = data->ctx.rx_buf;
uint32_t txrx; uint32_t txrx;
size_t fifo_cnt = 0;
data->tx_count = 0; data->tx_count = 0;
data->rx_count = 0; data->rx_count = 0;
@ -483,7 +484,8 @@ static void spi_pl022_xfer(const struct device *dev)
while (data->rx_count < chunk_len || data->tx_count < chunk_len) { while (data->rx_count < chunk_len || data->tx_count < chunk_len) {
/* Fill up fifo with available TX data */ /* Fill up fifo with available TX data */
while (SSP_TX_FIFO_NOT_FULL(cfg->reg) && data->tx_count < chunk_len) { while (SSP_TX_FIFO_NOT_FULL(cfg->reg) && data->tx_count < chunk_len &&
fifo_cnt < SSP_FIFO_DEPTH) {
/* Send 0 in the case of read only operation */ /* Send 0 in the case of read only operation */
txrx = 0; txrx = 0;
@ -492,8 +494,12 @@ static void spi_pl022_xfer(const struct device *dev)
} }
SSP_WRITE_REG(SSP_DR(cfg->reg), txrx); SSP_WRITE_REG(SSP_DR(cfg->reg), txrx);
data->tx_count++; data->tx_count++;
fifo_cnt++;
} }
while (SSP_RX_FIFO_NOT_EMPTY(cfg->reg) && data->rx_count < chunk_len) { while (data->rx_count < chunk_len && fifo_cnt > 0) {
if (!SSP_RX_FIFO_NOT_EMPTY(cfg->reg))
continue;
txrx = SSP_READ_REG(SSP_DR(cfg->reg)); txrx = SSP_READ_REG(SSP_DR(cfg->reg));
/* Discard received data if rx buffer not assigned */ /* Discard received data if rx buffer not assigned */
@ -501,6 +507,7 @@ static void spi_pl022_xfer(const struct device *dev)
((uint8_t *)rxbuf)[data->rx_count] = (uint8_t)txrx; ((uint8_t *)rxbuf)[data->rx_count] = (uint8_t)txrx;
} }
data->rx_count++; data->rx_count++;
fifo_cnt--;
} }
} }
} }