@@ -14,6 +14,7 @@ LOG_MODULE_REGISTER(spi_mcux_lpspi, CONFIG_SPI_LOG_LEVEL);
14
14
struct lpspi_driver_data {
15
15
size_t fill_len ;
16
16
uint8_t word_size_bytes ;
17
+ uint8_t lpspi_op_mode ;
17
18
};
18
19
19
20
static inline uint8_t rx_fifo_cur_len (LPSPI_Type * base )
@@ -222,6 +223,25 @@ static inline void lpspi_handle_tx_irq(const struct device *dev)
222
223
lpspi_next_tx_fill (data -> dev );
223
224
}
224
225
226
+ static inline void lpspi_handle_err051588 (LPSPI_Type * base , uint32_t status_flags , uint8_t op_mode )
227
+ {
228
+ if (op_mode != SPI_OP_MODE_SLAVE ) {
229
+ /* this errata is only for slave mode */
230
+ return ;
231
+ }
232
+
233
+ if (!(status_flags & LPSPI_SR_TEF_MASK )) {
234
+ /* the errata happens when transmit error (underrun) occurs */
235
+ return ;
236
+ }
237
+
238
+ /* clear the w1c error flag as usual */
239
+ base -> SR = LPSPI_SR_TEF_MASK ;
240
+
241
+ /* workaround is to reset the transmit fifo before writing any new data */
242
+ base -> CR |= LPSPI_CR_RTF_MASK ;
243
+ }
244
+
225
245
static void lpspi_isr (const struct device * dev )
226
246
{
227
247
LPSPI_Type * base = (LPSPI_Type * )DEVICE_MMIO_NAMED_GET (dev , reg_base );
@@ -230,20 +250,22 @@ static void lpspi_isr(const struct device *dev)
230
250
struct spi_mcux_data * data = dev -> data ;
231
251
struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
232
252
struct spi_context * ctx = & data -> ctx ;
253
+ uint8_t op_mode = lpspi_data -> lpspi_op_mode ;
233
254
234
255
if (status_flags & kLPSPI_RxDataReadyFlag ) {
235
256
lpspi_handle_rx_irq (dev );
236
257
}
237
258
238
259
if (status_flags & kLPSPI_TxDataRequestFlag ) {
260
+ lpspi_handle_err051588 (base , status_flags , op_mode );
239
261
lpspi_handle_tx_irq (dev );
240
262
}
241
263
242
264
if (spi_context_tx_on (ctx )) {
243
265
return ;
244
266
}
245
267
246
- if (spi_context_rx_len_left (ctx ) == 1 ) {
268
+ if (op_mode == SPI_OP_MODE_MASTER && spi_context_rx_len_left (ctx ) == 1 ) {
247
269
base -> TCR &= ~LPSPI_TCR_CONT_MASK ;
248
270
} else if (spi_context_rx_on (ctx )) {
249
271
size_t rx_fifo_len = rx_fifo_cur_len (base );
@@ -269,9 +291,11 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
269
291
bool asynchronous , spi_callback_t cb , void * userdata )
270
292
{
271
293
LPSPI_Type * base = (LPSPI_Type * )DEVICE_MMIO_NAMED_GET (dev , reg_base );
294
+ const struct spi_mcux_config * config = dev -> config ;
272
295
struct spi_mcux_data * data = dev -> data ;
273
296
struct lpspi_driver_data * lpspi_data = (struct lpspi_driver_data * )data -> driver_data ;
274
297
struct spi_context * ctx = & data -> ctx ;
298
+ uint8_t op_mode = SPI_OP_MODE_GET (spi_cfg -> operation );
275
299
int ret = 0 ;
276
300
277
301
spi_context_lock (& data -> ctx , asynchronous , cb , userdata , spi_cfg );
@@ -284,26 +308,34 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
284
308
}
285
309
286
310
spi_context_buffers_setup (ctx , tx_bufs , rx_bufs , lpspi_data -> word_size_bytes );
311
+ lpspi_data -> lpspi_op_mode = op_mode ;
287
312
288
313
ret = spi_mcux_configure (dev , spi_cfg );
289
314
if (ret ) {
290
315
goto error ;
291
316
}
292
317
293
- LPSPI_FlushFifo (base , true , true);
318
+ LPSPI_FlushFifo (base , false , true);
294
319
LPSPI_ClearStatusFlags (base , (uint32_t )kLPSPI_AllStatusFlag );
295
320
LPSPI_DisableInterrupts (base , (uint32_t )kLPSPI_AllInterruptEnable );
296
321
297
322
LOG_DBG ("Starting LPSPI transfer" );
298
323
spi_context_cs_control (ctx , true);
299
324
300
- LPSPI_SetFifoWatermarks (base , 0 , 0 );
325
+ if (op_mode == SPI_OP_MODE_MASTER ) {
326
+ LPSPI_SetFifoWatermarks (base , 0 , 0 );
327
+ } else {
328
+ LPSPI_SetFifoWatermarks (base , config -> tx_fifo_size - 2 , 0 );
329
+ }
330
+
301
331
LPSPI_Enable (base , true);
302
332
303
- /* keep the chip select asserted until the end of the zephyr xfer */
304
- base -> TCR |= LPSPI_TCR_CONT_MASK ;
305
- /* tcr is written to tx fifo */
306
- lpspi_wait_tx_fifo_empty (dev );
333
+ if (op_mode == SPI_OP_MODE_MASTER ) {
334
+ /* keep the chip select active until the end of the zephyr xfer */
335
+ base -> TCR |= LPSPI_TCR_CONT_MASK ;
336
+ /* tcr is written to tx fifo */
337
+ lpspi_wait_tx_fifo_empty (dev );
338
+ }
307
339
308
340
/* start the transfer sequence which are handled by irqs */
309
341
lpspi_next_tx_fill (dev );
@@ -312,7 +344,6 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
312
344
(uint32_t )kLPSPI_RxInterruptEnable );
313
345
314
346
return spi_context_wait_for_completion (ctx );
315
-
316
347
error :
317
348
spi_context_release (ctx , ret );
318
349
return ret ;
0 commit comments