Skip to content

Commit

Permalink
feat: add support for aborting DMA transfers
Browse files Browse the repository at this point in the history
  • Loading branch information
EliseZeroTwo committed Jun 2, 2024
1 parent dfbdb9a commit b830913
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
34 changes: 34 additions & 0 deletions rp2040-hal/src/dma/single_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,38 @@ where

(self.ch, self.from, self.to)
}

/// Aborts the current transfer, returning the channel and targets
pub fn abort(mut self) -> (CH, FROM, TO) {
let irq0_was_enabled = self.ch.is_enabled_irq0();
let irq1_was_enabled = self.ch.is_enabled_irq1();
self.ch.disable_irq0();
self.ch.disable_irq1();

let chan_abort = unsafe { &*crate::pac::DMA::ptr() }.chan_abort();
let abort_mask = (1 << self.ch.id()) as u16;

chan_abort.write(|w| unsafe { w.chan_abort().bits(abort_mask) });

while chan_abort.read().chan_abort().bits() != 0 {}

while !self.is_done() {}

self.ch.check_irq0();
self.ch.check_irq1();

if irq0_was_enabled {
self.ch.enable_irq0();
}

if irq1_was_enabled {
self.ch.enable_irq1();
}

// Make sure that memory contents reflect what the user intended.
cortex_m::asm::dsb();
compiler_fence(Ordering::SeqCst);

(self.ch, self.from, self.to)
}
}
10 changes: 10 additions & 0 deletions rp2040-hal/src/dma/single_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ pub trait SingleChannel: Sealed {
}
}

/// Check if the DMA_IRQ_0 signal for this channel is enabled.
fn is_enabled_irq0(&mut self) -> bool {
unsafe { ((*DMA::ptr()).inte0().read().bits() & (1 << self.id())) != 0 }
}

#[deprecated(note = "Renamed to disable_irq0")]
/// Disables the DMA_IRQ_0 signal for this channel.
fn unlisten_irq0(&mut self) {
Expand Down Expand Up @@ -75,6 +80,11 @@ pub trait SingleChannel: Sealed {
}
}

/// Check if the DMA_IRQ_1 signal for this channel is enabled.
fn is_enabled_irq1(&mut self) -> bool {
unsafe { ((*DMA::ptr()).inte1().read().bits() & (1 << self.id())) != 0 }
}

#[deprecated(note = "Renamed to disable_irq1")]
/// Disables the DMA_IRQ_1 signal for this channel.
fn unlisten_irq1(&mut self) {
Expand Down

0 comments on commit b830913

Please sign in to comment.