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:
parent
af4a87af8e
commit
1e87837f2a
1 changed files with 9 additions and 2 deletions
|
@ -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--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue