diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs index c94894eda7..856a2e9633 100644 --- a/embassy-mspm0/build.rs +++ b/embassy-mspm0/build.rs @@ -334,6 +334,13 @@ fn get_singletons(cfgs: &mut common::CfgSet) -> Vec { } } + // TODO: Generate this more generally for other signals (e.g. FCC_IN, HFCLKIN, HFXIN, HFXOUT, etc) + // Generate CLK_OUT manually for SYSCTL. + singletons.push(Singleton { + name: String::from("CLK_OUT"), + cfg: None, + }); + // DMA channels get their own singletons for dma_channel in METADATA.dma_channels.iter() { singletons.push(Singleton { @@ -721,6 +728,7 @@ fn generate_pin_trait_impls() -> TokenStream { } ("i2c", "SDA") => Some(quote! { impl_i2c_sda_pin!(#peri, #pin_name, #pf); }), ("i2c", "SCL") => Some(quote! { impl_i2c_scl_pin!(#peri, #pin_name, #pf); }), + ("sysctl", "CLK_OUT") => Some(quote! { impl_clk_out_pin!(#pin_name, #pf); }), ("tim", "CCP0") => Some(quote! { impl_tim_pin!(#peri, #pin_name, #pf, Ch0); }), ("tim", "CCP1") => Some(quote! { impl_tim_pin!(#peri, #pin_name, #pf, Ch1); }), ("tim", "CCP2") => Some(quote! { impl_tim_pin!(#peri, #pin_name, #pf, Ch2); }), diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index 8004bd15f0..76bcee6fa1 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs @@ -22,6 +22,7 @@ pub mod i2c; pub mod i2c_target; #[cfg(any(mspm0g150x, mspm0g151x, mspm0g350x, mspm0g351x))] pub mod mathacl; +pub mod sysctl; pub mod tim; #[cfg(any(mspm0g150x, mspm0g151x, mspm0g350x, mspm0g351x, mspm0l122x, mspm0l222x))] pub mod trng; diff --git a/embassy-mspm0/src/sysctl/c1103_1104.rs b/embassy-mspm0/src/sysctl/c1103_1104.rs new file mode 100644 index 0000000000..a841bf4875 --- /dev/null +++ b/embassy-mspm0/src/sysctl/c1103_1104.rs @@ -0,0 +1,58 @@ +//! SYSCTL configuration for MSPM0C1103/4 SYSCTL. + +use mspm0_metapac::sysctl::vals; + +use crate::sysctl::{ClkOutDiv, div_to_pac}; + +/// Source and configuration for CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutSource { + /// Use SYSOSC as the source. + /// + /// The divider is optional for this clock source. + Sysosc(Option), + + /// Use ULPCLK as the source. + /// + /// The divider is required for this clock source. + UlpClk(ClkOutDiv), + + /// Use LFCLK as the source. + /// + /// The divider is optional for this clock source. + LfClk(Option), + + /// Use MFPCLK as the source. + /// + /// The divider is required for this clock source. + MfpClk(ClkOutDiv), + + /// Use HFCLK as the source. + /// + /// The divider is optional for this clock source. + Hfclk(Option), +} + +impl ClkOutSource { + pub(super) fn convert_div(self) -> (bool, vals::Exclkdivval) { + match self { + ClkOutSource::Sysosc(div) => div_to_pac(div), + ClkOutSource::UlpClk(div) => div_to_pac(Some(div)), + ClkOutSource::LfClk(div) => div_to_pac(div), + ClkOutSource::MfpClk(div) => div_to_pac(Some(div)), + ClkOutSource::Hfclk(div) => div_to_pac(div), + } + } + + pub(super) fn convert_src(self) -> vals::Exclksrc { + match self { + ClkOutSource::Sysosc(_) => vals::Exclksrc::SYSOSC, + ClkOutSource::UlpClk(_) => vals::Exclksrc::ULPCLK, + ClkOutSource::LfClk(_) => vals::Exclksrc::LFCLK, + // FIXME: Wrong name from SVD + ClkOutSource::MfpClk(_) => vals::Exclksrc::MFCLK, + ClkOutSource::Hfclk(_) => vals::Exclksrc::HFCLK, + } + } +} diff --git a/embassy-mspm0/src/sysctl/c1105_1106.rs b/embassy-mspm0/src/sysctl/c1105_1106.rs new file mode 100644 index 0000000000..47e71c405a --- /dev/null +++ b/embassy-mspm0/src/sysctl/c1105_1106.rs @@ -0,0 +1,58 @@ +//! SYSCTL configuration for MSPM0C1105/6 SYSCTL. + +use mspm0_metapac::sysctl::vals; + +use crate::sysctl::{ClkOutDiv, div_to_pac}; + +/// Source and configuration for CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutSource { + /// Use SYSOSC as the source. + /// + /// The divider is optional for this clock source. + Sysosc(Option), + + /// Use ULPCLK as the source. + /// + /// The divider is required for this clock source. + UlpClk(ClkOutDiv), + + /// Use LFCLK as the source. + /// + /// The divider is optional for this clock source. + LfClk(Option), + + /// Use MFPCLK as the source. + /// + /// The divider is required for this clock source. + MfpClk(ClkOutDiv), + + /// Use HFCLK as the source. + /// + /// The divider is optional for this clock source. + Hfclk(Option), +} + +impl ClkOutSource { + pub(super) fn convert_div(self) -> (bool, vals::Exclkdivval) { + match self { + ClkOutSource::Sysosc(div) => div_to_pac(div), + ClkOutSource::UlpClk(div) => div_to_pac(Some(div)), + ClkOutSource::LfClk(div) => div_to_pac(div), + ClkOutSource::MfpClk(div) => div_to_pac(Some(div)), + ClkOutSource::Hfclk(div) => div_to_pac(div), + } + } + + pub(super) fn convert_src(self) -> vals::Exclksrc { + match self { + ClkOutSource::Sysosc(_) => vals::Exclksrc::SYSOSC, + ClkOutSource::UlpClk(_) => vals::Exclksrc::ULPCLK, + ClkOutSource::LfClk(_) => vals::Exclksrc::LFCLK, + // FIXME: Wrong name from SVD + ClkOutSource::MfpClk(_) => vals::Exclksrc::MFCLK, + ClkOutSource::Hfclk(_) => vals::Exclksrc::HFCLK, + } + } +} diff --git a/embassy-mspm0/src/sysctl/g110x_150x_310x_350x.rs b/embassy-mspm0/src/sysctl/g110x_150x_310x_350x.rs new file mode 100644 index 0000000000..cf3bf55735 --- /dev/null +++ b/embassy-mspm0/src/sysctl/g110x_150x_310x_350x.rs @@ -0,0 +1,64 @@ +//! SYSCTL configuration for G110x, G150x, G310x and G350x. + +use mspm0_metapac::sysctl::vals; + +use crate::sysctl::{ClkOutDiv, div_to_pac}; + +/// Source and configuration for CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutSource { + /// Use SYSOSC as the source. + /// + /// The divider is optional for this clock source. + Sysosc(Option), + + /// Use ULPCLK as the source. + /// + /// The divider is required for this clock source. + UlpClk(ClkOutDiv), + + /// Use LFCLK as the source. + /// + /// The divider is optional for this clock source. + LfClk(Option), + + /// Use MFPCLK as the source. + /// + /// The divider is required for this clock source. + MfpClk(ClkOutDiv), + + /// Use HFCLK as the source. + /// + /// The divider is optional for this clock source. + Hfclk(Option), + + /// Use SYSPLLCLK1 as the source. + /// + /// The divider is optional for this clock source. + SysPllClk1(Option), +} + +impl ClkOutSource { + pub(super) fn convert_div(self) -> (bool, vals::Exclkdivval) { + match self { + ClkOutSource::Sysosc(div) => div_to_pac(div), + ClkOutSource::UlpClk(div) => div_to_pac(Some(div)), + ClkOutSource::LfClk(div) => div_to_pac(div), + ClkOutSource::MfpClk(div) => div_to_pac(Some(div)), + ClkOutSource::Hfclk(div) => div_to_pac(div), + ClkOutSource::SysPllClk1(div) => div_to_pac(div), + } + } + + pub(super) fn convert_src(self) -> vals::Exclksrc { + match self { + ClkOutSource::Sysosc(_) => vals::Exclksrc::SYSOSC, + ClkOutSource::UlpClk(_) => vals::Exclksrc::ULPCLK, + ClkOutSource::LfClk(_) => vals::Exclksrc::LFCLK, + ClkOutSource::MfpClk(_) => vals::Exclksrc::MFPCLK, + ClkOutSource::Hfclk(_) => vals::Exclksrc::HFCLK, + ClkOutSource::SysPllClk1(_) => vals::Exclksrc::SYSPLLOUT1, + } + } +} diff --git a/embassy-mspm0/src/sysctl/g151x_351x.rs b/embassy-mspm0/src/sysctl/g151x_351x.rs new file mode 100644 index 0000000000..5f078af89a --- /dev/null +++ b/embassy-mspm0/src/sysctl/g151x_351x.rs @@ -0,0 +1,64 @@ +//! SYSCTL configuration for G151x and G351x. + +use mspm0_metapac::sysctl::vals; + +use crate::sysctl::{ClkOutDiv, div_to_pac}; + +/// Source and configuration for CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutSource { + /// Use SYSOSC as the source. + /// + /// The divider is optional for this clock source. + Sysosc(Option), + + /// Use ULPCLK as the source. + /// + /// The divider is required for this clock source. + UlpClk(ClkOutDiv), + + /// Use LFCLK as the source. + /// + /// The divider is optional for this clock source. + LfClk(Option), + + /// Use MFPCLK as the source. + /// + /// The divider is required for this clock source. + MfpClk(ClkOutDiv), + + /// Use HFCLK as the source. + /// + /// The divider is optional for this clock source. + Hfclk(Option), + + /// Use SYSPLLCLK1 as the source. + /// + /// The divider is optional for this clock source. + SysPllClk1(Option), +} + +impl ClkOutSource { + pub(super) fn convert_div(self) -> (bool, vals::Exclkdivval) { + match self { + ClkOutSource::Sysosc(div) => div_to_pac(div), + ClkOutSource::UlpClk(div) => div_to_pac(Some(div)), + ClkOutSource::LfClk(div) => div_to_pac(div), + ClkOutSource::MfpClk(div) => div_to_pac(Some(div)), + ClkOutSource::Hfclk(div) => div_to_pac(div), + ClkOutSource::SysPllClk1(div) => div_to_pac(div), + } + } + + pub(super) fn convert_src(self) -> vals::Exclksrc { + match self { + ClkOutSource::Sysosc(_) => vals::Exclksrc::SYSOSC, + ClkOutSource::UlpClk(_) => vals::Exclksrc::ULPCLK, + ClkOutSource::LfClk(_) => vals::Exclksrc::LFCLK, + ClkOutSource::MfpClk(_) => vals::Exclksrc::MFPCLK, + ClkOutSource::Hfclk(_) => vals::Exclksrc::HFCLK, + ClkOutSource::SysPllClk1(_) => vals::Exclksrc::SYSPLLOUT1, + } + } +} diff --git a/embassy-mspm0/src/sysctl/g511x_518x.rs b/embassy-mspm0/src/sysctl/g511x_518x.rs new file mode 100644 index 0000000000..eeb2716641 --- /dev/null +++ b/embassy-mspm0/src/sysctl/g511x_518x.rs @@ -0,0 +1,72 @@ +//! SYSCTL configuration for G518x. + +use mspm0_metapac::sysctl::vals; + +use crate::sysctl::{ClkOutDiv, div_to_pac}; + +/// Source and configuration for CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutSource { + /// Use SYSOSC as the source. + /// + /// The divider is optional for this clock source. + Sysosc(Option), + + /// Use ULPCLK as the source. + /// + /// The divider is required for this clock source. + UlpClk(ClkOutDiv), + + /// Use LFCLK as the source. + /// + /// The divider is optional for this clock source. + LfClk(Option), + + /// Use MFPCLK as the source. + /// + /// The divider is required for this clock source. + MfpClk(ClkOutDiv), + + /// Use HFCLK as the source. + /// + /// The divider is optional for this clock source. + Hfclk(Option), + + /// Use SYSPLLCLK1 as the source. + /// + /// The divider is optional for this clock source. + SysPllClk1(Option), + + /// Use USBFLL as the source. + /// + /// The divider is required for this clock source. + UsbFll(ClkOutDiv), +} + +impl ClkOutSource { + pub(super) fn convert_div(self) -> (bool, vals::Exclkdivval) { + match self { + ClkOutSource::Sysosc(div) => div_to_pac(div), + ClkOutSource::UlpClk(div) => div_to_pac(Some(div)), + ClkOutSource::LfClk(div) => div_to_pac(div), + ClkOutSource::MfpClk(div) => div_to_pac(Some(div)), + ClkOutSource::Hfclk(div) => div_to_pac(div), + ClkOutSource::SysPllClk1(div) => div_to_pac(div), + ClkOutSource::UsbFll(div) => div_to_pac(Some(div)), + } + } + + pub(super) fn convert_src(self) -> vals::Exclksrc { + match self { + ClkOutSource::Sysosc(_) => vals::Exclksrc::SYSOSC, + ClkOutSource::UlpClk(_) => vals::Exclksrc::ULPCLK, + ClkOutSource::LfClk(_) => vals::Exclksrc::LFCLK, + ClkOutSource::MfpClk(_) => vals::Exclksrc::MFPCLK, + ClkOutSource::Hfclk(_) => vals::Exclksrc::HFCLK, + ClkOutSource::SysPllClk1(_) => vals::Exclksrc::SYSPLLOUT1, + // FIXME: Update SVD to define _RESERVED_6 as USBFLL + ClkOutSource::UsbFll(_) => vals::Exclksrc::_RESERVED_6, + } + } +} diff --git a/embassy-mspm0/src/sysctl/h321x.rs b/embassy-mspm0/src/sysctl/h321x.rs new file mode 100644 index 0000000000..4a4ca72ae7 --- /dev/null +++ b/embassy-mspm0/src/sysctl/h321x.rs @@ -0,0 +1,58 @@ +//! SYSCTL configuration for MSPM0H3215/6 SYSCTL. + +use mspm0_metapac::sysctl::vals; + +use crate::sysctl::{ClkOutDiv, div_to_pac}; + +/// Source and configuration for CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutSource { + /// Use SYSOSC as the source. + /// + /// The divider is optional for this clock source. + Sysosc(Option), + + /// Use ULPCLK as the source. + /// + /// The divider is required for this clock source. + UlpClk(ClkOutDiv), + + /// Use LFCLK as the source. + /// + /// The divider is optional for this clock source. + LfClk(Option), + + /// Use MFPCLK as the source. + /// + /// The divider is required for this clock source. + MfpClk(ClkOutDiv), + + /// Use HFCLK as the source. + /// + /// The divider is optional for this clock source. + Hfclk(Option), +} + +impl ClkOutSource { + pub(super) fn convert_div(self) -> (bool, vals::Exclkdivval) { + match self { + ClkOutSource::Sysosc(div) => div_to_pac(div), + ClkOutSource::UlpClk(div) => div_to_pac(Some(div)), + ClkOutSource::LfClk(div) => div_to_pac(div), + ClkOutSource::MfpClk(div) => div_to_pac(Some(div)), + ClkOutSource::Hfclk(div) => div_to_pac(div), + } + } + + pub(super) fn convert_src(self) -> vals::Exclksrc { + match self { + ClkOutSource::Sysosc(_) => vals::Exclksrc::SYSOSC, + ClkOutSource::UlpClk(_) => vals::Exclksrc::ULPCLK, + ClkOutSource::LfClk(_) => vals::Exclksrc::LFCLK, + // FIXME: Wrong name from SVD + ClkOutSource::MfpClk(_) => vals::Exclksrc::MFPCLK, + ClkOutSource::Hfclk(_) => vals::Exclksrc::HFCLK, + } + } +} diff --git a/embassy-mspm0/src/sysctl/l_typea.rs b/embassy-mspm0/src/sysctl/l_typea.rs new file mode 100644 index 0000000000..e52b21550e --- /dev/null +++ b/embassy-mspm0/src/sysctl/l_typea.rs @@ -0,0 +1,50 @@ +//! SYSCTL configuration for TYPE A (L111x, L130x, L134x) L-series SYSCTL + +use mspm0_metapac::sysctl::vals; + +use crate::sysctl::{ClkOutDiv, div_to_pac}; + +/// Source and configuration for CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutSource { + /// Use SYSOSC as the source. + /// + /// The divider is optional for this clock source. + Sysosc(Option), + + /// Use ULPCLK as the source. + /// + /// The divider is required for this clock source. + UlpClk(ClkOutDiv), + + /// Use LFCLK as the source. + /// + /// The divider is optional for this clock source. + LfClk(Option), + + /// Use MFPCLK as the source. + /// + /// The divider is required for this clock source. + MfpClk(ClkOutDiv), +} + +impl ClkOutSource { + pub(super) fn convert_div(self) -> (bool, vals::Exclkdivval) { + match self { + ClkOutSource::Sysosc(div) => div_to_pac(div), + ClkOutSource::UlpClk(div) => div_to_pac(Some(div)), + ClkOutSource::LfClk(div) => div_to_pac(div), + ClkOutSource::MfpClk(div) => div_to_pac(Some(div)), + } + } + + pub(super) fn convert_src(self) -> vals::Exclksrc { + match self { + ClkOutSource::Sysosc(_) => vals::Exclksrc::SYSOSC, + ClkOutSource::UlpClk(_) => vals::Exclksrc::ULPCLK, + ClkOutSource::LfClk(_) => vals::Exclksrc::LFCLK, + ClkOutSource::MfpClk(_) => vals::Exclksrc::MFPCLK, + } + } +} diff --git a/embassy-mspm0/src/sysctl/l_typeb.rs b/embassy-mspm0/src/sysctl/l_typeb.rs new file mode 100644 index 0000000000..caf35d483d --- /dev/null +++ b/embassy-mspm0/src/sysctl/l_typeb.rs @@ -0,0 +1,57 @@ +//! SYSCTL configuration for TYPE B (L122x, L222x) L-series SYSCTL. + +use mspm0_metapac::sysctl::vals; + +use crate::sysctl::{ClkOutDiv, div_to_pac}; + +/// Source and configuration for CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutSource { + /// Use SYSOSC as the source. + /// + /// The divider is optional for this clock source. + Sysosc(Option), + + /// Use ULPCLK as the source. + /// + /// The divider is required for this clock source. + UlpClk(ClkOutDiv), + + /// Use LFCLK as the source. + /// + /// The divider is optional for this clock source. + LfClk(Option), + + /// Use MFPCLK as the source. + /// + /// The divider is required for this clock source. + MfpClk(ClkOutDiv), + + /// Use HFCLK as the source. + /// + /// The divider is optional for this clock source. + Hfclk(Option), +} + +impl ClkOutSource { + pub(super) fn convert_div(self) -> (bool, vals::Exclkdivval) { + match self { + ClkOutSource::Sysosc(div) => div_to_pac(div), + ClkOutSource::UlpClk(div) => div_to_pac(Some(div)), + ClkOutSource::LfClk(div) => div_to_pac(div), + ClkOutSource::MfpClk(div) => div_to_pac(Some(div)), + ClkOutSource::Hfclk(div) => div_to_pac(div), + } + } + + pub(super) fn convert_src(self) -> vals::Exclksrc { + match self { + ClkOutSource::Sysosc(_) => vals::Exclksrc::SYSOSC, + ClkOutSource::UlpClk(_) => vals::Exclksrc::ULPCLK, + ClkOutSource::LfClk(_) => vals::Exclksrc::LFCLK, + ClkOutSource::MfpClk(_) => vals::Exclksrc::MFPCLK, + ClkOutSource::Hfclk(_) => vals::Exclksrc::HFCLK, + } + } +} diff --git a/embassy-mspm0/src/sysctl/mod.rs b/embassy-mspm0/src/sysctl/mod.rs new file mode 100644 index 0000000000..c8d4588ba0 --- /dev/null +++ b/embassy-mspm0/src/sysctl/mod.rs @@ -0,0 +1,124 @@ +//! System controller (SYSCTL) driver. + +#![macro_use] + +use crate::gpio::{AnyPin, PfType, Pin, Pull, SealedPin}; +use crate::pac::sysctl::vals; +use crate::peripherals::CLK_OUT; +use crate::{Peri, pac}; + +// TODO: Use sysctl version instead +#[cfg_attr(mspm0c110x, path = "c1103_1104.rs")] +#[cfg_attr(mspm0c1105_c1106, path = "c1105_1106.rs")] +#[cfg_attr( + any(mspm0g110x, mspm0g150x, mspm0g310x, mspm0g350x), + path = "g110x_150x_310x_350x.rs" +)] +#[cfg_attr(any(mspm0g151x, mspm0g351x), path = "g151x_351x.rs")] +#[cfg_attr(mspm0g518x, path = "g511x_518x.rs")] +#[cfg_attr(mspm0h321x, path = "h321x.rs")] +#[cfg_attr(any(mspm0l110x, mspm0l130x, mspm0l134x), path = "l_typea.rs")] +#[cfg_attr(any(mspm0l122x, mspm0l222x), path = "l_typeb.rs")] +mod inner; + +pub use inner::ClkOutSource; + +/// Divider applied to the clock source of the CLK_OUT pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClkOutDiv { + /// Divide by 2. + Div2, + + /// Divide by 4. + Div4, + + /// Divide by 6. + Div6, + + /// Divide by 8. + Div8, + + /// Divide by 10. + Div10, + + /// Divide by 12. + Div12, + + /// Divide by 14. + Div14, + + /// Divide by 16. + Div16, +} + +/// CLK_OUT pin driver. +pub struct ClkOut<'d> { + pin: Peri<'d, AnyPin>, +} + +impl<'d> ClkOut<'d> { + /// Create a bew CLK_OUT instance. + pub fn new(_peri: Peri<'d, CLK_OUT>, pin: Peri<'d, impl ClkOutPin>, source: ClkOutSource) -> Self { + // FIXME: Config (pull, invert, etc?) + let pf = PfType::output(Pull::None, false); + // FIXME: Infallible operation + let pin = unwrap!(new_pin!(pin, pf)); + + let (en_div, div) = source.convert_div(); + let src = source.convert_src(); + pac::SYSCTL.genclkcfg().modify(|w| { + w.set_exclksrc(src); + w.set_exclkdivval(div); + w.set_exclkdiven(en_div); + }); + + pac::SYSCTL.genclken().modify(|w| { + w.set_exclken(true); + }); + + Self { pin } + } +} + +impl<'d> Drop for ClkOut<'d> { + fn drop(&mut self) { + pac::SYSCTL.genclken().modify(|w| { + w.set_exclken(false); + }); + + self.pin.set_as_disconnected(); + } +} + +/// ClkOut pin trait. +pub trait ClkOutPin: Pin { + /// Get the PF number needed to use this pin aas ClkOut pin. + fn pf_num(&self) -> u8; +} + +macro_rules! impl_clk_out_pin { + ($pin: ident, $pf: expr) => { + impl crate::sysctl::ClkOutPin for $crate::peripherals::$pin { + fn pf_num(&self) -> u8 { + $pf + } + } + }; +} + +/// (DIVEN, DIVVAL) +fn div_to_pac(div: Option) -> (bool, vals::Exclkdivval) { + match div { + Some(ClkOutDiv::Div2) => (true, vals::Exclkdivval::DIV2), + Some(ClkOutDiv::Div4) => (true, vals::Exclkdivval::DIV4), + Some(ClkOutDiv::Div6) => (true, vals::Exclkdivval::DIV6), + Some(ClkOutDiv::Div8) => (true, vals::Exclkdivval::DIV8), + Some(ClkOutDiv::Div10) => (true, vals::Exclkdivval::DIV10), + Some(ClkOutDiv::Div12) => (true, vals::Exclkdivval::DIV12), + Some(ClkOutDiv::Div14) => (true, vals::Exclkdivval::DIV14), + Some(ClkOutDiv::Div16) => (true, vals::Exclkdivval::DIV16), + // divider is ignored. set to default value + None => (false, vals::Exclkdivval::DIV2), + } +} diff --git a/examples/mspm0c1104/src/bin/clk_out.rs b/examples/mspm0c1104/src/bin/clk_out.rs new file mode 100644 index 0000000000..c51e7f86ba --- /dev/null +++ b/examples/mspm0c1104/src/bin/clk_out.rs @@ -0,0 +1,32 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::sysctl::{ClkOut, ClkOutDiv, ClkOutSource}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_mspm0::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PA0, Level::High); + + // SYSRST must be initiated for the output to actually change. probe-rs currently does not do this. + // To see changes you will need to flash and then power cycle or press reset button on your board. + let division = Some(ClkOutDiv::Div2); + let _clk_out = ClkOut::new(p.CLK_OUT, p.PA22, ClkOutSource::Sysosc(division)); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(500).await; + + info!("low"); + led.set_low(); + Timer::after_millis(500).await; + } +} diff --git a/examples/mspm0g3507/src/bin/clk_out.rs b/examples/mspm0g3507/src/bin/clk_out.rs new file mode 100644 index 0000000000..c51e7f86ba --- /dev/null +++ b/examples/mspm0g3507/src/bin/clk_out.rs @@ -0,0 +1,32 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::sysctl::{ClkOut, ClkOutDiv, ClkOutSource}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_mspm0::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PA0, Level::High); + + // SYSRST must be initiated for the output to actually change. probe-rs currently does not do this. + // To see changes you will need to flash and then power cycle or press reset button on your board. + let division = Some(ClkOutDiv::Div2); + let _clk_out = ClkOut::new(p.CLK_OUT, p.PA22, ClkOutSource::Sysosc(division)); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(500).await; + + info!("low"); + led.set_low(); + Timer::after_millis(500).await; + } +} diff --git a/examples/mspm0g3519/src/bin/clk_out.rs b/examples/mspm0g3519/src/bin/clk_out.rs new file mode 100644 index 0000000000..d74c7650b0 --- /dev/null +++ b/examples/mspm0g3519/src/bin/clk_out.rs @@ -0,0 +1,32 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::sysctl::{ClkOut, ClkOutDiv, ClkOutSource}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_mspm0::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PA0, Level::High); + + // SYSRST must be initiated for the output to actually change. probe-rs currently does not do this. + // To see changes you will need to flash and then power cycle or press reset button on your board. + let division = Some(ClkOutDiv::Div2); + let _clk_out = ClkOut::new(p.CLK_OUT, p.PA7, ClkOutSource::LfClk(division)); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(500).await; + + info!("low"); + led.set_low(); + Timer::after_millis(500).await; + } +} diff --git a/examples/mspm0g5187/src/bin/clk_out.rs b/examples/mspm0g5187/src/bin/clk_out.rs new file mode 100644 index 0000000000..d74c7650b0 --- /dev/null +++ b/examples/mspm0g5187/src/bin/clk_out.rs @@ -0,0 +1,32 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::sysctl::{ClkOut, ClkOutDiv, ClkOutSource}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_mspm0::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PA0, Level::High); + + // SYSRST must be initiated for the output to actually change. probe-rs currently does not do this. + // To see changes you will need to flash and then power cycle or press reset button on your board. + let division = Some(ClkOutDiv::Div2); + let _clk_out = ClkOut::new(p.CLK_OUT, p.PA7, ClkOutSource::LfClk(division)); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(500).await; + + info!("low"); + led.set_low(); + Timer::after_millis(500).await; + } +} diff --git a/examples/mspm0l1306/src/bin/clk_out.rs b/examples/mspm0l1306/src/bin/clk_out.rs new file mode 100644 index 0000000000..c51e7f86ba --- /dev/null +++ b/examples/mspm0l1306/src/bin/clk_out.rs @@ -0,0 +1,32 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::sysctl::{ClkOut, ClkOutDiv, ClkOutSource}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_mspm0::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PA0, Level::High); + + // SYSRST must be initiated for the output to actually change. probe-rs currently does not do this. + // To see changes you will need to flash and then power cycle or press reset button on your board. + let division = Some(ClkOutDiv::Div2); + let _clk_out = ClkOut::new(p.CLK_OUT, p.PA22, ClkOutSource::Sysosc(division)); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(500).await; + + info!("low"); + led.set_low(); + Timer::after_millis(500).await; + } +} diff --git a/examples/mspm0l2228/src/bin/clk_out.rs b/examples/mspm0l2228/src/bin/clk_out.rs new file mode 100644 index 0000000000..c51e7f86ba --- /dev/null +++ b/examples/mspm0l2228/src/bin/clk_out.rs @@ -0,0 +1,32 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::sysctl::{ClkOut, ClkOutDiv, ClkOutSource}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_mspm0::init(Default::default()); + info!("Hello World!"); + + let mut led = Output::new(p.PA0, Level::High); + + // SYSRST must be initiated for the output to actually change. probe-rs currently does not do this. + // To see changes you will need to flash and then power cycle or press reset button on your board. + let division = Some(ClkOutDiv::Div2); + let _clk_out = ClkOut::new(p.CLK_OUT, p.PA22, ClkOutSource::Sysosc(division)); + + loop { + info!("high"); + led.set_high(); + Timer::after_millis(500).await; + + info!("low"); + led.set_low(); + Timer::after_millis(500).await; + } +}