Skip to content

Commit 2e0f6cf

Browse files
authored
Merge pull request embassy-rs#5602 from jamesmunns/james/577-sosc
[MCXA5] Ungate SOSC and SPLL
2 parents 75e8c52 + 3612f0d commit 2e0f6cf

5 files changed

Lines changed: 132 additions & 34 deletions

File tree

embassy-mcxa/src/clocks/config.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,9 @@ pub struct ClocksConfig {
130130
/// SOSC, clk_in clock source
131131
///
132132
/// NOTE: Requires `sosc-as-gpio` feature disabled, which also disables GPIO access to P1_30 and P1_31
133-
#[cfg(feature = "mcxa2xx")]
134133
#[cfg(not(feature = "sosc-as-gpio"))]
135134
pub sosc: Option<SoscConfig>,
136135
/// SPLL
137-
#[cfg(feature = "mcxa2xx")]
138136
pub spll: Option<SpllConfig>,
139137
}
140138

@@ -281,7 +279,6 @@ pub enum MainClockSource {
281279
/// Clock derived from `clk_in`, via the external oscillator (8-50MHz)
282280
///
283281
/// NOTE: Requires `sosc-as-gpio` feature disabled, which also disables GPIO access to P1_30 and P1_31
284-
#[cfg(feature = "mcxa2xx")]
285282
#[cfg(not(feature = "sosc-as-gpio"))]
286283
SoscClkIn,
287284
/// Clock derived from `fro_12m`, via the internal 12MHz oscillator (12MHz)
@@ -296,7 +293,6 @@ pub enum MainClockSource {
296293
#[cfg(all(feature = "mcxa5xx", not(feature = "rosc-32k-as-gpio")))]
297294
RoscOsc32K,
298295
/// Clock derived from `pll1_clk`, via the internal PLL
299-
#[cfg(feature = "mcxa2xx")]
300296
SPll1,
301297
}
302298

@@ -354,6 +350,7 @@ pub enum SpllSource {
354350
/// Fast Internal Oscillator (45MHz)
355351
// NOTE: Figure 69 says "firc_45mhz"/"clk_45m", not "fro_hf_gated",
356352
// so this is is always 45MHz.
353+
#[cfg(feature = "mcxa2xx")]
357354
Firc,
358355
/// S Internal Oscillator (12M)
359356
Sirc,
@@ -673,10 +670,8 @@ impl Default for ClocksConfig {
673670
}),
674671
#[cfg(all(feature = "mcxa5xx", not(feature = "rosc-32k-as-gpio")))]
675672
osc32k: None,
676-
#[cfg(feature = "mcxa2xx")]
677673
#[cfg(not(feature = "sosc-as-gpio"))]
678674
sosc: None,
679-
#[cfg(feature = "mcxa2xx")]
680675
spll: None,
681676
}
682677
}

embassy-mcxa/src/clocks/mod.rs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,20 @@ use periph_helpers::{PreEnableParts, SPConfHelper};
5050
use crate::chips::{ClockLimits, clock_limits};
5151
use crate::pac;
5252
use crate::pac::cmc::vals::CkctrlCkmode;
53-
#[cfg(feature = "mcxa2xx")]
5453
use crate::pac::scg::vals::{
55-
Erefs, Fircacc, FircaccIe, FirccsrLk, Fircerr, FircerrIe, Fircsten, Fircvld, FreqSel, Range, SosccsrLk, Soscerr,
56-
Source, SpllLock, SpllcsrLk, Spllerr, Spllsten, TrimUnlock,
54+
Erefs, Range, Scs, SirccsrLk, Sircerr, Sircvld, SosccsrLk, Soscerr, Source, SpllLock, SpllcsrLk, Spllerr, Spllsten,
55+
TrimUnlock,
5756
};
58-
use crate::pac::scg::vals::{Scs, SirccsrLk, Sircerr, Sircvld};
57+
#[cfg(feature = "mcxa2xx")]
58+
use crate::pac::scg::vals::{Fircacc, FircaccIe, FirccsrLk, Fircerr, FircerrIe, Fircsten, Fircvld, FreqSel};
5959
use crate::pac::spc::vals::{
6060
ActiveCfgBgmode, ActiveCfgCoreldoVddDs, ActiveCfgCoreldoVddLvl, LpCfgBgmode, LpCfgCoreldoVddLvl, Vsm,
6161
};
62-
use crate::pac::syscon::vals::{AhbclkdivUnstab, FrolfdivHalt, FrolfdivReset, FrolfdivUnstab};
63-
#[cfg(feature = "mcxa2xx")]
6462
use crate::pac::syscon::vals::{
65-
FrohfdivHalt, FrohfdivReset, FrohfdivUnstab, Pll1clkdivHalt, Pll1clkdivReset, Pll1clkdivUnstab,
63+
AhbclkdivUnstab, FrolfdivHalt, FrolfdivReset, FrolfdivUnstab, Pll1clkdivHalt, Pll1clkdivReset, Pll1clkdivUnstab,
6664
};
65+
#[cfg(feature = "mcxa2xx")]
66+
use crate::pac::syscon::vals::{FrohfdivHalt, FrohfdivReset, FrohfdivUnstab};
6767
pub mod config;
6868
pub mod periph_helpers;
6969

