1pub use crate::chip::config::ccm::*;
7
8pub mod ahb_clk;
9pub mod analog;
10pub mod clock_gate;
11pub mod output_source;
12
13use crate::ral;
14
15pub use crate::common::ccm::XTAL_OSCILLATOR_HZ;
16
17pub mod perclk_clk {
50 use crate::ral::{self, ccm::CCM};
51
52 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
54 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
55 #[repr(u32)]
56 pub enum Selection {
57 Ipg = 0,
59 Oscillator = 1,
61 }
62
63 #[inline(always)]
65 pub fn set_selection(ccm: &mut CCM, selection: Selection) {
66 ral::modify_reg!(ral::ccm, ccm, CSCMR1, PERCLK_CLK_SEL: selection as u32);
67 }
68
69 #[inline(always)]
71 pub fn selection(ccm: &CCM) -> Selection {
72 if ral::read_reg!(ral::ccm, ccm, CSCMR1, PERCLK_CLK_SEL == 1) {
73 Selection::Oscillator
74 } else {
75 Selection::Ipg
76 }
77 }
78
79 pub const MIN_DIVIDER: u32 = 1;
81 pub const MAX_DIVIDER: u32 = 64;
83
84 #[inline(always)]
88 pub fn set_divider(ccm: &mut CCM, divider: u32) {
89 let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
90 ral::modify_reg!(ral::ccm, ccm, CSCMR1, PERCLK_PODF: podf);
91 }
92
93 #[inline(always)]
95 pub fn divider(ccm: &CCM) -> u32 {
96 ral::read_reg!(ral::ccm, ccm, CSCMR1, PERCLK_PODF) + 1
97 }
98}
99
100pub mod ipg_clk {
104 use crate::ral::{self, ccm::CCM};
105
106 #[inline(always)]
108 pub fn divider(ccm: &CCM) -> u32 {
109 ral::read_reg!(ral::ccm, ccm, CBCDR, IPG_PODF) + 1
110 }
111
112 pub const MIN_DIVIDER: u32 = 1;
114 pub const MAX_DIVIDER: u32 = 4;
116
117 #[inline(always)]
121 pub fn set_divider(ccm: &mut CCM, divider: u32) {
122 let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
123 ral::modify_reg!(ral::ccm, ccm, CBCDR, IPG_PODF: podf);
124 }
125}
126
127pub(crate) fn wait_handshake(ccm: &crate::ral::ccm::CCM) {
129 while crate::ral::read_reg!(crate::ral::ccm, ccm, CDHIPR) != 0 {}
130}
131
132#[cfg_attr(feature = "defmt", derive(defmt::Format))]
141#[derive(Debug, Clone, Copy, PartialEq, Eq)]
142#[repr(u32)]
143pub enum LowPowerMode {
144 RemainInRun = 0,
146 TransferToWait = 1,
148 TransferToStop = 2,
150}
151
152pub fn set_low_power_mode(ccm: &mut ral::ccm::CCM, mode: LowPowerMode) {
154 ral::modify_reg!(ral::ccm, ccm, CLPCR, LPM: mode as u32);
155}
156
157pub fn low_power_mode(ccm: &ral::ccm::CCM) -> LowPowerMode {
159 match ral::read_reg!(ral::ccm, ccm, CLPCR, LPM) {
160 0 => LowPowerMode::RemainInRun,
161 1 => LowPowerMode::TransferToWait,
162 2 => LowPowerMode::TransferToStop,
163 _ => unreachable!(),
164 }
165}
166
167pub mod uart_clk {
198 use crate::ral::{self, ccm::CCM};
199
200 #[inline(always)]
202 pub fn divider(ccm: &CCM) -> u32 {
203 ral::read_reg!(ral::ccm, ccm, CSCDR1, UART_CLK_PODF) + 1
204 }
205
206 pub const MIN_DIVIDER: u32 = 1;
208 pub const MAX_DIVIDER: u32 = 1 << 6;
210
211 #[inline(always)]
215 pub fn set_divider(ccm: &mut CCM, divider: u32) {
216 let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
217 ral::modify_reg!(ral::ccm, ccm, CSCDR1, UART_CLK_PODF: podf);
218 }
219
220 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
222 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
223 #[repr(u32)]
224 pub enum Selection {
225 Pll3Div6 = 0,
229 Oscillator = 1,
231 }
232
233 #[inline(always)]
235 pub fn selection(ccm: &CCM) -> Selection {
236 match ral::read_reg!(ral::ccm, ccm, CSCDR1, UART_CLK_SEL) {
237 0 => Selection::Pll3Div6,
238 1 => Selection::Oscillator,
239 _ => unreachable!(),
240 }
241 }
242
243 #[inline(always)]
245 pub fn set_selection(ccm: &mut CCM, selection: Selection) {
246 ral::modify_reg!(ral::ccm, ccm, CSCDR1, UART_CLK_SEL: selection as u32);
247 }
248}
249
250pub mod lpi2c_clk {
276 use crate::ral::{self, ccm::CCM};
277
278 #[inline(always)]
280 pub fn divider(ccm: &CCM) -> u32 {
281 ral::read_reg!(ral::ccm, ccm, CSCDR2, LPI2C_CLK_PODF) + 1
282 }
283
284 pub const MIN_DIVIDER: u32 = 1;
286 pub const MAX_DIVIDER: u32 = 64;
288
289 #[inline(always)]
293 pub fn set_divider(ccm: &mut CCM, divider: u32) {
294 let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
295 ral::modify_reg!(ral::ccm, ccm, CSCDR2, LPI2C_CLK_PODF: podf);
296 }
297
298 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
300 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
301 #[repr(u32)]
302 pub enum Selection {
303 Pll3Div8 = 0,
305 Oscillator = 1,
307 }
308
309 #[inline(always)]
311 pub fn selection(ccm: &CCM) -> Selection {
312 match ral::read_reg!(ral::ccm, ccm, CSCDR2, LPI2C_CLK_SEL) {
313 0 => Selection::Pll3Div8,
314 1 => Selection::Oscillator,
315 _ => unreachable!(),
316 }
317 }
318
319 #[inline(always)]
321 pub fn set_selection(ccm: &mut CCM, selection: Selection) {
322 ral::modify_reg!(ral::ccm, ccm, CSCDR2, LPI2C_CLK_SEL: selection as u32);
323 }
324}
325
326pub mod lpspi_clk {
354 use crate::ral::{self, ccm::CCM};
355
356 #[inline(always)]
358 pub fn divider(ccm: &CCM) -> u32 {
359 ral::read_reg!(ral::ccm, ccm, CBCMR, LPSPI_PODF) + 1
360 }
361
362 pub const MIN_DIVIDER: u32 = 1;
364 pub const MAX_DIVIDER: u32 = 8;
366
367 #[inline(always)]
371 pub fn set_divider(ccm: &mut CCM, divider: u32) {
372 let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
375 ral::modify_reg!(ral::ccm, ccm, CBCMR, LPSPI_PODF: podf);
376 }
377
378 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
380 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
381 #[repr(u32)]
382 pub enum Selection {
383 Pll3Pfd1 = 0,
385 Pll3Pfd0 = 1,
387 Pll2 = 2,
389 Pll2Pfd2 = 3,
391 }
392
393 #[inline(always)]
395 pub fn selection(ccm: &CCM) -> Selection {
396 match ral::read_reg!(ral::ccm, ccm, CBCMR, LPSPI_CLK_SEL) {
397 0 => Selection::Pll3Pfd1,
398 1 => Selection::Pll3Pfd0,
399 2 => Selection::Pll2,
400 3 => Selection::Pll2Pfd2,
401 _ => unreachable!(),
402 }
403 }
404
405 #[inline(always)]
407 pub fn set_selection(ccm: &mut CCM, selection: Selection) {
408 ral::modify_reg!(ral::ccm, ccm, CBCMR, LPSPI_CLK_SEL: selection as u32);
409 }
410}
411
412macro_rules! ccm_flexio {
413 (
414 $name:ident, $desc:literal,
415 divider: ($divider_reg:ident, $divider_field:ident),
416 predivider: ($predivider_reg:ident, $predivider_field:ident),
417 selection: ($sel_reg:ident, $sel_field:ident)$(,)?
418 ) => {
419 #[doc = concat!($desc, " clock root.")]
420 pub mod $name {
421 use crate::ral::{self, ccm::CCM};
422
423 #[doc = concat!("Returns the ", $desc, " clock divider.")]
424 #[inline(always)]
425 pub fn divider(ccm: &CCM) -> u32 {
426 ral::read_reg!(ral::ccm, ccm, $divider_reg, $divider_field) + 1
427 }
428
429 #[doc = concat!("The smallest ", $desc, " clock divider.")]
430 pub const MIN_DIVIDER: u32 = 1;
431 #[doc = concat!("The largest ", $desc, " clock divider.")]
432 pub const MAX_DIVIDER: u32 = 8;
433
434 #[doc = concat!("Set the ", $desc, " clock divider.")]
435 #[inline(always)]
438 pub fn set_divider(ccm: &mut CCM, divider: u32) {
439 let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
442 ral::modify_reg!(ral::ccm, ccm, $divider_reg, $divider_field: podf);
443 }
444
445 #[doc = concat!("Returns the ", $desc, " clock predivider.")]
446 #[inline(always)]
447 pub fn predivider(ccm: &CCM) -> u32 {
448 ral::read_reg!(ral::ccm, ccm, $predivider_reg, $predivider_field) + 1
449 }
450
451 #[doc = concat!("The smallest ", $desc, " clock predivider.")]
452 pub const MIN_PREDIVIDER: u32 = 1;
453 #[doc = concat!("The largest ", $desc, " clock predivider.")]
454 pub const MAX_PREDIVIDER: u32 = 8;
455
456 #[doc = concat!("Set the ", $desc, " clock predivider.")]
457 #[inline(always)]
460 pub fn set_predivider(ccm: &mut CCM, predivider: u32) {
461 let podf = predivider.clamp(MIN_PREDIVIDER, MAX_PREDIVIDER) - 1;
462 ral::modify_reg!(ral::ccm, ccm, $predivider_reg, $predivider_field: podf);
463 }
464
465 #[doc = concat!($desc, " clock selections.")]
466 #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
467 #[repr(u32)]
468 pub enum Selection {
469 Pll4 = 0,
471 Pll3Pfd2 = 1,
473
474 #[cfg(any(feature = "imxrt1060", feature = "imxrt1064"))]
475 Pll5 = 2,
477 #[cfg(feature = "imxrt1010")]
478 Pll2 = 2,
480
481 Pll3SwClk = 3,
487 }
488
489 #[doc = concat!("Returns the ", $desc, " clock selections.")]
490 #[inline(always)]
491 pub fn selection(ccm: &CCM) -> Selection {
492 match ral::read_reg!(ral::ccm, ccm, $sel_reg, $sel_field) {
493 0 => Selection::Pll4,
494 1 => Selection::Pll3Pfd2,
495 #[cfg(any(feature = "imxrt1060", feature = "imxrt1064"))]
496 2 => Selection::Pll5,
497 #[cfg(feature = "imxrt1010")]
498 2 => Selection::Pll2,
499 3 => Selection::Pll3SwClk,
500 _ => unreachable!(),
501 }
502 }
503
504 #[doc = concat!("Set the ", $desc, " clock selections.")]
505 #[inline(always)]
506 pub fn set_selection(ccm: &mut CCM, selection: Selection) {
507 ral::modify_reg!(ral::ccm, ccm, $sel_reg, $sel_field: selection as u32);
508 }
509 }
510 };
511}
512
513pub mod sai_clk {
542 use crate::ral::{self, ccm::CCM};
543
544 #[inline(always)]
546 pub fn predivider<const N: u8>(ccm: &CCM) -> u32
547 where
548 ral::sai::Instance<N>: ral::Valid,
549 {
550 1 + (match N {
551 1 => ral::read_reg!(ral::ccm, ccm, CS1CDR, SAI1_CLK_PRED),
552 #[cfg(not(feature = "imxrt1010"))]
553 2 => ral::read_reg!(ral::ccm, ccm, CS2CDR, SAI2_CLK_PRED),
554 3 => ral::read_reg!(ral::ccm, ccm, CS1CDR, SAI3_CLK_PRED),
555 _ => unreachable!(),
556 })
557 }
558
559 pub const MIN_PREDIVIDER: u32 = 1;
561 pub const MAX_PREDIVIDER: u32 = 8;
563
564 #[inline(always)]
568 pub fn set_predivider<const N: u8>(ccm: &mut CCM, predivider: u32)
569 where
570 ral::sai::Instance<N>: ral::Valid,
571 {
572 let pred = predivider.clamp(MIN_PREDIVIDER, MAX_PREDIVIDER) - 1;
573 match N {
574 1 => ral::modify_reg!(ral::ccm, ccm, CS1CDR, SAI1_CLK_PRED: pred),
575 #[cfg(not(feature = "imxrt1010"))]
576 2 => ral::modify_reg!(ral::ccm, ccm, CS2CDR, SAI2_CLK_PRED: pred),
577 3 => ral::modify_reg!(ral::ccm, ccm, CS1CDR, SAI3_CLK_PRED: pred),
578 _ => unreachable!(),
579 }
580 }
581 #[inline(always)]
583 pub fn divider<const N: u8>(ccm: &CCM) -> u32
584 where
585 ral::sai::Instance<N>: ral::Valid,
586 {
587 1 + (match N {
588 1 => ral::read_reg!(ral::ccm, ccm, CS1CDR, SAI1_CLK_PODF),
589 #[cfg(not(feature = "imxrt1010"))]
590 2 => ral::read_reg!(ral::ccm, ccm, CS2CDR, SAI2_CLK_PODF),
591 3 => ral::read_reg!(ral::ccm, ccm, CS1CDR, SAI3_CLK_PODF),
592 _ => unreachable!(),
593 })
594 }
595
596 pub const MIN_DIVIDER: u32 = 1;
598 pub const MAX_DIVIDER: u32 = 64;
600
601 #[inline(always)]
605 pub fn set_divider<const N: u8>(ccm: &mut CCM, divider: u32)
606 where
607 ral::sai::Instance<N>: ral::Valid,
608 {
609 let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
610 match N {
611 1 => ral::modify_reg!(ral::ccm, ccm, CS1CDR, SAI1_CLK_PODF: podf),
612 #[cfg(not(feature = "imxrt1010"))]
613 2 => ral::modify_reg!(ral::ccm, ccm, CS2CDR, SAI2_CLK_PODF: podf),
614 3 => ral::modify_reg!(ral::ccm, ccm, CS1CDR, SAI3_CLK_PODF: podf),
615 _ => unreachable!(),
616 }
617 }
618
619 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
621 #[repr(u32)]
622 pub enum Selection {
623 Pll3Pfd2 = 0,
625 #[cfg(not(feature = "imxrt1010"))]
626 Pll5 = 1,
628 #[cfg(feature = "imxrt1010")]
629 Pll3SwClk = 1,
631 Pll4 = 2,
633 Reserved = 3,
635 }
636
637 #[inline(always)]
639 pub fn selection<const N: u8>(ccm: &CCM) -> Selection
640 where
641 ral::sai::Instance<N>: ral::Valid,
642 {
643 let sel: u32 = match N {
644 1 => ral::read_reg!(ral::ccm, ccm, CSCMR1, SAI1_CLK_SEL),
645 #[cfg(not(feature = "imxrt1010"))]
646 2 => ral::read_reg!(ral::ccm, ccm, CSCMR1, SAI2_CLK_SEL),
647 3 => ral::read_reg!(ral::ccm, ccm, CSCMR1, SAI3_CLK_SEL),
648 _ => unreachable!(),
649 };
650 match sel {
651 0 => Selection::Pll3Pfd2,
652 #[cfg(not(feature = "imxrt1010"))]
653 1 => Selection::Pll5,
654 #[cfg(feature = "imxrt1010")]
655 1 => Selection::Pll3SwClk,
656 2 => Selection::Pll4,
657 _ => unreachable!(),
658 }
659 }
660
661 #[inline(always)]
663 pub fn set_selection<const N: u8>(ccm: &mut CCM, selection: Selection)
664 where
665 ral::sai::Instance<N>: ral::Valid,
666 {
667 match N {
668 1 => ral::modify_reg!(ral::ccm, ccm, CSCMR1, SAI1_CLK_SEL: selection as u32),
669 #[cfg(not(feature = "imxrt1010"))]
670 2 => ral::modify_reg!(ral::ccm, ccm, CSCMR1, SAI2_CLK_SEL: selection as u32),
671 3 => ral::modify_reg!(ral::ccm, ccm, CSCMR1, SAI3_CLK_SEL: selection as u32),
672 _ => unreachable!(),
673 }
674 }
675}