Implement extended Channel trait to bdma.rs
This commit is contained in:
parent
2d2c6d0e01
commit
3411039cb9
1 changed files with 48 additions and 9 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
use core::future::Future;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
use core::task::Poll;
|
||||
use core::task::{Poll, Waker};
|
||||
|
||||
use embassy::interrupt::{Interrupt, InterruptExt};
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
|
@ -58,14 +58,7 @@ pub(crate) unsafe fn do_transfer(
|
|||
});
|
||||
|
||||
let on_drop = OnDrop::new(move || unsafe {
|
||||
// Disable the channel and interrupts with the default value.
|
||||
ch.cr().write(|_| ());
|
||||
|
||||
// Wait for the transfer to complete when it was ongoing.
|
||||
while ch.cr().read().en() {}
|
||||
|
||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||
fence(Ordering::Acquire);
|
||||
_stop(dma , channel_number);
|
||||
});
|
||||
|
||||
#[cfg(dmamux)]
|
||||
|
@ -118,6 +111,40 @@ pub(crate) unsafe fn do_transfer(
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn _stop(dma:pac::bdma::Dma, ch: u8) {
|
||||
let ch = dma.ch(ch as _);
|
||||
|
||||
// Disable the channel and interrupts with the default value.
|
||||
ch.cr().write(|_| ());
|
||||
|
||||
// Wait for the transfer to complete when it was ongoing.
|
||||
while ch.cr().read().en() {}
|
||||
|
||||
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
|
||||
fence(Ordering::Acquire);
|
||||
}
|
||||
|
||||
unsafe fn _is_stopped(dma:pac::bdma::Dma, ch: u8) -> bool {
|
||||
let ch = dma.ch(ch as _);
|
||||
ch.cr().read().en()
|
||||
}
|
||||
|
||||
/// Gets the total remaining transfers for the channel
|
||||
/// Note: this will be zero for transfers that completed without cancellation.
|
||||
unsafe fn _get_remaining_transfers(dma: pac::bdma::Dma, ch: u8) -> u16{
|
||||
// get a handle on the channel itself
|
||||
let ch = dma.ch(ch as _);
|
||||
// read the remaining transfer count. If this is zero, the transfer completed fully.
|
||||
ch.ndtr().read().ndt()
|
||||
}
|
||||
|
||||
/// Sets the waker for the specified DMA channel
|
||||
unsafe fn _set_waker(dma: pac::bdma::Dma, state_number: u8, waker: &Waker){
|
||||
let n = state_number as usize;
|
||||
STATE.ch_wakers[n].register(waker);
|
||||
|
||||
}
|
||||
|
||||
macro_rules! dma_num {
|
||||
(DMA1) => {
|
||||
0
|
||||
|
@ -245,6 +272,18 @@ pac::dma_channels! {
|
|||
)
|
||||
}
|
||||
}
|
||||
fn stop <'a>(&'a mut self){
|
||||
unsafe {_stop(crate::pac::$dma_peri, $channel_num);}
|
||||
}
|
||||
fn is_stopped<'a>(&'a self) -> bool {
|
||||
unsafe {_is_stopped(crate::pac::$dma_peri, $channel_num)}
|
||||
}
|
||||
fn remaining_transfers<'a>(&'a mut self) -> u16 {
|
||||
unsafe {_get_remaining_transfers(crate::pac::$dma_peri, $channel_num)}
|
||||
}
|
||||
fn set_waker<'a>(&'a mut self, waker: &'a Waker) {
|
||||
unsafe {_set_waker(crate::pac::$dma_peri, $channel_num, waker )}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue