diff options
| author | James Munns <[email protected]> | 2025-11-12 17:41:48 +0100 |
|---|---|---|
| committer | James Munns <[email protected]> | 2025-11-12 17:41:48 +0100 |
| commit | c004f3616e2959df51ed4785ee0bba4e4c373fc6 (patch) | |
| tree | 0a84c174d1917d715340f551924a9d0fbd839947 | |
| parent | 1ec472aa864d8add5dd14246324d671217fab304 (diff) | |
Comment out old clock gating logic, will be restored
| -rw-r--r-- | src/clocks.rs | 260 |
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 | ||
| 8 | use crate::pac; | 8 | use crate::pac; |
| 9 | 9 | ||
| 10 | /// Trait describing an AHB clock gate that can be toggled through MRCC. | 10 | pub trait SPConfHelper { |
| 11 | pub 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] | ||
| 21 | pub 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] | ||
| 30 | pub fn is_enabled<G: Gate>(peripherals: &pac::Peripherals) -> bool { | ||
| 31 | G::is_enabled(&peripherals.mrcc0) | ||
| 32 | } | 12 | } |
| 33 | 13 | ||
| 34 | macro_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 | ||
| 52 | pub 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) { |
| 65 | pub 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() |
| 71 | pub 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 { |
| 77 | pub 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); | |
| 81 | pub 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 | ||
| 88 | pub 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 | // } |
| 99 | pub 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) }); |
| 110 | pub 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; | |
| 115 | pub 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; | |
| 129 | pub 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). | |
| 134 | pub 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 | ||
