33//! # Initializing
44//!
55//! The DMAC should be initialized using the
6- //! [`DmaController::init `] method. It will consume the
6+ //! [`DmaController::new `] method. It will consume the
77//! DMAC object generated by the PAC. By default, all four priority levels
88//! will be enabled, but can be selectively enabled/disabled through the
99//! [`DmaController::enable_levels`] ansd [`DmaController::disable_levels`]
@@ -44,10 +44,12 @@ use super::{
4444 channel:: { Channel , Uninitialized } ,
4545 sram,
4646} ;
47- use crate :: {
48- pac:: { Dmac , Pm } ,
49- typelevel:: NoneT ,
50- } ;
47+ #[ hal_cfg( any( "dmac-d11" , "dmac-d21" ) ) ]
48+ use crate :: pac:: Pm ;
49+ use crate :: { pac:: Dmac , typelevel:: NoneT } ;
50+
51+ #[ hal_cfg( "dmac-d5x" ) ]
52+ type DmacAhbClk = crate :: clock:: v2:: ahb:: AhbClk < crate :: clock:: v2:: types:: Dmac > ;
5153
5254/// Trait representing a DMA channel ID
5355pub trait ChId {
@@ -150,28 +152,18 @@ macro_rules! define_channels_struct_future {
150152with_num_channels ! ( define_channels_struct_future) ;
151153
152154/// Initialized DMA Controller
155+ #[ hal_macro_helper]
153156pub struct DmaController < I = NoneT > {
154157 dmac : Dmac ,
158+ #[ hal_cfg( "dmac-d5x" ) ]
159+ ahb_clk : DmacAhbClk ,
155160 _irqs : PhantomData < I > ,
156161}
157162
158163impl DmaController {
159- /// Initialize the DMAC and return a DmaController object useable by
160- /// [`Transfer`](super::transfer::Transfer)'s. By default, all
161- /// priority levels are enabled unless subsequently disabled using the
162- /// `level_x_enabled` methods.
163- #[ inline]
164- #[ hal_macro_helper]
165- pub fn init ( mut dmac : Dmac , _pm : & mut Pm ) -> Self {
166- // ----- Initialize clocking ----- //
167- #[ hal_cfg( any( "dmac-d11" , "dmac-d21" ) ) ]
168- {
169- // Enable clocking
170- _pm. ahbmask ( ) . modify ( |_, w| w. dmac_ ( ) . set_bit ( ) ) ;
171- _pm. apbbmask ( ) . modify ( |_, w| w. dmac_ ( ) . set_bit ( ) ) ;
172- }
173-
174- Self :: swreset ( & mut dmac) ;
164+ /// Reset and enable the DMA controller.
165+ fn init ( dmac : & mut Dmac ) {
166+ Self :: swreset ( dmac) ;
175167
176168 // SAFETY:
177169 //
@@ -196,36 +188,77 @@ impl DmaController {
196188
197189 // Enable DMA controller
198190 dmac. ctrl ( ) . modify ( |_, w| w. dmaenable ( ) . set_bit ( ) ) ;
191+ }
192+
193+ #[ hal_cfg( any( "dmac-d11" , "dmac-d21" ) ) ]
194+ /// Initialize the DMAC and return a DmaController object useable by
195+ /// [`Transfer`](super::transfer::Transfer)'s. By default, all
196+ /// priority levels are enabled unless subsequently disabled using the
197+ /// `level_x_enabled` methods.
198+ #[ inline]
199+ pub fn new ( mut dmac : Dmac , pm : & mut Pm ) -> Self {
200+ // ----- Initialize clocking ----- //
201+ // Enable clocking
202+ pm. ahbmask ( ) . modify ( |_, w| w. dmac_ ( ) . set_bit ( ) ) ;
203+ pm. apbbmask ( ) . modify ( |_, w| w. dmac_ ( ) . set_bit ( ) ) ;
204+
205+ Self :: init ( & mut dmac) ;
199206
200207 Self {
201208 dmac,
202209 _irqs : PhantomData ,
203210 }
204211 }
205212
213+ #[ hal_cfg( "dmac-d5x" ) ]
214+ /// Initialize the DMAC and return a DmaController object useable by
215+ /// [`Transfer`](super::transfer::Transfer)'s. By default, all
216+ /// priority levels are enabled unless subsequently disabled using the
217+ /// `level_x_enabled` methods.
218+ #[ inline]
219+ pub fn new ( mut dmac : Dmac , ahb_clk : DmacAhbClk ) -> Self {
220+ Self :: init ( & mut dmac) ;
221+
222+ Self {
223+ dmac,
224+ ahb_clk,
225+ _irqs : PhantomData ,
226+ }
227+ }
228+
229+ #[ hal_cfg( any( "dmac-d11" , "dmac-d21" ) ) ]
206230 /// Release the DMAC and return the register block.
207231 ///
208232 /// **Note**: The [`Channels`] struct is consumed by this method. This means
209233 /// that any [`Channel`] obtained by [`split`](DmaController::split) must be
210234 /// moved back into the [`Channels`] struct before being able to pass it
211235 /// into [`free`](DmaController::free).
212236 #[ inline]
213- #[ hal_macro_helper]
214- pub fn free ( mut self , _channels : Channels , _pm : & mut Pm ) -> Dmac {
215- self . dmac . ctrl ( ) . modify ( |_, w| w. dmaenable ( ) . clear_bit ( ) ) ;
237+ pub fn free ( mut self , _channels : Channels , pm : & mut Pm ) -> Dmac {
238+ Self :: disable_and_reset ( & mut self . dmac ) ;
216239
217- Self :: swreset ( & mut self . dmac ) ;
218-
219- #[ hal_cfg( any( "dmac-d11" , "dmac-d21" ) ) ]
220- {
221- // Disable the DMAC clocking
222- _pm. apbbmask ( ) . modify ( |_, w| w. dmac_ ( ) . clear_bit ( ) ) ;
223- _pm. ahbmask ( ) . modify ( |_, w| w. dmac_ ( ) . clear_bit ( ) ) ;
224- }
240+ // Disable the DMAC clocking
241+ pm. apbbmask ( ) . modify ( |_, w| w. dmac_ ( ) . clear_bit ( ) ) ;
242+ pm. ahbmask ( ) . modify ( |_, w| w. dmac_ ( ) . clear_bit ( ) ) ;
225243
226244 // Release the DMAC
227245 self . dmac
228246 }
247+
248+ #[ hal_cfg( "dmac-d5x" ) ]
249+ /// Release the DMAC and return the register block.
250+ ///
251+ /// **Note**: The [`Channels`] struct is consumed by this method. This means
252+ /// that any [`Channel`] obtained by [`split`](DmaController::split) must be
253+ /// moved back into the [`Channels`] struct before being able to pass it
254+ /// into [`free`](DmaController::free).
255+ #[ inline]
256+ pub fn free ( mut self , _channels : Channels ) -> ( Dmac , DmacAhbClk ) {
257+ Self :: disable_and_reset ( & mut self . dmac ) ;
258+
259+ // Release the DMAC and bus clock
260+ ( self . dmac , self . ahb_clk )
261+ }
229262}
230263
231264impl < T > DmaController < T > {
@@ -290,6 +323,7 @@ impl<T> DmaController<T> {
290323 /// [`bind_interrupts`](crate::bind_interrupts).
291324 #[ cfg( feature = "async" ) ]
292325 #[ inline]
326+ #[ hal_macro_helper]
293327 pub fn into_future < I > ( self , _interrupts : I ) -> DmaController < I >
294328 where
295329 I : crate :: async_hal:: interrupts:: Binding <
@@ -304,10 +338,20 @@ impl<T> DmaController<T> {
304338
305339 DmaController {
306340 dmac : self . dmac ,
341+ #[ hal_cfg( "dmac-d5x" ) ]
342+ ahb_clk : self . ahb_clk ,
307343 _irqs : PhantomData ,
308344 }
309345 }
310346
347+ /// Disable and reset the DMAC
348+ #[ inline]
349+ fn disable_and_reset ( dmac : & mut Dmac ) {
350+ dmac. ctrl ( ) . modify ( |_, w| w. dmaenable ( ) . clear_bit ( ) ) ;
351+
352+ Self :: swreset ( dmac) ;
353+ }
354+
311355 /// Issue a software reset to the DMAC and wait for reset to complete
312356 #[ inline]
313357 fn swreset ( dmac : & mut Dmac ) {
@@ -324,29 +368,39 @@ where
324368 super :: async_api:: InterruptHandler ,
325369 > ,
326370{
371+ #[ hal_cfg( any( "dmac-d11" , "dmac-d21" ) ) ]
327372 /// Release the DMAC and return the register block.
328373 ///
329374 /// **Note**: The [`Channels`] struct is consumed by this method. This means
330375 /// that any [`Channel`] obtained by [`split`](DmaController::split) must be
331376 /// moved back into the [`Channels`] struct before being able to pass it
332377 /// into [`free`](DmaController::free).
333378 #[ inline]
334- #[ hal_macro_helper]
335- pub fn free ( mut self , _channels : FutureChannels , _pm : & mut Pm ) -> Dmac {
336- self . dmac . ctrl ( ) . modify ( |_, w| w. dmaenable ( ) . clear_bit ( ) ) ;
379+ pub fn free ( mut self , _channels : FutureChannels , pm : & mut Pm ) -> Dmac {
380+ Self :: disable_and_reset ( & mut self . dmac ) ;
337381
338- Self :: swreset ( & mut self . dmac ) ;
339-
340- #[ hal_cfg( any( "dmac-d11" , "dmac-d21" ) ) ]
341- {
342- // Disable the DMAC clocking
343- _pm. apbbmask ( ) . modify ( |_, w| w. dmac_ ( ) . clear_bit ( ) ) ;
344- _pm. ahbmask ( ) . modify ( |_, w| w. dmac_ ( ) . clear_bit ( ) ) ;
345- }
382+ // Disable the DMAC clocking
383+ pm. apbbmask ( ) . modify ( |_, w| w. dmac_ ( ) . clear_bit ( ) ) ;
384+ pm. ahbmask ( ) . modify ( |_, w| w. dmac_ ( ) . clear_bit ( ) ) ;
346385
347386 // Release the DMAC
348387 self . dmac
349388 }
389+
390+ #[ hal_cfg( "dmac-d5x" ) ]
391+ /// Release the DMAC and return the register block.
392+ ///
393+ /// **Note**: The [`Channels`] struct is consumed by this method. This means
394+ /// that any [`Channel`] obtained by [`split`](DmaController::split) must be
395+ /// moved back into the [`Channels`] struct before being able to pass it
396+ /// into [`free`](DmaController::free).
397+ #[ inline]
398+ pub fn free ( mut self , _channels : FutureChannels ) -> ( Dmac , DmacAhbClk ) {
399+ Self :: disable_and_reset ( & mut self . dmac ) ;
400+
401+ // Release the DMAC and bus clock
402+ ( self . dmac , self . ahb_clk )
403+ }
350404}
351405
352406macro_rules! define_split {
0 commit comments