@@ -12,6 +12,8 @@ LOG_MODULE_DECLARE(spi_lpspi, CONFIG_SPI_LOG_LEVEL);
12
12
#include "spi_nxp_lpspi_priv.h"
13
13
14
14
struct lpspi_driver_data {
15
+ size_t total_words_to_clock ;
16
+ size_t words_clocked ;
15
17
uint8_t word_size_bytes ;
16
18
uint8_t lpspi_op_mode ;
17
19
};
@@ -72,10 +74,10 @@ static inline void lpspi_handle_rx_irq(const struct device *dev)
72
74
struct lpspi_data * data = dev -> data ;
73
75
struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
74
76
struct spi_context * ctx = & data -> ctx ;
75
- uint8_t rx_fsr = rx_fifo_cur_len (base );
76
77
uint8_t total_words_written = 0 ;
77
78
uint8_t total_words_read = 0 ;
78
79
uint8_t words_read ;
80
+ uint8_t rx_fsr ;
79
81
80
82
base -> SR = LPSPI_SR_RDF_MASK ;
81
83
@@ -125,18 +127,22 @@ static inline void lpspi_fill_tx_fifo(const struct device *dev, const uint8_t *b
125
127
buf_len -= word_size ;
126
128
}
127
129
130
+ lpspi_data -> words_clocked += fill_len ;
128
131
LOG_DBG ("Filled TX FIFO to %d words (%d bytes)" , fill_len , offset );
129
132
}
130
133
131
134
/* just fills TX fifo with the specified amount of NOPS */
132
135
static void lpspi_fill_tx_fifo_nop (const struct device * dev , size_t fill_len )
133
136
{
134
137
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 ;
135
140
136
141
for (int i = 0 ; i < fill_len ; i ++ ) {
137
142
base -> TDR = 0 ;
138
143
}
139
144
145
+ lpspi_data -> words_clocked += fill_len ;
140
146
LOG_DBG ("Filled TX fifo with %d NOPs" , fill_len );
141
147
}
142
148
@@ -243,15 +249,14 @@ static void lpspi_isr(const struct device *dev)
243
249
struct lpspi_data * data = dev -> data ;
244
250
struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
245
251
uint8_t word_size_bytes = lpspi_data -> word_size_bytes ;
246
- uint8_t op_mode = lpspi_data -> lpspi_op_mode ;
247
252
struct spi_context * ctx = & data -> ctx ;
248
253
uint32_t status_flags = base -> SR ;
249
254
250
- if (status_flags & LPSPI_SR_RDF_MASK ) {
255
+ if (status_flags & LPSPI_SR_RDF_MASK && base -> IER & LPSPI_IER_RDIE_MASK ) {
251
256
lpspi_handle_rx_irq (dev );
252
257
}
253
258
254
- if (status_flags & LPSPI_SR_TDF_MASK ) {
259
+ if (status_flags & LPSPI_SR_TDF_MASK && base -> IER & LPSPI_IER_TDIE_MASK ) {
255
260
lpspi_handle_tx_irq (dev );
256
261
}
257
262
@@ -264,65 +269,59 @@ static void lpspi_isr(const struct device *dev)
264
269
return ;
265
270
}
266
271
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
+ }
288
277
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
+ */
289
283
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.
294
289
*/
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
+ }
303
293
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
+ */
310
297
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 ;
314
313
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 );
321
323
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 );
326
325
}
327
326
328
327
static 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
372
371
goto error ;
373
372
}
374
373
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
+
375
382
spi_context_buffers_setup (ctx , tx_bufs , rx_bufs , lpspi_data -> word_size_bytes );
376
383
lpspi_data -> lpspi_op_mode = op_mode ;
377
384
@@ -384,6 +391,12 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
384
391
base -> IER = 0 ;
385
392
base -> SR |= LPSPI_INTERRUPT_BITS ;
386
393
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
+
387
400
LOG_DBG ("Starting LPSPI transfer" );
388
401
spi_context_cs_control (ctx , true);
389
402
0 commit comments