Skip to content

Commit ef763f4

Browse files
committed
Impl the getting of systime as a clock count impl
1 parent a0a02ce commit ef763f4

File tree

3 files changed

+86
-56
lines changed

3 files changed

+86
-56
lines changed

esp-hal/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ usb-device = { version = "0.3.2", optional = true }
5151
rand_core = "0.6.4"
5252
ufmt-write = { version = "0.1.0", optional = true }
5353
xtensa-lx = { version = "0.9.0", optional = true }
54+
counters = {git = "https://github.com/Ben-PH/counter-proposal.git", rev = "07d19fe62c36219663c3917bb8cf1fe5eb752eaa"}
5455

5556
# IMPORTANT:
5657
# Each supported device MUST have its PAC included below along with a

esp-hal/src/soc/esp32/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub unsafe extern "C" fn ESP32Reset() -> ! {
8585
}
8686

8787
crate::interrupt::setup_interrupts();
88-
crate::time::time_init();
88+
let _ = crate::time::SysUptime::time_init();
8989

9090
// continue with default reset handler
9191
xtensa_lx_rt::Reset();

esp-hal/src/time.rs

Lines changed: 84 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,105 @@
1-
//! The `time` module offers a way to get the system uptime.
1+
//! `SysUptime` implements proposed embedded-hal `TimeCount` trait to get system uptime
22
//!
33
//! ### Example
44
//! ```no_run
55
//! let time = time::current_time();
66
//! ```
77
#![warn(missing_docs)]
8+
use counters::TimeCount;
89

