@@ -944,38 +944,6 @@ pub trait DmaEligible {
944944 fn dma_peripheral ( & self ) -> DmaPeripheral ;
945945}
946946
947- /// Helper type to get the DMA (Rx and Tx) channel for a peripheral.
948- pub type DmaChannelFor < T > = <T as DmaEligible >:: Dma ;
949- /// Helper type to get the DMA Rx channel for a peripheral.
950- pub type RxChannelFor < T > = <DmaChannelFor < T > as DmaChannel >:: Rx ;
951- /// Helper type to get the DMA Tx channel for a peripheral.
952- pub type TxChannelFor < T > = <DmaChannelFor < T > as DmaChannel >:: Tx ;
953-
954- #[ doc( hidden) ]
955- #[ macro_export]
956- macro_rules! impl_dma_eligible {
957- ( [ $dma_ch: ident] $name: ident => $dma: ident) => {
958- impl $crate:: dma:: DmaEligible for $crate:: peripherals:: $name {
959- type Dma = $dma_ch;
960-
961- fn dma_peripheral( & self ) -> $crate:: dma:: DmaPeripheral {
962- $crate:: dma:: DmaPeripheral :: $dma
963- }
964- }
965- } ;
966-
967- (
968- $dma_ch: ident {
969- $( $( #[ $cfg: meta] ) ? $name: ident => $dma: ident, ) *
970- }
971- ) => {
972- $(
973- $( #[ $cfg] ) ?
974- $crate:: impl_dma_eligible!( [ $dma_ch] $name => $dma) ;
975- ) *
976- } ;
977- }
978-
979947#[ doc( hidden) ]
980948#[ derive( Debug ) ]
981949pub struct DescriptorChain {
@@ -1593,6 +1561,38 @@ impl RxCircularState {
15931561 }
15941562}
15951563
1564+ #[ doc( hidden) ]
1565+ #[ macro_export]
1566+ macro_rules! impl_dma_eligible {
1567+ ( [ $dma_ch: ident] $name: ident => $dma: ident) => {
1568+ impl $crate:: dma:: DmaEligible for $crate:: peripherals:: $name {
1569+ type Dma = $dma_ch;
1570+
1571+ fn dma_peripheral( & self ) -> $crate:: dma:: DmaPeripheral {
1572+ $crate:: dma:: DmaPeripheral :: $dma
1573+ }
1574+ }
1575+ } ;
1576+
1577+ (
1578+ $dma_ch: ident {
1579+ $( $( #[ $cfg: meta] ) ? $name: ident => $dma: ident, ) *
1580+ }
1581+ ) => {
1582+ $(
1583+ $( #[ $cfg] ) ?
1584+ $crate:: impl_dma_eligible!( [ $dma_ch] $name => $dma) ;
1585+ ) *
1586+ } ;
1587+ }
1588+
1589+ /// Helper type to get the DMA (Rx and Tx) channel for a peripheral.
1590+ pub type PeripheralDmaChannel < T > = <T as DmaEligible >:: Dma ;
1591+ /// Helper type to get the DMA Rx channel for a peripheral.
1592+ pub type PeripheralRxChannel < T > = <PeripheralDmaChannel < T > as DmaChannel >:: Rx ;
1593+ /// Helper type to get the DMA Tx channel for a peripheral.
1594+ pub type PeripheralTxChannel < T > = <PeripheralDmaChannel < T > as DmaChannel >:: Tx ;
1595+
15961596#[ doc( hidden) ]
15971597pub trait DmaRxChannel :
15981598 RxRegisterAccess + InterruptAccess < DmaRxInterrupt > + Peripheral < P = Self >
@@ -1647,7 +1647,7 @@ pub trait DmaChannelExt: DmaChannel {
16471647 note = "Not all channels are useable with all peripherals"
16481648) ]
16491649#[ doc( hidden) ]
1650- pub trait DmaChannelConvert < DEG > : DmaChannel {
1650+ pub trait DmaChannelConvert < DEG > {
16511651 fn degrade ( self ) -> DEG ;
16521652}
16531653
@@ -1657,6 +1657,94 @@ impl<DEG: DmaChannel> DmaChannelConvert<DEG> for DEG {
16571657 }
16581658}
16591659
1660+ /// Trait implemented for DMA channels that are compatible with a particular
1661+ /// peripheral.
1662+ ///
1663+ /// You can use this in places where a peripheral driver would expect a
1664+ /// `DmaChannel` implementation.
1665+ #[ cfg_attr( pdma, doc = "" ) ]
1666+ #[ cfg_attr(
1667+ pdma,
1668+ doc = "Note that using mismatching channels (e.g. trying to use `spi2channel` with SPI3) may compile, but will panic in runtime."
1669+ ) ]
1670+ #[ cfg_attr( pdma, doc = "" ) ]
1671+ /// ## Example
1672+ ///
1673+ /// The following example demonstrates how this trait can be used to only accept
1674+ /// types compatible with a specific peripheral.
1675+ ///
1676+ /// ```rust,no_run
1677+ #[ doc = crate :: before_snippet!( ) ]
1678+ /// use esp_hal::spi::master::{Spi, SpiDma, Config, Instance as SpiInstance};
1679+ /// use esp_hal::dma::DmaChannelFor;
1680+ /// use esp_hal::peripheral::Peripheral;
1681+ /// use esp_hal::Blocking;
1682+ /// use esp_hal::dma::Dma;
1683+ ///
1684+ /// fn configures_spi_dma<'d, S, CH>(
1685+ /// spi: Spi<'d, Blocking, S>,
1686+ /// channel: impl Peripheral<P = CH> + 'd,
1687+ /// ) -> SpiDma<'d, Blocking, S>
1688+ /// where
1689+ /// S: SpiInstance,
1690+ /// CH: DmaChannelFor<S> + 'd,
1691+ /// {
1692+ /// spi.with_dma(channel)
1693+ /// }
1694+ ///
1695+ /// let dma = Dma::new(peripherals.DMA);
1696+ #[ cfg_attr( pdma, doc = "let dma_channel = dma.spi2channel;" ) ]
1697+ #[ cfg_attr( gdma, doc = "let dma_channel = dma.channel0;" ) ]
1698+ #[ doc = "" ]
1699+ /// let spi = Spi::new_with_config(
1700+ /// peripherals.SPI2,
1701+ /// Config::default(),
1702+ /// );
1703+ ///
1704+ /// let spi_dma = configures_spi_dma(spi, dma_channel);
1705+ /// # }
1706+ /// ```
1707+ pub trait DmaChannelFor < P : DmaEligible > :
1708+ DmaChannel + DmaChannelConvert < PeripheralDmaChannel < P > >
1709+ {
1710+ }
1711+ impl < P , CH > DmaChannelFor < P > for CH
1712+ where
1713+ P : DmaEligible ,
1714+ CH : DmaChannel + DmaChannelConvert < PeripheralDmaChannel < P > > ,
1715+ {
1716+ }
1717+
1718+ /// Trait implemented for the RX half of split DMA channels that are compatible
1719+ /// with a particular peripheral. Accepts complete DMA channels or split halves.
1720+ ///
1721+ /// This trait is similar in use to [`DmaChannelFor`].
1722+ ///
1723+ /// You can use this in places where a peripheral driver would expect a
1724+ /// `DmaRxChannel` implementation.
1725+ pub trait RxChannelFor < P : DmaEligible > : DmaChannelConvert < PeripheralRxChannel < P > > { }
1726+ impl < P , RX > RxChannelFor < P > for RX
1727+ where
1728+ P : DmaEligible ,
1729+ RX : DmaChannelConvert < PeripheralRxChannel < P > > ,
1730+ {
1731+ }
1732+
1733+ /// Trait implemented for the TX half of split DMA channels that are compatible
1734+ /// with a particular peripheral. Accepts complete DMA channels or split halves.
1735+ ///
1736+ /// This trait is similar in use to [`DmaChannelFor`].
1737+ ///
1738+ /// You can use this in places where a peripheral driver would expect a
1739+ /// `DmaTxChannel` implementation.
1740+ pub trait TxChannelFor < PER : DmaEligible > : DmaChannelConvert < PeripheralTxChannel < PER > > { }
1741+ impl < P , TX > TxChannelFor < P > for TX
1742+ where
1743+ P : DmaEligible ,
1744+ TX : DmaChannelConvert < PeripheralTxChannel < P > > ,
1745+ {
1746+ }
1747+
16601748/// The functions here are not meant to be used outside the HAL
16611749#[ doc( hidden) ]
16621750pub trait Rx : crate :: private:: Sealed {
0 commit comments