diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-06-28 23:58:51 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-06-28 23:58:51 +0200 |
| commit | f501907f9e69c1d47571b6e0980f22dde723b45d (patch) | |
| tree | fb29dbf1cbef12744840c6d612dc0211ae6373b9 | |
| parent | cdb0c72849558db2b210301f5d13a922308e6bf1 (diff) | |
| parent | 51583afc1e1e5d6eafefbb994c153d1d923a502f (diff) | |
Merge pull request #259 from thalesfragoso/block-timer
Add BlockingTimer and features to choose tick rate
| -rw-r--r-- | embassy/Cargo.toml | 5 | ||||
| -rw-r--r-- | embassy/src/time/mod.rs | 71 |
2 files changed, 74 insertions, 2 deletions
diff --git a/embassy/Cargo.toml b/embassy/Cargo.toml index 6364f9902..87f54409a 100644 --- a/embassy/Cargo.toml +++ b/embassy/Cargo.toml | |||
| @@ -5,7 +5,11 @@ authors = ["Dario Nieuwenhuis <[email protected]>"] | |||
| 5 | edition = "2018" | 5 | edition = "2018" |
| 6 | 6 | ||
| 7 | [features] | 7 | [features] |
| 8 | default = ["tick-32768hz"] | ||
| 8 | std = ["futures/std", "embassy-traits/std"] | 9 | std = ["futures/std", "embassy-traits/std"] |
| 10 | tick-32768hz = [] | ||
| 11 | tick-1000hz = [] | ||
| 12 | tick-1mhz = [] | ||
| 9 | 13 | ||
| 10 | defmt-trace = [] | 14 | defmt-trace = [] |
| 11 | defmt-debug = [] | 15 | defmt-debug = [] |
| @@ -26,6 +30,7 @@ embassy-macros = { version = "0.1.0", path = "../embassy-macros"} | |||
| 26 | embassy-traits = { version = "0.1.0", path = "../embassy-traits"} | 30 | embassy-traits = { version = "0.1.0", path = "../embassy-traits"} |
| 27 | atomic-polyfill = { version = "0.1.1" } | 31 | atomic-polyfill = { version = "0.1.1" } |
| 28 | critical-section = "0.2.1" | 32 | critical-section = "0.2.1" |
| 33 | embedded-hal = "0.2.5" | ||
| 29 | 34 | ||
| 30 | # Workaround https://github.com/japaric/cast.rs/pull/27 | 35 | # Workaround https://github.com/japaric/cast.rs/pull/27 |
| 31 | cast = { version = "=0.2.3", default-features = false } | 36 | cast = { version = "=0.2.3", default-features = false } |
diff --git a/embassy/src/time/mod.rs b/embassy/src/time/mod.rs index 21b93d384..d50d9ef0d 100644 --- a/embassy/src/time/mod.rs +++ b/embassy/src/time/mod.rs | |||
| @@ -10,8 +10,22 @@ pub use duration::Duration; | |||
| 10 | pub use instant::Instant; | 10 | pub use instant::Instant; |
| 11 | pub use traits::*; | 11 | pub use traits::*; |
| 12 | 12 | ||
| 13 | // TODO allow customizing, probably via Cargo features `tick-hz-32768` or something. | 13 | #[cfg(any( |
| 14 | pub const TICKS_PER_SECOND: u64 = 32768; | 14 | all(feature = "tick-32768hz", feature = "tick-1000hz"), |
| 15 | all(feature = "tick-32768hz", feature = "tick-1mhz"), | ||
| 16 | ))] | ||
| 17 | compile_error!( | ||
| 18 | "Disable default-features to be able to use a tick rate other than the default (32768 Hz)" | ||
| 19 | ); | ||
| 20 | |||
| 21 | #[cfg(feature = "tick-1000hz")] | ||
| 22 | pub const TICKS_PER_SECOND: u64 = 1_000; | ||
| 23 | |||
| 24 | #[cfg(feature = "tick-32768hz")] | ||
| 25 | pub const TICKS_PER_SECOND: u64 = 32_768; | ||
| 26 | |||
| 27 | #[cfg(feature = "tick-1mhz")] | ||
| 28 | pub const TICKS_PER_SECOND: u64 = 1_000_000; | ||
| 15 | 29 | ||
| 16 | static mut CLOCK: Option<&'static dyn Clock> = None; | 30 | static mut CLOCK: Option<&'static dyn Clock> = None; |
| 17 | 31 | ||
| @@ -28,3 +42,56 @@ pub unsafe fn set_clock(clock: &'static dyn Clock) { | |||
| 28 | pub(crate) fn now() -> u64 { | 42 | pub(crate) fn now() -> u64 { |
| 29 | unsafe { unwrap!(CLOCK, "No clock set").now() } | 43 | unsafe { unwrap!(CLOCK, "No clock set").now() } |
| 30 | } | 44 | } |
| 45 | |||
| 46 | /// Type used for blocking delays through embedded-hal traits. | ||
| 47 | /// | ||
| 48 | /// For this interface to work, the Executor's clock must be correctly initialized before using it. | ||
| 49 | /// The delays are implemented in a "best-effort" way, meaning that the cpu will block for at least | ||
| 50 | /// the amount provided, but accuracy can be affected by many factors, including interrupt usage. | ||
| 51 | /// Make sure to use a suitable tick rate for your use case. The tick rate can be chosen through | ||
| 52 | /// features flags of this crate. | ||
| 53 | pub struct BlockingTimer; | ||
| 54 | |||
| 55 | impl embedded_hal::blocking::delay::DelayMs<u8> for BlockingTimer { | ||
| 56 | fn delay_ms(&mut self, ms: u8) { | ||
| 57 | block_for(Duration::from_millis(ms as u64)) | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | impl embedded_hal::blocking::delay::DelayMs<u16> for BlockingTimer { | ||
| 62 | fn delay_ms(&mut self, ms: u16) { | ||
| 63 | block_for(Duration::from_millis(ms as u64)) | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | impl embedded_hal::blocking::delay::DelayMs<u32> for BlockingTimer { | ||
| 68 | fn delay_ms(&mut self, ms: u32) { | ||
| 69 | block_for(Duration::from_millis(ms as u64)) | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | impl embedded_hal::blocking::delay::DelayUs<u8> for BlockingTimer { | ||
| 74 | fn delay_us(&mut self, us: u8) { | ||
| 75 | block_for(Duration::from_micros(us as u64)) | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | impl embedded_hal::blocking::delay::DelayUs<u16> for BlockingTimer { | ||
| 80 | fn delay_us(&mut self, us: u16) { | ||
| 81 | block_for(Duration::from_micros(us as u64)) | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | impl embedded_hal::blocking::delay::DelayUs<u32> for BlockingTimer { | ||
| 86 | fn delay_us(&mut self, us: u32) { | ||
| 87 | block_for(Duration::from_micros(us as u64)) | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | /// Blocks the cpu for at least `duration`. | ||
| 92 | /// | ||
| 93 | /// For this interface to work, the Executor's clock must be correctly initialized before using it. | ||
| 94 | pub fn block_for(duration: Duration) { | ||
| 95 | let expires_at = Instant::now() + duration; | ||
| 96 | while Instant::now() < expires_at {} | ||
| 97 | } | ||
