@@ -12,6 +12,8 @@ LOG_MODULE_DECLARE(spi_lpspi, CONFIG_SPI_LOG_LEVEL);
1212#include "spi_nxp_lpspi_priv.h"
1313
1414struct lpspi_driver_data {
15+ size_t total_words_to_clock ;
16+ size_t words_clocked ;
1517 uint8_t word_size_bytes ;
1618 uint8_t lpspi_op_mode ;
1719};
@@ -72,10 +74,10 @@ static inline void lpspi_handle_rx_irq(const struct device *dev)
7274 struct lpspi_data * data = dev -> data ;
7375 struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
7476 struct spi_context * ctx = & data -> ctx ;
75- uint8_t rx_fsr = rx_fifo_cur_len (base );
7677 uint8_t total_words_written = 0 ;
7778 uint8_t total_words_read = 0 ;
7879 uint8_t words_read ;
80+ uint8_t rx_fsr ;
7981
8082 base -> SR = LPSPI_SR_RDF_MASK ;
8183
@@ -125,18 +127,22 @@ static inline void lpspi_fill_tx_fifo(const struct device *dev, const uint8_t *b
125127 buf_len -= word_size ;
126128 }
127129
130+ lpspi_data -> words_clocked += fill_len ;
128131 LOG_DBG ("Filled TX FIFO to %d words (%d bytes)" , fill_len , offset );
129132}
130133
131134/* just fills TX fifo with the specified amount of NOPS */
132135static void lpspi_fill_tx_fifo_nop (const struct device * dev , size_t fill_len )
133136{
134137 LPSPI_Type * base = (LPSPI_Type * )DEVICE_MMIO_NAMED_GET (dev , reg_base );
138+ struct lpspi_data * data = dev -> data ;
139+ struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
135140
136141 for (int i = 0 ; i < fill_len ; i ++ ) {
137142 base -> TDR = 0 ;
138143 }
139144
145+ lpspi_data -> words_clocked += fill_len ;
140146 LOG_DBG ("Filled TX fifo with %d NOPs" , fill_len );
141147}
142148
@@ -243,15 +249,14 @@ static void lpspi_isr(const struct device *dev)
243249 struct lpspi_data * data = dev -> data ;
244250 struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
245251 uint8_t word_size_bytes = lpspi_data -> word_size_bytes ;
246- uint8_t op_mode = lpspi_data -> lpspi_op_mode ;
247252 struct spi_context * ctx = & data -> ctx ;
248253 uint32_t status_flags = base -> SR ;
249254
250- if (status_flags & LPSPI_SR_RDF_MASK ) {
255+ if (status_flags & LPSPI_SR_RDF_MASK && base -> IER & LPSPI_IER_RDIE_MASK ) {
251256 lpspi_handle_rx_irq (dev );
252257 }
253258
254- if (status_flags & LPSPI_SR_TDF_MASK ) {
259+ if (status_flags & LPSPI_SR_TDF_MASK && base -> IER & LPSPI_IER_TDIE_MASK ) {
255260 lpspi_handle_tx_irq (dev );
256261 }
257262
@@ -264,65 +269,59 @@ static void lpspi_isr(const struct device *dev)
264269 return ;
265270 }
266271
267- /* the lpspi v1 has an errata where it doesn't clock the last bit
268- * in continuous master mode until you write the TCR
269- */
270- bool likely_stalling_v1 = (data -> major_version < 2 ) && (op_mode == SPI_OP_MODE_MASTER ) &&
271- (DIV_ROUND_UP (spi_context_rx_len_left (ctx , word_size_bytes ), word_size_bytes ) == 1 );
272-
273- if (spi_context_rx_on (ctx )) {
274- /* capture these values because they could change during this code block */
275- size_t rx_fifo_len = rx_fifo_cur_len (base );
276- size_t tx_fifo_len = tx_fifo_cur_len (base );
277-
278- /*
279- * Goal here is to provide the number of TX NOPS to match the amount of RX
280- * we have left to receive, so that we provide the correct number of
281- * clocks to the bus, since the clocks only happen when TX data is being sent.
282- *
283- * The expected RX left is essentially what is left in the spi transfer
284- * minus what we have just got in the fifo, but prevent underflow of this
285- * subtraction since it is unsigned.
286- */
287- size_t expected_rx_left = rx_fifo_len < ctx -> rx_len ? ctx -> rx_len - rx_fifo_len : 0 ;
272+ /* Both receive and transmit parts disable their interrupt once finished. */
273+ if (base -> IER == 0 ) {
274+ lpspi_end_xfer (dev );
275+ return ;
276+ }
288277
278+ /* only explanation at this point is one of two things:
279+ * 1) that rx is bigger than tx and we need to clock nops
280+ * 2) this is a version of LPSPI which will not clock the last bit of the transfer
281+ * in continuous mode until the TCR is written to end the XFER
282+ */
289283
290- /*
291- * We know the expected amount of RX we have left but only fill up to the
292- * max of the RX fifo size so that we don't have some overflow of the FIFO later.
293- * Similarly, we shouldn't overfill the TX fifo with too many NOPs.
284+ if (lpspi_data -> words_clocked >= lpspi_data -> total_words_to_clock ) {
285+ /* Due to stalling behavior on older LPSPI, if we know we already wrote all the
286+ * words into the fifo, then we need to end xfer manually by writing TCR
287+ * in order to get last bit clocked out on bus. So all we need to do is touch the
288+ * TCR by writing to fifo through TCR register and wait for final RX interrupt.
294289 */
295- size_t tx_fifo_space_left = config -> tx_fifo_size - tx_fifo_len ;
296- size_t rx_fifo_space_left = config -> rx_fifo_size - rx_fifo_len ;
297- size_t max_fifo_fill = MIN (tx_fifo_space_left , rx_fifo_space_left );
298- size_t max_fill = MIN (max_fifo_fill , expected_rx_left );
299-
300- if (likely_stalling_v1 && max_fill > 0 ) {
301- max_fill -= 1 ;
302- }
290+ base -> TCR = base -> TCR ;
291+ return ;
292+ }
303293
304- /* If we already have some words in the tx fifo, we should count those */
305- if (max_fill > tx_fifo_len ) {
306- max_fill -= tx_fifo_len ;
307- } else {
308- max_fill = 0 ;
309- }
294+ /* At this point we know only case is that we need to put NOPs in the TX fifo
295+ * in order to get the rest of the RX
296+ */
310297
311- /* So now we want to fill the fifo with the max amount of NOPs */
312- lpspi_fill_tx_fifo_nop (dev , max_fill );
313- }
298+ size_t rx_fifo_len = rx_fifo_cur_len (base );
299+ size_t tx_fifo_len = tx_fifo_cur_len (base );
300+ size_t words_really_left = lpspi_data -> total_words_to_clock - lpspi_data -> words_clocked ;
301+
302+ /*
303+ * Goal here is to provide the number of TX NOPS to match the amount of RX
304+ * we have left to receive, so that we provide the correct number of
305+ * clocks to the bus, since the clocks only happen when TX data is being sent.
306+ *
307+ * The expected RX left is essentially what is left in the spi transfer
308+ * minus what we have just got in the fifo, but prevent underflow of this
309+ * subtraction since it is unsigned.
310+ */
311+ size_t expected_rx_left = rx_fifo_len < words_really_left ?
312+ words_really_left - rx_fifo_len : 0 ;
314313
315- if (likely_stalling_v1 ) {
316- /* Due to stalling behavior on older LPSPI,
317- * need to end xfer in order to get last bit clocked out on bus.
318- */
319- base -> TCR |= LPSPI_TCR_CONT_MASK ;
320- }
314+ /*
315+ * We know the expected amount of RX we have left but only fill up to the
316+ * max of the RX fifo size so that we don't have some overflow of the FIFO later.
317+ * Similarly, we shouldn't overfill the TX fifo with too many NOPs.
318+ */
319+ size_t tx_fifo_space_left = config -> tx_fifo_size - tx_fifo_len ;
320+ size_t rx_fifo_space_left = config -> rx_fifo_size - rx_fifo_len ;
321+ size_t max_fifo_fill = MIN (tx_fifo_space_left , rx_fifo_space_left );
322+ size_t max_fill = MIN (max_fifo_fill , expected_rx_left );
321323
322- /* Both receive and transmit parts disable their interrupt once finished. */
323- if (base -> IER == 0 ) {
324- lpspi_end_xfer (dev );
325- }
324+ lpspi_fill_tx_fifo_nop (dev , max_fill );
326325}
327326
328327static void lpspi_master_setup_native_cs (const struct device * dev , const struct spi_config * spi_cfg )
@@ -372,6 +371,14 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
372371 goto error ;
373372 }
374373
374+ if (data -> major_version < 2 && spi_cfg -> operation & SPI_HOLD_ON_CS ) {
375+ /* on this version of LPSPI, due to errata in design
376+ * CS must be deasserted in order to clock all words,
377+ * so HOLD_ON_CS flag cannot be supported.
378+ */
379+ return - EINVAL ;
380+ }
381+
375382 spi_context_buffers_setup (ctx , tx_bufs , rx_bufs , lpspi_data -> word_size_bytes );
376383 lpspi_data -> lpspi_op_mode = op_mode ;
377384
@@ -384,6 +391,12 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
384391 base -> IER = 0 ;
385392 base -> SR |= LPSPI_INTERRUPT_BITS ;
386393
394+ size_t max_side_clocks = MAX (spi_context_total_tx_len (ctx ), spi_context_total_rx_len (ctx ));
395+
396+ lpspi_data -> total_words_to_clock =
397+ DIV_ROUND_UP (max_side_clocks , lpspi_data -> word_size_bytes );
398+ lpspi_data -> words_clocked = 0 ;
399+
387400 LOG_DBG ("Starting LPSPI transfer" );
388401 spi_context_cs_control (ctx , true);
389402
0 commit comments