Skip to content

Commit 3dfcd02

Browse files
committed
clocks: Fix comments & rename approximate_frequency
1 parent 6cbfae2 commit 3dfcd02

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

rp2040-hal/src/clocks/mod.rs

+35-5
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,30 @@ pub use clock_sources::{GPin0, GPin1};
8484

8585
use clock_sources::{PllSys, PllUsb, Rosc, Xosc};
8686

87+
/// Frequency counter accuracy
88+
///
89+
/// See: https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#table-fc-test-interval
90+
#[repr(u8)]
91+
#[allow(missing_docs)]
92+
pub enum FCAccuracy {
93+
_2048kHz = 0,
94+
_1024kHz,
95+
_512kHz,
96+
_256kHz,
97+
_128kHz,
98+
_64kHz,
99+
_32kHz,
100+
_16kHz,
101+
_8kHz,
102+
_4kHz,
103+
_2kHz,
104+
_1kHz,
105+
_500Hz,
106+
_250Hz,
107+
_125Hz,
108+
_62_5Hz,
109+
}
110+
87111
#[derive(Copy, Clone)]
88112
/// Provides refs to the CLOCKS block.
89113
struct ShareableClocks {
@@ -305,8 +329,8 @@ impl ClocksManager {
305329
.configure_clock(&self.system_clock, self.system_clock.freq())
306330
}
307331

308-
/// Approximates the frequency of the given clock source.
309-
pub fn approximate_frequency<C: ClockSource>(&mut self, _trg_clk: C) -> HertzU32 {
332+
/// Measure the frequency of the given clock source by approximation.
333+
pub fn measure_frequency<C: ClockSource>(&mut self, _trg_clk: C, accuracy: FCAccuracy) -> HertzU32 {
310334
// Wait for the frequency counter to be ready
311335
while self.clocks.fc0_status.read().running().bit_is_set() {
312336
core::hint::spin_loop()
@@ -318,10 +342,14 @@ impl ClocksManager {
318342
.bits(self.reference_clock.get_freq().to_kHz())
319343
});
320344

321-
// Corresponds to a 1ms test time, which seems to give good enough accuracy
345+
// > The test interval is 0.98us * 2**interval, but let's call it 1us * 2**interval.
346+
// > The default gives a test interval of 250us
347+
//
348+
// https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#reg-clocks-FC0_INTERVAL
349+
// https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#table-fc-test-interval
322350
self.clocks
323351
.fc0_interval
324-
.write(|w| unsafe { w.fc0_interval().bits(10) });
352+
.write(|w| unsafe { w.fc0_interval().bits(accuracy as u8) });
325353

326354
// We don't really care about the min/max, so these are just set to min/max values.
327355
self.clocks
@@ -331,7 +359,7 @@ impl ClocksManager {
331359
.fc0_max_khz
332360
.write(|w| unsafe { w.fc0_max_khz().bits(0xffffffff) });
333361

334-
// To measure rosc directly we use the value 0x03.
362+
// Select which clock to measure.
335363
self.clocks
336364
.fc0_src
337365
.write(|w| w.fc0_src().variant(C::FCOUNTER_SRC));
@@ -341,6 +369,8 @@ impl ClocksManager {
341369
core::hint::spin_loop()
342370
}
343371

372+
// TODO: the result may not be valid (eg clock stopped during measurement). We may want to
373+
// return a Result instead. Is it worth the hassle though?
344374
let speed_hz = self.clocks.fc0_result.read().khz().bits() * 1000;
345375
speed_hz.Hz()
346376
}

0 commit comments

Comments
 (0)