mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-27 04:10:25 +00:00
fix: modified dma channel state management
See https://github.com/embassy-rs/embassy/pull/3923#discussion_r2094570176
This commit is contained in:
parent
7d224d94c4
commit
fec14213ea
@ -341,21 +341,25 @@ impl AnyChannel {
|
||||
ch.cr().modify(|w| w.set_en(true));
|
||||
}
|
||||
|
||||
fn request_stop(&self) {
|
||||
fn request_suspend(&self) {
|
||||
let info = self.info();
|
||||
let ch = info.dma.ch(info.num);
|
||||
|
||||
ch.cr().modify(|w| w.set_susp(true))
|
||||
}
|
||||
|
||||
fn request_pause(&self) {
|
||||
fn request_resume(&self) {
|
||||
let info = self.info();
|
||||
let ch = info.dma.ch(info.num);
|
||||
|
||||
// Disable the channel without overwriting the existing configuration
|
||||
ch.cr().modify(|w| {
|
||||
w.set_en(false);
|
||||
});
|
||||
ch.cr().modify(|w| w.set_susp(false));
|
||||
}
|
||||
|
||||
fn request_reset(&self) {
|
||||
let info = self.info();
|
||||
let ch = info.dma.ch(info.num);
|
||||
|
||||
ch.cr().modify(|w| w.set_reset(true));
|
||||
}
|
||||
|
||||
fn is_running(&self) -> bool {
|
||||
@ -406,11 +410,26 @@ impl<'a, const ITEM_COUNT: usize> LinkedListTransfer<'a, ITEM_COUNT> {
|
||||
Self { channel }
|
||||
}
|
||||
|
||||
/// Request the transfer to stop.
|
||||
/// Request the transfer to suspend.
|
||||
///
|
||||
/// To resume the transfer, call [`request_resume`](Self::request_resume) again.
|
||||
///
|
||||
/// 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) {
|
||||
self.channel.request_stop()
|
||||
pub fn request_suspend(&mut self) {
|
||||
self.channel.request_suspend()
|
||||
}
|
||||
|
||||
/// Request the transfer to resume after being suspended.
|
||||
pub fn request_resume(&mut self) {
|
||||
self.channel.request_resume()
|
||||
}
|
||||
|
||||
/// Request the DMA to reset.
|
||||
///
|
||||
/// 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_suspend`](Self::request_suspend) instead.
|
||||
pub fn request_reset(&mut self) {
|
||||
self.channel.request_reset()
|
||||
}
|
||||
|
||||
/// Return whether this transfer is still running.
|
||||
@ -440,7 +459,7 @@ impl<'a, const ITEM_COUNT: usize> LinkedListTransfer<'a, ITEM_COUNT> {
|
||||
|
||||
impl<'a, const ITEM_COUNT: usize> Drop for LinkedListTransfer<'a, ITEM_COUNT> {
|
||||
fn drop(&mut self) {
|
||||
self.request_stop();
|
||||
self.request_suspend();
|
||||
while self.is_running() {}
|
||||
|
||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||
@ -589,21 +608,26 @@ impl<'a> Transfer<'a> {
|
||||
Self { channel }
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// Request the transfer to suspend.
|
||||
///
|
||||
/// To resume the transfer, call [`request_resume`](Self::request_resume) again.
|
||||
///
|
||||
/// 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) {
|
||||
self.channel.request_stop()
|
||||
pub fn request_suspend(&mut self) {
|
||||
self.channel.request_suspend()
|
||||
}
|
||||
|
||||
/// Request the transfer to pause, keeping the existing configuration for this channel.
|
||||
/// To restart the transfer, call [`start`](Self::start) again.
|
||||
/// Request the transfer to resume after being suspended.
|
||||
pub fn request_resume(&mut self) {
|
||||
self.channel.request_resume()
|
||||
}
|
||||
|
||||
/// Request the DMA to reset.
|
||||
///
|
||||
/// 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()
|
||||
/// 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_suspend`](Self::request_suspend) instead.
|
||||
pub fn request_reset(&mut self) {
|
||||
self.channel.request_reset()
|
||||
}
|
||||
|
||||
/// Return whether this transfer is still running.
|
||||
@ -633,7 +657,7 @@ impl<'a> Transfer<'a> {
|
||||
|
||||
impl<'a> Drop for Transfer<'a> {
|
||||
fn drop(&mut self) {
|
||||
self.request_stop();
|
||||
self.request_suspend();
|
||||
while self.is_running() {}
|
||||
|
||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||
|
@ -139,21 +139,26 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
|
||||
DmaCtrlImpl(self.channel.reborrow()).set_waker(waker);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// Request the DMA to suspend.
|
||||
///
|
||||
/// To resume the transfer, call [`request_resume`](Self::request_resume) again.
|
||||
///
|
||||
/// 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) {
|
||||
self.channel.request_stop()
|
||||
pub fn request_suspend(&mut self) {
|
||||
self.channel.request_suspend()
|
||||
}
|
||||
|
||||
/// Request the transfer to pause, keeping the existing configuration for this channel.
|
||||
/// To restart the transfer, call [`start`](Self::start) again.
|
||||
/// Request the DMA to resume transfers after being suspended.
|
||||
pub fn request_resume(&mut self) {
|
||||
self.channel.request_resume()
|
||||
}
|
||||
|
||||
/// Request the DMA to reset.
|
||||
///
|
||||
/// 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()
|
||||
/// 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_suspend`](Self::request_suspend) instead.
|
||||
pub fn request_reset(&mut self) {
|
||||
self.channel.request_reset()
|
||||
}
|
||||
|
||||
/// Return whether DMA is still running.
|
||||
@ -185,7 +190,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
|
||||
|
||||
impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> {
|
||||
fn drop(&mut self) {
|
||||
self.request_stop();
|
||||
self.request_suspend();
|
||||
while self.is_running() {}
|
||||
|
||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||
@ -285,21 +290,26 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
|
||||
DmaCtrlImpl(self.channel.reborrow()).set_waker(waker);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// Request the DMA to suspend.
|
||||
///
|
||||
/// To resume the transfer, call [`request_resume`](Self::request_resume) again.
|
||||
///
|
||||
/// 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) {
|
||||
self.channel.request_stop()
|
||||
pub fn request_suspend(&mut self) {
|
||||
self.channel.request_suspend()
|
||||
}
|
||||
|
||||
/// Request the transfer to pause, keeping the existing configuration for this channel.
|
||||
/// To restart the transfer, call [`start`](Self::start) again.
|
||||
/// Request the DMA to resume transfers after being suspended.
|
||||
pub fn request_resume(&mut self) {
|
||||
self.channel.request_resume()
|
||||
}
|
||||
|
||||
/// Request the DMA to reset.
|
||||
///
|
||||
/// 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()
|
||||
/// 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_suspend`](Self::request_suspend) instead.
|
||||
pub fn request_reset(&mut self) {
|
||||
self.channel.request_reset()
|
||||
}
|
||||
|
||||
/// Return whether DMA is still running.
|
||||
@ -331,7 +341,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
|
||||
|
||||
impl<'a, W: Word> Drop for WritableRingBuffer<'a, W> {
|
||||
fn drop(&mut self) {
|
||||
self.request_stop();
|
||||
self.request_suspend();
|
||||
while self.is_running() {}
|
||||
|
||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||
|
@ -490,14 +490,14 @@ impl<'d, T: Instance> PdPhy<'d, T> {
|
||||
let sr = r.sr().read();
|
||||
|
||||
if sr.rxhrstdet() {
|
||||
dma.request_stop();
|
||||
dma.request_suspend();
|
||||
|
||||
// Clean and re-enable hard reset receive interrupt.
|
||||
r.icr().write(|w| w.set_rxhrstdetcf(true));
|
||||
r.imr().modify(|w| w.set_rxhrstdetie(true));
|
||||
Poll::Ready(Err(RxError::HardReset))
|
||||
} else if sr.rxmsgend() {
|
||||
dma.request_stop();
|
||||
dma.request_suspend();
|
||||
// Should be read immediately on interrupt.
|
||||
rxpaysz = r.rx_payszr().read().rxpaysz().into();
|
||||
|
||||
|
@ -165,7 +165,7 @@ impl<'d> RingBufferedUartRx<'d> {
|
||||
|
||||
/// Stop DMA backed UART receiver
|
||||
fn stop_uart(&mut self) {
|
||||
self.ring_buf.request_pause();
|
||||
self.ring_buf.request_suspend();
|
||||
|
||||
let r = self.info.regs;
|
||||
// clear all interrupts and DMA Rx Request
|
||||
|
Loading…
x
Reference in New Issue
Block a user