@@ -473,14 +473,40 @@ static inline void dma_channel_start(uint channel) {
473
473
*
474
474
* Function will only return once the DMA has stopped.
475
475
*
476
+ * Note that due to errata RP2040-E13, aborting a channel which has transfers
477
+ * in-flight (i.e. an individual read has taken place but the corresponding write has not), the ABORT
478
+ * status bit will clear prematurely, and subsequently the in-flight
479
+ * transfers will trigger a completion interrupt once they complete.
480
+ *
481
+ * The effect of this is that you \em may see a spurious completion interrupt
482
+ * on the channel as a result of calling this method.
483
+ *
484
+ * The calling code should be sure to ignore a completion IRQ as a result of this method. This may
485
+ * not require any additional work, as aborting a channel which may be about to complete, when you have a completion
486
+ * IRQ handler registered, is inherently race-prone, and so code is likely needed to disambiguate the two occurrences.
487
+ *
488
+ * If that is not the case, but you do have a channel completion IRQ handler registered, you can simply
489
+ * disable/re-enable the IRQ around the call to this method as shown by this code fragment (using DMA IRQ0).
490
+ *
491
+ * \code
492
+ * // disable the channel on IRQ0
493
+ * dma_channel_set_irq0_enabled(channel, false);
494
+ * // abort the channel
495
+ * dma_channel_abort(channel);
496
+ * // clear the spurious IRQ (if there was one)
497
+ * dma_channel_acknowledge_irq0(channel);
498
+ * // re-enable the channel on IRQ0
499
+ * dma_channel_set_irq0_enabled(channel, true);
500
+ *\endcode
501
+ *
476
502
* \param channel DMA channel
477
503
*/
478
504
static inline void dma_channel_abort (uint channel ) {
479
505
check_dma_channel_param (channel );
480
506
dma_hw -> abort = 1u << channel ;
481
507
// Bit will go 0 once channel has reached safe state
482
508
// (i.e. any in-flight transfers have retired)
483
- while (dma_hw -> abort & ( 1ul << channel ) ) tight_loop_contents ();
509
+ while (dma_hw -> ch [ channel ]. ctrl_trig & DMA_CH0_CTRL_TRIG_BUSY_BITS ) tight_loop_contents ();
484
510
}
485
511
486
512
/*! \brief Enable single DMA channel's interrupt via DMA_IRQ_0
0 commit comments