Skip to content

Commit

Permalink
Add 10xx FlexIO CCM configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
Florob authored and mciantyre committed Nov 25, 2023
1 parent e443ce9 commit 26b1b79
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/chip/imxrt10xx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! Shared modules may rely on configurations from the `config` module.

pub mod adc;
#[macro_use]
pub mod ccm;
pub mod dcdc;
#[path = "dma.rs"]
Expand Down
101 changes: 101 additions & 0 deletions src/chip/imxrt10xx/ccm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,104 @@ pub mod lpspi_clk {
ral::modify_reg!(ral::ccm, ccm, CBCMR, LPSPI_CLK_SEL: selection as u32);
}
}

macro_rules! ccm_flexio {
(
$name:ident, $desc:literal,
divider: ($divider_reg:ident, $divider_field:ident),
predivider: ($predivider_reg:ident, $predivider_field:ident),
selection: ($sel_reg:ident, $sel_field:ident)$(,)?
) => {
#[doc = concat!($desc, " clock root.")]
pub mod $name {
use crate::ral::{self, ccm::CCM};

#[doc = concat!("Returns the ", $desc, " clock divider.")]
#[inline(always)]
pub fn divider(ccm: &CCM) -> u32 {
ral::read_reg!(ral::ccm, ccm, $divider_reg, $divider_field) + 1
}

#[doc = concat!("The smallest ", $desc, " clock divider.")]
pub const MIN_DIVIDER: u32 = 1;
#[doc = concat!("The largest ", $desc, " clock divider.")]
pub const MAX_DIVIDER: u32 = 8;

#[doc = concat!("Set the ", $desc, " clock divider.")]
///
/// The implementation clamps `divider` between [`MIN_DIVIDER`] and [`MAX_DIVIDER`].
#[inline(always)]
pub fn set_divider(ccm: &mut CCM, divider: u32) {
// 1010 MCUs support an extra bit in this field, so this
// could be a max of 16 for those chips.
let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
ral::modify_reg!(ral::ccm, ccm, $divider_reg, $divider_field: podf);
}

#[doc = concat!("Returns the ", $desc, " clock predivider.")]
#[inline(always)]
pub fn predivider(ccm: &CCM) -> u32 {
ral::read_reg!(ral::ccm, ccm, $predivider_reg, $predivider_field) + 1
}

#[doc = concat!("The smallest ", $desc, " clock predivider.")]
pub const MIN_PREDIVIDER: u32 = 1;
#[doc = concat!("The largest ", $desc, " clock predivider.")]
pub const MAX_PREDIVIDER: u32 = 8;

#[doc = concat!("Set the ", $desc, " clock predivider.")]
///
/// The implementation clamps `predivider` between [`MIN_PREDIVIDER`] and [`MAX_PREDIVIDER`].
#[inline(always)]
pub fn set_predivider(ccm: &mut CCM, predivider: u32) {
let podf = predivider.clamp(MIN_PREDIVIDER, MAX_PREDIVIDER) - 1;
ral::modify_reg!(ral::ccm, ccm, $predivider_reg, $predivider_field: podf);
}

#[doc = concat!($desc, " clock selections.")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum Selection {
/// Derive from PLL4.
Pll4 = 0,
/// Derive from PLL3_PFD2.
Pll3Pfd2 = 1,

#[cfg(any(feature = "imxrt1060", feature = "imxrt1064"))]
/// Derive from PLL5.
Pll5 = 2,
#[cfg(feature = "imxrt1010")]
/// Derive from PLL2.
Pll2 = 2,

//
// '2' reserved on 1020.
//

/// Derive from pll3_sw_clk.
Pll3SwClk = 3,
}

#[doc = concat!("Returns the ", $desc, " clock selections.")]
#[inline(always)]
pub fn selection(ccm: &CCM) -> Selection {
match ral::read_reg!(ral::ccm, ccm, $sel_reg, $sel_field) {
0 => Selection::Pll4,
1 => Selection::Pll3Pfd2,
#[cfg(any(feature = "imxrt1060", feature = "imxrt1064"))]
2 => Selection::Pll5,
#[cfg(feature = "imxrt1010")]
2 => Selection::Pll2,
3 => Selection::Pll3SwClk,
_ => unreachable!(),
}
}

#[doc = concat!("Set the ", $desc, " clock selections.")]
#[inline(always)]
pub fn set_selection(ccm: &mut CCM, selection: Selection) {
ral::modify_reg!(ral::ccm, ccm, $sel_reg, $sel_field: selection as u32);
}
}
};
}
7 changes: 7 additions & 0 deletions src/chip/imxrt10xx/imxrt1010.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,12 @@ pub(crate) mod ccm {
pub const TracClk: Clko2Selection = Clko2Selection::TraceClk;
}
}

ccm_flexio!(
flexio1_clk, "FLEXIO1",
divider: (CS1CDR, FLEXIO1_CLK_PODF),
predivider: (CS1CDR, FLEXIO1_CLK_PRED),
selection: (CSCMR2, FLEXIO1_CLK_SEL),
);
}
pub(crate) const DMA_CHANNEL_COUNT: usize = 16;
7 changes: 7 additions & 0 deletions src/chip/imxrt10xx/imxrt1020.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ pub(crate) mod ccm {
Spdif0Clk = 0b11101,
}
}

ccm_flexio!(
flexio1_clk, "FLEXIO1",
divider: (CS1CDR, FLEXIO1_CLK_PODF),
predivider: (CS1CDR, FLEXIO1_CLK_PRED),
selection: (CSCMR2, FLEXIO1_CLK_SEL),
);
}

pub(crate) const DMA_CHANNEL_COUNT: usize = 32;
14 changes: 14 additions & 0 deletions src/chip/imxrt10xx/imxrt1060.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ pub(crate) mod ccm {

pub enum Clko2Selection {}
}

ccm_flexio!(
flexio1_clk, "FLEXIO1",
divider: (CDCDR, FLEXIO1_CLK_PODF),
predivider: (CDCDR, FLEXIO1_CLK_PRED),
selection: (CDCDR, FLEXIO1_CLK_SEL),
);

ccm_flexio!(
flexio2_clk, "FLEXIO2",
divider: (CS1CDR, FLEXIO2_CLK_PODF),
predivider: (CS1CDR, FLEXIO2_CLK_PRED),
selection: (CSCMR2, FLEXIO2_CLK_SEL),
);
}

pub(crate) const DMA_CHANNEL_COUNT: usize = 32;

0 comments on commit 26b1b79

Please sign in to comment.