aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jorge Aparicio <jorge@japaric.io> 2019-07-11 13:28:25 +0200
committerGravatar Jorge Aparicio <jorge@japaric.io> 2019-07-11 13:28:25 +0200
commita87cb2486f488666450636c9cb68f79681f5f358 (patch)
tree69d8ce0cda38b9ff7cef307fae53fd6a275df3ef /src
parent6a8404ac92a7d4a57188e962862c450be9b9b31a (diff)
downloadrtic-a87cb2486f488666450636c9cb68f79681f5f358.tar.gz
rtic-a87cb2486f488666450636c9cb68f79681f5f358.tar.zst
rtic-a87cb2486f488666450636c9cb68f79681f5f358.zip
change Monotonic::ratio return type to Fraction
Diffstat (limited to '')
-rw-r--r--src/cyccnt.rs16
-rw-r--r--src/lib.rs14
-rw-r--r--src/tq.rs10
3 files changed, 29 insertions, 11 deletions
diff --git a/src/cyccnt.rs b/src/cyccnt.rs
index 468aa712..c8a1b7ee 100644
--- a/src/cyccnt.rs
+++ b/src/cyccnt.rs
@@ -10,9 +10,15 @@ use core::{
use cortex_m::peripheral::DWT;
+use crate::Fraction;
+
/// A measurement of the CYCCNT. Opaque and useful only with `Duration`
///
/// This data type is only available on ARMv7-M
+///
+/// Note that this value is tied to the CYCCNT of one core and that sending it a different core
+/// makes it lose its meaning -- each Cortex-M core has its own CYCCNT counter and these are usually
+/// unsynchronized and they may even be running at different frequencies.
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Instant {
inner: i32,
@@ -21,7 +27,6 @@ pub struct Instant {
unsafe impl Sync for Instant {}
-#[cfg(not(feature = "heterogeneous"))]
unsafe impl Send for Instant {}
impl Instant {
@@ -182,15 +187,16 @@ impl U32Ext for u32 {
}
/// Implementation of the `Monotonic` trait based on CYCle CouNTer
-#[cfg(not(feature = "heterogeneous"))]
pub struct CYCCNT;
-#[cfg(not(feature = "heterogeneous"))]
impl crate::Monotonic for CYCCNT {
type Instant = Instant;
- fn ratio() -> u32 {
- 1
+ fn ratio() -> Fraction {
+ Fraction {
+ numerator: 1,
+ denominator: 1,
+ }
}
unsafe fn reset() {
diff --git a/src/lib.rs b/src/lib.rs
index decd2da1..22eff5ac 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -116,13 +116,25 @@ impl From<cortex_m::Peripherals> for Peripherals {
}
}
+/// A fraction
+pub struct Fraction {
+ /// The numerator
+ pub numerator: u32,
+
+ /// The denominator
+ pub denominator: u32,
+}
+
/// A monotonic clock / counter
pub trait Monotonic {
/// A measurement of this clock
type Instant: Copy + Ord + Sub;
/// The ratio between the SysTick (system timer) frequency and this clock frequency
- fn ratio() -> u32;
+ ///
+ /// The ratio must be expressed in *reduced* `Fraction` form to prevent overflows. That is
+ /// `2 / 3` instead of `4 / 6`
+ fn ratio() -> Fraction;
/// Returns the current time
fn now() -> Self::Instant;
diff --git a/src/tq.rs b/src/tq.rs
index 4f9b6e7e..4edb40a7 100644
--- a/src/tq.rs
+++ b/src/tq.rs
@@ -62,11 +62,11 @@ where
// set a new timeout
const MAX: u32 = 0x00ffffff;
- let dur = match (instant - now)
- .try_into()
- .ok()
- .and_then(|x| x.checked_mul(M::ratio()))
- {
+ let ratio = M::ratio();
+ let dur = match (instant - now).try_into().ok().and_then(|x| {
+ x.checked_mul(ratio.numerator)
+ .map(|x| x / ratio.denominator)
+ }) {
None => MAX,
Some(x) => cmp::min(MAX, x),
};