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