@@ -26,6 +26,17 @@ static inline void lpspi_wait_tx_fifo_empty(const struct device *dev)
26
26
}
27
27
}
28
28
29
+ static inline uint8_t rx_fifo_cur_len (LPSPI_Type * base )
30
+ {
31
+ return (base -> FSR & LPSPI_FSR_RXCOUNT_MASK ) >> LPSPI_FSR_RXCOUNT_SHIFT ;
32
+ }
33
+
34
+ static inline uint8_t tx_fifo_cur_len (LPSPI_Type * base )
35
+ {
36
+ return (base -> FSR & LPSPI_FSR_TXCOUNT_MASK ) >> LPSPI_FSR_TXCOUNT_SHIFT ;
37
+ }
38
+
39
+
29
40
/* Reads a word from the RX fifo and handles writing it into the RX spi buf */
30
41
static inline void lpspi_rx_word_write_bytes (const struct device * dev , size_t offset )
31
42
{
@@ -66,21 +77,16 @@ static inline size_t lpspi_rx_buf_write_words(const struct device *dev, uint8_t
66
77
return words_read ;
67
78
}
68
79
69
- static inline uint8_t rx_fifo_cur_len (LPSPI_Type * base )
70
- {
71
- return (base -> FSR & LPSPI_FSR_RXCOUNT_MASK ) >> LPSPI_FSR_RXCOUNT_SHIFT ;
72
- }
73
-
74
80
static inline void lpspi_handle_rx_irq (const struct device * dev )
75
81
{
76
82
LPSPI_Type * base = (LPSPI_Type * )DEVICE_MMIO_NAMED_GET (dev , reg_base );
77
83
struct spi_mcux_data * data = dev -> data ;
78
84
struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
79
85
struct spi_context * ctx = & data -> ctx ;
86
+ uint8_t rx_fsr = rx_fifo_cur_len (base );
80
87
uint8_t total_words_written = 0 ;
81
88
uint8_t total_words_read = 0 ;
82
89
uint8_t words_read ;
83
- uint8_t rx_fsr ;
84
90
85
91
LPSPI_ClearStatusFlags (base , kLPSPI_RxDataReadyFlag );
86
92
@@ -95,7 +101,7 @@ static inline void lpspi_handle_rx_irq(const struct device *dev)
95
101
96
102
LOG_DBG ("RX done %d words to spi buf" , total_words_written );
97
103
98
- if (! spi_context_rx_on (ctx )) {
104
+ if (spi_context_rx_len_left (ctx ) == 0 ) {
99
105
LPSPI_DisableInterrupts (base , (uint32_t )kLPSPI_RxInterruptEnable );
100
106
LPSPI_FlushFifo (base , false, true);
101
107
}
@@ -132,7 +138,7 @@ static inline void lpspi_fill_tx_fifo(const struct device *dev)
132
138
LOG_DBG ("Filled TX FIFO to %d words (%d bytes)" , lpspi_data -> fill_len , offset );
133
139
}
134
140
135
- static inline void lpspi_fill_tx_fifo_nop (const struct device * dev )
141
+ static void lpspi_fill_tx_fifo_nop (const struct device * dev )
136
142
{
137
143
LPSPI_Type * base = (LPSPI_Type * )DEVICE_MMIO_NAMED_GET (dev , reg_base );
138
144
struct spi_mcux_data * data = dev -> data ;
@@ -176,55 +182,21 @@ static inline void lpspi_handle_tx_irq(const struct device *dev)
176
182
177
183
LPSPI_ClearStatusFlags (base , kLPSPI_TxDataRequestFlag );
178
184
179
- /* Having no buffer length left indicates transfer is done, if there
180
- * was RX to do left, the TX buf would be null but
181
- * ctx still tracks length of dummy data
182
- */
183
185
if (!spi_context_tx_on (ctx )) {
184
- /* Disable chip select and end transfer clocks last word */
185
- base -> TCR = 0 ;
186
- lpspi_wait_tx_fifo_empty (dev );
187
- spi_context_cs_control (ctx , false);
188
186
LPSPI_DisableInterrupts (base , (uint32_t )kLPSPI_TxInterruptEnable );
189
187
return ;
190
188
}
191
189
192
190
lpspi_next_tx_fill (data -> dev );
193
191
}
194
192
195
- static inline bool lpspi_is_rx_done (const struct device * dev )
196
- {
197
- struct spi_mcux_data * data = dev -> data ;
198
- struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
199
- struct spi_context * ctx = & data -> ctx ;
200
- size_t tx_total = lpspi_data -> tx_total_len ;
201
- size_t rx_total = lpspi_data -> rx_total_len ;
202
-
203
- if (tx_total >= rx_total ) {
204
- return (spi_context_total_rx_len (ctx ) == 0 );
205
- } else {
206
- return (tx_total <= (rx_total - spi_context_rx_len_left (ctx )));
207
- }
208
- }
209
-
210
- static inline void lpspi_clear_remaining_rx (struct spi_context * ctx )
211
- {
212
- size_t remaining_len ;
213
-
214
- while ((remaining_len = spi_context_rx_len_left (ctx )) > 0 ) {
215
- for (int i = 0 ; i < ctx -> rx_len ; i ++ ) {
216
- ctx -> rx_buf [i ] = 0 ;
217
- }
218
- spi_context_update_rx (ctx , 1 , ctx -> rx_len );
219
- }
220
- }
221
-
222
193
static void lpspi_isr (const struct device * dev )
223
194
{
224
195
LPSPI_Type * base = (LPSPI_Type * )DEVICE_MMIO_NAMED_GET (dev , reg_base );
225
196
const struct spi_mcux_config * config = dev -> config ;
226
197
uint32_t status_flags = LPSPI_GetStatusFlags (base );
227
198
struct spi_mcux_data * data = dev -> data ;
199
+ struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
228
200
struct spi_context * ctx = & data -> ctx ;
229
201
230
202
if (status_flags & kLPSPI_RxDataReadyFlag ) {
@@ -235,10 +207,29 @@ static void lpspi_isr(const struct device *dev)
235
207
lpspi_handle_tx_irq (dev );
236
208
}
237
209
238
- if (!spi_context_tx_on (ctx ) && lpspi_is_rx_done (dev )) {
210
+ if (spi_context_tx_on (ctx )) {
211
+ return ;
212
+ }
213
+
214
+ if (spi_context_rx_len_left (ctx ) == 1 ) {
215
+ base -> TCR = 0 ;
216
+ } else if (spi_context_rx_on (ctx )) {
217
+ size_t rx_fifo_len = rx_fifo_cur_len (base );
218
+ size_t expected_rx_left = rx_fifo_len < ctx -> rx_len ? ctx -> rx_len - rx_fifo_len : 0 ;
219
+ size_t max_fill = MIN (expected_rx_left , config -> rx_fifo_size );
220
+ size_t tx_current_fifo_len = tx_fifo_cur_len (base );
221
+
222
+ lpspi_data -> fill_len = tx_current_fifo_len < ctx -> rx_len ?
223
+ max_fill - tx_current_fifo_len : 0 ;
224
+
225
+ lpspi_fill_tx_fifo_nop (dev );
226
+ } else {
239
227
spi_context_complete (ctx , dev , 0 );
240
228
NVIC_ClearPendingIRQ (config -> irqn );
241
- lpspi_clear_remaining_rx (ctx );
229
+ base -> TCR = 0 ;
230
+ lpspi_wait_tx_fifo_empty (dev );
231
+ spi_context_cs_control (ctx , false);
232
+ spi_context_release (& data -> ctx , 0 );
242
233
}
243
234
}
244
235
@@ -257,7 +248,7 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
257
248
if (lpspi_data -> word_size_bytes > 4 ) {
258
249
LOG_ERR ("Maximum 4 byte word size" );
259
250
ret = - EINVAL ;
260
- goto out ;
251
+ return ret ;
261
252
}
262
253
263
254
spi_context_buffers_setup (& data -> ctx , tx_bufs , rx_bufs , lpspi_data -> word_size_bytes );
@@ -267,7 +258,7 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
267
258
268
259
ret = spi_mcux_configure (dev , spi_cfg );
269
260
if (ret ) {
270
- goto out ;
261
+ return ret ;
271
262
}
272
263
273
264
LPSPI_FlushFifo (base , true, true);
@@ -291,11 +282,7 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
291
282
LPSPI_EnableInterrupts (base , (uint32_t )kLPSPI_TxInterruptEnable |
292
283
(uint32_t )kLPSPI_RxInterruptEnable );
293
284
294
- ret = spi_context_wait_for_completion (& data -> ctx );
295
- out :
296
- spi_context_release (& data -> ctx , ret );
297
-
298
- return ret ;
285
+ return spi_context_wait_for_completion (& data -> ctx );
299
286
}
300
287
301
288
static int spi_mcux_transceive_sync (const struct device * dev , const struct spi_config * spi_cfg ,
0 commit comments