stm32: Added request_pause to DMA, and use it for RingBufferedUartRx

This commit is contained in:
Peter Krull 2024-09-19 18:14:09 +02:00
parent d7780fcf83
commit 907d55ea82
2 changed files with 53 additions and 3 deletions

View File

@ -493,6 +493,26 @@ impl AnyChannel {
} }
} }
fn request_pause(&self) {
let info = self.info();
match self.info().dma {
#[cfg(dma)]
DmaInfo::Dma(r) => {
r.st(info.num).cr().modify(|w| {
// Disable the channel without overwriting the existing configuration
w.set_en(false);
});
}
#[cfg(bdma)]
DmaInfo::Bdma(r) => {
r.ch(info.num).cr().modify(|w| {
// Disable the channel without overwriting the existing configuration
w.set_en(false);
});
}
}
}
fn is_running(&self) -> bool { fn is_running(&self) -> bool {
let info = self.info(); let info = self.info();
match self.info().dma { match self.info().dma {
@ -667,12 +687,22 @@ impl<'a> Transfer<'a> {
} }
/// Request the transfer to stop. /// Request the transfer to stop.
/// The configuration for this channel will **not be preserved**. If you need to restart the transfer
/// at a later point with the same configuration, see [`request_pause`](Self::request_pause) instead.
/// ///
/// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
pub fn request_stop(&mut self) { pub fn request_stop(&mut self) {
self.channel.request_stop() self.channel.request_stop()
} }
/// Request the transfer to pause, keeping the existing configuration for this channel.
/// To restart the transfer, call [`start`](Self::start) again.
///
/// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
pub fn request_pause(&mut self) {
self.channel.request_pause()
}
/// Return whether this transfer is still running. /// Return whether this transfer is still running.
/// ///
/// If this returns `false`, it can be because either the transfer finished, or /// If this returns `false`, it can be because either the transfer finished, or
@ -846,13 +876,23 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
DmaCtrlImpl(self.channel.reborrow()).set_waker(waker); DmaCtrlImpl(self.channel.reborrow()).set_waker(waker);
} }
/// Request DMA to stop. /// Request the DMA to stop.
/// The configuration for this channel will **not be preserved**. If you need to restart the transfer
/// at a later point with the same configuration, see [`request_pause`](Self::request_pause) instead.
/// ///
/// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
pub fn request_stop(&mut self) { pub fn request_stop(&mut self) {
self.channel.request_stop() self.channel.request_stop()
} }
/// Request the transfer to pause, keeping the existing configuration for this channel.
/// To restart the transfer, call [`start`](Self::start) again.
///
/// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
pub fn request_pause(&mut self) {
self.channel.request_pause()
}
/// Return whether DMA is still running. /// Return whether DMA is still running.
/// ///
/// If this returns `false`, it can be because either the transfer finished, or /// If this returns `false`, it can be because either the transfer finished, or
@ -977,13 +1017,23 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
DmaCtrlImpl(self.channel.reborrow()).set_waker(waker); DmaCtrlImpl(self.channel.reborrow()).set_waker(waker);
} }
/// Request DMA to stop. /// Request the DMA to stop.
/// The configuration for this channel will **not be preserved**. If you need to restart the transfer
/// at a later point with the same configuration, see [`request_pause`](Self::request_pause) instead.
/// ///
/// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
pub fn request_stop(&mut self) { pub fn request_stop(&mut self) {
self.channel.request_stop() self.channel.request_stop()
} }
/// Request the transfer to pause, keeping the existing configuration for this channel.
/// To restart the transfer, call [`start`](Self::start) again.
///
/// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
pub fn request_pause(&mut self) {
self.channel.request_pause()
}
/// Return whether DMA is still running. /// Return whether DMA is still running.
/// ///
/// If this returns `false`, it can be because either the transfer finished, or /// If this returns `false`, it can be because either the transfer finished, or

View File

@ -120,7 +120,7 @@ impl<'d> RingBufferedUartRx<'d> {
/// Stop uart background receive /// Stop uart background receive
fn teardown_uart(&mut self) { fn teardown_uart(&mut self) {
self.ring_buf.request_stop(); self.ring_buf.request_pause();
let r = self.info.regs; let r = self.info.regs;
// clear all interrupts and DMA Rx Request // clear all interrupts and DMA Rx Request