@@ -195,7 +195,7 @@ static void tx_data(const struct device *dev,
195
195
dev_data -> buf_pos = (uint8_t * )buf_pos ;
196
196
}
197
197
198
- static bool tx_dummy_bytes (const struct device * dev )
198
+ static bool tx_dummy_bytes (const struct device * dev , bool * repeat )
199
199
{
200
200
struct mspi_dw_data * dev_data = dev -> data ;
201
201
const struct mspi_dw_config * dev_config = dev -> config ;
@@ -209,8 +209,17 @@ static bool tx_dummy_bytes(const struct device *dev)
209
209
* FIFO to avoid overflowing it; `max_queued_dummy_bytes` accounts
210
210
* that one byte that can be partially received, thus not included
211
211
* in the value from the RXFLR register.
212
+ * This check also handles the case when the function is called but
213
+ * the TX FIFO is already filled up (fifo_room == 0).
212
214
*/
213
215
if (fifo_room <= rx_fifo_items ) {
216
+ if (repeat ) {
217
+ /* If no dummy bytes can be sent now, there is no point
218
+ * in repeating the loop that reads the RX FIFO.
219
+ */
220
+ * repeat = false;
221
+ }
222
+
214
223
return false;
215
224
}
216
225
fifo_room -= rx_fifo_items ;
@@ -329,7 +338,9 @@ static void handle_fifos(const struct device *dev)
329
338
finished = true;
330
339
}
331
340
} else {
332
- for (;;) {
341
+ bool repeat = true;
342
+
343
+ do {
333
344
/* Always read everything from the RX FIFO, regardless
334
345
* of the interrupt status.
335
346
* tx_dummy_bytes() subtracts the number of items that
@@ -363,19 +374,28 @@ static void handle_fifos(const struct device *dev)
363
374
break ;
364
375
}
365
376
366
- if (dev_data -> dummy_bytes == 0 ||
367
- !(int_status & RISR_TXEIR_BIT )) {
377
+ /* If there are still some dummy bytes to transmit,
378
+ * always try to put some into the TX FIFO, no matter
379
+ * what's the TXE interrupt status - the TX FIFO may be
380
+ * filled above its threshold level (then its interrupt
381
+ * flag is not set), but below its transfer start level,
382
+ * so the controller may be waiting for more items to
383
+ * appear there.
384
+ */
385
+ if (dev_data -> dummy_bytes == 0 ) {
368
386
break ;
369
387
}
370
388
371
- if (tx_dummy_bytes (dev )) {
389
+ if (tx_dummy_bytes (dev , & repeat )) {
372
390
/* All the required dummy bytes were written
373
391
* to the FIFO; disable the TXE interrupt,
374
392
* as it's no longer needed.
375
393
*/
376
394
set_imr (dev , IMR_RXFIM_BIT );
377
395
}
378
- }
396
+
397
+ /* Repeat the loop only if any dummy bytes were sent. */
398
+ } while (repeat );
379
399
}
380
400
381
401
if (finished ) {
@@ -404,6 +424,8 @@ static void fifo_work_handler(struct k_work *work)
404
424
405
425
static void mspi_dw_isr (const struct device * dev )
406
426
{
427
+ NRF_P9 -> OUTSET = BIT (1 );
428
+
407
429
#if defined(CONFIG_MSPI_DW_HANDLE_FIFOS_IN_SYSTEM_WORKQUEUE )
408
430
struct mspi_dw_data * dev_data = dev -> data ;
409
431
int rc ;
@@ -420,6 +442,8 @@ static void mspi_dw_isr(const struct device *dev)
420
442
#endif
421
443
422
444
vendor_specific_irq_clear (dev );
445
+
446
+ NRF_P9 -> OUTCLR = BIT (1 );
423
447
}
424
448
425
449
static int api_config (const struct mspi_dt_spec * spec )
@@ -1151,7 +1175,7 @@ static int start_next_packet(const struct device *dev, k_timeout_t timeout)
1151
1175
}
1152
1176
1153
1177
/* Prefill TX FIFO with any data we can */
1154
- if (dev_data -> dummy_bytes && tx_dummy_bytes (dev )) {
1178
+ if (dev_data -> dummy_bytes && tx_dummy_bytes (dev , NULL )) {
1155
1179
imr = IMR_RXFIM_BIT ;
1156
1180
} else if (packet -> dir == MSPI_TX && packet -> num_bytes ) {
1157
1181
tx_data (dev , packet );
0 commit comments