Struct mnemos_d1_core::dmac::Dmac
source · pub struct Dmac {
_p: (),
}
Expand description
A handle to the DMA controller (DMAC) peripheral.
A Dmac
can be used used to claim DMA Channel
s from the DMAC’s shared
pool of 16 channels, using the claim_channel
and
try_claim_channel
methods. Once a Channel
has
been claimed, it may be used to perform DMA transfers using the
Channel::transfer
method. Dropping a Channel
releases it back to the
DMAC’s channel pool, allowing it to be claimed by other drivers.
The Dmac
also provides a Dmac::transfer
convenience method, which
claims a channel to perform a single transfer and immediately releases it
back to the pool once the transfer has completed.
This struct is constructed using Dmac::new
, which initializes the DMA
controller and returns a Dmac
. Since this struct is essentially a token
representing that the DMAC has been initialized, it may be freely copied
into any driver that wishes to perform DMA operations.
Fields§
§_p: ()
Implementations§
source§impl Dmac
impl Dmac
sourcepub const CHANNEL_COUNT: u8 = 16u8
pub const CHANNEL_COUNT: u8 = 16u8
The total number of DMA channels available on the DMAC.
sourcepub fn new(dmac: DMAC, ccu: &mut Ccu) -> Self
pub fn new(dmac: DMAC, ccu: &mut Ccu) -> Self
Initializes the DMAC, enabling the queue IRQ for all channels.
sourcepub async unsafe fn transfer(
&self,
src: ChannelMode,
dst: ChannelMode,
desc: NonNull<Descriptor>,
)
pub async unsafe fn transfer( &self, src: ChannelMode, dst: ChannelMode, desc: NonNull<Descriptor>, )
Performs a DMA transfer described by the provided Descriptor
on any
available free DMA Channel
.
This function will first use Dmac::claim_channel
to claim an
available DMA channel, waiting for one to become available if all
channels are currently in use. Once a channel has been acquired, it sets
the src
and dst
ChannelMode
s using
Channel::set_channel_modes
. Then, it performs the transfer using
Channel::transfer
.
If multiple transfers will be made in sequence, it may be more efficient to
call Dmac::claim_channel
once and perform multiple transfers on the same
channel, to avoid releasing and re-claiming a channel in between transfers.
§Safety
The caller must ensure that the descriptor pointed to by desc
, and the
associated memory region used by the transfer, is valid for as long as
the DMA transfer is active. When this function returns, the transfer has
completed, and it is safe to drop the descriptor. If this future is
cancelled, the transfer is cancelled and the descriptor
and its associated buffer may be dropped safely. However, it is super
ultra not okay to core::mem::forget
this future. If you
mem::forget
a DMA transfer future inside your driver, you deserve
whatever happens next.
§Cancel Safety
Dropping this future cancels the DMA transfer. If this future is dropped, the descriptor and its associated memory region may also be dropped safely.
Of course, the transfer may still have completed partially. If we were writing to a device, the device may be unhappy to have only gotten some of the data it wanted. If we were reading from a device, reads may have side effects and incomplete reads may leave the device in a weird state. Cancelling an incomplete transfer may result in, for example, writing out half of a string to the UART, or only part of a structured message over SPI, and so on. But, at least we don’t have abandoned DMA transfers running around in random parts of the heap you probably wanted to use for normal stuff like having strings, or whatever it is that people do on the computer.
sourcepub async fn claim_channel(&self) -> Channel
pub async fn claim_channel(&self) -> Channel
Claims an idle DMA Channel
from the DMAC’s channel pool, waiting for
one to become available if none are currently idle.
For a version of this method which does not wait, see
Dmac::try_claim_channel
.
§Cancel Safety
This future can be cancelled freely with no potential negative
consequences. Dropping this future cancels the attempt to claim a
Channel
from the DMAC pool. If a channel has been acquired, it will
be released back to the pool, and may be acquired by other tasks.
sourcepub fn try_claim_channel(&self) -> Option<Channel>
pub fn try_claim_channel(&self) -> Option<Channel>
Claims an idle DMA channel, if one is available.
If no DMA channels are currently free, this function returns None
.
To instead wait for an active DMA channel to become free, use
Dmac::claim_channel
instead.
§Returns
sourcepub fn handle_interrupt()
pub fn handle_interrupt()
Handle a DMAC interrupt.
sourcepub unsafe fn cancel_all()
pub unsafe fn cancel_all()
Cancel all currently active DMA transfers.
This is generally used when shutting down the system, such as in panic and exception handlers.
§Safety
Cancelling DMA transfers abruptly might put peripherals in a weird state i guess?
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Dmac
impl RefUnwindSafe for Dmac
impl Send for Dmac
impl Sync for Dmac
impl Unpin for Dmac
impl UnwindSafe for Dmac
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T> CloneToUninit for Twhere
T: Copy,
impl<T> CloneToUninit for Twhere
T: Copy,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)