Skip to main content

ws63_hal/
clock.rs

1//! Clock definitions for WS63.
2//!
3//! The WS63 uses a CLDO_CRG (Clock and Reset Generator) for peripheral clock
4//! gating. Clocks default to **enabled** out of reset, so the drivers do not
5//! gate them; this module keeps the [`Peripheral`] enum and its CKEN bit map
6//! ([`Peripheral::cken_info`]) as the authoritative peripheral → clock-gate
7//! reference (verified against the WS63 SVD / fbb_ws63), used by `safety.rs`'s
8//! drift checks and available to future clock-gating code.
9//!
10//! The earlier `ClockControl` / `PeripheralGuard` RAII layer was removed: it had
11//! zero consumers (the drivers rely on the reset-default clocks) and was dead
12//! scaffolding. Re-introduce a clock-gating API alongside a real consumer if one
13//! is needed, deriving the gate bits from [`Peripheral::cken_info`].
14
15/// Enumeration of all peripheral clocks.
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum Peripheral {
18    Uart0,
19    Uart1,
20    Uart2,
21    I2c0,
22    I2c1,
23    Spi0,
24    Spi1,
25    Pwm,
26    Timer,
27    Lsadc,
28    Tsensor,
29    I2s,
30    Dma,
31    Sdma,
32    Sfc,
33    Trng,
34    SecurityGroup,
35}
36
37impl Peripheral {
38    /// The CLDO_CRG clock-gate register index (0 = `CKEN_CTL0`, 1 = `CKEN_CTL1`)
39    /// and bit position for this peripheral.
40    ///
41    /// PWM occupies 9 contiguous gates (`CKEN_CTL0` bits 2..=10); this returns
42    /// its base bit (2), and a bulk write would be needed to gate all nine.
43    pub fn cken_info(&self) -> (u8, u8) {
44        match self {
45            Peripheral::Pwm => (0, 2),
46            Peripheral::I2c0 => (0, 18),
47            Peripheral::I2c1 => (0, 19),
48            Peripheral::Timer => (0, 21),
49            Peripheral::Lsadc => (0, 22),
50            Peripheral::Tsensor => (0, 23),
51            Peripheral::I2s => (0, 24),
52            Peripheral::Trng => (0, 25),
53            Peripheral::SecurityGroup => (0, 26),
54            Peripheral::Uart0 => (1, 18),
55            Peripheral::Uart1 => (1, 19),
56            Peripheral::Uart2 => (1, 20),
57            Peripheral::Dma => (1, 22),
58            Peripheral::Sdma => (1, 23),
59            Peripheral::Sfc => (1, 24),
60            Peripheral::Spi0 => (1, 25),
61            Peripheral::Spi1 => (1, 26),
62        }
63    }
64}
65
66/// Number of [`Peripheral`] enum variants. Update when adding variants.
67pub const PERIPHERAL_COUNT: usize = 17;
68
69// ── Tests ──────────────────────────────────────────────────────
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74    use crate::soc::ws63::SYSTEM_CLOCK_HZ;
75
76    #[test]
77    fn test_system_clock_240mhz() {
78        assert_eq!(SYSTEM_CLOCK_HZ, 240_000_000);
79    }
80
81    #[test]
82    fn test_peripheral_count() {
83        assert_eq!(PERIPHERAL_COUNT, 17);
84    }
85
86    #[test]
87    fn test_peripheral_cken_info_coverage() {
88        let peripherals = [
89            Peripheral::Pwm,
90            Peripheral::I2c0,
91            Peripheral::I2c1,
92            Peripheral::Timer,
93            Peripheral::Lsadc,
94            Peripheral::Tsensor,
95            Peripheral::I2s,
96            Peripheral::Trng,
97            Peripheral::SecurityGroup,
98            Peripheral::Uart0,
99            Peripheral::Uart1,
100            Peripheral::Uart2,
101            Peripheral::Dma,
102            Peripheral::Sdma,
103            Peripheral::Sfc,
104            Peripheral::Spi0,
105            Peripheral::Spi1,
106        ];
107        for p in &peripherals {
108            let (reg, bit) = p.cken_info();
109            assert!(reg <= 1, "Peripheral {:?} has invalid reg={}", p, reg);
110            assert!(bit < 32, "Peripheral {:?} has invalid bit={}", p, bit);
111        }
112    }
113
114    #[test]
115    fn test_pwm_cken_info_returns_base_bit() {
116        let (reg, bit) = Peripheral::Pwm.cken_info();
117        assert_eq!(reg, 0);
118        assert_eq!(bit, 2);
119    }
120
121    #[test]
122    fn test_peripheral_variants_are_unique() {
123        let variants: [Peripheral; 17] = [
124            Peripheral::Uart0,
125            Peripheral::Uart1,
126            Peripheral::Uart2,
127            Peripheral::I2c0,
128            Peripheral::I2c1,
129            Peripheral::Spi0,
130            Peripheral::Spi1,
131            Peripheral::Pwm,
132            Peripheral::Timer,
133            Peripheral::Lsadc,
134            Peripheral::Tsensor,
135            Peripheral::I2s,
136            Peripheral::Dma,
137            Peripheral::Sdma,
138            Peripheral::Sfc,
139            Peripheral::Trng,
140            Peripheral::SecurityGroup,
141        ];
142        for i in 0..variants.len() {
143            for j in (i + 1)..variants.len() {
144                assert_ne!(variants[i], variants[j]);
145            }
146        }
147    }
148}