1- //! Direct Memory Access (DMA) driver for i.MX RT processors
1+ //! Direct Memory Access (DMA) driver for i.MX RT processors.
22//!
33//! `imxrt-dma` provides
44//!
5- //! - an unsafe API for defining and scheduling transfers with DMA `Channel`s
6- //! and `Transfer`s
5+ //! - an unsafe API for defining and scheduling transfers with DMA `Channel`s.
76//! - safe DMA futures for memcpy, peripheral-to-memory, and memory-to-peripheral
8- //! transfers
7+ //! transfers.
98//!
10- //! This DMA driver may be re-exported from a HAL. If it is, you should consider
11- //! using the safer APIs provided by your HAL.
9+ //! This DMA driver may be re-exported from a hardware abstraction layer
10+ //! (HAL). If it is, you should use the safer APIs provided by your HAL.
1211//!
13- //! # Portability
12+ //! # Getting started
1413//!
15- //! This DMA driver works across all considered i.MX RT variants (1010 and 1060
16- //! family). You must make sure that the DMA channel you're creating is valid for
17- //! your i.MX RT processor. This only matters on i.MX RT 1010 processors, which
18- //! only support 16 DMA channels. Creating an invalid channel for your 1010 processor
19- //! will result in a channel that references reserved memory.
14+ //! To allocate a [`Dma`](crate::Dma) driver, you'll need to know
15+ //!
16+ //! 1. the location of the DMA controller registers.
17+ //! 2. the location of the DMAMUX registers.
18+ //! 3. the number of DMA channels supported by your chip.
19+ //!
20+ //! These parameters depend on the i.MX RT chip you're targeting. If you're
21+ //! already using [`imxrt-ral`](https://docs.rs/imxrt-ral), consider using the
22+ //! `DMA` and `DMAMUX` constants for the addresses. You're always responsible
23+ //! for configuring the number of DMA channels.
24+ //!
25+ //! With those three parameters, assign a `Dma` to a static. Then, use that
26+ //! object to create DMA [`Channel`](crate::channel::Channel)s.
27+ //!
28+ //! ```
29+ //! use imxrt_dma::Dma;
30+ //! # const DMA_PTR: *const () = core::ptr::null() as _;
31+ //! # const DMAMUX_PTR: *const () = core::ptr::null() as _;
32+ //!
33+ //! // Safety: addresses and channel count are valid for this target.
34+ //! static DMA: Dma<32> = unsafe { Dma::new(DMA_PTR, DMAMUX_PTR) };
35+ //!
36+ //! // Safety: we only allocate one DMA channel 7 object.
37+ //! let mut channel = unsafe { DMA.channel(7) };
38+ //! ```
39+ //!
40+ //! Once you have a channel, you can use the higher-level DMA APIs, like
41+ //!
42+ //! - [`memcpy`](crate::memcpy::memcpy) for memory copies.
43+ //! - [`transfer`](crate::peripheral::transfer) to transmit data from memory to
44+ //! a peripheral.
45+ //! - [`receive`](crate::peripheral::receive) to receive data from a peripheral.
46+ //! - [`full_duplex`](crate::peripheral::full_duplex) to read / write with a
47+ //! peripheral using a single buffer.
48+ //!
49+ //! Peripheral transfers depends on a peripheral's DMA support. These are signaled
50+ //! through various [`peripheral`](crate::peripheral) traits.
51+ //!
52+ //! For a lower-level API, use the [`channel`](crate::channel) objects and helper
53+ //! functions.
2054//!
2155//! ### License
2256//!
@@ -49,7 +83,7 @@ pub use ral::tcd::BandwidthControl;
4983/// A DMA result
5084pub type Result < T > = core:: result:: Result < T , Error > ;
5185
52- /// A DMA peripheral .
86+ /// A DMA driver .
5387///
5488/// This DMA driver manages the DMA controller and the multiplexer.
5589/// It's configured with pointers to both peripherals.
@@ -68,22 +102,23 @@ unsafe impl<const CHANNELS: usize> Sync for Dma<CHANNELS> {}
68102impl < const CHANNELS : usize > Dma < CHANNELS > {
69103 /// Create the DMA driver.
70104 ///
71- /// Note that this can evaluate at compile time. Consider using this to expose
72- /// a `DMA` constant through your higher-level API that you can use to allocate
73- /// DMA channels.
105+ /// Note that this can evaluate at compile time. Consider using this to
106+ /// expose a `Dma` through your higher-level API that you can use to
107+ /// allocate DMA channels.
74108 ///
75- /// `max_channels ` specifies the total number of channels supported by the DMA
109+ /// `CHANNELS ` specifies the total number of channels supported by the DMA
76110 /// controller. It's referenced when allocating channels.
77111 ///
78112 /// # Safety
79113 ///
80- /// Caller must make sure that `controller` is a pointer to the start of the DMA
81- /// controller register block. Caller must also make sure that `multiplexer` is
82- /// a pointer to the start of the DMA multiplexer. Both pointers must be valid
83- /// for your MCU.
114+ /// Caller must make sure that `controller` is a pointer to the start of the
115+ /// DMA controller register block. Caller must also make sure that
116+ /// `multiplexer` is a pointer to the start of the DMA multiplexer. Both
117+ /// pointers must be valid for your MCU.
84118 ///
85- /// An incorrect `max_channels` value prevents proper bounds checking when allocating
86- /// channels. This may result in DMA channels that point to invalid memory.
119+ /// An incorrect `CHANNELS` value prevents proper bounds checking when
120+ /// allocating channels. This may result in DMA channels that point to
121+ /// invalid memory.
87122 pub const unsafe fn new ( controller : * const ( ) , multiplexer : * const ( ) ) -> Self {
88123 Self {
89124 controller : ral:: Static ( controller. cast ( ) ) ,
0 commit comments