stm32h7xx_hal/rcc/rec.rs
1//! Peripheral Reset and Enable Control (REC)
2//!
3//! This module contains safe accessors to the RCC functionality for each
4//! peripheral.
5//!
6//! At a minimum each peripheral implements
7//! [ResetEnable](trait.ResetEnable.html). Peripherals that have an
8//! individual clock multiplexer in the PKSU also have methods
9//! `kernel_clk_mux` and `get_kernel_clk_mux`. These set and get the state
10//! of the kernel clock multiplexer respectively.
11//!
12//! Peripherals that share a clock multiplexer in the PKSU with other
13//! peripherals implement a trait with a `get_kernel_clk_mux` method that
14//! returns the current kernel clock state. Because the kernel_clk_mux is shared
15//! between multiple peripherals, it cannot be set by any individual one of
16//! them. Instead it can only be set by methods on the
17//! [`PeripheralRec`](struct.PeripheralREC.html) itself. These methods are named
18//! `kernel_xxxx_clk_mux()`.
19//!
20//! # Reset/Enable Example
21//!
22//! ```
23//! // Constrain and Freeze power
24//! ...
25//! let rcc = dp.RCC.constrain();
26//! let ccdr = rcc.sys_ck(100.MHz()).freeze(pwrcfg, &dp.SYSCFG);
27//!
28//! // Enable the clock to a peripheral and reset it
29//! ccdr.peripheral.FDCAN.enable().reset();
30//! ```
31//!
32//! # Individual Kernel Clock Example
33//! ```
34//! let ccdr = ...; // Returned by `freeze()`, see example above
35//!
36//! // Set individual kernel clock
37//! let cec_prec = ccdr.peripheral.CEC.kernel_clk_mux(CecClkSel::LSI);
38//!
39//! assert_eq!(cec_prec.get_kernel_clk_mux(), CecClkSel::LSI);
40//! ```
41//!
42//! # Group Kernel Clock Example
43//! ```
44//! let mut ccdr = ...; // Returned by `freeze()`, see example above
45//!
46//! // Set group kernel clock mux
47//! ccdr.peripheral.kernel_i2c123_clk_mux(I2c123ClkSel::PLL3_R);
48//!
49//! // Enable and reset peripheral
50//! let i2c3_prec = ccdr.peripheral.I2C3.enable().reset();
51//!
52//! assert_eq!(i2c3_prec.get_kernel_clk_mux(), I2c123ClkSel::PLL3_R);
53//!
54//! // Some method that consumes the i2c3 prec
55//! init_i2c3(..., i2c3_prec);
56//!
57//! // Can't set group kernel clock (it would also affect I2C3)
58//! // ccdr.peripheral.kernel_i2c123_clk_mux(I2c123ClkSel::HSI_KER);
59//! ```
60//!
61//! # REC object
62//!
63//! There is a REC object for each peripheral. For example:
64//!
65//! ```
66//! let rec_object = ccdr.peripheral.FDCAN;
67//! ```
68//!
69//! If REC object is dropped by user code, then the Reset or Enable state of
70//! this peripheral cannot be modified for the lifetime of the program.
71#![deny(missing_docs)]
72
73use core::marker::PhantomData;
74
75use super::Rcc;
76use crate::stm32::{rcc, RCC};
77use cortex_m::interrupt;
78
79/// A trait for Resetting, Enabling and Disabling a single peripheral
80pub trait ResetEnable {
81 /// Enable this peripheral
82 #[allow(clippy::return_self_not_must_use)]
83 fn enable(self) -> Self;
84 /// Disable this peripheral
85 #[allow(clippy::return_self_not_must_use)]
86 fn disable(self) -> Self;
87 /// Reset this peripheral
88 #[allow(clippy::return_self_not_must_use)]
89 fn reset(self) -> Self;
90}
91
92/// The clock gating state of a peripheral in low-power mode
93///
94/// See RM0433 rev 7. Section 8.5.11
95#[derive(Default, Copy, Clone, PartialEq, Eq)]
96pub enum LowPowerMode {
97 /// Kernel and bus interface clocks are not provided in low-power modes.
98 Off,
99 /// Kernel and bus interface clocks are provided in CSleep mode.
100 #[default]
101 Enabled,
102 /// Kernel and bus interface clocks are provided in both CSleep and CStop
103 /// modes. Only applies to peripherals in the D3 / SRD. If the peripheral is
104 /// not in the D3 / SRD then this has the same effect as `Enabled`.
105 Autonomous,
106}
107
108impl Rcc {
109 /// Returns all the peripherals resets / enables / kernel clocks.
110 ///
111 /// # Use case
112 ///
113 /// Allows peripherals to be reset / enabled before the calling
114 /// freeze. For example, the internal watchdog could be enabled to
115 /// issue a reset if the call to freeze hangs waiting for an external
116 /// clock that is stopped.
117 ///
118 /// # Safety
119 ///
120 /// If this method is called multiple times, or is called before the
121 /// [freeze](struct.Rcc.html#freeze), then multiple accesses to the
122 /// same memory exist.
123 #[inline]
124 pub unsafe fn steal_peripheral_rec(&self) -> PeripheralREC {
125 PeripheralREC::new_singleton()
126 }
127}
128
129// This macro uses the paste::item! macro to create identifiers.
130//
131// https://crates.io/crates/paste
132macro_rules! peripheral_reset_and_enable_control {
133 ($( #[ $tmeta:meta ] $AXBn:ident, $axb_doc:expr => [
134 $(
135 $( #[ $pmeta:meta ] )*
136 $(($Auto:ident))* $p:ident
137 $([ kernel $clk:ident: $pk:ident $(($Variant:ident))* $ccip:ident $clk_doc:expr ])*
138 $([ group clk: $pk_g:ident $( $(($Variant_g:ident))* $ccip_g:ident $clk_doc_g:expr )* ])*
139 $([ fixed clk: $clk_doc_f:expr ])*
140 ),*
141 ];)+) => {
142 paste::item! {
143 /// Peripheral Reset and Enable Control
144 #[allow(non_snake_case)]
145 #[non_exhaustive]
146 pub struct PeripheralREC {
147 $(
148 $(
149 #[allow(missing_docs)]
150 #[ $tmeta ]
151 $( #[ $pmeta ] )*
152 pub [< $p:upper >]: $p,
153 )*
154 )+
155 }
156 impl PeripheralREC {
157 /// Return a new instance of the peripheral resets /
158 /// enables / kernel clocks
159 ///
160 /// # Safety
161 ///
162 /// If this method is called multiple times, then multiple
163 /// accesses to the same memory exist.
164 pub(super) unsafe fn new_singleton() -> PeripheralREC {
165 PeripheralREC {
166 $(
167 $(
168 #[ $tmeta ]
169 $( #[ $pmeta ] )*
170 [< $p:upper >]: $p {
171 _marker: PhantomData,
172 },
173 )*
174 )+
175 }
176 }
177 }
178 $(
179 $(
180 #[ $tmeta ]
181 peripheral_reset_and_enable_control_generator! (
182 $AXBn, $(($Auto))* $p, [< $p:upper >], [< $p:lower >],
183 $( $pmeta )*
184 $(
185 [kernel $clk: $pk $(($Variant))* $ccip $clk_doc]
186 )*
187 $(
188 [group clk: $pk_g [< $pk_g:lower >] $( $(($Variant_g))* $ccip_g $clk_doc_g )* ]
189 )*
190 $(
191 [fixed clk: $clk_doc_f]
192 )*
193 );
194 )*
195 )+
196 }
197 }
198}
199
200// This macro uses the paste::item! macro to create identifiers.
201//
202// https://crates.io/crates/paste
203//
204// The macro is intended only to be called from within the
205// peripheral_reset_and_enable_control macro
206macro_rules! peripheral_reset_and_enable_control_generator {
207 (
208 $AXBn:ident,
209 $(($Auto:ident))* $p:ident,
210 $p_upper:ident, // Lower and upper case $p available for use in
211 $p_lower:ident, // comments, equivalent to with the paste macro.
212
213 $( $pmeta:meta )*
214 $([ kernel $clk:ident: $pk:ident $(($Variant:ident))* $ccip:ident $clk_doc:expr ])*
215 $([ group clk: $pk_g:ident $pk_g_lower:ident $( $(($Variant_g:ident))* $ccip_g:ident $clk_doc_g:expr )* ])*
216 $([ fixed clk: $clk_doc_f:expr ])*
217 ) => {
218 paste::item! {
219 #[doc = " Reset, Enable and Clock functionality for " $p]
220 ///
221 /// # Reset/Enable Example
222 ///
223 /// ```
224 /// let ccdr = ...; // From RCC
225 ///
226 /// // Enable the clock to the peripheral and reset it
227 #[doc = "ccdr.peripheral." $p_upper ".enable().reset();"]
228 /// ```
229 ///
230 $( // Individual kernel clocks
231 /// # Individual Kernel Clock
232 ///
233 /// This peripheral has its own dedicated kernel clock.
234 #[doc = "See [" $pk "ClkSel](crate::rcc::rec::" $pk "ClkSel) "
235 "for possible clock sources."]
236 ///
237 /// ```
238 /// let ccdr = ...; // From RCC
239 ///
240 /// // Set individual kernel clock
241 #[doc = "let " $p_lower "_prec = ccdr.peripheral." $p_upper
242 ".kernel_clk_mux(" $pk "ClkSel::XX_clock_soruce_XX);"]
243 ///
244 #[doc = "assert_eq!(" $p_lower "_prec.get_kernel_clk_mux(), "
245 $pk "ClkSel::XX_clock_source_XX);"]
246 /// ```
247 )*
248 $( // Group kernel clocks
249 /// # Group Kernel Clock
250 ///
251 /// This peripheral has a kernel clock that is shared with other
252 /// peripherals.
253 ///
254 #[doc = "Since it is shared, it must be set using the "
255 "[kernel_" $pk_g_lower "_clk_mux](crate::rcc::rec::PeripheralREC#method"
256 ".kernel_" $pk_g_lower "_clk_mux) method."]
257 ///
258 /// ```
259 /// let mut ccdr = ...; // From RCC
260 ///
261 /// // Set group kernel clock mux
262 #[doc = " ccdr.peripheral."
263 "kernel_" $pk_g_lower "_clk_mux("
264 $pk_g "ClkSel::XX_clock_source_XX);"]
265 ///
266 #[doc = " assert_eq!(ccdr.peripheral." $p_upper
267 ".get_kernel_clk_mux(), " $pk_g "ClkSel::XX_clock_source_XX);"]
268 )*
269 $( // Fixed kernel clocks
270 /// # Fixed Kernel Clock
271 ///
272 /// This peripheral has a kernel clock that is always equal to
273 #[doc= $clk_doc_f "."]
274 )*
275 $( #[ $pmeta ] )*
276 pub struct $p {
277 pub(crate) _marker: PhantomData<*const ()>,
278 }
279 $( #[ $pmeta ] )*
280 impl $p {
281 /// Set Low Power Mode for peripheral
282 #[allow(clippy::return_self_not_must_use)]
283 pub fn low_power(self, lpm: LowPowerMode) -> Self {
284 // unsafe: Owned exclusive access to this bitfield
285 interrupt::free(|_| {
286 // LPEN
287 let lpenr = unsafe {
288 &(*RCC::ptr()).[< $AXBn:lower lpenr >]
289 };
290 lpenr.modify(|_, w| w.[< $p:lower lpen >]()
291 .bit(lpm != LowPowerMode::Off));
292 // AMEN
293 $(
294 let amr = unsafe { autonomous!($Auto) };
295 amr.modify(|_, w| w.[< $p:lower amen >]()
296 .bit(lpm == LowPowerMode::Autonomous));
297 )*
298 });
299 self
300 }
301 }
302 $( #[ $pmeta ] )*
303 unsafe impl Send for $p {}
304 $( #[ $pmeta ] )*
305 impl ResetEnable for $p {
306 #[inline(always)]
307 fn enable(self) -> Self {
308 // unsafe: Owned exclusive access to this bitfield
309 interrupt::free(|_| {
310 let enr = unsafe {
311 &(*RCC::ptr()).[< $AXBn:lower enr >]
312 };
313 enr.modify(|_, w| w.
314 [< $p:lower en >]().set_bit());
315 });
316 self
317 }
318 #[inline(always)]
319 fn disable(self) -> Self {
320 // unsafe: Owned exclusive access to this bitfield
321 interrupt::free(|_| {
322 let enr = unsafe {
323 &(*RCC::ptr()).[< $AXBn:lower enr >]
324 };
325 enr.modify(|_, w| w.
326 [< $p:lower en >]().clear_bit());
327 });
328 self
329 }
330 #[inline(always)]
331 fn reset(self) -> Self {
332 // unsafe: Owned exclusive access to this bitfield
333 interrupt::free(|_| {
334 let rstr = unsafe {
335 &(*RCC::ptr()).[< $AXBn:lower rstr >]
336 };
337 rstr.modify(|_, w| w.
338 [< $p:lower rst >]().set_bit());
339 rstr.modify(|_, w| w.
340 [< $p:lower rst >]().clear_bit());
341 });
342 self
343 }
344 }
345 $( #[ $pmeta ] )*
346 impl $p {
347 $( // Individual kernel clocks
348 #[inline(always)]
349 #[allow(clippy::return_self_not_must_use)]
350 /// Modify the kernel clock for
351 #[doc=$clk_doc "."]
352 /// See RM0433 Rev 7 Section 8.5.8.
353 ///
354 /// It is possible to switch this clock dynamically without
355 /// generating spurs or timing violations. However, the user
356 /// must ensure that both clocks are running. See RM0433 Rev
357 /// 7 Section 8.5.10.
358 pub fn [< kernel_ $clk _mux >](self, sel: [< $pk ClkSel >]) -> Self {
359 // unsafe: Owned exclusive access to this bitfield
360 interrupt::free(|_| {
361 let ccip = unsafe {
362 &(*RCC::ptr()).[< $ccip r >]
363 };
364 ccip.modify(|_, w| w.
365 [< $pk:lower sel >]().variant(sel));
366 });
367 self
368 }
369
370 #[inline(always)]
371 /// Return the current kernel clock selection
372 pub fn [< get_kernel_ $clk _mux>](&self) ->
373 variant_return_type!([< $pk ClkSel >] $(, $Variant)*)
374 {
375 // unsafe: We only read from this bitfield
376 let ccip = unsafe {
377 &(*RCC::ptr()).[< $ccip r >]
378 };
379 ccip.read().[< $pk:lower sel >]().variant()
380 }
381 )*
382 }
383 $( // Individual kernel clocks
384 #[doc=$clk_doc]
385 /// kernel clock source selection
386 pub type [< $pk ClkSel >] =
387 rcc::[< $ccip r >]::[< $pk:upper SEL_A >];
388 )*
389 $( // Group kernel clocks
390 impl [< $pk_g ClkSelGetter >] for $p {}
391 )*
392 $( // Group kernel clocks
393 $(
394 #[doc=$clk_doc_g]
395 /// kernel clock source selection.
396 pub type [< $pk_g ClkSel >] =
397 rcc::[< $ccip_g r >]::[< $pk_g:upper SEL_A >];
398
399 /// Can return
400 #[doc=$clk_doc_g]
401 /// kernel clock source selection
402 pub trait [< $pk_g ClkSelGetter >] {
403 #[inline(always)]
404 #[allow(unused)]
405 /// Return the
406 #[doc=$clk_doc_g]
407 /// kernel clock selection
408 fn get_kernel_clk_mux(&self) ->
409 variant_return_type!([< $pk_g ClkSel >] $(, $Variant_g)*)
410 {
411 // unsafe: We only read from this bitfield
412 let ccip = unsafe {
413 &(*RCC::ptr()).[< $ccip_g r >]
414 };
415 ccip.read().[< $pk_g:lower sel >]().variant()
416 }
417 }
418 )*
419 )*
420 impl PeripheralREC {
421 $( // Group kernel clocks
422 $(
423 /// Modify the kernel clock for
424 #[doc=$clk_doc_g "."]
425 /// See RM0433 Rev 7 Section 8.5.8.
426 ///
427 /// It is possible to switch this clock dynamically
428 /// without generating spurs or timing
429 /// violations. However, the user must ensure that both
430 /// clocks are running. See RM0433 Rev 7 Section 8.5.10.
431 pub fn [< kernel_ $pk_g:lower _clk_mux >](&mut self, sel: [< $pk_g ClkSel >]) -> &mut Self {
432 // unsafe: Owned exclusive access to this bitfield
433 interrupt::free(|_| {
434 let ccip = unsafe {
435 &(*RCC::ptr()).[< $ccip_g r >]
436 };
437 ccip.modify(|_, w| w.
438 [< $pk_g:lower sel >]().variant(sel));
439 });
440 self
441 }
442 )*
443 )*
444 }
445 }
446 }
447}
448
449// If the PAC does not fully specify a CCIP field (perhaps because one or
450// more values are reserved), then we use a different return type
451macro_rules! variant_return_type {
452 ($t:ty) => { $t };
453 ($t:ty, $Variant: ident) => {
454 Option<$t>
455 };
456}
457
458// Register for autonomous mode enable bits
459#[cfg(not(feature = "rm0455"))]
460macro_rules! autonomous {
461 ($Auto:ident) => {
462 &(*RCC::ptr()).d3amr
463 };
464}
465#[cfg(feature = "rm0455")]
466macro_rules! autonomous {
467 ($Auto:ident) => {
468 &(*RCC::ptr()).srdamr
469 };
470}
471
472// Enumerate all peripherals and optional clock multiplexers
473//
474// Peripherals are grouped by bus for convenience. Each bus is specified like:
475// #[attribute] name, "description" => [..];
476//
477// The attribute is mandatory for the bus grouping, but can just be
478// #[cfg(all())]. The description is not used. Each bus grouping can be repeated
479// multiple times if needed.
480//
481// As well as busses, peripherals can optionally be preceeded by a conditional
482// compilation attribute. However, this only works for peripherals without
483// kernel clock multiplexers.
484//
485// Peripherals with an individual kernel clock must be marked "kernel clk". If a
486// kernel clock multiplexer is shared between multiple peripherals, all those
487// peripherals must instead be marked with a common "group clk".
488peripheral_reset_and_enable_control! {
489 #[cfg(all())]
490 AHB1, "AMBA High-performance Bus (AHB1) peripherals" => [
491 Dma2, Dma1
492 ];
493 #[cfg(not(feature = "rm0455"))]
494 AHB1, "" => [
495 Eth1Mac,
496 #[cfg(any(feature = "rm0399"))] Art,
497 Adc12 [group clk: Adc(Variant) d3ccip "ADC"],
498 Usb1Otg [group clk: Usb d2ccip2 "USB"]
499 ];
500 #[cfg(any(feature = "rm0433", feature = "rm0399"))]
501 AHB1, "" => [
502 Usb2Otg [group clk: Usb]
503 ];
504 #[cfg(feature = "rm0455")]
505 AHB1, "" => [
506 Crc,
507 Usb1Otg [group clk: Usb cdccip2 "USB"],
508 Adc12 [group clk: Adc(Variant) srdccip "ADC"]
509 ];
510
511
512 #[cfg(all())]
513 AHB2, "AMBA High-performance Bus (AHB2) peripherals" => [
514 Hash, Crypt,
515 Sdmmc2 [group clk: Sdmmc]
516 ];
517 #[cfg(not(feature = "rm0455"))]
518 AHB2, "" => [
519 Rng [kernel clk: Rng d2ccip2 "RNG"]
520 ];
521 #[cfg(feature = "rm0455")]
522 AHB2, "" => [
523 Rng [kernel clk: Rng cdccip2 "RNG"]
524 ];
525 #[cfg(feature = "rm0468")]
526 AHB2, "" => [
527 Cordic, Fmac
528 ];
529
530
531 #[cfg(all())]
532 AHB3, "AMBA High-performance Bus (AHB3) peripherals" => [
533 Dma2d, Mdma
534 ];
535 #[cfg(not(feature = "rm0455"))]
536 AHB3, "" => [
537 Sdmmc1 [group clk: Sdmmc d1ccip "SDMMC"],
538 Fmc [kernel clk: Fmc d1ccip "FMC"]
539 ];
540 #[cfg(any(feature = "rm0433", feature = "rm0399"))]
541 AHB3, "" => [
542 Jpgdec,
543 Qspi [kernel clk: Qspi d1ccip "QUADSPI"]
544 ];
545 #[cfg(feature = "rm0455")]
546 AHB3, "" => [
547 Jpgdec,
548 Sdmmc1 [group clk: Sdmmc cdccip "SDMMC"],
549 Fmc [kernel clk: Fmc cdccip "FMC"],
550 Octospi1 [group clk: Octospi cdccip "OCTOSPI"],
551 Octospi2 [group clk: Octospi]
552 ];
553 #[cfg(feature = "rm0468")]
554 AHB3, "" => [
555 Octospi1 [group clk: Octospi d1ccip "OCTOSPI"],
556 Octospi2 [group clk: Octospi]
557 ];
558
559
560 #[cfg(all())]
561 AHB4, "AMBA High-performance Bus (AHB4) peripherals" => [
562 Gpioa, Gpiob, Gpioc, Gpiod, Gpioe, Gpiof, Gpiog, Gpioh, Gpioi, Gpioj, Gpiok
563 ];
564 #[cfg(not(feature = "rm0455"))]
565 AHB4, "" => [
566 (Auto) Crc,
567 (Auto) Bdma,
568 (Auto) Adc3 [group clk: Adc]
569 ];
570 #[cfg(feature = "rm0455")]
571 AHB4, "" => [
572 (Auto) Bdma2
573 ];
574
575
576 #[cfg(all())]
577 APB1L, "Advanced Peripheral Bus 1L (APB1L) peripherals" => [
578 Spi2 [group clk: Spi123],
579 Spi3 [group clk: Spi123],
580
581 Tim2, Tim3, Tim4, Tim5, Tim6, Tim7, Tim12, Tim13, Tim14,
582
583 Usart3 [group clk: Usart234578],
584 Uart4 [group clk: Usart234578],
585 Uart5 [group clk: Usart234578],
586 Uart7 [group clk: Usart234578],
587 Uart8 [group clk: Usart234578]
588 ];
589 #[cfg(not(feature = "rm0455"))]
590 APB1L, "" => [
591 Dac12,
592
593 Cec [kernel clk: Cec(Variant) d2ccip2 "CEC"],
594 Lptim1 [kernel clk: Lptim1(Variant) d2ccip2 "LPTIM1"],
595 Usart2 [group clk: Usart234578(Variant) d2ccip2 "USART2/3/4/5/7/8"]
596 ];
597 #[cfg(any(feature = "rm0433", feature = "rm0399"))]
598 APB1L, "" => [
599 I2c1 [group clk: I2c123 d2ccip2 "I2C1/2/3"],
600 I2c2 [group clk: I2c123],
601 I2c3 [group clk: I2c123]
602 ];
603 #[cfg(feature = "rm0455")]
604 APB1L, "" => [
605 Dac1,
606
607 I2c1 [group clk: I2c123 cdccip2 "I2C1/2/3"],
608 I2c2 [group clk: I2c123],
609 I2c3 [group clk: I2c123],
610 Cec [kernel clk: Cec(Variant) cdccip2 "CEC"],
611 Lptim1 [kernel clk: Lptim1(Variant) cdccip2 "LPTIM1"],
612 Usart2 [group clk: Usart234578(Variant) cdccip2 "USART2/3/4/5/7/8"]
613 ];
614 #[cfg(feature = "rm0468")]
615 APB1L, "" => [
616 I2c1 [group clk: I2c1235 d2ccip2 "I2C1/2/3/5"],
617 I2c2 [group clk: I2c1235],
618 I2c3 [group clk: I2c1235],
619 I2c5 [group clk: I2c1235]
620 ];
621
622
623 #[cfg(all())]
624 APB1H, "Advanced Peripheral Bus 1H (APB1H) peripherals" => [
625 Crs, Mdios, Opamp
626 ];
627 #[cfg(not(feature = "rm0455"))]
628 APB1H, "" => [
629 Fdcan [kernel clk: Fdcan(Variant) d2ccip1 "FDCAN"]
630 ];
631 #[cfg(any(feature = "rm0433", feature = "rm0399"))]
632 APB1H, "" => [
633 Swp [kernel clk: Swp d2ccip1 "SWPMI"]
634 ];
635 #[cfg(feature = "rm0455")]
636 APB1H, "" => [
637 Fdcan [kernel clk: Fdcan(Variant) cdccip1 "FDCAN"],
638 Swpmi [kernel clk: Swpmi cdccip1 "SWPMI"]
639 ];
640 #[cfg(feature = "rm0468")]
641 APB1H, "" => [
642 Swpmi [kernel clk: Swpmi d2ccip1 "SWPMI"],
643
644 Tim23, Tim24
645 ];
646
647
648 #[cfg(all())]
649 APB2, "Advanced Peripheral Bus 2 (APB2) peripherals" => [
650 Tim1, Tim8, Tim15, Tim16, Tim17
651 ];
652 #[cfg(not(feature = "rm0455"))]
653 APB2, "" => [
654 Dfsdm1 [kernel clk: Dfsdm1 d2ccip1 "DFSDM1"],
655
656 Sai1 [kernel clk: Sai1(Variant) d2ccip1 "SAI1"],
657
658 Spi1 [group clk: Spi123(Variant) d2ccip1 "SPI1/2/3"],
659 Spi4 [group clk: Spi45(Variant) d2ccip1 "SPI4/5"],
660 Spi5 [group clk: Spi45]
661 ];
662 #[cfg(any(feature = "rm0433", feature = "rm0399"))]
663 APB2, "" => [
664 Hrtim,
665
666 Sai2 [group clk: Sai23(Variant) d2ccip1 "SAI2/3"],
667 Sai3 [group clk: Sai23],
668
669 Usart1 [group clk: Usart16(Variant) d2ccip2 "USART1/6"],
670 Usart6 [group clk: Usart16]
671 ];
672 #[cfg(feature = "rm0455")]
673 APB2, "" => [
674 Dfsdm1 [kernel clk: Dfsdm1 cdccip1 "DFSDM1"],
675
676 Sai1 [kernel clk: Sai1(Variant) cdccip1 "SAI1"],
677 Sai2 [kernel clk_a: Sai2A(Variant) cdccip1
678 "Sub-Block A of SAI2"]
679 [kernel clk_b: Sai2B(Variant) cdccip1
680 "Sub-Block B of SAI2"],
681
682 Spi1 [group clk: Spi123(Variant) cdccip1 "SPI1/2/3"],
683 Spi4 [group clk: Spi45(Variant) cdccip1 "SPI4/5"],
684 Spi5 [group clk: Spi45],
685
686 Usart1 [group clk: Usart16910(Variant) cdccip2 "USART1/6/9/10"],
687 Usart6 [group clk: Usart16910],
688 Uart9 [group clk: Usart16910],
689 Usart10 [group clk: Usart16910]
690 ];
691 #[cfg(feature = "rm0468")]
692 APB2, "" => [
693 Usart1 [group clk: Usart16910(Variant) d2ccip2 "USART1/6/9/10"],
694 Usart6 [group clk: Usart16910],
695 Uart9 [group clk: Usart16910],
696 Usart10 [group clk: Usart16910]
697 ];
698
699
700 #[cfg(all())]
701 APB3, "Advanced Peripheral Bus 3 (APB3) peripherals" => [
702 Ltdc [fixed clk: "pll3_r_ck"],
703 #[cfg(any(feature = "rm0399"))] Dsi
704 ];
705
706
707 #[cfg(all())]
708 APB4, "Advanced Peripheral Bus 4 (APB4) peripherals" => [
709 (Auto) Vref,
710 (Auto) Comp12
711 ];
712 #[cfg(not(feature = "rm0455"))]
713 APB4, "" => [
714 (Auto) Lptim2 [kernel clk: Lptim2(Variant) d3ccip "LPTIM2"],
715 (Auto) Lptim3 [group clk: Lptim345(Variant) d3ccip "LPTIM3/4/5"],
716 (Auto) Lptim4 [group clk: Lptim345],
717 (Auto) Lptim5 [group clk: Lptim345],
718
719 (Auto) I2c4 [kernel clk: I2c4 d3ccip "I2C4"],
720 (Auto) Spi6 [kernel clk: Spi6(Variant) d3ccip "SPI6"],
721 (Auto) Sai4 [kernel clk_a: Sai4A(Variant) d3ccip
722 "Sub-Block A of SAI4"]
723 [kernel clk_b: Sai4B(Variant) d3ccip
724 "Sub-Block B of SAI4"]
725 ];
726 #[cfg(feature = "rm0455")]
727 APB4, "" => [
728 (Auto) Dac2,
729
730 (Auto) Lptim2 [kernel clk: Lptim2(Variant) srdccip "LPTIM2"],
731 (Auto) Lptim3,// TODO [group clk: Lptim3(Variant) srdccip "LPTIM3"],
732
733 (Auto) I2c4 [kernel clk: I2c4 srdccip "I2C4"],
734 (Auto) Spi6 [kernel clk: Spi6(Variant) srdccip "SPI6"]
735 ];
736}