aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Munns <[email protected]>2025-11-12 17:41:48 +0100
committerJames Munns <[email protected]>2025-11-12 17:41:48 +0100
commitc004f3616e2959df51ed4785ee0bba4e4c373fc6 (patch)
tree0a84c174d1917d715340f551924a9d0fbd839947
parent1ec472aa864d8add5dd14246324d671217fab304 (diff)
Comment out old clock gating logic, will be restored
-rw-r--r--src/clocks.rs260
1 files changed, 132 insertions, 128 deletions
diff --git a/src/clocks.rs b/src/clocks.rs
index a00b3e4c5..c86ed1cd5 100644
--- a/src/clocks.rs
+++ b/src/clocks.rs
@@ -7,136 +7,140 @@ use mcxa_pac::scg0::{
7 7
8use crate::pac; 8use crate::pac;
9 9
10/// Trait describing an AHB clock gate that can be toggled through MRCC. 10pub trait SPConfHelper {
11pub trait Gate { 11 fn post_enable_config(&self, clocks: &Clocks) -> Result<u32, ClockError>;
12 /// Enable the clock gate.
13 unsafe fn enable(mrcc: &pac::mrcc0::RegisterBlock);
14
15 /// Return whether the clock gate is currently enabled.
16 fn is_enabled(mrcc: &pac::mrcc0::RegisterBlock) -> bool;
17}
18
19/// Enable a clock gate for the given peripheral set.
20#[inline]
21pub unsafe fn enable<G: Gate>(peripherals: &pac::Peripherals) {
22 let mrcc = &peripherals.mrcc0;
23 G::enable(mrcc);
24 while !G::is_enabled(mrcc) {}
25 core::arch::asm!("dsb sy; isb sy", options(nomem, nostack, preserves_flags));
26}
27
28/// Check whether a gate is currently enabled.
29#[inline]
30pub fn is_enabled<G: Gate>(peripherals: &pac::Peripherals) -> bool {
31 G::is_enabled(&peripherals.mrcc0)
32} 12}
33 13
34macro_rules! impl_cc_gate { 14// /// Trait describing an AHB clock gate that can be toggled through MRCC.
35 ($name:ident, $reg:ident, $field:ident) => { 15// pub trait Gate {
36 pub struct $name; 16// /// Enable the clock gate.
37 17// unsafe fn enable(mrcc: &pac::mrcc0::RegisterBlock);
38 impl Gate for $name { 18
39 #[inline] 19// /// Return whether the clock gate is currently enabled.
40 unsafe fn enable(mrcc: &pac::mrcc0::RegisterBlock) { 20// fn is_enabled(mrcc: &pac::mrcc0::RegisterBlock) -> bool;
41 mrcc.$reg().modify(|_, w| w.$field().enabled()); 21// }
42 } 22
43 23// /// Enable a clock gate for the given peripheral set.
44 #[inline] 24// #[inline]
45 fn is_enabled(mrcc: &pac::mrcc0::RegisterBlock) -> bool { 25// pub unsafe fn enable<G: Gate>(peripherals: &pac::Peripherals) {
46 mrcc.$reg().read().$field().is_enabled() 26// let mrcc = &peripherals.mrcc0;
47 } 27// G::enable(mrcc);
48 } 28// while !G::is_enabled(mrcc) {}
49 }; 29// core::arch::asm!("dsb sy; isb sy", options(nomem, nostack, preserves_flags));
50} 30// }
51 31
52pub mod gate { 32// /// Check whether a gate is currently enabled.
53 use super::*; 33// #[inline]
54 34// pub fn is_enabled<G: Gate>(peripherals: &pac::Peripherals) -> bool {
55 impl_cc_gate!(Port2, mrcc_glb_cc1, port2); 35// G::is_enabled(&peripherals.mrcc0)
56 impl_cc_gate!(Port3, mrcc_glb_cc1, port3); 36// }
57 impl_cc_gate!(Ostimer0, mrcc_glb_cc1, ostimer0); 37
58 impl_cc_gate!(Lpuart2, mrcc_glb_cc0, lpuart2); 38// macro_rules! impl_cc_gate {
59 impl_cc_gate!(Gpio3, mrcc_glb_cc2, gpio3); 39// ($name:ident, $reg:ident, $field:ident) => {
60 impl_cc_gate!(Port1, mrcc_glb_cc1, port1); 40// pub struct $name;
61 impl_cc_gate!(Adc1, mrcc_glb_cc1, adc1); 41
62} 42// impl Gate for $name {
63 43// #[inline]
64/// Convenience helper enabling the PORT2 and LPUART2 gates required for the debug UART. 44// unsafe fn enable(mrcc: &pac::mrcc0::RegisterBlock) {
65pub unsafe fn enable_uart2_port2(peripherals: &pac::Peripherals) { 45// mrcc.$reg().modify(|_, w| w.$field().enabled());
66 enable::<gate::Port2>(peripherals); 46// }
67 enable::<gate::Lpuart2>(peripherals); 47
68} 48// #[inline]
69 49// fn is_enabled(mrcc: &pac::mrcc0::RegisterBlock) -> bool {
70/// Convenience helper enabling the PORT3 and GPIO3 gates used by the LED in the examples. 50// mrcc.$reg().read().$field().is_enabled()
71pub unsafe fn enable_led_port(peripherals: &pac::Peripherals) { 51// }
72 enable::<gate::Port3>(peripherals); 52// }
73 enable::<gate::Gpio3>(peripherals); 53// };
74} 54// }
75 55
76/// Convenience helper enabling the OSTIMER0 clock gate. 56// pub mod gate {
77pub unsafe fn enable_ostimer0(peripherals: &pac::Peripherals) { 57// use super::*;
78 enable::<gate::Ostimer0>(peripherals); 58
79} 59// impl_cc_gate!(Port2, mrcc_glb_cc1, port2);
80 60// impl_cc_gate!(Port3, mrcc_glb_cc1, port3);
81pub unsafe fn select_uart2_clock(peripherals: &pac::Peripherals) { 61// impl_cc_gate!(Ostimer0, mrcc_glb_cc1, ostimer0);
82 // Use FRO_LF_DIV (already running) MUX=0 DIV=0 62// impl_cc_gate!(Lpuart2, mrcc_glb_cc0, lpuart2);
83 let mrcc = &peripherals.mrcc0; 63// impl_cc_gate!(Gpio3, mrcc_glb_cc2, gpio3);
84 mrcc.mrcc_lpuart2_clksel().write(|w| w.mux().clkroot_func_0()); 64// impl_cc_gate!(Port1, mrcc_glb_cc1, port1);
85 mrcc.mrcc_lpuart2_clkdiv().write(|w| unsafe { w.bits(0) }); 65// impl_cc_gate!(Adc1, mrcc_glb_cc1, adc1);
86} 66// }
87 67
88pub unsafe fn ensure_frolf_running(peripherals: &pac::Peripherals) { 68// /// Convenience helper enabling the PORT2 and LPUART2 gates required for the debug UART.
89 // Ensure FRO_LF divider clock is running (reset default HALT=1 stops it) 69// pub unsafe fn enable_uart2_port2(peripherals: &pac::Peripherals) {
90 let sys = &peripherals.syscon; 70// enable::<gate::Port2>(peripherals);
91 sys.frolfdiv().modify(|_, w| { 71// enable::<gate::Lpuart2>(peripherals);
92 // DIV defaults to 0; keep it explicit and clear HALT 72// }
93 unsafe { w.div().bits(0) }.halt().run() 73
94 }); 74// /// Convenience helper enabling the PORT3 and GPIO3 gates used by the LED in the examples.
95} 75// pub unsafe fn enable_led_port(peripherals: &pac::Peripherals) {
96 76// enable::<gate::Port3>(peripherals);
97/// Compute the FRO_LF_DIV output frequency currently selected for LPUART2. 77// enable::<gate::Gpio3>(peripherals);
98/// Assumes select_uart2_clock() has chosen MUX=0 (FRO_LF_DIV) and DIV is set in SYSCON.FRO_LF_DIV. 78// }
99pub unsafe fn uart2_src_hz(peripherals: &pac::Peripherals) -> u32 { 79
100 // SYSCON.FRO_LF_DIV: DIV field is simple divider: freq_out = 12_000_000 / (DIV+1) for many NXP parts. 80// /// Convenience helper enabling the OSTIMER0 clock gate.
101 // On MCXA276 FRO_LF base is 12 MHz; our init keeps DIV=0, so result=12_000_000. 81// pub unsafe fn enable_ostimer0(peripherals: &pac::Peripherals) {
102 // Read it anyway for future generality. 82// enable::<gate::Ostimer0>(peripherals);
103 let div = peripherals.syscon.frolfdiv().read().div().bits() as u32; 83// }
104 let base = 12_000_000u32; 84
105 base / (div + 1) 85// pub unsafe fn select_uart2_clock(peripherals: &pac::Peripherals) {
106} 86// // Use FRO_LF_DIV (already running) MUX=0 DIV=0
107 87// let mrcc = &peripherals.mrcc0;
108/// Enable clock gate and release reset for OSTIMER0. 88// mrcc.mrcc_lpuart2_clksel().write(|w| w.mux().clkroot_func_0());
109/// Select OSTIMER0 clock source = 1 MHz root (working bring-up configuration). 89// mrcc.mrcc_lpuart2_clkdiv().write(|w| unsafe { w.bits(0) });
110pub unsafe fn select_ostimer0_clock_1m(peripherals: &pac::Peripherals) { 90// }
111 let mrcc = &peripherals.mrcc0; 91
112 mrcc.mrcc_ostimer0_clksel().write(|w| w.mux().clkroot_1m()); 92// pub unsafe fn ensure_frolf_running(peripherals: &pac::Peripherals) {
113} 93// // Ensure FRO_LF divider clock is running (reset default HALT=1 stops it)
114 94// let sys = &peripherals.syscon;
115pub unsafe fn init_fro16k(peripherals: &pac::Peripherals) { 95// sys.frolfdiv().modify(|_, w| {
116 let vbat = &peripherals.vbat0; 96// // DIV defaults to 0; keep it explicit and clear HALT
117 // Enable FRO16K oscillator 97// unsafe { w.div().bits(0) }.halt().run()
118 vbat.froctla().modify(|_, w| w.fro_en().set_bit()); 98// });
119 99// }
120 // Lock the control register 100
121 vbat.frolcka().modify(|_, w| w.lock().set_bit()); 101// /// Compute the FRO_LF_DIV output frequency currently selected for LPUART2.
122 102// /// Assumes select_uart2_clock() has chosen MUX=0 (FRO_LF_DIV) and DIV is set in SYSCON.FRO_LF_DIV.
123 // Enable clock outputs to both VSYS and VDD_CORE domains 103// pub unsafe fn uart2_src_hz(peripherals: &pac::Peripherals) -> u32 {
124 // Bit 0: clk_16k0 to VSYS domain 104// // SYSCON.FRO_LF_DIV: DIV field is simple divider: freq_out = 12_000_000 / (DIV+1) for many NXP parts.
125 // Bit 1: clk_16k1 to VDD_CORE domain 105// // On MCXA276 FRO_LF base is 12 MHz; our init keeps DIV=0, so result=12_000_000.
126 vbat.froclke().modify(|_, w| unsafe { w.clke().bits(0x3) }); 106// // Read it anyway for future generality.
127} 107// let div = peripherals.syscon.frolfdiv().read().div().bits() as u32;
128 108// let base = 12_000_000u32;
129pub unsafe fn enable_adc(peripherals: &pac::Peripherals) { 109// base / (div + 1)
130 enable::<gate::Port1>(peripherals); 110// }
131 enable::<gate::Adc1>(peripherals); 111
132} 112// /// Enable clock gate and release reset for OSTIMER0.
133 113// /// Select OSTIMER0 clock source = 1 MHz root (working bring-up configuration).
134pub unsafe fn select_adc_clock(peripherals: &pac::Peripherals) { 114// pub unsafe fn select_ostimer0_clock_1m(peripherals: &pac::Peripherals) {
135 // Use FRO_LF_DIV (already running) MUX=0 DIV=0 115// let mrcc = &peripherals.mrcc0;
136 let mrcc = &peripherals.mrcc0; 116// mrcc.mrcc_ostimer0_clksel().write(|w| w.mux().clkroot_1m());
137 mrcc.mrcc_adc_clksel().write(|w| w.mux().clkroot_func_0()); 117// }
138 mrcc.mrcc_adc_clkdiv().write(|w| unsafe { w.bits(0) }); 118
139} 119// pub unsafe fn init_fro16k(peripherals: &pac::Peripherals) {
120// let vbat = &peripherals.vbat0;
121// // Enable FRO16K oscillator
122// vbat.froctla().modify(|_, w| w.fro_en().set_bit());
123
124// // Lock the control register
125// vbat.frolcka().modify(|_, w| w.lock().set_bit());
126
127// // Enable clock outputs to both VSYS and VDD_CORE domains
128// // Bit 0: clk_16k0 to VSYS domain
129// // Bit 1: clk_16k1 to VDD_CORE domain
130// vbat.froclke().modify(|_, w| unsafe { w.clke().bits(0x3) });
131// }
132
133// pub unsafe fn enable_adc(peripherals: &pac::Peripherals) {
134// enable::<gate::Port1>(peripherals);
135// enable::<gate::Adc1>(peripherals);
136// }
137
138// pub unsafe fn select_adc_clock(peripherals: &pac::Peripherals) {
139// // Use FRO_LF_DIV (already running) MUX=0 DIV=0
140// let mrcc = &peripherals.mrcc0;
141// mrcc.mrcc_adc_clksel().write(|w| w.mux().clkroot_func_0());
142// mrcc.mrcc_adc_clkdiv().write(|w| unsafe { w.bits(0) });
143// }
140 144
141// ============================================== 145// ==============================================
142 146