@@ -132,10 +132,8 @@ pub fn init(settings: ClocksConfig) -> Result<(), ClockError> {
132132
#[cfg(all(feature = "mcxa5xx", not(feature = "rosc-32k-as-gpio")))]
133133
operator.configure_osc32k_clocks()?;
134134

135-
#[cfg(feature = "mcxa2xx")]
136135
#[cfg(not(feature = "sosc-as-gpio"))]
137136
operator.configure_sosc()?;
138-
#[cfg(feature = "mcxa2xx")]
139137
operator.configure_spll()?;
140138

141139
// Finally, setup main clock
@@ -307,7 +305,6 @@ unsafe fn restart_active_only_clocks(_cs: &CriticalSection) {
307305
}
308306

309307
// Ensure SOSC is up and running
310-
#[cfg(feature = "mcxa2xx")]
311308
#[cfg(not(feature = "sosc-as-gpio"))]
312309
if let Some(clk_in) = clocks.clk_in.as_ref()
313310
&& !matches!(clk_in.power, PoweredClock::AlwaysEnabled)
@@ -316,7 +313,6 @@ unsafe fn restart_active_only_clocks(_cs: &CriticalSection) {
316313
}
317314

318315
// Ensure SPLL is up and running
319-
#[cfg(feature = "mcxa2xx")]
320316
if let Some(spll) = clocks.pll1_clk.as_ref()
321317
&& !matches!(spll.power, PoweredClock::AlwaysEnabled)
322318
{
@@ -401,7 +397,6 @@ pub struct Clocks {
401397

402398
/// The `clk_in` is a clock provided by an external oscillator
403399
/// AKA SOSC
404-
#[cfg(feature = "mcxa2xx")]
405400
#[cfg(not(feature = "sosc-as-gpio"))]
406401
pub clk_in: Option<Clock>,
407402

@@ -493,11 +488,9 @@ pub struct Clocks {
493488
pub cpu_system_clk: Option<Clock>,
494489

495490
/// `pll1_clk` is the output of the main system PLL, `pll1`.
496-
#[cfg(feature = "mcxa2xx")]
497491
pub pll1_clk: Option<Clock>,
498492

499493
/// `pll1_clk_div` is a configurable frequency clock, sourced from `pll1_clk`
500-
#[cfg(feature = "mcxa2xx")]
501494
pub pll1_clk_div: Option<Clock>,
502495
}
503496

@@ -800,7 +793,6 @@ impl Clocks {
800793
}
801794

802795
/// Ensure the `clk_in` clock is active and valid at the given power state.
803-
#[cfg(feature = "mcxa2xx")]
804796
#[cfg(not(feature = "sosc-as-gpio"))]
805797
#[inline]
806798
pub fn ensure_clk_in_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> {
@@ -875,14 +867,12 @@ impl Clocks {
875867
}
876868

877869
/// Ensure the `pll1_clk` clock is active and valid at the given power state.
878-
#[cfg(feature = "mcxa2xx")]
879870
#[inline]
880871
pub fn ensure_pll1_clk_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> {
881872
self.ensure_clock_active(&self.pll1_clk, "pll1_clk", at_level)
882873
}
883874

884875
/// Ensure the `pll1_clk_div` clock is active and valid at the given power state.
885-
#[cfg(feature = "mcxa2xx")]
886876
#[inline]
887877
pub fn ensure_pll1_clk_div_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> {
888878
self.ensure_clock_active(&self.pll1_clk_div, "pll1_clk_div", at_level)
@@ -1576,7 +1566,6 @@ impl ClockOperator<'_> {
15761566
Ok(())
15771567
}
15781568

1579-
#[cfg(feature = "mcxa2xx")]
15801569
fn ensure_ldo_active(&mut self, for_clock: &'static str, for_power: &PoweredClock) -> Result<(), ClockError> {
15811570
let bg_good = match for_power {
15821571
PoweredClock::NormalEnabledDeepSleepDisabled => self.clocks.bandgap_active,
@@ -1607,7 +1596,6 @@ impl ClockOperator<'_> {
16071596
}
16081597

16091598
/// Configure the SOSC/clk_in oscillator
1610-
#[cfg(feature = "mcxa2xx")]
16111599
#[cfg(not(feature = "sosc-as-gpio"))]
16121600
fn configure_sosc(&mut self) -> Result<(), ClockError> {
16131601
let Some(parts) = self.config.sosc.as_ref() else {
@@ -1712,7 +1700,6 @@ impl ClockOperator<'_> {
17121700
Ok(())
17131701
}
17141702

1715-
#[cfg(feature = "mcxa2xx")]
17161703
fn configure_spll(&mut self) -> Result<(), ClockError> {
17171704
// # Vocab
17181705
//
@@ -1746,6 +1733,7 @@ impl ClockOperator<'_> {
17461733
.as_ref()
17471734
.map(|c| (c, Source::SOSC))
17481735
.ok_or("sosc not active"),
1736+
#[cfg(feature = "mcxa2xx")]
17491737
config::SpllSource::Firc => self
17501738
.clocks
17511739
.clk_45m
@@ -2091,7 +2079,6 @@ impl ClockOperator<'_> {
20912079

20922080
fn configure_main_clk(&mut self) -> Result<(), ClockError> {
20932081
let (var, name, clk) = match self.config.main_clock.source {
2094-
#[cfg(feature = "mcxa2xx")]
20952082
#[cfg(not(feature = "sosc-as-gpio"))]
20962083
MainClockSource::SoscClkIn => (Scs::SOSC, "clk_in", self.clocks.clk_in.as_ref()),
20972084
MainClockSource::SircFro12M => (Scs::SIRC, "fro_12m", self.clocks.fro_12m.as_ref()),
@@ -2101,7 +2088,6 @@ impl ClockOperator<'_> {
21012088
MainClockSource::RoscFro16K => (Scs::ROSC, "fro16k", self.clocks.clk_16k_vdd_core.as_ref()),
21022089
#[cfg(all(feature = "mcxa5xx", not(feature = "rosc-32k-as-gpio")))]
21032090
MainClockSource::RoscOsc32K => (Scs::ROSC, "osc32k", self.clocks.clk_32k_vdd_core.as_ref()),
2104-
#[cfg(feature = "mcxa2xx")]
21052091
MainClockSource::SPll1 => (Scs::SPLL, "pll1_clk", self.clocks.pll1_clk.as_ref()),
21062092
};
21072093
let Some(main_clk_src) = clk else {

embassy-mcxa/src/clocks/periph_helpers/mod.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ pub enum CTimerClockSel {
297297
#[cfg(feature = "mcxa2xx")]
298298
FroHfDiv,
299299
/// SOSC/XTAL/EXTAL clock source
300-
#[cfg(feature = "mcxa2xx")]
301300
#[cfg(not(feature = "sosc-as-gpio"))]
302301
ClkIn,
303302
/// FRO16K/clk_16k source
@@ -306,7 +305,6 @@ pub enum CTimerClockSel {
306305
/// clk_1m/FRO_LF divided by 12
307306
Clk1M,
308307
/// Internal PLL output, with configurable divisor
309-
#[cfg(feature = "mcxa2xx")]
310308
Pll1ClkDiv,
311309
/// Disabled
312310
None,
@@ -372,11 +370,17 @@ impl SPConfHelper for CTimerConfig {
372370
let freq = clocks.ensure_fro_hf_div_active(&self.power)?;
373371
(freq, CtimerClkselMux::CLKROOT_FUNC_1)
374372
}
375-
#[cfg(feature = "mcxa2xx")]
376373
#[cfg(not(feature = "sosc-as-gpio"))]
377374
CTimerClockSel::ClkIn => {
378375
let freq = clocks.ensure_clk_in_active(&self.power)?;
379-
(freq, CtimerClkselMux::CLKROOT_FUNC_3)
376+
377+
// TODO: fix PAC names for consistency
378+
#[cfg(feature = "mcxa2xx")]
379+
let mux = CtimerClkselMux::CLKROOT_FUNC_3;
380+
#[cfg(feature = "mcxa5xx")]
381+
let mux = CtimerClkselMux::I3_CLKROOT_SOSC;
382+
383+
(freq, mux)
380384
}
381385
#[cfg(feature = "mcxa2xx")]
382386
CTimerClockSel::Clk16K => {
@@ -394,10 +398,16 @@ impl SPConfHelper for CTimerConfig {
394398

395399
(freq, mux)
396400
}
397-
#[cfg(feature = "mcxa2xx")]
398401
CTimerClockSel::Pll1ClkDiv => {
399402
let freq = clocks.ensure_pll1_clk_div_active(&self.power)?;
400-
(freq, CtimerClkselMux::CLKROOT_FUNC_6)
403+
404+
// TODO: fix PAC names for consistency
405+
#[cfg(feature = "mcxa2xx")]
406+
let mux = CtimerClkselMux::CLKROOT_FUNC_6;
407+
#[cfg(feature = "mcxa5xx")]
408+
let mux = CtimerClkselMux::I6_CLKROOT_SPLL_DIV;
409+
410+
(freq, mux)
401411
}
402412
CTimerClockSel::None => {
403413
// no ClkrootFunc7, just write manually for now
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//! Similar to blinky, but clocked with external SOSC
2+
//!
3+
//! This will probably go away once we have the CLKOUT peripheral supported.
4+
5+
#![no_std]
6+
#![no_main]
7+
8+
use embassy_executor::Spawner;
9+
use embassy_mcxa::clocks::PoweredClock;
10+
use embassy_mcxa::clocks::config::{MainClockSource, SoscConfig, SoscMode};
11+
use embassy_time::Timer;
12+
use hal::gpio::{DriveStrength, Level, Output, SlewRate};
13+
use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
14+
15+
#[embassy_executor::main]
16+
async fn main(_spawner: Spawner) {
17+
let mut cfg = hal::config::Config::default();
18+
let osc = SoscConfig {
19+
mode: SoscMode::CrystalOscillator,
20+
frequency: 24_000_000,
21+
power: PoweredClock::NormalEnabledDeepSleepDisabled,
22+
};
23+
cfg.clock_cfg.sosc = Some(osc);
24+
cfg.clock_cfg.main_clock.source = MainClockSource::SoscClkIn;
25+
let p = hal::init(cfg);
26+
27+
defmt::info!("Blink example");
28+
29+
let mut red = Output::new(p.P2_14, Level::High, DriveStrength::Normal, SlewRate::Fast);
30+
let mut green = Output::new(p.P2_22, Level::High, DriveStrength::Normal, SlewRate::Fast);
31+
let mut blue = Output::new(p.P2_23, Level::High, DriveStrength::Normal, SlewRate::Fast);
32+
33+
loop {
34+
defmt::info!("Toggle LEDs");
35+
36+
red.toggle();
37+
Timer::after_millis(250).await;
38+
39+
red.toggle();
40+
green.toggle();
41+
Timer::after_millis(250).await;
42+
43+
green.toggle();
44+
blue.toggle();
45+
Timer::after_millis(250).await;
46+
blue.toggle();
47+
48+
Timer::after_millis(250).await;
49+
}
50+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//! Similar to blinky, but clocked with external SOSC
2+
//!
3+
//! This will probably go away once we have the CLKOUT peripheral supported.
4+
5+
#![no_std]
6+
#![no_main]
7+
8+
use embassy_executor::Spawner;
9+
use embassy_mcxa::clocks::PoweredClock;
10+
use embassy_mcxa::clocks::config::{MainClockSource, SpllConfig, SpllMode, SpllSource};
11+
use embassy_time::Timer;
12+
use hal::gpio::{DriveStrength, Level, Output, SlewRate};
13+
use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
14+
15+
#[embassy_executor::main]
16+
async fn main(_spawner: Spawner) {
17+
let mut cfg = hal::config::Config::default();
18+
cfg.clock_cfg.spll = Some(SpllConfig {
19+
source: SpllSource::Sirc,
20+
// 12MHz
21+
// 12 x 32 => 384MHz
22+
// 384 / (16 x 2) => 12.0MHz
23+
mode: SpllMode::Mode1b {
24+
m_mult: 32,
25+
p_div: 16,
26+
bypass_p2_div: false,
27+
},
28+
power: PoweredClock::NormalEnabledDeepSleepDisabled,
29+
pll1_clk_div: None,
30+
});
31+
cfg.clock_cfg.main_clock.source = MainClockSource::SPll1;
32+
let p = hal::init(cfg);
33+
34+
defmt::info!("Blink example");
35+
36+
let mut red = Output::new(p.P2_14, Level::High, DriveStrength::Normal, SlewRate::Fast);
37+
let mut green = Output::new(p.P2_22, Level::High, DriveStrength::Normal, SlewRate::Fast);
38+
let mut blue = Output::new(p.P2_23, Level::High, DriveStrength::Normal, SlewRate::Fast);
39+
40+
loop {
41+
defmt::info!("Toggle LEDs");
42+
43+
red.toggle();
44+
Timer::after_millis(250).await;
45+
46+
red.toggle();
47+
green.toggle();
48+
Timer::after_millis(250).await;
49+
50+
green.toggle();
51+
blue.toggle();
52+
Timer::after_millis(250).await;
53+
blue.toggle();
54+
55+
Timer::after_millis(250).await;
56+
}
57+
}

0 commit comments

Comments
 (0)