From 84d2f7f4deafd324e4112ca0074eef0a1c248292 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 12 Jun 2025 17:38:43 -0500 Subject: [PATCH] spi_nxp_lpspi: Fix extra byte sent on v1 lpspi This stupid errata will not leave me alone, here is another bandaid to deal with an issue where an extra byte was being sent on version 1 LPSPIs due to the algorithm of filling NOPs when only RX is left was not expecting the situation where the LPSPI actually consumed everything from the fifo but is not sending it due to this ridiculous stalling errata. Signed-off-by: Declan Snyder --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c index 367d30e7116..ad729cd414e 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c @@ -252,6 +252,12 @@ static void lpspi_isr(const struct device *dev) return; } + /* the lpspi v1 has an errata where it doesn't clock the last bit + * in continuous mode until you write the TCR + */ + bool likely_stalling_v1 = data->major_version < 2 && + (DIV_ROUND_UP(spi_context_rx_len_left(ctx, word_size_bytes), word_size_bytes) == 1); + if (spi_context_rx_on(ctx)) { /* capture these values because they could change during this code block */ size_t rx_fifo_len = rx_fifo_cur_len(base); @@ -279,6 +285,10 @@ static void lpspi_isr(const struct device *dev) size_t max_fifo_fill = MIN(tx_fifo_space_left, rx_fifo_space_left); size_t max_fill = MIN(max_fifo_fill, expected_rx_left); + if (likely_stalling_v1 && max_fill > 0) { + max_fill -= 1; + } + /* If we already have some words in the tx fifo, we should count those */ if (max_fill > tx_fifo_len) { max_fill -= tx_fifo_len; @@ -290,8 +300,7 @@ static void lpspi_isr(const struct device *dev) lpspi_fill_tx_fifo_nop(dev, max_fill); } - if ((DIV_ROUND_UP(spi_context_rx_len_left(ctx, word_size_bytes), word_size_bytes) == 1) && - (data->major_version < 2)) { + if (likely_stalling_v1) { /* Due to stalling behavior on older LPSPI, * need to end xfer in order to get last bit clocked out on bus. */