9-
/// Provides time since system start in microseconds precision
10+
/// Provides an interface by which to access the platforms clock. Can be used where
11+
/// (proposed) embedded-hal `TimeCount` implementor is expected.
12+
pub struct SysUptime;
13+
14+
/// Provides time since system start
1015
///
1116
/// The counter won’t measure time in sleep-mode.
1217
///
1318
/// The timer will wrap after
1419
#[cfg_attr(esp32, doc = "36_558 years")]
1520
#[cfg_attr(esp32s2, doc = "7_311 years")]
1621
#[cfg_attr(not(any(esp32, esp32s2)), doc = "more than 7 years")]
17-
pub fn current_time() -> fugit::Instant<u64, 1, 1_000_000> {
22+
impl counters::TimeCount for SysUptime {
23+
type RawData = u64;
24+
25+
26+
27+
/// Defines granularity of the timer. Combines with the raw tick count to derive an instant
28+
#[cfg(not(esp32))]
29+
type TickMeasure = fugit::Instant<Self::RawData, 1, {crate::timer::systimer::TICKS_PER_SECOND}>;
1830
#[cfg(esp32)]
19-
let (ticks, div) = {
20-
// on ESP32 use LACT
21-
let tg0 = unsafe { crate::peripherals::TIMG0::steal() };
22-
tg0.lactupdate().write(|w| unsafe { w.update().bits(1) });
23-
24-
// The peripheral doesn't have a bit to indicate that the update is done, so we
25-
// poll the lower 32 bit part of the counter until it changes, or a timeout
26-
// expires.
27-
let lo_initial = tg0.lactlo().read().bits();
28-
let mut div = tg0.lactconfig().read().divider().bits();
29-
let lo = loop {
30-
let lo = tg0.lactlo().read().bits();
31-
if lo != lo_initial || div == 0 {
32-
break lo;
33-
}
34-
div -= 1;
31+
type TickMeasure = fugit::Duration<Self::RawData, 1, 16_000_000>;
32+
33+
type Error = ();
34+
35+
fn try_now_raw(&self) -> Result<Self::RawData, Self::Error> {
36+
#[cfg(esp32)]
37+
let ticks = {
38+
// on ESP32 use LACT
39+
let tg0 = unsafe { crate::peripherals::TIMG0::steal() };
40+
tg0.lactupdate().write(|w| unsafe { w.update().bits(1) });
41+
42+
// The peripheral doesn't have a bit to indicate that the update is done, so we
43+
// poll the lower 32 bit part of the counter until it changes, or a timeout
44+
// expires.
45+
let lo_initial = tg0.lactlo().read().bits();
46+
let mut div = tg0.lactconfig().read().divider().bits();
47+
let lo = loop {
48+
let lo = tg0.lactlo().read().bits();
49+
if lo != lo_initial || div == 0 {
50+
break lo;
51+
}
52+
div -= 1;
53+
};
54+
let hi = tg0.lacthi().read().bits();
55+
56+
let ticks = (hi as u64) << 32u64 | lo as u64;
57+
ticks
3558
};
36-
let hi = tg0.lacthi().read().bits();
3759

38-
let ticks = (hi as u64) << 32u64 | lo as u64;
39-
(ticks, 16)
40-
};
60+
#[cfg(not(esp32))]
61+
let ticks = {
62+
// otherwise use SYSTIMER
63+
crate::timer::systimer::SystemTimer::now()
64+
};
4165

42-
#[cfg(not(esp32))]
43-
let (ticks, div) = {
44-
// otherwise use SYSTIMER
45-
let ticks = crate::timer::systimer::SystemTimer::now();
46-
(
47-
ticks,
48-
(crate::timer::systimer::SystemTimer::TICKS_PER_SECOND / 1_000_000),
49-
)
50-
};
51-
52-
fugit::Instant::<u64, 1, 1_000_000>::from_ticks(ticks / div)
66+
Ok(ticks)
67+
}
68+
69+
fn try_now(&self) -> Result<Self::TickMeasure, Self::Error> {
70+
let ticks = self.try_now_raw()?;
71+
Ok(Self::TickMeasure::from_ticks(ticks))
72+
73+
}
5374
}
5475

55-
#[cfg(esp32)]
56-
pub(crate) fn time_init() {
57-
// we assume 80MHz APB clock source - there is no way to configure it in a
58-
// different way currently
59-
const APB_FREQUENCY: u32 = 80_000_000u32;
60-
61-
let tg0 = unsafe { crate::peripherals::TIMG0::steal() };
62-
63-
tg0.lactconfig().write(|w| unsafe { w.bits(0) });
64-
tg0.lactalarmhi().write(|w| unsafe { w.bits(u32::MAX) });
65-
tg0.lactalarmlo().write(|w| unsafe { w.bits(u32::MAX) });
66-
tg0.lactload().write(|w| unsafe { w.load().bits(1) });
67-
68-
// 16 MHz counter
69-
tg0.lactconfig()
70-
.modify(|_, w| unsafe { w.divider().bits((APB_FREQUENCY / 16_000_000u32) as u16) });
71-
tg0.lactconfig().modify(|_, w| {
72-
w.increase().bit(true);
73-
w.autoreload().bit(true);
74-
w.en().bit(true)
75-
});
76+
impl SysUptime {
77+
#[cfg(esp32)]
78+
pub(crate) fn time_init() -> Self {
79+
// we assume 80MHz APB clock source - there is no way to configure it in a
80+
// different way currently
81+
const APB_FREQUENCY: u32 = 80_000_000u32;
82+
83+
let tg0 = unsafe { crate::peripherals::TIMG0::steal() };
84+
85+
tg0.lactconfig().write(|w| unsafe { w.bits(0) });
86+
tg0.lactalarmhi().write(|w| unsafe { w.bits(u32::MAX) });
87+
tg0.lactalarmlo().write(|w| unsafe { w.bits(u32::MAX) });
88+
tg0.lactload().write(|w| unsafe { w.load().bits(1) });
89+
90+
// 16 MHz counter
91+
tg0.lactconfig()
92+
.modify(|_, w| unsafe { w.divider().bits((APB_FREQUENCY / 16_000_000u32) as u16) });
93+
tg0.lactconfig().modify(|_, w| {
94+
w.increase().bit(true);
95+
w.autoreload().bit(true);
96+
w.en().bit(true)
97+
});
98+
Self
99+
}
100+
#[deprecated(note = "Use SysUptime::try_now() instead")]
101+
#[allow(missing_docs)]
102+
pub fn current_time(&self) -> <Self as counters::TimeCount>::TickMeasure {
103+
self.try_now().unwrap()
104+
}
76105
}

0 commit comments

Comments
 (0)