Skip to main content

pic32_hal/
clock.rs

1//! Clock helper and control functions
2// Work in progress, can calculate pb_clock only, no real control functions
3// implemented
4//
5
6use crate::time::Hertz;
7use crate::time::U32Ext;
8use core::marker::PhantomData;
9
10#[cfg(any(
11    feature = "pic32mx1xxfxxxb",
12    feature = "pic32mx2xxfxxxb",
13    feature = "pic32mx2x4fxxxb",
14    feature = "pic32mx37x",
15    feature = "pic32mx47x",
16))]
17pub mod refclock;
18
19#[cfg(feature = "pic32mx2x4fxxxb")]
20use crate::pac::CRU;
21
22#[cfg(any(
23    feature = "pic32mx1xxfxxxb",
24    feature = "pic32mx2xxfxxxb",
25    feature = "pic32mx37x",
26    feature = "pic32mx47x",
27))]
28use crate::pac::OSC;
29
30#[cfg(feature = "pic32mx2x4fxxxb")]
31pub struct Osc {
32    cru: CRU,
33    sysclock: Hertz,
34}
35
36#[cfg(any(
37    feature = "pic32mx1xxfxxxb",
38    feature = "pic32mx2xxfxxxb",
39    feature = "pic32mx37x",
40    feature = "pic32mx47x",
41))]
42pub struct Osc {
43    osc: OSC,
44    sysclock: Hertz,
45}
46
47pub struct Simple;
48
49pub struct WithRefclock;
50
51/// Clock module errors
52#[derive(PartialEq, Eq, Clone, Copy, Debug)]
53pub enum Error {
54    /// Operation cannot performed in the current state of the clock module
55    InvalidState,
56
57    /// Value is out of range supported by the hardware
58    InvalidArgument,
59}
60
61#[cfg(feature = "pic32mx2x4fxxxb")]
62impl Osc {
63    /// Create a new `Osc` from a possibly constant sysclock value. The sysclock
64    /// value should be set to the core clock resulting from the configuration
65    /// words and, if a crystal oscillator is used, the crystal frequency.
66    pub const fn new(cru: CRU, sysclock: Hertz) -> Osc {
67        Osc { cru, sysclock }
68    }
69
70    /// Create a new `Osc` and `Refclock` from a possibly constant sysclock
71    /// value. The sysclock value should be set to the core clock resulting from
72    /// the configuration words and, if a crystal oscillator is used, the
73    /// crystal frequency.
74    pub const fn new_with_refclock(cru: CRU, sysclock: Hertz) -> (Osc, refclock::Refclock) {
75        (
76            Osc { cru, sysclock },
77            refclock::Refclock {
78                _private: PhantomData,
79            },
80        )
81    }
82
83    /// Get the sysclock
84    pub fn sysclock(&self) -> Hertz {
85        self.sysclock
86    }
87
88    /// Determine the peripheral clock frequency based on the sysclock value
89    /// and the peripheral clock divider setting
90    pub fn pb_clock(&self) -> Hertz {
91        let div = self.cru.pb1div.read().pbdiv().bits();
92        let freq = self.sysclock.0 / (div as u32 + 1);
93        freq.hz()
94    }
95}
96
97#[cfg(any(
98    feature = "pic32mx1xxfxxxb",
99    feature = "pic32mx2xxfxxxb",
100    feature = "pic32mx37x",
101    feature = "pic32mx47x",
102))]
103impl Osc {
104    /// Create a new `Osc` from a possibly constant sysclock value. The sysclock
105    /// value should be set to the core clock resulting from the configuration
106    /// words and, if a crystal oscillator is used, the crystal frequency.
107    pub const fn new(osc: OSC, sysclock: Hertz) -> Osc {
108        Osc { osc, sysclock }
109    }
110
111    /// Create a new `Osc` and `Refclock` from a possibly constant sysclock
112    /// value. The sysclock value should be set to the core clock resulting from
113    /// the configuration words and, if a crystal oscillator is used, the
114    /// crystal frequency.
115    pub const fn new_with_refclock(osc: OSC, sysclock: Hertz) -> (Osc, refclock::Refclock) {
116        (
117            Osc { osc, sysclock },
118            refclock::Refclock {
119                _private: PhantomData,
120            },
121        )
122    }
123
124    /// Get the sysclock
125    pub fn sysclock(&self) -> Hertz {
126        self.sysclock
127    }
128
129    /// Determine the peripheral clock frequency based on the sysclock value
130    /// and the peripheral clock divider setting
131    pub fn pb_clock(&self) -> Hertz {
132        let div = self.osc.osccon.read().pbdiv().bits();
133        let freq = self.sysclock.0 >> div;
134        freq.hz()
135    }
136}