Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 10xx FlexIO CCM configuration #140

Merged
merged 1 commit into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Loading