aboutsummaryrefslogtreecommitdiff
path: root/embassy-time
diff options
context:
space:
mode:
authorFrostie314159 <[email protected]>2024-03-31 20:48:05 +0200
committerGitHub <[email protected]>2024-03-31 20:48:05 +0200
commit67c9cc2c4b886e6962ecdd6eff8794b14c1accdc (patch)
treef176ab269949d26f48e04c950cebc5489bae8c56 /embassy-time
parenta2f9aa592ec61beb247065003016515f0d423c13 (diff)
parent6634cc90bcd3eb25b64712688920f383584b2964 (diff)
Merge branch 'embassy-rs:main' into ticker_send_sync
Diffstat (limited to 'embassy-time')
-rw-r--r--embassy-time/CHANGELOG.md6
-rw-r--r--embassy-time/Cargo.toml558
-rw-r--r--embassy-time/README.md36
-rw-r--r--embassy-time/build.rs18
-rw-r--r--embassy-time/gen_tick.py60
-rw-r--r--embassy-time/src/delay.rs1
-rw-r--r--embassy-time/src/driver.rs175
-rw-r--r--embassy-time/src/driver_mock.rs191
-rw-r--r--embassy-time/src/driver_std.rs5
-rw-r--r--embassy-time/src/driver_wasm.rs5
-rw-r--r--embassy-time/src/fmt.rs3
-rw-r--r--embassy-time/src/instant.rs6
-rw-r--r--embassy-time/src/lib.rs19
-rw-r--r--embassy-time/src/queue.rs58
-rw-r--r--embassy-time/src/queue_generic.rs112
-rw-r--r--embassy-time/src/tick.rs482
-rw-r--r--embassy-time/src/timer.rs50
17 files changed, 620 insertions, 1165 deletions
diff --git a/embassy-time/CHANGELOG.md b/embassy-time/CHANGELOG.md
index d8c0c7d08..df093949f 100644
--- a/embassy-time/CHANGELOG.md
+++ b/embassy-time/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 7
8## 0.3.0 - 2024-01-11
9
10- Update `embedded-hal-async` to `1.0.0`
11- Update `embedded-hal v1` to `1.0.0`
12- Split the time driver to a separate `embassy-time-driver` crate.
13
8## 0.2.0 - 2023-12-04 14## 0.2.0 - 2023-12-04
9 15
10- Added tick rates in multiples of 10 kHz 16- Added tick rates in multiples of 10 kHz
diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml
index 94e79382f..6b0a0f22d 100644
--- a/embassy-time/Cargo.toml
+++ b/embassy-time/Cargo.toml
@@ -1,9 +1,10 @@
1[package] 1[package]
2name = "embassy-time" 2name = "embassy-time"
3version = "0.2.0" 3version = "0.3.0"
4edition = "2021" 4edition = "2021"
5description = "Instant and Duration for embedded no-std systems, with async timer support" 5description = "Instant and Duration for embedded no-std systems, with async timer support"
6repository = "https://github.com/embassy-rs/embassy" 6repository = "https://github.com/embassy-rs/embassy"
7documentation = "https://docs.embassy.dev/embassy-time"
7readme = "README.md" 8readme = "README.md"
8license = "MIT OR Apache-2.0" 9license = "MIT OR Apache-2.0"
9categories = [ 10categories = [
@@ -13,12 +14,6 @@ categories = [
13 "asynchronous", 14 "asynchronous",
14] 15]
15 16
16# Prevent multiple copies of this crate in the same binary.
17# Needed because different copies might get different tick rates, causing
18# wrong delays if the time driver is using one copy and user code is using another.
19# This is especially common when mixing crates from crates.io and git.
20links = "embassy-time"
21
22[package.metadata.embassy_docs] 17[package.metadata.embassy_docs]
23src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-v$VERSION/embassy-time/src/" 18src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-v$VERSION/embassy-time/src/"
24src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time/src/" 19src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time/src/"
@@ -32,217 +27,394 @@ features = ["defmt", "std"]
32std = ["tick-hz-1_000_000", "critical-section/std"] 27std = ["tick-hz-1_000_000", "critical-section/std"]
33wasm = ["dep:wasm-bindgen", "dep:js-sys", "dep:wasm-timer", "tick-hz-1_000_000"] 28wasm = ["dep:wasm-bindgen", "dep:js-sys", "dep:wasm-timer", "tick-hz-1_000_000"]
34 29
35# Display a timestamp of the number of seconds since startup next to defmt log messages 30## Display a timestamp of the number of seconds since startup next to defmt log messages
36# To use this you must have a time driver provided. 31## To use this you must have a time driver provided.
37defmt-timestamp-uptime = ["defmt"] 32defmt-timestamp-uptime = ["defmt"]
38 33
39# Create a global, generic queue that can be used with any executor 34## Create a `MockDriver` that can be manually advanced for testing purposes.
40# To use this you must have a time driver provided. 35mock-driver = ["tick-hz-1_000_000"]
36
37#! ### Generic Queue
38
39## Create a global, generic queue that can be used with any executor.
40## To use this you must have a time driver provided.
41generic-queue = [] 41generic-queue = []
42 42
43# Set the number of timers for the generic queue. 43#! The following features set how many timers are used for the generic queue. At most one
44# 44#! `generic-queue-*` feature can be enabled. If none is enabled, a default of 64 timers is used.
45# At most 1 `generic-queue-*` feature can be enabled. If none is enabled, a default of 64 timers is used. 45#!
46# 46#! When using embassy-time from libraries, you should *not* enable any `generic-queue-*` feature, to allow the
47# When using embassy-time from libraries, you should *not* enable any `generic-queue-*` feature, to allow the 47#! end user to pick.
48# end user to pick. 48
49## Generic Queue with 8 timers
49generic-queue-8 = ["generic-queue"] 50generic-queue-8 = ["generic-queue"]
51## Generic Queue with 16 timers
50generic-queue-16 = ["generic-queue"] 52generic-queue-16 = ["generic-queue"]
53## Generic Queue with 32 timers
51generic-queue-32 = ["generic-queue"] 54generic-queue-32 = ["generic-queue"]
55## Generic Queue with 64 timers
52generic-queue-64 = ["generic-queue"] 56generic-queue-64 = ["generic-queue"]
57## Generic Queue with 128 timers
53generic-queue-128 = ["generic-queue"] 58generic-queue-128 = ["generic-queue"]
54 59
55# Create a `MockDriver` that can be manually advanced for testing purposes. 60#! ### Tick Rate
56mock-driver = ["tick-hz-1_000_000"] 61#!
57 62#! At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used.
58# Set the `embassy_time` tick rate. 63#!
59# 64#! If the time driver in use supports using arbitrary tick rates, you can enable one `tick-*`
60# At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used. 65#! feature from your binary crate to set the tick rate. The driver will use configured tick rate.
61# 66#! If the time driver supports a fixed tick rate, it will enable one feature itself, so you should
62# If the time driver in use supports using arbitrary tick rates, you can enable one `tick-*` 67#! not enable one. Check the time driver documentation for details.
63# feature from your binary crate to set the tick rate. The driver will use configured tick rate. 68#!
64# If the time driver supports a fixed tick rate, it will enable one feature itself, so you should 69#! When using embassy-time from libraries, you should *not* enable any `tick-*` feature, to allow the
65# not enable one. Check the time driver documentation for details. 70#! end user or the driver to pick.
66# 71#! <details>
67# When using embassy-time from libraries, you should *not* enable any `tick-*` feature, to allow the 72#! <summary>Available tick rates:</summary>
68# end user or the driver to pick. 73#! <!-- Next line must be left empty for the features to render correctly! -->
74#!
69 75
70# BEGIN TICKS 76# BEGIN TICKS
71# Generated by gen_tick.py. DO NOT EDIT. 77# Generated by gen_tick.py. DO NOT EDIT.
72tick-hz-1 = [] 78## 1Hz Tick Rate
73tick-hz-10 = [] 79tick-hz-1 = ["embassy-time-driver/tick-hz-1"]
74tick-hz-100 = [] 80## 2Hz Tick Rate
75tick-hz-1_000 = [] 81tick-hz-2 = ["embassy-time-driver/tick-hz-2"]
76tick-hz-10_000 = [] 82## 4Hz Tick Rate
77tick-hz-100_000 = [] 83tick-hz-4 = ["embassy-time-driver/tick-hz-4"]
78tick-hz-1_000_000 = [] 84## 8Hz Tick Rate
79tick-hz-10_000_000 = [] 85tick-hz-8 = ["embassy-time-driver/tick-hz-8"]
80tick-hz-100_000_000 = [] 86## 10Hz Tick Rate
81tick-hz-1_000_000_000 = [] 87tick-hz-10 = ["embassy-time-driver/tick-hz-10"]
82tick-hz-2 = [] 88## 16Hz Tick Rate
83tick-hz-4 = [] 89tick-hz-16 = ["embassy-time-driver/tick-hz-16"]
84tick-hz-8 = [] 90## 32Hz Tick Rate
85tick-hz-16 = [] 91tick-hz-32 = ["embassy-time-driver/tick-hz-32"]
86tick-hz-32 = [] 92## 64Hz Tick Rate
87tick-hz-64 = [] 93tick-hz-64 = ["embassy-time-driver/tick-hz-64"]
88tick-hz-128 = [] 94## 100Hz Tick Rate
89tick-hz-256 = [] 95tick-hz-100 = ["embassy-time-driver/tick-hz-100"]
90tick-hz-512 = [] 96## 128Hz Tick Rate
91tick-hz-1_024 = [] 97tick-hz-128 = ["embassy-time-driver/tick-hz-128"]
92tick-hz-2_048 = [] 98## 256Hz Tick Rate
93tick-hz-4_096 = [] 99tick-hz-256 = ["embassy-time-driver/tick-hz-256"]
94tick-hz-8_192 = [] 100## 512Hz Tick Rate
95tick-hz-16_384 = [] 101tick-hz-512 = ["embassy-time-driver/tick-hz-512"]
96tick-hz-32_768 = [] 102## 1.0kHz Tick Rate
97tick-hz-65_536 = [] 103tick-hz-1_000 = ["embassy-time-driver/tick-hz-1_000"]
98tick-hz-131_072 = [] 104## 1.024kHz Tick Rate
99tick-hz-262_144 = [] 105tick-hz-1_024 = ["embassy-time-driver/tick-hz-1_024"]
100tick-hz-524_288 = [] 106## 2.0kHz Tick Rate
101tick-hz-1_048_576 = [] 107tick-hz-2_000 = ["embassy-time-driver/tick-hz-2_000"]
102tick-hz-2_097_152 = [] 108## 2.048kHz Tick Rate
103tick-hz-4_194_304 = [] 109tick-hz-2_048 = ["embassy-time-driver/tick-hz-2_048"]
104tick-hz-8_388_608 = [] 110## 4.0kHz Tick Rate
105tick-hz-16_777_216 = [] 111tick-hz-4_000 = ["embassy-time-driver/tick-hz-4_000"]
106tick-hz-2_000 = [] 112## 4.096kHz Tick Rate
107tick-hz-4_000 = [] 113tick-hz-4_096 = ["embassy-time-driver/tick-hz-4_096"]
108tick-hz-8_000 = [] 114## 8.0kHz Tick Rate
109tick-hz-16_000 = [] 115tick-hz-8_000 = ["embassy-time-driver/tick-hz-8_000"]
110tick-hz-32_000 = [] 116## 8.192kHz Tick Rate
111tick-hz-64_000 = [] 117tick-hz-8_192 = ["embassy-time-driver/tick-hz-8_192"]
112tick-hz-128_000 = [] 118## 10.0kHz Tick Rate
113tick-hz-256_000 = [] 119tick-hz-10_000 = ["embassy-time-driver/tick-hz-10_000"]
114tick-hz-512_000 = [] 120## 16.0kHz Tick Rate
115tick-hz-1_024_000 = [] 121tick-hz-16_000 = ["embassy-time-driver/tick-hz-16_000"]
116tick-hz-2_048_000 = [] 122## 16.384kHz Tick Rate
117tick-hz-4_096_000 = [] 123tick-hz-16_384 = ["embassy-time-driver/tick-hz-16_384"]
118tick-hz-8_192_000 = [] 124## 20.0kHz Tick Rate
119tick-hz-16_384_000 = [] 125tick-hz-20_000 = ["embassy-time-driver/tick-hz-20_000"]
120tick-hz-32_768_000 = [] 126## 32.0kHz Tick Rate
121tick-hz-65_536_000 = [] 127tick-hz-32_000 = ["embassy-time-driver/tick-hz-32_000"]
122tick-hz-131_072_000 = [] 128## 32.768kHz Tick Rate
123tick-hz-262_144_000 = [] 129tick-hz-32_768 = ["embassy-time-driver/tick-hz-32_768"]
124tick-hz-524_288_000 = [] 130## 40.0kHz Tick Rate
125tick-hz-20_000 = [] 131tick-hz-40_000 = ["embassy-time-driver/tick-hz-40_000"]
126tick-hz-40_000 = [] 132## 64.0kHz Tick Rate
127tick-hz-80_000 = [] 133tick-hz-64_000 = ["embassy-time-driver/tick-hz-64_000"]
128tick-hz-160_000 = [] 134## 65.536kHz Tick Rate
129tick-hz-320_000 = [] 135tick-hz-65_536 = ["embassy-time-driver/tick-hz-65_536"]
130tick-hz-640_000 = [] 136## 80.0kHz Tick Rate
131tick-hz-1_280_000 = [] 137tick-hz-80_000 = ["embassy-time-driver/tick-hz-80_000"]
132tick-hz-2_560_000 = [] 138## 100.0kHz Tick Rate
133tick-hz-5_120_000 = [] 139tick-hz-100_000 = ["embassy-time-driver/tick-hz-100_000"]
134tick-hz-10_240_000 = [] 140## 128.0kHz Tick Rate
135tick-hz-20_480_000 = [] 141tick-hz-128_000 = ["embassy-time-driver/tick-hz-128_000"]
136tick-hz-40_960_000 = [] 142## 131.072kHz Tick Rate
137tick-hz-81_920_000 = [] 143tick-hz-131_072 = ["embassy-time-driver/tick-hz-131_072"]
138tick-hz-163_840_000 = [] 144## 160.0kHz Tick Rate
139tick-hz-327_680_000 = [] 145tick-hz-160_000 = ["embassy-time-driver/tick-hz-160_000"]
140tick-hz-655_360_000 = [] 146## 256.0kHz Tick Rate
141tick-hz-1_310_720_000 = [] 147tick-hz-256_000 = ["embassy-time-driver/tick-hz-256_000"]
142tick-hz-2_621_440_000 = [] 148## 262.144kHz Tick Rate
143tick-hz-5_242_880_000 = [] 149tick-hz-262_144 = ["embassy-time-driver/tick-hz-262_144"]
144tick-hz-2_000_000 = [] 150## 320.0kHz Tick Rate
145tick-hz-3_000_000 = [] 151tick-hz-320_000 = ["embassy-time-driver/tick-hz-320_000"]
146tick-hz-4_000_000 = [] 152## 512.0kHz Tick Rate
147tick-hz-6_000_000 = [] 153tick-hz-512_000 = ["embassy-time-driver/tick-hz-512_000"]
148tick-hz-8_000_000 = [] 154## 524.288kHz Tick Rate
149tick-hz-9_000_000 = [] 155tick-hz-524_288 = ["embassy-time-driver/tick-hz-524_288"]
150tick-hz-12_000_000 = [] 156## 640.0kHz Tick Rate
151tick-hz-16_000_000 = [] 157tick-hz-640_000 = ["embassy-time-driver/tick-hz-640_000"]
152tick-hz-18_000_000 = [] 158## 1.0MHz Tick Rate
153tick-hz-24_000_000 = [] 159tick-hz-1_000_000 = ["embassy-time-driver/tick-hz-1_000_000"]
154tick-hz-32_000_000 = [] 160## 1.024MHz Tick Rate
155tick-hz-36_000_000 = [] 161tick-hz-1_024_000 = ["embassy-time-driver/tick-hz-1_024_000"]
156tick-hz-48_000_000 = [] 162## 1.048576MHz Tick Rate
157tick-hz-64_000_000 = [] 163tick-hz-1_048_576 = ["embassy-time-driver/tick-hz-1_048_576"]
158tick-hz-72_000_000 = [] 164## 1.28MHz Tick Rate
159tick-hz-96_000_000 = [] 165tick-hz-1_280_000 = ["embassy-time-driver/tick-hz-1_280_000"]
160tick-hz-128_000_000 = [] 166## 2.0MHz Tick Rate
161tick-hz-144_000_000 = [] 167tick-hz-2_000_000 = ["embassy-time-driver/tick-hz-2_000_000"]
162tick-hz-192_000_000 = [] 168## 2.048MHz Tick Rate
163tick-hz-256_000_000 = [] 169tick-hz-2_048_000 = ["embassy-time-driver/tick-hz-2_048_000"]
164tick-hz-288_000_000 = [] 170## 2.097152MHz Tick Rate
165tick-hz-384_000_000 = [] 171tick-hz-2_097_152 = ["embassy-time-driver/tick-hz-2_097_152"]
166tick-hz-512_000_000 = [] 172## 2.56MHz Tick Rate
167tick-hz-576_000_000 = [] 173tick-hz-2_560_000 = ["embassy-time-driver/tick-hz-2_560_000"]
168tick-hz-768_000_000 = [] 174## 3.0MHz Tick Rate
169tick-hz-20_000_000 = [] 175tick-hz-3_000_000 = ["embassy-time-driver/tick-hz-3_000_000"]
170tick-hz-30_000_000 = [] 176## 4.0MHz Tick Rate
171tick-hz-40_000_000 = [] 177tick-hz-4_000_000 = ["embassy-time-driver/tick-hz-4_000_000"]
172tick-hz-50_000_000 = [] 178## 4.096MHz Tick Rate
173tick-hz-60_000_000 = [] 179tick-hz-4_096_000 = ["embassy-time-driver/tick-hz-4_096_000"]
174tick-hz-70_000_000 = [] 180## 4.194304MHz Tick Rate
175tick-hz-80_000_000 = [] 181tick-hz-4_194_304 = ["embassy-time-driver/tick-hz-4_194_304"]
176tick-hz-90_000_000 = [] 182## 5.12MHz Tick Rate
177tick-hz-110_000_000 = [] 183tick-hz-5_120_000 = ["embassy-time-driver/tick-hz-5_120_000"]
178tick-hz-120_000_000 = [] 184## 6.0MHz Tick Rate
179tick-hz-130_000_000 = [] 185tick-hz-6_000_000 = ["embassy-time-driver/tick-hz-6_000_000"]
180tick-hz-140_000_000 = [] 186## 8.0MHz Tick Rate
181tick-hz-150_000_000 = [] 187tick-hz-8_000_000 = ["embassy-time-driver/tick-hz-8_000_000"]
182tick-hz-160_000_000 = [] 188## 8.192MHz Tick Rate
183tick-hz-170_000_000 = [] 189tick-hz-8_192_000 = ["embassy-time-driver/tick-hz-8_192_000"]
184tick-hz-180_000_000 = [] 190## 8.388608MHz Tick Rate
185tick-hz-190_000_000 = [] 191tick-hz-8_388_608 = ["embassy-time-driver/tick-hz-8_388_608"]
186tick-hz-200_000_000 = [] 192## 9.0MHz Tick Rate
187tick-hz-210_000_000 = [] 193tick-hz-9_000_000 = ["embassy-time-driver/tick-hz-9_000_000"]
188tick-hz-220_000_000 = [] 194## 10.0MHz Tick Rate
189tick-hz-230_000_000 = [] 195tick-hz-10_000_000 = ["embassy-time-driver/tick-hz-10_000_000"]
190tick-hz-240_000_000 = [] 196## 10.24MHz Tick Rate
191tick-hz-250_000_000 = [] 197tick-hz-10_240_000 = ["embassy-time-driver/tick-hz-10_240_000"]
192tick-hz-260_000_000 = [] 198## 12.0MHz Tick Rate
193tick-hz-270_000_000 = [] 199tick-hz-12_000_000 = ["embassy-time-driver/tick-hz-12_000_000"]
194tick-hz-280_000_000 = [] 200## 16.0MHz Tick Rate
195tick-hz-290_000_000 = [] 201tick-hz-16_000_000 = ["embassy-time-driver/tick-hz-16_000_000"]
196tick-hz-300_000_000 = [] 202## 16.384MHz Tick Rate
197tick-hz-320_000_000 = [] 203tick-hz-16_384_000 = ["embassy-time-driver/tick-hz-16_384_000"]
198tick-hz-340_000_000 = [] 204## 16.777216MHz Tick Rate
199tick-hz-360_000_000 = [] 205tick-hz-16_777_216 = ["embassy-time-driver/tick-hz-16_777_216"]
200tick-hz-380_000_000 = [] 206## 18.0MHz Tick Rate
201tick-hz-400_000_000 = [] 207tick-hz-18_000_000 = ["embassy-time-driver/tick-hz-18_000_000"]
202tick-hz-420_000_000 = [] 208## 20.0MHz Tick Rate
203tick-hz-440_000_000 = [] 209tick-hz-20_000_000 = ["embassy-time-driver/tick-hz-20_000_000"]
204tick-hz-460_000_000 = [] 210## 20.48MHz Tick Rate
205tick-hz-480_000_000 = [] 211tick-hz-20_480_000 = ["embassy-time-driver/tick-hz-20_480_000"]
206tick-hz-500_000_000 = [] 212## 24.0MHz Tick Rate
207tick-hz-520_000_000 = [] 213tick-hz-24_000_000 = ["embassy-time-driver/tick-hz-24_000_000"]
208tick-hz-540_000_000 = [] 214## 30.0MHz Tick Rate
209tick-hz-560_000_000 = [] 215tick-hz-30_000_000 = ["embassy-time-driver/tick-hz-30_000_000"]
210tick-hz-580_000_000 = [] 216## 32.0MHz Tick Rate
211tick-hz-600_000_000 = [] 217tick-hz-32_000_000 = ["embassy-time-driver/tick-hz-32_000_000"]
212tick-hz-620_000_000 = [] 218## 32.768MHz Tick Rate
213tick-hz-640_000_000 = [] 219tick-hz-32_768_000 = ["embassy-time-driver/tick-hz-32_768_000"]
214tick-hz-660_000_000 = [] 220## 36.0MHz Tick Rate
215tick-hz-680_000_000 = [] 221tick-hz-36_000_000 = ["embassy-time-driver/tick-hz-36_000_000"]
216tick-hz-700_000_000 = [] 222## 40.0MHz Tick Rate
217tick-hz-720_000_000 = [] 223tick-hz-40_000_000 = ["embassy-time-driver/tick-hz-40_000_000"]
218tick-hz-740_000_000 = [] 224## 40.96MHz Tick Rate
219tick-hz-760_000_000 = [] 225tick-hz-40_960_000 = ["embassy-time-driver/tick-hz-40_960_000"]
220tick-hz-780_000_000 = [] 226## 48.0MHz Tick Rate
221tick-hz-800_000_000 = [] 227tick-hz-48_000_000 = ["embassy-time-driver/tick-hz-48_000_000"]
222tick-hz-820_000_000 = [] 228## 50.0MHz Tick Rate
223tick-hz-840_000_000 = [] 229tick-hz-50_000_000 = ["embassy-time-driver/tick-hz-50_000_000"]
224tick-hz-860_000_000 = [] 230## 60.0MHz Tick Rate
225tick-hz-880_000_000 = [] 231tick-hz-60_000_000 = ["embassy-time-driver/tick-hz-60_000_000"]
226tick-hz-900_000_000 = [] 232## 64.0MHz Tick Rate
227tick-hz-920_000_000 = [] 233tick-hz-64_000_000 = ["embassy-time-driver/tick-hz-64_000_000"]
228tick-hz-940_000_000 = [] 234## 65.536MHz Tick Rate
229tick-hz-960_000_000 = [] 235tick-hz-65_536_000 = ["embassy-time-driver/tick-hz-65_536_000"]
230tick-hz-980_000_000 = [] 236## 70.0MHz Tick Rate
237tick-hz-70_000_000 = ["embassy-time-driver/tick-hz-70_000_000"]
238## 72.0MHz Tick Rate
239tick-hz-72_000_000 = ["embassy-time-driver/tick-hz-72_000_000"]
240## 80.0MHz Tick Rate
241tick-hz-80_000_000 = ["embassy-time-driver/tick-hz-80_000_000"]
242## 81.92MHz Tick Rate
243tick-hz-81_920_000 = ["embassy-time-driver/tick-hz-81_920_000"]
244## 90.0MHz Tick Rate
245tick-hz-90_000_000 = ["embassy-time-driver/tick-hz-90_000_000"]
246## 96.0MHz Tick Rate
247tick-hz-96_000_000 = ["embassy-time-driver/tick-hz-96_000_000"]
248## 100.0MHz Tick Rate
249tick-hz-100_000_000 = ["embassy-time-driver/tick-hz-100_000_000"]
250## 110.0MHz Tick Rate
251tick-hz-110_000_000 = ["embassy-time-driver/tick-hz-110_000_000"]
252## 120.0MHz Tick Rate
253tick-hz-120_000_000 = ["embassy-time-driver/tick-hz-120_000_000"]
254## 128.0MHz Tick Rate
255tick-hz-128_000_000 = ["embassy-time-driver/tick-hz-128_000_000"]
256## 130.0MHz Tick Rate
257tick-hz-130_000_000 = ["embassy-time-driver/tick-hz-130_000_000"]
258## 131.072MHz Tick Rate
259tick-hz-131_072_000 = ["embassy-time-driver/tick-hz-131_072_000"]
260## 140.0MHz Tick Rate
261tick-hz-140_000_000 = ["embassy-time-driver/tick-hz-140_000_000"]
262## 144.0MHz Tick Rate
263tick-hz-144_000_000 = ["embassy-time-driver/tick-hz-144_000_000"]
264## 150.0MHz Tick Rate
265tick-hz-150_000_000 = ["embassy-time-driver/tick-hz-150_000_000"]
266## 160.0MHz Tick Rate
267tick-hz-160_000_000 = ["embassy-time-driver/tick-hz-160_000_000"]
268## 163.84MHz Tick Rate
269tick-hz-163_840_000 = ["embassy-time-driver/tick-hz-163_840_000"]
270## 170.0MHz Tick Rate
271tick-hz-170_000_000 = ["embassy-time-driver/tick-hz-170_000_000"]
272## 180.0MHz Tick Rate
273tick-hz-180_000_000 = ["embassy-time-driver/tick-hz-180_000_000"]
274## 190.0MHz Tick Rate
275tick-hz-190_000_000 = ["embassy-time-driver/tick-hz-190_000_000"]
276## 192.0MHz Tick Rate
277tick-hz-192_000_000 = ["embassy-time-driver/tick-hz-192_000_000"]
278## 200.0MHz Tick Rate
279tick-hz-200_000_000 = ["embassy-time-driver/tick-hz-200_000_000"]
280## 210.0MHz Tick Rate
281tick-hz-210_000_000 = ["embassy-time-driver/tick-hz-210_000_000"]
282## 220.0MHz Tick Rate
283tick-hz-220_000_000 = ["embassy-time-driver/tick-hz-220_000_000"]
284## 230.0MHz Tick Rate
285tick-hz-230_000_000 = ["embassy-time-driver/tick-hz-230_000_000"]
286## 240.0MHz Tick Rate
287tick-hz-240_000_000 = ["embassy-time-driver/tick-hz-240_000_000"]
288## 250.0MHz Tick Rate
289tick-hz-250_000_000 = ["embassy-time-driver/tick-hz-250_000_000"]
290## 256.0MHz Tick Rate
291tick-hz-256_000_000 = ["embassy-time-driver/tick-hz-256_000_000"]
292## 260.0MHz Tick Rate
293tick-hz-260_000_000 = ["embassy-time-driver/tick-hz-260_000_000"]
294## 262.144MHz Tick Rate
295tick-hz-262_144_000 = ["embassy-time-driver/tick-hz-262_144_000"]
296## 270.0MHz Tick Rate
297tick-hz-270_000_000 = ["embassy-time-driver/tick-hz-270_000_000"]
298## 280.0MHz Tick Rate
299tick-hz-280_000_000 = ["embassy-time-driver/tick-hz-280_000_000"]
300## 288.0MHz Tick Rate
301tick-hz-288_000_000 = ["embassy-time-driver/tick-hz-288_000_000"]
302## 290.0MHz Tick Rate
303tick-hz-290_000_000 = ["embassy-time-driver/tick-hz-290_000_000"]
304## 300.0MHz Tick Rate
305tick-hz-300_000_000 = ["embassy-time-driver/tick-hz-300_000_000"]
306## 320.0MHz Tick Rate
307tick-hz-320_000_000 = ["embassy-time-driver/tick-hz-320_000_000"]
308## 327.68MHz Tick Rate
309tick-hz-327_680_000 = ["embassy-time-driver/tick-hz-327_680_000"]
310## 340.0MHz Tick Rate
311tick-hz-340_000_000 = ["embassy-time-driver/tick-hz-340_000_000"]
312## 360.0MHz Tick Rate
313tick-hz-360_000_000 = ["embassy-time-driver/tick-hz-360_000_000"]
314## 380.0MHz Tick Rate
315tick-hz-380_000_000 = ["embassy-time-driver/tick-hz-380_000_000"]
316## 384.0MHz Tick Rate
317tick-hz-384_000_000 = ["embassy-time-driver/tick-hz-384_000_000"]
318## 400.0MHz Tick Rate
319tick-hz-400_000_000 = ["embassy-time-driver/tick-hz-400_000_000"]
320## 420.0MHz Tick Rate
321tick-hz-420_000_000 = ["embassy-time-driver/tick-hz-420_000_000"]
322## 440.0MHz Tick Rate
323tick-hz-440_000_000 = ["embassy-time-driver/tick-hz-440_000_000"]
324## 460.0MHz Tick Rate
325tick-hz-460_000_000 = ["embassy-time-driver/tick-hz-460_000_000"]
326## 480.0MHz Tick Rate
327tick-hz-480_000_000 = ["embassy-time-driver/tick-hz-480_000_000"]
328## 500.0MHz Tick Rate
329tick-hz-500_000_000 = ["embassy-time-driver/tick-hz-500_000_000"]
330## 512.0MHz Tick Rate
331tick-hz-512_000_000 = ["embassy-time-driver/tick-hz-512_000_000"]
332## 520.0MHz Tick Rate
333tick-hz-520_000_000 = ["embassy-time-driver/tick-hz-520_000_000"]
334## 524.288MHz Tick Rate
335tick-hz-524_288_000 = ["embassy-time-driver/tick-hz-524_288_000"]
336## 540.0MHz Tick Rate
337tick-hz-540_000_000 = ["embassy-time-driver/tick-hz-540_000_000"]
338## 560.0MHz Tick Rate
339tick-hz-560_000_000 = ["embassy-time-driver/tick-hz-560_000_000"]
340## 576.0MHz Tick Rate
341tick-hz-576_000_000 = ["embassy-time-driver/tick-hz-576_000_000"]
342## 580.0MHz Tick Rate
343tick-hz-580_000_000 = ["embassy-time-driver/tick-hz-580_000_000"]
344## 600.0MHz Tick Rate
345tick-hz-600_000_000 = ["embassy-time-driver/tick-hz-600_000_000"]
346## 620.0MHz Tick Rate
347tick-hz-620_000_000 = ["embassy-time-driver/tick-hz-620_000_000"]
348## 640.0MHz Tick Rate
349tick-hz-640_000_000 = ["embassy-time-driver/tick-hz-640_000_000"]
350## 655.36MHz Tick Rate
351tick-hz-655_360_000 = ["embassy-time-driver/tick-hz-655_360_000"]
352## 660.0MHz Tick Rate
353tick-hz-660_000_000 = ["embassy-time-driver/tick-hz-660_000_000"]
354## 680.0MHz Tick Rate
355tick-hz-680_000_000 = ["embassy-time-driver/tick-hz-680_000_000"]
356## 700.0MHz Tick Rate
357tick-hz-700_000_000 = ["embassy-time-driver/tick-hz-700_000_000"]
358## 720.0MHz Tick Rate
359tick-hz-720_000_000 = ["embassy-time-driver/tick-hz-720_000_000"]
360## 740.0MHz Tick Rate
361tick-hz-740_000_000 = ["embassy-time-driver/tick-hz-740_000_000"]
362## 760.0MHz Tick Rate
363tick-hz-760_000_000 = ["embassy-time-driver/tick-hz-760_000_000"]
364## 768.0MHz Tick Rate
365tick-hz-768_000_000 = ["embassy-time-driver/tick-hz-768_000_000"]
366## 780.0MHz Tick Rate
367tick-hz-780_000_000 = ["embassy-time-driver/tick-hz-780_000_000"]
368## 800.0MHz Tick Rate
369tick-hz-800_000_000 = ["embassy-time-driver/tick-hz-800_000_000"]
370## 820.0MHz Tick Rate
371tick-hz-820_000_000 = ["embassy-time-driver/tick-hz-820_000_000"]
372## 840.0MHz Tick Rate
373tick-hz-840_000_000 = ["embassy-time-driver/tick-hz-840_000_000"]
374## 860.0MHz Tick Rate
375tick-hz-860_000_000 = ["embassy-time-driver/tick-hz-860_000_000"]
376## 880.0MHz Tick Rate
377tick-hz-880_000_000 = ["embassy-time-driver/tick-hz-880_000_000"]
378## 900.0MHz Tick Rate
379tick-hz-900_000_000 = ["embassy-time-driver/tick-hz-900_000_000"]
380## 920.0MHz Tick Rate
381tick-hz-920_000_000 = ["embassy-time-driver/tick-hz-920_000_000"]
382## 940.0MHz Tick Rate
383tick-hz-940_000_000 = ["embassy-time-driver/tick-hz-940_000_000"]
384## 960.0MHz Tick Rate
385tick-hz-960_000_000 = ["embassy-time-driver/tick-hz-960_000_000"]
386## 980.0MHz Tick Rate
387tick-hz-980_000_000 = ["embassy-time-driver/tick-hz-980_000_000"]
388## 1.0GHz Tick Rate
389tick-hz-1_000_000_000 = ["embassy-time-driver/tick-hz-1_000_000_000"]
390## 1.31072GHz Tick Rate
391tick-hz-1_310_720_000 = ["embassy-time-driver/tick-hz-1_310_720_000"]
392## 2.62144GHz Tick Rate
393tick-hz-2_621_440_000 = ["embassy-time-driver/tick-hz-2_621_440_000"]
394## 5.24288GHz Tick Rate
395tick-hz-5_242_880_000 = ["embassy-time-driver/tick-hz-5_242_880_000"]
231# END TICKS 396# END TICKS
232 397
398#! </details>
399
233[dependencies] 400[dependencies]
401embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver" }
402embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver" }
403
234defmt = { version = "0.3", optional = true } 404defmt = { version = "0.3", optional = true }
235log = { version = "0.4.14", optional = true } 405log = { version = "0.4.14", optional = true }
236 406
237embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } 407embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
238embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" } 408embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
239embedded-hal-async = { version = "=1.0.0-rc.2" } 409embedded-hal-async = { version = "1.0" }
240 410
241futures-util = { version = "0.3.17", default-features = false } 411futures-util = { version = "0.3.17", default-features = false }
242critical-section = "1.1" 412critical-section = "1.1"
243cfg-if = "1.0.0" 413cfg-if = "1.0.0"
244heapless = "0.8" 414heapless = "0.8"
245 415
416document-features = "0.2.7"
417
246# WASM dependencies 418# WASM dependencies
247wasm-bindgen = { version = "0.2.81", optional = true } 419wasm-bindgen = { version = "0.2.81", optional = true }
248js-sys = { version = "0.3", optional = true } 420js-sys = { version = "0.3", optional = true }
@@ -251,4 +423,4 @@ wasm-timer = { version = "0.2.5", optional = true }
251[dev-dependencies] 423[dev-dependencies]
252serial_test = "0.9" 424serial_test = "0.9"
253critical-section = { version = "1.1", features = ["std"] } 425critical-section = { version = "1.1", features = ["std"] }
254embassy-executor = { version = "0.4.0", path = "../embassy-executor" } 426embassy-executor = { version = "0.5.0", path = "../embassy-executor" }
diff --git a/embassy-time/README.md b/embassy-time/README.md
index 2be80ff9c..f5d46df7b 100644
--- a/embassy-time/README.md
+++ b/embassy-time/README.md
@@ -3,25 +3,40 @@
3Timekeeping, delays and timeouts. 3Timekeeping, delays and timeouts.
4 4
5Timekeeping is done with elapsed time since system boot. Time is represented in 5Timekeeping is done with elapsed time since system boot. Time is represented in
6ticks, where the tick rate is defined by the current driver, usually to match 6ticks, where the tick rate is defined either by the driver (in the case of a fixed-rate
7the tick rate of the hardware. 7tick) or chosen by the user with a [tick rate](#tick-rate) feature. The chosen
8tick rate applies to everything in `embassy-time` and thus determines the maximum
9timing resolution of <code>(1 / tick_rate) seconds</code>.
8 10
9Tick counts are 64 bits. At the highest supported tick rate of 1Mhz this supports 11Tick counts are 64 bits. The default tick rate of 1Mhz supports
10representing time spans of up to ~584558 years, which is big enough for all practical 12representing time spans of up to ~584558 years, which is big enough for all practical
11purposes and allows not having to worry about overflows. 13purposes and allows not having to worry about overflows.
12 14
15## Global time driver
16
17The `time` module is backed by a global "time driver" specified at build time.
18Only one driver can be active in a program.
19
20All methods and structs transparently call into the active driver. This makes it
21possible for libraries to use `embassy_time` in a driver-agnostic way without
22requiring generic parameters.
23
24For more details, check the [`embassy_time_driver`](https://crates.io/crates/embassy-time-driver) crate.
25
26## Instants and Durations
27
13[`Instant`] represents a given instant of time (relative to system boot), and [`Duration`] 28[`Instant`] represents a given instant of time (relative to system boot), and [`Duration`]
14represents the duration of a span of time. They implement the math operations you'd expect, 29represents the duration of a span of time. They implement the math operations you'd expect,
15like addition and substraction. 30like addition and substraction.
16 31
17# Delays and timeouts 32## Delays and timeouts
18 33
19[`Timer`] allows performing async delays. [`Ticker`] allows periodic delays without drifting over time. 34[`Timer`] allows performing async delays. [`Ticker`] allows periodic delays without drifting over time.
20 35
21An implementation of the `embedded-hal` delay traits is provided by [`Delay`], for compatibility 36An implementation of the `embedded-hal` delay traits is provided by [`Delay`], for compatibility
22with libraries from the ecosystem. 37with libraries from the ecosystem.
23 38
24# Wall-clock time 39## Wall-clock time
25 40
26The `time` module deals exclusively with a monotonically increasing tick count. 41The `time` module deals exclusively with a monotonically increasing tick count.
27Therefore it has no direct support for wall-clock time ("real life" datetimes 42Therefore it has no direct support for wall-clock time ("real life" datetimes
@@ -30,14 +45,3 @@ like `2021-08-24 13:33:21`).
30If persistence across reboots is not needed, support can be built on top of 45If persistence across reboots is not needed, support can be built on top of
31`embassy_time` by storing the offset between "seconds elapsed since boot" 46`embassy_time` by storing the offset between "seconds elapsed since boot"
32and "seconds since unix epoch". 47and "seconds since unix epoch".
33
34# Time driver
35
36The `time` module is backed by a global "time driver" specified at build time.
37Only one driver can be active in a program.
38
39All methods and structs transparently call into the active driver. This makes it
40possible for libraries to use `embassy_time` in a driver-agnostic way without
41requiring generic parameters.
42
43For more details, check the [`driver`] module.
diff --git a/embassy-time/build.rs b/embassy-time/build.rs
deleted file mode 100644
index 78bd27ec7..000000000
--- a/embassy-time/build.rs
+++ /dev/null
@@ -1,18 +0,0 @@
1use std::env;
2use std::ffi::OsString;
3use std::process::Command;
4
5fn main() {
6 println!("cargo:rerun-if-changed=build.rs");
7
8 let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
9
10 let output = Command::new(rustc)
11 .arg("--version")
12 .output()
13 .expect("failed to run `rustc --version`");
14
15 if String::from_utf8_lossy(&output.stdout).contains("nightly") {
16 println!("cargo:rustc-cfg=nightly");
17 }
18}
diff --git a/embassy-time/gen_tick.py b/embassy-time/gen_tick.py
deleted file mode 100644
index d4a175914..000000000
--- a/embassy-time/gen_tick.py
+++ /dev/null
@@ -1,60 +0,0 @@
1import os
2import toml
3from glob import glob
4
5abspath = os.path.abspath(__file__)
6dname = os.path.dirname(abspath)
7os.chdir(dname)
8
9ticks = []
10for i in range(10):
11 ticks.append(10**i)
12for i in range(1, 25):
13 ticks.append(2**i)
14for i in range(1, 20):
15 ticks.append(2**i * 1000)
16for i in range(1, 20):
17 ticks.append(2**i * 10000)
18for i in range(1, 10):
19 ticks.append(2**i * 1000000)
20 ticks.append(2**i * 9 // 8 * 1000000)
21 ticks.append(2**i * 3 // 2 * 1000000)
22for i in range(1, 30):
23 ticks.append(10 * i * 1_000_000)
24for i in range(15, 50):
25 ticks.append(20 * i * 1_000_000)
26
27seen = set()
28ticks = [x for x in ticks if not (x in seen or seen.add(x))]
29
30# ========= Update Cargo.toml
31
32things = {f'tick-hz-{hz:_}': [] for hz in ticks}
33
34SEPARATOR_START = '# BEGIN TICKS\n'
35SEPARATOR_END = '# END TICKS\n'
36HELP = '# Generated by gen_tick.py. DO NOT EDIT.\n'
37with open('Cargo.toml', 'r') as f:
38 data = f.read()
39before, data = data.split(SEPARATOR_START, maxsplit=1)
40_, after = data.split(SEPARATOR_END, maxsplit=1)
41data = before + SEPARATOR_START + HELP + \
42 toml.dumps(things) + SEPARATOR_END + after
43with open('Cargo.toml', 'w') as f:
44 f.write(data)
45
46# ========= Update src/tick.rs
47
48with open('src/tick.rs', 'w') as f:
49
50 f.write('// Generated by gen_tick.py. DO NOT EDIT.\n\n')
51 for hz in ticks:
52 f.write(
53 f'#[cfg(feature = "tick-hz-{hz:_}")] pub const TICK_HZ: u64 = {hz:_};\n')
54 f.write('#[cfg(not(any(\n')
55 for hz in ticks:
56 f.write(f'feature = "tick-hz-{hz:_}",\n')
57 f.write(')))] pub const TICK_HZ: u64 = 1_000_000;')
58
59
60os.system('rustfmt src/tick.rs')
diff --git a/embassy-time/src/delay.rs b/embassy-time/src/delay.rs
index 7ef5961f0..f77859d4a 100644
--- a/embassy-time/src/delay.rs
+++ b/embassy-time/src/delay.rs
@@ -13,6 +13,7 @@ pub fn block_for(duration: Duration) {
13/// the amount provided, but accuracy can be affected by many factors, including interrupt usage. 13/// the amount provided, but accuracy can be affected by many factors, including interrupt usage.
14/// Make sure to use a suitable tick rate for your use case. The tick rate is defined by the currently 14/// Make sure to use a suitable tick rate for your use case. The tick rate is defined by the currently
15/// active driver. 15/// active driver.
16#[derive(Clone)]
16pub struct Delay; 17pub struct Delay;
17 18
18impl embedded_hal_1::delay::DelayNs for Delay { 19impl embedded_hal_1::delay::DelayNs for Delay {
diff --git a/embassy-time/src/driver.rs b/embassy-time/src/driver.rs
deleted file mode 100644
index 5fe7becaf..000000000
--- a/embassy-time/src/driver.rs
+++ /dev/null
@@ -1,175 +0,0 @@
1//! Time driver interface
2//!
3//! This module defines the interface a driver needs to implement to power the `embassy_time` module.
4//!
5//! # Implementing a driver
6//!
7//! - Define a struct `MyDriver`
8//! - Implement [`Driver`] for it
9//! - Register it as the global driver with [`time_driver_impl`](crate::time_driver_impl).
10//! - Enable the Cargo features `embassy-executor/time` and one of `embassy-time/tick-*` corresponding to the
11//! tick rate of your driver.
12//!
13//! If you wish to make the tick rate configurable by the end user, you should do so by exposing your own
14//! Cargo features and having each enable the corresponding `embassy-time/tick-*`.
15//!
16//! # Linkage details
17//!
18//! Instead of the usual "trait + generic params" approach, calls from embassy to the driver are done via `extern` functions.
19//!
20//! `embassy` internally defines the driver functions as `extern "Rust" { fn _embassy_time_now() -> u64; }` and calls them.
21//! The driver crate defines the functions as `#[no_mangle] fn _embassy_time_now() -> u64`. The linker will resolve the
22//! calls from the `embassy` crate to call into the driver crate.
23//!
24//! If there is none or multiple drivers in the crate tree, linking will fail.
25//!
26//! This method has a few key advantages for something as foundational as timekeeping:
27//!
28//! - The time driver is available everywhere easily, without having to thread the implementation
29//! through generic parameters. This is especially helpful for libraries.
30//! - It means comparing `Instant`s will always make sense: if there were multiple drivers
31//! active, one could compare an `Instant` from driver A to an `Instant` from driver B, which
32//! would yield incorrect results.
33//!
34//! # Example
35//!
36//! ```
37//! use embassy_time::driver::{Driver, AlarmHandle};
38//!
39//! struct MyDriver{} // not public!
40//! embassy_time::time_driver_impl!(static DRIVER: MyDriver = MyDriver{});
41//!
42//! impl Driver for MyDriver {
43//! fn now(&self) -> u64 {
44//! todo!()
45//! }
46//! unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
47//! todo!()
48//! }
49//! fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
50//! todo!()
51//! }
52//! fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool {
53//! todo!()
54//! }
55//! }
56//! ```
57
58/// Alarm handle, assigned by the driver.
59#[derive(Clone, Copy)]
60pub struct AlarmHandle {
61 id: u8,
62}
63
64impl AlarmHandle {
65 /// Create an AlarmHandle
66 ///
67 /// Safety: May only be called by the current global Driver impl.
68 /// The impl is allowed to rely on the fact that all `AlarmHandle` instances
69 /// are created by itself in unsafe code (e.g. indexing operations)
70 pub unsafe fn new(id: u8) -> Self {
71 Self { id }
72 }
73
74 /// Get the ID of the AlarmHandle.
75 pub fn id(&self) -> u8 {
76 self.id
77 }
78}
79
80/// Time driver
81pub trait Driver: Send + Sync + 'static {
82 /// Return the current timestamp in ticks.
83 ///
84 /// Implementations MUST ensure that:
85 /// - This is guaranteed to be monotonic, i.e. a call to now() will always return
86 /// a greater or equal value than earler calls. Time can't "roll backwards".
87 /// - It "never" overflows. It must not overflow in a sufficiently long time frame, say
88 /// in 10_000 years (Human civilization is likely to already have self-destructed
89 /// 10_000 years from now.). This means if your hardware only has 16bit/32bit timers
90 /// you MUST extend them to 64-bit, for example by counting overflows in software,
91 /// or chaining multiple timers together.
92 fn now(&self) -> u64;
93
94 /// Try allocating an alarm handle. Returns None if no alarms left.
95 /// Initially the alarm has no callback set, and a null `ctx` pointer.
96 ///
97 /// # Safety
98 /// It is UB to make the alarm fire before setting a callback.
99 unsafe fn allocate_alarm(&self) -> Option<AlarmHandle>;
100
101 /// Sets the callback function to be called when the alarm triggers.
102 /// The callback may be called from any context (interrupt or thread mode).
103 fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ());
104
105 /// Sets an alarm at the given timestamp. When the current timestamp reaches the alarm
106 /// timestamp, the provided callback function will be called.
107 ///
108 /// The `Driver` implementation should guarantee that the alarm callback is never called synchronously from `set_alarm`.
109 /// Rather - if `timestamp` is already in the past - `false` should be returned and alarm should not be set,
110 /// or alternatively, the driver should return `true` and arrange to call the alarm callback as soon as possible, but not synchronously.
111 ///
112 /// When callback is called, it is guaranteed that now() will return a value greater or equal than timestamp.
113 ///
114 /// Only one alarm can be active at a time for each AlarmHandle. This overwrites any previously-set alarm if any.
115 fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool;
116}
117
118extern "Rust" {
119 fn _embassy_time_now() -> u64;
120 fn _embassy_time_allocate_alarm() -> Option<AlarmHandle>;
121 fn _embassy_time_set_alarm_callback(alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ());
122 fn _embassy_time_set_alarm(alarm: AlarmHandle, timestamp: u64) -> bool;
123}
124
125/// See [`Driver::now`]
126pub fn now() -> u64 {
127 unsafe { _embassy_time_now() }
128}
129
130/// See [`Driver::allocate_alarm`]
131///
132/// Safety: it is UB to make the alarm fire before setting a callback.
133pub unsafe fn allocate_alarm() -> Option<AlarmHandle> {
134 _embassy_time_allocate_alarm()
135}
136
137/// See [`Driver::set_alarm_callback`]
138pub fn set_alarm_callback(alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
139 unsafe { _embassy_time_set_alarm_callback(alarm, callback, ctx) }
140}
141
142/// See [`Driver::set_alarm`]
143pub fn set_alarm(alarm: AlarmHandle, timestamp: u64) -> bool {
144 unsafe { _embassy_time_set_alarm(alarm, timestamp) }
145}
146
147/// Set the time Driver implementation.
148///
149/// See the module documentation for an example.
150#[macro_export]
151macro_rules! time_driver_impl {
152 (static $name:ident: $t: ty = $val:expr) => {
153 static $name: $t = $val;
154
155 #[no_mangle]
156 fn _embassy_time_now() -> u64 {
157 <$t as $crate::driver::Driver>::now(&$name)
158 }
159
160 #[no_mangle]
161 unsafe fn _embassy_time_allocate_alarm() -> Option<$crate::driver::AlarmHandle> {
162 <$t as $crate::driver::Driver>::allocate_alarm(&$name)
163 }
164
165 #[no_mangle]
166 fn _embassy_time_set_alarm_callback(alarm: $crate::driver::AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
167 <$t as $crate::driver::Driver>::set_alarm_callback(&$name, alarm, callback, ctx)
168 }
169
170 #[no_mangle]
171 fn _embassy_time_set_alarm(alarm: $crate::driver::AlarmHandle, timestamp: u64) -> bool {
172 <$t as $crate::driver::Driver>::set_alarm(&$name, alarm, timestamp)
173 }
174 };
175}
diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs
index c255615c7..8587f9172 100644
--- a/embassy-time/src/driver_mock.rs
+++ b/embassy-time/src/driver_mock.rs
@@ -1,14 +1,14 @@
1use core::cell::Cell; 1use core::cell::RefCell;
2 2
3use critical_section::Mutex as CsMutex; 3use critical_section::Mutex as CsMutex;
4use embassy_time_driver::{AlarmHandle, Driver};
4 5
5use crate::driver::{AlarmHandle, Driver};
6use crate::{Duration, Instant}; 6use crate::{Duration, Instant};
7 7
8/// A mock driver that can be manually advanced. 8/// A mock driver that can be manually advanced.
9/// This is useful for testing code that works with [`Instant`] and [`Duration`]. 9/// This is useful for testing code that works with [`Instant`] and [`Duration`].
10/// 10///
11/// This driver cannot currently be used to test runtime functionality, such as 11/// This driver can also be used to test runtime functionality, such as
12/// timers, delays, etc. 12/// timers, delays, etc.
13/// 13///
14/// # Example 14/// # Example
@@ -26,43 +26,196 @@ use crate::{Duration, Instant};
26/// assert_eq!(true, has_a_second_passed(reference)); 26/// assert_eq!(true, has_a_second_passed(reference));
27/// } 27/// }
28/// ``` 28/// ```
29pub struct MockDriver { 29pub struct MockDriver(CsMutex<RefCell<InnerMockDriver>>);
30 now: CsMutex<Cell<Instant>>,
31}
32 30
33crate::time_driver_impl!(static DRIVER: MockDriver = MockDriver { 31embassy_time_driver::time_driver_impl!(static DRIVER: MockDriver = MockDriver::new());
34 now: CsMutex::new(Cell::new(Instant::from_ticks(0))),
35});
36 32
37impl MockDriver { 33impl MockDriver {
34 /// Creates a new mock driver.
35 pub const fn new() -> Self {
36 Self(CsMutex::new(RefCell::new(InnerMockDriver::new())))
37 }
38
38 /// Gets a reference to the global mock driver. 39 /// Gets a reference to the global mock driver.
39 pub fn get() -> &'static MockDriver { 40 pub fn get() -> &'static MockDriver {
40 &DRIVER 41 &DRIVER
41 } 42 }
42 43
43 /// Advances the time by the specified [`Duration`]. 44 /// Resets the internal state of the mock driver
44 pub fn advance(&self, duration: Duration) { 45 /// This will clear and deallocate all alarms, and reset the current time to 0.
46 pub fn reset(&self) {
45 critical_section::with(|cs| { 47 critical_section::with(|cs| {
46 let now = self.now.borrow(cs).get().as_ticks(); 48 self.0.borrow(cs).replace(InnerMockDriver::new());
47 self.now.borrow(cs).set(Instant::from_ticks(now + duration.as_ticks()));
48 }); 49 });
49 } 50 }
51
52 /// Advances the time by the specified [`Duration`].
53 /// Calling any alarm callbacks that are due.
54 pub fn advance(&self, duration: Duration) {
55 let notify = {
56 critical_section::with(|cs| {
57 let mut inner = self.0.borrow_ref_mut(cs);
58
59 inner.now += duration;
60
61 let now = inner.now.as_ticks();
62
63 inner
64 .alarm
65 .as_mut()
66 .filter(|alarm| alarm.timestamp <= now)
67 .map(|alarm| {
68 alarm.timestamp = u64::MAX;
69
70 (alarm.callback, alarm.ctx)
71 })
72 })
73 };
74
75 if let Some((callback, ctx)) = notify {
76 (callback)(ctx);
77 }
78 }
50} 79}
51 80
52impl Driver for MockDriver { 81impl Driver for MockDriver {
53 fn now(&self) -> u64 { 82 fn now(&self) -> u64 {
54 critical_section::with(|cs| self.now.borrow(cs).get().as_ticks() as u64) 83 critical_section::with(|cs| self.0.borrow_ref(cs).now).as_ticks()
55 } 84 }
56 85
57 unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> { 86 unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
58 unimplemented!("MockDriver does not support runtime features that require an executor"); 87 critical_section::with(|cs| {
88 let mut inner = self.0.borrow_ref_mut(cs);
89
90 if inner.alarm.is_some() {
91 None
92 } else {
93 inner.alarm.replace(AlarmState::new());
94
95 Some(AlarmHandle::new(0))
96 }
97 })
59 } 98 }
60 99
61 fn set_alarm_callback(&self, _alarm: AlarmHandle, _callback: fn(*mut ()), _ctx: *mut ()) { 100 fn set_alarm_callback(&self, _alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
62 unimplemented!("MockDriver does not support runtime features that require an executor"); 101 critical_section::with(|cs| {
102 let mut inner = self.0.borrow_ref_mut(cs);
103
104 let Some(alarm) = inner.alarm.as_mut() else {
105 panic!("Alarm not allocated");
106 };
107
108 alarm.callback = callback;
109 alarm.ctx = ctx;
110 });
63 } 111 }
64 112
65 fn set_alarm(&self, _alarm: AlarmHandle, _timestamp: u64) -> bool { 113 fn set_alarm(&self, _alarm: AlarmHandle, timestamp: u64) -> bool {
66 unimplemented!("MockDriver does not support runtime features that require an executor"); 114 critical_section::with(|cs| {
115 let mut inner = self.0.borrow_ref_mut(cs);
116
117 if timestamp <= inner.now.as_ticks() {
118 false
119 } else {
120 let Some(alarm) = inner.alarm.as_mut() else {
121 panic!("Alarm not allocated");
122 };
123
124 alarm.timestamp = timestamp;
125 true
126 }
127 })
128 }
129}
130
131struct InnerMockDriver {
132 now: Instant,
133 alarm: Option<AlarmState>,
134}
135
136impl InnerMockDriver {
137 const fn new() -> Self {
138 Self {
139 now: Instant::from_ticks(0),
140 alarm: None,
141 }
142 }
143}
144
145struct AlarmState {
146 timestamp: u64,
147 callback: fn(*mut ()),
148 ctx: *mut (),
149}
150
151impl AlarmState {
152 const fn new() -> Self {
153 Self {
154 timestamp: u64::MAX,
155 callback: Self::noop,
156 ctx: core::ptr::null_mut(),
157 }
158 }
159
160 fn noop(_ctx: *mut ()) {}
161}
162
163unsafe impl Send for AlarmState {}
164
165#[cfg(test)]
166mod tests {
167 use serial_test::serial;
168
169 use super::*;
170
171 fn setup() {
172 DRIVER.reset();
173 }
174
175 #[test]
176 #[serial]
177 fn test_advance() {
178 setup();
179
180 let driver = MockDriver::get();
181 let reference = driver.now();
182 driver.advance(Duration::from_secs(1));
183 assert_eq!(Duration::from_secs(1).as_ticks(), driver.now() - reference);
184 }
185
186 #[test]
187 #[serial]
188 fn test_set_alarm_not_in_future() {
189 setup();
190
191 let driver = MockDriver::get();
192 let alarm = unsafe { AlarmHandle::new(0) };
193 assert_eq!(false, driver.set_alarm(alarm, driver.now()));
194 }
195
196 #[test]
197 #[serial]
198 fn test_alarm() {
199 setup();
200
201 let driver = MockDriver::get();
202 let alarm = unsafe { driver.allocate_alarm() }.expect("No alarms available");
203 static mut CALLBACK_CALLED: bool = false;
204 let ctx = &mut () as *mut ();
205 driver.set_alarm_callback(alarm, |_| unsafe { CALLBACK_CALLED = true }, ctx);
206 driver.set_alarm(alarm, driver.now() + 1);
207 assert_eq!(false, unsafe { CALLBACK_CALLED });
208 driver.advance(Duration::from_secs(1));
209 assert_eq!(true, unsafe { CALLBACK_CALLED });
210 }
211
212 #[test]
213 #[serial]
214 fn test_allocate_alarm() {
215 setup();
216
217 let driver = MockDriver::get();
218 assert!(unsafe { driver.allocate_alarm() }.is_some());
219 assert!(unsafe { driver.allocate_alarm() }.is_none());
67 } 220 }
68} 221}
diff --git a/embassy-time/src/driver_std.rs b/embassy-time/src/driver_std.rs
index 32db47a37..d182f8331 100644
--- a/embassy-time/src/driver_std.rs
+++ b/embassy-time/src/driver_std.rs
@@ -6,8 +6,7 @@ use std::time::{Duration as StdDuration, Instant as StdInstant};
6use std::{mem, ptr, thread}; 6use std::{mem, ptr, thread};
7 7
8use critical_section::Mutex as CsMutex; 8use critical_section::Mutex as CsMutex;
9 9use embassy_time_driver::{AlarmHandle, Driver};
10use crate::driver::{AlarmHandle, Driver};
11 10
12const ALARM_COUNT: usize = 4; 11const ALARM_COUNT: usize = 4;
13 12
@@ -45,7 +44,7 @@ struct TimeDriver {
45} 44}
46 45
47const ALARM_NEW: AlarmState = AlarmState::new(); 46const ALARM_NEW: AlarmState = AlarmState::new();
48crate::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver { 47embassy_time_driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
49 alarm_count: AtomicU8::new(0), 48 alarm_count: AtomicU8::new(0),
50 49
51 once: Once::new(), 50 once: Once::new(),
diff --git a/embassy-time/src/driver_wasm.rs b/embassy-time/src/driver_wasm.rs
index 0f672dc75..ad884f060 100644
--- a/embassy-time/src/driver_wasm.rs
+++ b/embassy-time/src/driver_wasm.rs
@@ -4,11 +4,10 @@ use std::mem::MaybeUninit;
4use std::ptr; 4use std::ptr;
5use std::sync::{Mutex, Once}; 5use std::sync::{Mutex, Once};
6 6
7use embassy_time_driver::{AlarmHandle, Driver};
7use wasm_bindgen::prelude::*; 8use wasm_bindgen::prelude::*;
8use wasm_timer::Instant as StdInstant; 9use wasm_timer::Instant as StdInstant;
9 10
10use crate::driver::{AlarmHandle, Driver};
11
12const ALARM_COUNT: usize = 4; 11const ALARM_COUNT: usize = 4;
13 12
14struct AlarmState { 13struct AlarmState {
@@ -42,7 +41,7 @@ struct TimeDriver {
42} 41}
43 42
44const ALARM_NEW: AlarmState = AlarmState::new(); 43const ALARM_NEW: AlarmState = AlarmState::new();
45crate::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver { 44embassy_time_driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
46 alarm_count: AtomicU8::new(0), 45 alarm_count: AtomicU8::new(0),
47 once: Once::new(), 46 once: Once::new(),
48 alarms: UninitCell::uninit(), 47 alarms: UninitCell::uninit(),
diff --git a/embassy-time/src/fmt.rs b/embassy-time/src/fmt.rs
index 78e583c1c..2ac42c557 100644
--- a/embassy-time/src/fmt.rs
+++ b/embassy-time/src/fmt.rs
@@ -1,5 +1,5 @@
1#![macro_use] 1#![macro_use]
2#![allow(unused_macros)] 2#![allow(unused)]
3 3
4use core::fmt::{Debug, Display, LowerHex}; 4use core::fmt::{Debug, Display, LowerHex};
5 5
@@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
229 } 229 }
230} 230}
231 231
232#[allow(unused)]
233pub(crate) struct Bytes<'a>(pub &'a [u8]); 232pub(crate) struct Bytes<'a>(pub &'a [u8]);
234 233
235impl<'a> Debug for Bytes<'a> { 234impl<'a> Debug for Bytes<'a> {
diff --git a/embassy-time/src/instant.rs b/embassy-time/src/instant.rs
index 5571cdd15..909f1b173 100644
--- a/embassy-time/src/instant.rs
+++ b/embassy-time/src/instant.rs
@@ -1,7 +1,7 @@
1use core::fmt; 1use core::fmt;
2use core::ops::{Add, AddAssign, Sub, SubAssign}; 2use core::ops::{Add, AddAssign, Sub, SubAssign};
3 3
4use super::{driver, Duration, GCD_1K, GCD_1M, TICK_HZ}; 4use super::{Duration, GCD_1K, GCD_1M, TICK_HZ};
5 5
6#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 6#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))] 7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -18,7 +18,9 @@ impl Instant {
18 18
19 /// Returns an Instant representing the current time. 19 /// Returns an Instant representing the current time.
20 pub fn now() -> Instant { 20 pub fn now() -> Instant {
21 Instant { ticks: driver::now() } 21 Instant {
22 ticks: embassy_time_driver::now(),
23 }
22 } 24 }
23 25
24 /// Create an Instant from a tick count since system boot. 26 /// Create an Instant from a tick count since system boot.
diff --git a/embassy-time/src/lib.rs b/embassy-time/src/lib.rs
index 82a7ee0df..3c8575ee9 100644
--- a/embassy-time/src/lib.rs
+++ b/embassy-time/src/lib.rs
@@ -1,20 +1,18 @@
1#![cfg_attr(not(any(feature = "std", feature = "wasm", test)), no_std)] 1#![cfg_attr(not(any(feature = "std", feature = "wasm", test)), no_std)]
2#![cfg_attr(nightly, feature(async_fn_in_trait, impl_trait_projections))]
3#![cfg_attr(nightly, allow(stable_features, unknown_lints))]
4#![allow(async_fn_in_trait)] 2#![allow(async_fn_in_trait)]
5#![doc = include_str!("../README.md")] 3#![doc = include_str!("../README.md")]
6#![allow(clippy::new_without_default)] 4#![allow(clippy::new_without_default)]
7#![warn(missing_docs)] 5#![warn(missing_docs)]
8 6
7//! ## Feature flags
8#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
9
9// This mod MUST go first, so that the others see its macros. 10// This mod MUST go first, so that the others see its macros.
10pub(crate) mod fmt; 11pub(crate) mod fmt;
11 12
12mod delay; 13mod delay;
13pub mod driver;
14mod duration; 14mod duration;
15mod instant; 15mod instant;
16pub mod queue;
17mod tick;
18mod timer; 16mod timer;
19 17
20#[cfg(feature = "mock-driver")] 18#[cfg(feature = "mock-driver")]
@@ -32,16 +30,9 @@ mod queue_generic;
32 30
33pub use delay::{block_for, Delay}; 31pub use delay::{block_for, Delay};
34pub use duration::Duration; 32pub use duration::Duration;
33pub use embassy_time_driver::TICK_HZ;
35pub use instant::Instant; 34pub use instant::Instant;
36pub use timer::{with_timeout, Ticker, TimeoutError, Timer}; 35pub use timer::{with_deadline, with_timeout, Ticker, TimeoutError, Timer};
37
38/// Ticks per second of the global timebase.
39///
40/// This value is specified by the `tick-*` Cargo features, which
41/// should be set by the time driver. Some drivers support a fixed tick rate, others
42/// allow you to choose a tick rate with Cargo features of their own. You should not
43/// set the `tick-*` features for embassy yourself as an end user.
44pub const TICK_HZ: u64 = tick::TICK_HZ;
45 36
46const fn gcd(a: u64, b: u64) -> u64 { 37const fn gcd(a: u64, b: u64) -> u64 {
47 if b == 0 { 38 if b == 0 {
diff --git a/embassy-time/src/queue.rs b/embassy-time/src/queue.rs
deleted file mode 100644
index c6f8b440a..000000000
--- a/embassy-time/src/queue.rs
+++ /dev/null
@@ -1,58 +0,0 @@
1//! Timer queue implementation
2//!
3//! This module defines the interface a timer queue needs to implement to power the `embassy_time` module.
4//!
5//! # Implementing a timer queue
6//!
7//! - Define a struct `MyTimerQueue`
8//! - Implement [`TimerQueue`] for it
9//! - Register it as the global timer queue with [`timer_queue_impl`](crate::timer_queue_impl).
10//!
11//! # Linkage details
12//!
13//! Check the documentation of the [`driver`](crate::driver) module for more information.
14//!
15//! Similarly to driver, if there is none or multiple timer queues in the crate tree, linking will fail.
16//!
17//! # Example
18//!
19//! ```
20//! use core::task::Waker;
21//!
22//! use embassy_time::Instant;
23//! use embassy_time::queue::{TimerQueue};
24//!
25//! struct MyTimerQueue{}; // not public!
26//! embassy_time::timer_queue_impl!(static QUEUE: MyTimerQueue = MyTimerQueue{});
27//!
28//! impl TimerQueue for MyTimerQueue {
29//! fn schedule_wake(&'static self, at: Instant, waker: &Waker) {
30//! todo!()
31//! }
32//! }
33//! ```
34use core::task::Waker;
35
36use crate::Instant;
37
38/// Timer queue
39pub trait TimerQueue {
40 /// Schedules a waker in the queue to be awoken at moment `at`.
41 /// If this moment is in the past, the waker might be awoken immediately.
42 fn schedule_wake(&'static self, at: Instant, waker: &Waker);
43}
44
45/// Set the TimerQueue implementation.
46///
47/// See the module documentation for an example.
48#[macro_export]
49macro_rules! timer_queue_impl {
50 (static $name:ident: $t: ty = $val:expr) => {
51 static $name: $t = $val;
52
53 #[no_mangle]
54 fn _embassy_time_schedule_wake(at: $crate::Instant, waker: &core::task::Waker) {
55 <$t as $crate::queue::TimerQueue>::schedule_wake(&$name, at, waker);
56 }
57 };
58}
diff --git a/embassy-time/src/queue_generic.rs b/embassy-time/src/queue_generic.rs
index 77947ab29..cf7a986d5 100644
--- a/embassy-time/src/queue_generic.rs
+++ b/embassy-time/src/queue_generic.rs
@@ -3,10 +3,10 @@ use core::cmp::{min, Ordering};
3use core::task::Waker; 3use core::task::Waker;
4 4
5use critical_section::Mutex; 5use critical_section::Mutex;
6use embassy_time_driver::{allocate_alarm, set_alarm, set_alarm_callback, AlarmHandle};
7use embassy_time_queue_driver::TimerQueue;
6use heapless::Vec; 8use heapless::Vec;
7 9
8use crate::driver::{allocate_alarm, set_alarm, set_alarm_callback, AlarmHandle};
9use crate::queue::TimerQueue;
10use crate::Instant; 10use crate::Instant;
11 11
12#[cfg(feature = "generic-queue-8")] 12#[cfg(feature = "generic-queue-8")]
@@ -167,111 +167,25 @@ impl Queue {
167} 167}
168 168
169impl TimerQueue for Queue { 169impl TimerQueue for Queue {
170 fn schedule_wake(&'static self, at: Instant, waker: &Waker) { 170 fn schedule_wake(&'static self, at: u64, waker: &Waker) {
171 Queue::schedule_wake(self, at, waker); 171 Queue::schedule_wake(self, Instant::from_ticks(at), waker);
172 } 172 }
173} 173}
174 174
175crate::timer_queue_impl!(static QUEUE: Queue = Queue::new()); 175embassy_time_queue_driver::timer_queue_impl!(static QUEUE: Queue = Queue::new());
176 176
177#[cfg(test)] 177#[cfg(test)]
178#[cfg(feature = "mock-driver")]
178mod tests { 179mod tests {
179 use core::cell::Cell; 180 use core::cell::Cell;
180 use core::task::{RawWaker, RawWakerVTable, Waker}; 181 use core::task::{RawWaker, RawWakerVTable, Waker};
181 use std::rc::Rc; 182 use std::rc::Rc;
182 use std::sync::Mutex;
183 183
184 use serial_test::serial; 184 use serial_test::serial;
185 185
186 use crate::driver::{AlarmHandle, Driver}; 186 use crate::driver_mock::MockDriver;
187 use crate::queue_generic::QUEUE; 187 use crate::queue_generic::QUEUE;
188 use crate::Instant; 188 use crate::{Duration, Instant};
189
190 struct InnerTestDriver {
191 now: u64,
192 alarm: u64,
193 callback: fn(*mut ()),
194 ctx: *mut (),
195 }
196
197 impl InnerTestDriver {
198 const fn new() -> Self {
199 Self {
200 now: 0,
201 alarm: u64::MAX,
202 callback: Self::noop,
203 ctx: core::ptr::null_mut(),
204 }
205 }
206
207 fn noop(_ctx: *mut ()) {}
208 }
209
210 unsafe impl Send for InnerTestDriver {}
211
212 struct TestDriver(Mutex<InnerTestDriver>);
213
214 impl TestDriver {
215 const fn new() -> Self {
216 Self(Mutex::new(InnerTestDriver::new()))
217 }
218
219 fn reset(&self) {
220 *self.0.lock().unwrap() = InnerTestDriver::new();
221 }
222
223 fn set_now(&self, now: u64) {
224 let notify = {
225 let mut inner = self.0.lock().unwrap();
226
227 if inner.now < now {
228 inner.now = now;
229
230 if inner.alarm <= now {
231 inner.alarm = u64::MAX;
232
233 Some((inner.callback, inner.ctx))
234 } else {
235 None
236 }
237 } else {
238 panic!("Going back in time?");
239 }
240 };
241
242 if let Some((callback, ctx)) = notify {
243 (callback)(ctx);
244 }
245 }
246 }
247
248 impl Driver for TestDriver {
249 fn now(&self) -> u64 {
250 self.0.lock().unwrap().now
251 }
252
253 unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
254 Some(AlarmHandle::new(0))
255 }
256
257 fn set_alarm_callback(&self, _alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
258 let mut inner = self.0.lock().unwrap();
259
260 inner.callback = callback;
261 inner.ctx = ctx;
262 }
263
264 fn set_alarm(&self, _alarm: AlarmHandle, timestamp: u64) -> bool {
265 let mut inner = self.0.lock().unwrap();
266
267 if timestamp <= inner.now {
268 false
269 } else {
270 inner.alarm = timestamp;
271 true
272 }
273 }
274 }
275 189
276 struct TestWaker { 190 struct TestWaker {
277 pub awoken: Rc<Cell<bool>>, 191 pub awoken: Rc<Cell<bool>>,
@@ -312,10 +226,8 @@ mod tests {
312 } 226 }
313 } 227 }
314 228
315 crate::time_driver_impl!(static DRIVER: TestDriver = TestDriver::new());
316
317 fn setup() { 229 fn setup() {
318 DRIVER.reset(); 230 MockDriver::get().reset();
319 critical_section::with(|cs| *QUEUE.inner.borrow_ref_mut(cs) = None); 231 critical_section::with(|cs| *QUEUE.inner.borrow_ref_mut(cs) = None);
320 } 232 }
321 233
@@ -382,13 +294,13 @@ mod tests {
382 294
383 assert!(!waker.awoken.get()); 295 assert!(!waker.awoken.get());
384 296
385 DRIVER.set_now(Instant::from_secs(99).as_ticks()); 297 MockDriver::get().advance(Duration::from_secs(99));
386 298
387 assert!(!waker.awoken.get()); 299 assert!(!waker.awoken.get());
388 300
389 assert_eq!(queue_len(), 1); 301 assert_eq!(queue_len(), 1);
390 302
391 DRIVER.set_now(Instant::from_secs(100).as_ticks()); 303 MockDriver::get().advance(Duration::from_secs(1));
392 304
393 assert!(waker.awoken.get()); 305 assert!(waker.awoken.get());
394 306
@@ -404,7 +316,7 @@ mod tests {
404 316
405 QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker); 317 QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker);
406 318
407 DRIVER.set_now(Instant::from_secs(50).as_ticks()); 319 MockDriver::get().advance(Duration::from_secs(50));
408 320
409 let waker2 = TestWaker::new(); 321 let waker2 = TestWaker::new();
410 322
diff --git a/embassy-time/src/tick.rs b/embassy-time/src/tick.rs
deleted file mode 100644
index 834e7c095..000000000
--- a/embassy-time/src/tick.rs
+++ /dev/null
@@ -1,482 +0,0 @@
1// Generated by gen_tick.py. DO NOT EDIT.
2
3#[cfg(feature = "tick-hz-1")]
4pub const TICK_HZ: u64 = 1;
5#[cfg(feature = "tick-hz-10")]
6pub const TICK_HZ: u64 = 10;
7#[cfg(feature = "tick-hz-100")]
8pub const TICK_HZ: u64 = 100;
9#[cfg(feature = "tick-hz-1_000")]
10pub const TICK_HZ: u64 = 1_000;
11#[cfg(feature = "tick-hz-10_000")]
12pub const TICK_HZ: u64 = 10_000;
13#[cfg(feature = "tick-hz-100_000")]
14pub const TICK_HZ: u64 = 100_000;
15#[cfg(feature = "tick-hz-1_000_000")]
16pub const TICK_HZ: u64 = 1_000_000;
17#[cfg(feature = "tick-hz-10_000_000")]
18pub const TICK_HZ: u64 = 10_000_000;
19#[cfg(feature = "tick-hz-100_000_000")]
20pub const TICK_HZ: u64 = 100_000_000;
21#[cfg(feature = "tick-hz-1_000_000_000")]
22pub const TICK_HZ: u64 = 1_000_000_000;
23#[cfg(feature = "tick-hz-2")]
24pub const TICK_HZ: u64 = 2;
25#[cfg(feature = "tick-hz-4")]
26pub const TICK_HZ: u64 = 4;
27#[cfg(feature = "tick-hz-8")]
28pub const TICK_HZ: u64 = 8;
29#[cfg(feature = "tick-hz-16")]
30pub const TICK_HZ: u64 = 16;
31#[cfg(feature = "tick-hz-32")]
32pub const TICK_HZ: u64 = 32;
33#[cfg(feature = "tick-hz-64")]
34pub const TICK_HZ: u64 = 64;
35#[cfg(feature = "tick-hz-128")]
36pub const TICK_HZ: u64 = 128;
37#[cfg(feature = "tick-hz-256")]
38pub const TICK_HZ: u64 = 256;
39#[cfg(feature = "tick-hz-512")]
40pub const TICK_HZ: u64 = 512;
41#[cfg(feature = "tick-hz-1_024")]
42pub const TICK_HZ: u64 = 1_024;
43#[cfg(feature = "tick-hz-2_048")]
44pub const TICK_HZ: u64 = 2_048;
45#[cfg(feature = "tick-hz-4_096")]
46pub const TICK_HZ: u64 = 4_096;
47#[cfg(feature = "tick-hz-8_192")]
48pub const TICK_HZ: u64 = 8_192;
49#[cfg(feature = "tick-hz-16_384")]
50pub const TICK_HZ: u64 = 16_384;
51#[cfg(feature = "tick-hz-32_768")]
52pub const TICK_HZ: u64 = 32_768;
53#[cfg(feature = "tick-hz-65_536")]
54pub const TICK_HZ: u64 = 65_536;
55#[cfg(feature = "tick-hz-131_072")]
56pub const TICK_HZ: u64 = 131_072;
57#[cfg(feature = "tick-hz-262_144")]
58pub const TICK_HZ: u64 = 262_144;
59#[cfg(feature = "tick-hz-524_288")]
60pub const TICK_HZ: u64 = 524_288;
61#[cfg(feature = "tick-hz-1_048_576")]
62pub const TICK_HZ: u64 = 1_048_576;
63#[cfg(feature = "tick-hz-2_097_152")]
64pub const TICK_HZ: u64 = 2_097_152;
65#[cfg(feature = "tick-hz-4_194_304")]
66pub const TICK_HZ: u64 = 4_194_304;
67#[cfg(feature = "tick-hz-8_388_608")]
68pub const TICK_HZ: u64 = 8_388_608;
69#[cfg(feature = "tick-hz-16_777_216")]
70pub const TICK_HZ: u64 = 16_777_216;
71#[cfg(feature = "tick-hz-2_000")]
72pub const TICK_HZ: u64 = 2_000;
73#[cfg(feature = "tick-hz-4_000")]
74pub const TICK_HZ: u64 = 4_000;
75#[cfg(feature = "tick-hz-8_000")]
76pub const TICK_HZ: u64 = 8_000;
77#[cfg(feature = "tick-hz-16_000")]
78pub const TICK_HZ: u64 = 16_000;
79#[cfg(feature = "tick-hz-32_000")]
80pub const TICK_HZ: u64 = 32_000;
81#[cfg(feature = "tick-hz-64_000")]
82pub const TICK_HZ: u64 = 64_000;
83#[cfg(feature = "tick-hz-128_000")]
84pub const TICK_HZ: u64 = 128_000;
85#[cfg(feature = "tick-hz-256_000")]
86pub const TICK_HZ: u64 = 256_000;
87#[cfg(feature = "tick-hz-512_000")]
88pub const TICK_HZ: u64 = 512_000;
89#[cfg(feature = "tick-hz-1_024_000")]
90pub const TICK_HZ: u64 = 1_024_000;
91#[cfg(feature = "tick-hz-2_048_000")]
92pub const TICK_HZ: u64 = 2_048_000;
93#[cfg(feature = "tick-hz-4_096_000")]
94pub const TICK_HZ: u64 = 4_096_000;
95#[cfg(feature = "tick-hz-8_192_000")]
96pub const TICK_HZ: u64 = 8_192_000;
97#[cfg(feature = "tick-hz-16_384_000")]
98pub const TICK_HZ: u64 = 16_384_000;
99#[cfg(feature = "tick-hz-32_768_000")]
100pub const TICK_HZ: u64 = 32_768_000;
101#[cfg(feature = "tick-hz-65_536_000")]
102pub const TICK_HZ: u64 = 65_536_000;
103#[cfg(feature = "tick-hz-131_072_000")]
104pub const TICK_HZ: u64 = 131_072_000;
105#[cfg(feature = "tick-hz-262_144_000")]
106pub const TICK_HZ: u64 = 262_144_000;
107#[cfg(feature = "tick-hz-524_288_000")]
108pub const TICK_HZ: u64 = 524_288_000;
109#[cfg(feature = "tick-hz-20_000")]
110pub const TICK_HZ: u64 = 20_000;
111#[cfg(feature = "tick-hz-40_000")]
112pub const TICK_HZ: u64 = 40_000;
113#[cfg(feature = "tick-hz-80_000")]
114pub const TICK_HZ: u64 = 80_000;
115#[cfg(feature = "tick-hz-160_000")]
116pub const TICK_HZ: u64 = 160_000;
117#[cfg(feature = "tick-hz-320_000")]
118pub const TICK_HZ: u64 = 320_000;
119#[cfg(feature = "tick-hz-640_000")]
120pub const TICK_HZ: u64 = 640_000;
121#[cfg(feature = "tick-hz-1_280_000")]
122pub const TICK_HZ: u64 = 1_280_000;
123#[cfg(feature = "tick-hz-2_560_000")]
124pub const TICK_HZ: u64 = 2_560_000;
125#[cfg(feature = "tick-hz-5_120_000")]
126pub const TICK_HZ: u64 = 5_120_000;
127#[cfg(feature = "tick-hz-10_240_000")]
128pub const TICK_HZ: u64 = 10_240_000;
129#[cfg(feature = "tick-hz-20_480_000")]
130pub const TICK_HZ: u64 = 20_480_000;
131#[cfg(feature = "tick-hz-40_960_000")]
132pub const TICK_HZ: u64 = 40_960_000;
133#[cfg(feature = "tick-hz-81_920_000")]
134pub const TICK_HZ: u64 = 81_920_000;
135#[cfg(feature = "tick-hz-163_840_000")]
136pub const TICK_HZ: u64 = 163_840_000;
137#[cfg(feature = "tick-hz-327_680_000")]
138pub const TICK_HZ: u64 = 327_680_000;
139#[cfg(feature = "tick-hz-655_360_000")]
140pub const TICK_HZ: u64 = 655_360_000;
141#[cfg(feature = "tick-hz-1_310_720_000")]
142pub const TICK_HZ: u64 = 1_310_720_000;
143#[cfg(feature = "tick-hz-2_621_440_000")]
144pub const TICK_HZ: u64 = 2_621_440_000;
145#[cfg(feature = "tick-hz-5_242_880_000")]
146pub const TICK_HZ: u64 = 5_242_880_000;
147#[cfg(feature = "tick-hz-2_000_000")]
148pub const TICK_HZ: u64 = 2_000_000;
149#[cfg(feature = "tick-hz-3_000_000")]
150pub const TICK_HZ: u64 = 3_000_000;
151#[cfg(feature = "tick-hz-4_000_000")]
152pub const TICK_HZ: u64 = 4_000_000;
153#[cfg(feature = "tick-hz-6_000_000")]
154pub const TICK_HZ: u64 = 6_000_000;
155#[cfg(feature = "tick-hz-8_000_000")]
156pub const TICK_HZ: u64 = 8_000_000;
157#[cfg(feature = "tick-hz-9_000_000")]
158pub const TICK_HZ: u64 = 9_000_000;
159#[cfg(feature = "tick-hz-12_000_000")]
160pub const TICK_HZ: u64 = 12_000_000;
161#[cfg(feature = "tick-hz-16_000_000")]
162pub const TICK_HZ: u64 = 16_000_000;
163#[cfg(feature = "tick-hz-18_000_000")]
164pub const TICK_HZ: u64 = 18_000_000;
165#[cfg(feature = "tick-hz-24_000_000")]
166pub const TICK_HZ: u64 = 24_000_000;
167#[cfg(feature = "tick-hz-32_000_000")]
168pub const TICK_HZ: u64 = 32_000_000;
169#[cfg(feature = "tick-hz-36_000_000")]
170pub const TICK_HZ: u64 = 36_000_000;
171#[cfg(feature = "tick-hz-48_000_000")]
172pub const TICK_HZ: u64 = 48_000_000;
173#[cfg(feature = "tick-hz-64_000_000")]
174pub const TICK_HZ: u64 = 64_000_000;
175#[cfg(feature = "tick-hz-72_000_000")]
176pub const TICK_HZ: u64 = 72_000_000;
177#[cfg(feature = "tick-hz-96_000_000")]
178pub const TICK_HZ: u64 = 96_000_000;
179#[cfg(feature = "tick-hz-128_000_000")]
180pub const TICK_HZ: u64 = 128_000_000;
181#[cfg(feature = "tick-hz-144_000_000")]
182pub const TICK_HZ: u64 = 144_000_000;
183#[cfg(feature = "tick-hz-192_000_000")]
184pub const TICK_HZ: u64 = 192_000_000;
185#[cfg(feature = "tick-hz-256_000_000")]
186pub const TICK_HZ: u64 = 256_000_000;
187#[cfg(feature = "tick-hz-288_000_000")]
188pub const TICK_HZ: u64 = 288_000_000;
189#[cfg(feature = "tick-hz-384_000_000")]
190pub const TICK_HZ: u64 = 384_000_000;
191#[cfg(feature = "tick-hz-512_000_000")]
192pub const TICK_HZ: u64 = 512_000_000;
193#[cfg(feature = "tick-hz-576_000_000")]
194pub const TICK_HZ: u64 = 576_000_000;
195#[cfg(feature = "tick-hz-768_000_000")]
196pub const TICK_HZ: u64 = 768_000_000;
197#[cfg(feature = "tick-hz-20_000_000")]
198pub const TICK_HZ: u64 = 20_000_000;
199#[cfg(feature = "tick-hz-30_000_000")]
200pub const TICK_HZ: u64 = 30_000_000;
201#[cfg(feature = "tick-hz-40_000_000")]
202pub const TICK_HZ: u64 = 40_000_000;
203#[cfg(feature = "tick-hz-50_000_000")]
204pub const TICK_HZ: u64 = 50_000_000;
205#[cfg(feature = "tick-hz-60_000_000")]
206pub const TICK_HZ: u64 = 60_000_000;
207#[cfg(feature = "tick-hz-70_000_000")]
208pub const TICK_HZ: u64 = 70_000_000;
209#[cfg(feature = "tick-hz-80_000_000")]
210pub const TICK_HZ: u64 = 80_000_000;
211#[cfg(feature = "tick-hz-90_000_000")]
212pub const TICK_HZ: u64 = 90_000_000;
213#[cfg(feature = "tick-hz-110_000_000")]
214pub const TICK_HZ: u64 = 110_000_000;
215#[cfg(feature = "tick-hz-120_000_000")]
216pub const TICK_HZ: u64 = 120_000_000;
217#[cfg(feature = "tick-hz-130_000_000")]
218pub const TICK_HZ: u64 = 130_000_000;
219#[cfg(feature = "tick-hz-140_000_000")]
220pub const TICK_HZ: u64 = 140_000_000;
221#[cfg(feature = "tick-hz-150_000_000")]
222pub const TICK_HZ: u64 = 150_000_000;
223#[cfg(feature = "tick-hz-160_000_000")]
224pub const TICK_HZ: u64 = 160_000_000;
225#[cfg(feature = "tick-hz-170_000_000")]
226pub const TICK_HZ: u64 = 170_000_000;
227#[cfg(feature = "tick-hz-180_000_000")]
228pub const TICK_HZ: u64 = 180_000_000;
229#[cfg(feature = "tick-hz-190_000_000")]
230pub const TICK_HZ: u64 = 190_000_000;
231#[cfg(feature = "tick-hz-200_000_000")]
232pub const TICK_HZ: u64 = 200_000_000;
233#[cfg(feature = "tick-hz-210_000_000")]
234pub const TICK_HZ: u64 = 210_000_000;
235#[cfg(feature = "tick-hz-220_000_000")]
236pub const TICK_HZ: u64 = 220_000_000;
237#[cfg(feature = "tick-hz-230_000_000")]
238pub const TICK_HZ: u64 = 230_000_000;
239#[cfg(feature = "tick-hz-240_000_000")]
240pub const TICK_HZ: u64 = 240_000_000;
241#[cfg(feature = "tick-hz-250_000_000")]
242pub const TICK_HZ: u64 = 250_000_000;
243#[cfg(feature = "tick-hz-260_000_000")]
244pub const TICK_HZ: u64 = 260_000_000;
245#[cfg(feature = "tick-hz-270_000_000")]
246pub const TICK_HZ: u64 = 270_000_000;
247#[cfg(feature = "tick-hz-280_000_000")]
248pub const TICK_HZ: u64 = 280_000_000;
249#[cfg(feature = "tick-hz-290_000_000")]
250pub const TICK_HZ: u64 = 290_000_000;
251#[cfg(feature = "tick-hz-300_000_000")]
252pub const TICK_HZ: u64 = 300_000_000;
253#[cfg(feature = "tick-hz-320_000_000")]
254pub const TICK_HZ: u64 = 320_000_000;
255#[cfg(feature = "tick-hz-340_000_000")]
256pub const TICK_HZ: u64 = 340_000_000;
257#[cfg(feature = "tick-hz-360_000_000")]
258pub const TICK_HZ: u64 = 360_000_000;
259#[cfg(feature = "tick-hz-380_000_000")]
260pub const TICK_HZ: u64 = 380_000_000;
261#[cfg(feature = "tick-hz-400_000_000")]
262pub const TICK_HZ: u64 = 400_000_000;
263#[cfg(feature = "tick-hz-420_000_000")]
264pub const TICK_HZ: u64 = 420_000_000;
265#[cfg(feature = "tick-hz-440_000_000")]
266pub const TICK_HZ: u64 = 440_000_000;
267#[cfg(feature = "tick-hz-460_000_000")]
268pub const TICK_HZ: u64 = 460_000_000;
269#[cfg(feature = "tick-hz-480_000_000")]
270pub const TICK_HZ: u64 = 480_000_000;
271#[cfg(feature = "tick-hz-500_000_000")]
272pub const TICK_HZ: u64 = 500_000_000;
273#[cfg(feature = "tick-hz-520_000_000")]
274pub const TICK_HZ: u64 = 520_000_000;
275#[cfg(feature = "tick-hz-540_000_000")]
276pub const TICK_HZ: u64 = 540_000_000;
277#[cfg(feature = "tick-hz-560_000_000")]
278pub const TICK_HZ: u64 = 560_000_000;
279#[cfg(feature = "tick-hz-580_000_000")]
280pub const TICK_HZ: u64 = 580_000_000;
281#[cfg(feature = "tick-hz-600_000_000")]
282pub const TICK_HZ: u64 = 600_000_000;
283#[cfg(feature = "tick-hz-620_000_000")]
284pub const TICK_HZ: u64 = 620_000_000;
285#[cfg(feature = "tick-hz-640_000_000")]
286pub const TICK_HZ: u64 = 640_000_000;
287#[cfg(feature = "tick-hz-660_000_000")]
288pub const TICK_HZ: u64 = 660_000_000;
289#[cfg(feature = "tick-hz-680_000_000")]
290pub const TICK_HZ: u64 = 680_000_000;
291#[cfg(feature = "tick-hz-700_000_000")]
292pub const TICK_HZ: u64 = 700_000_000;
293#[cfg(feature = "tick-hz-720_000_000")]
294pub const TICK_HZ: u64 = 720_000_000;
295#[cfg(feature = "tick-hz-740_000_000")]
296pub const TICK_HZ: u64 = 740_000_000;
297#[cfg(feature = "tick-hz-760_000_000")]
298pub const TICK_HZ: u64 = 760_000_000;
299#[cfg(feature = "tick-hz-780_000_000")]
300pub const TICK_HZ: u64 = 780_000_000;
301#[cfg(feature = "tick-hz-800_000_000")]
302pub const TICK_HZ: u64 = 800_000_000;
303#[cfg(feature = "tick-hz-820_000_000")]
304pub const TICK_HZ: u64 = 820_000_000;
305#[cfg(feature = "tick-hz-840_000_000")]
306pub const TICK_HZ: u64 = 840_000_000;
307#[cfg(feature = "tick-hz-860_000_000")]
308pub const TICK_HZ: u64 = 860_000_000;
309#[cfg(feature = "tick-hz-880_000_000")]
310pub const TICK_HZ: u64 = 880_000_000;
311#[cfg(feature = "tick-hz-900_000_000")]
312pub const TICK_HZ: u64 = 900_000_000;
313#[cfg(feature = "tick-hz-920_000_000")]
314pub const TICK_HZ: u64 = 920_000_000;
315#[cfg(feature = "tick-hz-940_000_000")]
316pub const TICK_HZ: u64 = 940_000_000;
317#[cfg(feature = "tick-hz-960_000_000")]
318pub const TICK_HZ: u64 = 960_000_000;
319#[cfg(feature = "tick-hz-980_000_000")]
320pub const TICK_HZ: u64 = 980_000_000;
321#[cfg(not(any(
322 feature = "tick-hz-1",
323 feature = "tick-hz-10",
324 feature = "tick-hz-100",
325 feature = "tick-hz-1_000",
326 feature = "tick-hz-10_000",
327 feature = "tick-hz-100_000",
328 feature = "tick-hz-1_000_000",
329 feature = "tick-hz-10_000_000",
330 feature = "tick-hz-100_000_000",
331 feature = "tick-hz-1_000_000_000",
332 feature = "tick-hz-2",
333 feature = "tick-hz-4",
334 feature = "tick-hz-8",
335 feature = "tick-hz-16",
336 feature = "tick-hz-32",
337 feature = "tick-hz-64",
338 feature = "tick-hz-128",
339 feature = "tick-hz-256",
340 feature = "tick-hz-512",
341 feature = "tick-hz-1_024",
342 feature = "tick-hz-2_048",
343 feature = "tick-hz-4_096",
344 feature = "tick-hz-8_192",
345 feature = "tick-hz-16_384",
346 feature = "tick-hz-32_768",
347 feature = "tick-hz-65_536",
348 feature = "tick-hz-131_072",
349 feature = "tick-hz-262_144",
350 feature = "tick-hz-524_288",
351 feature = "tick-hz-1_048_576",
352 feature = "tick-hz-2_097_152",
353 feature = "tick-hz-4_194_304",
354 feature = "tick-hz-8_388_608",
355 feature = "tick-hz-16_777_216",
356 feature = "tick-hz-2_000",
357 feature = "tick-hz-4_000",
358 feature = "tick-hz-8_000",
359 feature = "tick-hz-16_000",
360 feature = "tick-hz-32_000",
361 feature = "tick-hz-64_000",
362 feature = "tick-hz-128_000",
363 feature = "tick-hz-256_000",
364 feature = "tick-hz-512_000",
365 feature = "tick-hz-1_024_000",
366 feature = "tick-hz-2_048_000",
367 feature = "tick-hz-4_096_000",
368 feature = "tick-hz-8_192_000",
369 feature = "tick-hz-16_384_000",
370 feature = "tick-hz-32_768_000",
371 feature = "tick-hz-65_536_000",
372 feature = "tick-hz-131_072_000",
373 feature = "tick-hz-262_144_000",
374 feature = "tick-hz-524_288_000",
375 feature = "tick-hz-20_000",
376 feature = "tick-hz-40_000",
377 feature = "tick-hz-80_000",
378 feature = "tick-hz-160_000",
379 feature = "tick-hz-320_000",
380 feature = "tick-hz-640_000",
381 feature = "tick-hz-1_280_000",
382 feature = "tick-hz-2_560_000",
383 feature = "tick-hz-5_120_000",
384 feature = "tick-hz-10_240_000",
385 feature = "tick-hz-20_480_000",
386 feature = "tick-hz-40_960_000",
387 feature = "tick-hz-81_920_000",
388 feature = "tick-hz-163_840_000",
389 feature = "tick-hz-327_680_000",
390 feature = "tick-hz-655_360_000",
391 feature = "tick-hz-1_310_720_000",
392 feature = "tick-hz-2_621_440_000",
393 feature = "tick-hz-5_242_880_000",
394 feature = "tick-hz-2_000_000",
395 feature = "tick-hz-3_000_000",
396 feature = "tick-hz-4_000_000",
397 feature = "tick-hz-6_000_000",
398 feature = "tick-hz-8_000_000",
399 feature = "tick-hz-9_000_000",
400 feature = "tick-hz-12_000_000",
401 feature = "tick-hz-16_000_000",
402 feature = "tick-hz-18_000_000",
403 feature = "tick-hz-24_000_000",
404 feature = "tick-hz-32_000_000",
405 feature = "tick-hz-36_000_000",
406 feature = "tick-hz-48_000_000",
407 feature = "tick-hz-64_000_000",
408 feature = "tick-hz-72_000_000",
409 feature = "tick-hz-96_000_000",
410 feature = "tick-hz-128_000_000",
411 feature = "tick-hz-144_000_000",
412 feature = "tick-hz-192_000_000",
413 feature = "tick-hz-256_000_000",
414 feature = "tick-hz-288_000_000",
415 feature = "tick-hz-384_000_000",
416 feature = "tick-hz-512_000_000",
417 feature = "tick-hz-576_000_000",
418 feature = "tick-hz-768_000_000",
419 feature = "tick-hz-20_000_000",
420 feature = "tick-hz-30_000_000",
421 feature = "tick-hz-40_000_000",
422 feature = "tick-hz-50_000_000",
423 feature = "tick-hz-60_000_000",
424 feature = "tick-hz-70_000_000",
425 feature = "tick-hz-80_000_000",
426 feature = "tick-hz-90_000_000",
427 feature = "tick-hz-110_000_000",
428 feature = "tick-hz-120_000_000",
429 feature = "tick-hz-130_000_000",
430 feature = "tick-hz-140_000_000",
431 feature = "tick-hz-150_000_000",
432 feature = "tick-hz-160_000_000",
433 feature = "tick-hz-170_000_000",
434 feature = "tick-hz-180_000_000",
435 feature = "tick-hz-190_000_000",
436 feature = "tick-hz-200_000_000",
437 feature = "tick-hz-210_000_000",
438 feature = "tick-hz-220_000_000",
439 feature = "tick-hz-230_000_000",
440 feature = "tick-hz-240_000_000",
441 feature = "tick-hz-250_000_000",
442 feature = "tick-hz-260_000_000",
443 feature = "tick-hz-270_000_000",
444 feature = "tick-hz-280_000_000",
445 feature = "tick-hz-290_000_000",
446 feature = "tick-hz-300_000_000",
447 feature = "tick-hz-320_000_000",
448 feature = "tick-hz-340_000_000",
449 feature = "tick-hz-360_000_000",
450 feature = "tick-hz-380_000_000",
451 feature = "tick-hz-400_000_000",
452 feature = "tick-hz-420_000_000",
453 feature = "tick-hz-440_000_000",
454 feature = "tick-hz-460_000_000",
455 feature = "tick-hz-480_000_000",
456 feature = "tick-hz-500_000_000",
457 feature = "tick-hz-520_000_000",
458 feature = "tick-hz-540_000_000",
459 feature = "tick-hz-560_000_000",
460 feature = "tick-hz-580_000_000",
461 feature = "tick-hz-600_000_000",
462 feature = "tick-hz-620_000_000",
463 feature = "tick-hz-640_000_000",
464 feature = "tick-hz-660_000_000",
465 feature = "tick-hz-680_000_000",
466 feature = "tick-hz-700_000_000",
467 feature = "tick-hz-720_000_000",
468 feature = "tick-hz-740_000_000",
469 feature = "tick-hz-760_000_000",
470 feature = "tick-hz-780_000_000",
471 feature = "tick-hz-800_000_000",
472 feature = "tick-hz-820_000_000",
473 feature = "tick-hz-840_000_000",
474 feature = "tick-hz-860_000_000",
475 feature = "tick-hz-880_000_000",
476 feature = "tick-hz-900_000_000",
477 feature = "tick-hz-920_000_000",
478 feature = "tick-hz-940_000_000",
479 feature = "tick-hz-960_000_000",
480 feature = "tick-hz-980_000_000",
481)))]
482pub const TICK_HZ: u64 = 1_000_000;
diff --git a/embassy-time/src/timer.rs b/embassy-time/src/timer.rs
index a123c1d01..757c3ff00 100644
--- a/embassy-time/src/timer.rs
+++ b/embassy-time/src/timer.rs
@@ -1,6 +1,6 @@
1use core::future::{poll_fn, Future}; 1use core::future::{poll_fn, Future};
2use core::pin::Pin; 2use core::pin::Pin;
3use core::task::{Context, Poll, Waker}; 3use core::task::{Context, Poll};
4 4
5use futures_util::future::{select, Either}; 5use futures_util::future::{select, Either};
6use futures_util::stream::FusedStream; 6use futures_util::stream::FusedStream;
@@ -8,7 +8,7 @@ use futures_util::{pin_mut, Stream};
8 8
9use crate::{Duration, Instant}; 9use crate::{Duration, Instant};
10 10
11/// Error returned by [`with_timeout`] on timeout. 11/// Error returned by [`with_timeout`] and [`with_deadline`] on timeout.
12#[derive(Debug, Clone, PartialEq, Eq)] 12#[derive(Debug, Clone, PartialEq, Eq)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))] 13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
14pub struct TimeoutError; 14pub struct TimeoutError;
@@ -26,6 +26,19 @@ pub async fn with_timeout<F: Future>(timeout: Duration, fut: F) -> Result<F::Out
26 } 26 }
27} 27}
28 28
29/// Runs a given future with a deadline time.
30///
31/// If the future completes before the deadline, its output is returned. Otherwise, on timeout,
32/// work on the future is stopped (`poll` is no longer called), the future is dropped and `Err(TimeoutError)` is returned.
33pub async fn with_deadline<F: Future>(at: Instant, fut: F) -> Result<F::Output, TimeoutError> {
34 let timeout_fut = Timer::at(at);
35 pin_mut!(fut);
36 match select(fut, timeout_fut).await {
37 Either::Left((r, _)) => Ok(r),
38 Either::Right(_) => Err(TimeoutError),
39 }
40}
41
29/// A future that completes at a specified [Instant](struct.Instant.html). 42/// A future that completes at a specified [Instant](struct.Instant.html).
30#[must_use = "futures do nothing unless you `.await` or poll them"] 43#[must_use = "futures do nothing unless you `.await` or poll them"]
31pub struct Timer { 44pub struct Timer {
@@ -47,9 +60,6 @@ impl Timer {
47 /// 60 ///
48 /// Example: 61 /// Example:
49 /// ``` no_run 62 /// ``` no_run
50 /// # #![feature(type_alias_impl_trait)]
51 /// #
52 /// # fn foo() {}
53 /// use embassy_time::{Duration, Timer}; 63 /// use embassy_time::{Duration, Timer};
54 /// 64 ///
55 /// #[embassy_executor::task] 65 /// #[embassy_executor::task]
@@ -119,7 +129,7 @@ impl Future for Timer {
119 if self.yielded_once && self.expires_at <= Instant::now() { 129 if self.yielded_once && self.expires_at <= Instant::now() {
120 Poll::Ready(()) 130 Poll::Ready(())
121 } else { 131 } else {
122 schedule_wake(self.expires_at, cx.waker()); 132 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
123 self.yielded_once = true; 133 self.yielded_once = true;
124 Poll::Pending 134 Poll::Pending
125 } 135 }
@@ -132,8 +142,6 @@ impl Future for Timer {
132/// 142///
133/// For instance, consider the following code fragment. 143/// For instance, consider the following code fragment.
134/// ``` no_run 144/// ``` no_run
135/// # #![feature(type_alias_impl_trait)]
136/// #
137/// use embassy_time::{Duration, Timer}; 145/// use embassy_time::{Duration, Timer};
138/// # fn foo() {} 146/// # fn foo() {}
139/// 147///
@@ -152,8 +160,6 @@ impl Future for Timer {
152/// Example using ticker, which will consistently call `foo` once a second. 160/// Example using ticker, which will consistently call `foo` once a second.
153/// 161///
154/// ``` no_run 162/// ``` no_run
155/// # #![feature(type_alias_impl_trait)]
156/// #
157/// use embassy_time::{Duration, Ticker}; 163/// use embassy_time::{Duration, Ticker};
158/// # fn foo(){} 164/// # fn foo(){}
159/// 165///
@@ -184,6 +190,18 @@ impl Ticker {
184 self.expires_at = Instant::now() + self.duration; 190 self.expires_at = Instant::now() + self.duration;
185 } 191 }
186 192
193 /// Reset the ticker at the deadline.
194 /// If the deadline is in the past, the ticker will fire instantly.
195 pub fn reset_at(&mut self, deadline: Instant) {
196 self.expires_at = deadline + self.duration;
197 }
198
199 /// Resets the ticker, after the specified duration has passed.
200 /// If the specified duration is zero, the next tick will be after the duration of the ticker.
201 pub fn reset_after(&mut self, after: Duration) {
202 self.expires_at = Instant::now() + after + self.duration;
203 }
204
187 /// Waits for the next tick. 205 /// Waits for the next tick.
188 pub fn next(&mut self) -> impl Future<Output = ()> + Send + Sync + '_ { 206 pub fn next(&mut self) -> impl Future<Output = ()> + Send + Sync + '_ {
189 poll_fn(|cx| { 207 poll_fn(|cx| {
@@ -192,7 +210,7 @@ impl Ticker {
192 self.expires_at += dur; 210 self.expires_at += dur;
193 Poll::Ready(()) 211 Poll::Ready(())
194 } else { 212 } else {
195 schedule_wake(self.expires_at, cx.waker()); 213 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
196 Poll::Pending 214 Poll::Pending
197 } 215 }
198 }) 216 })
@@ -209,7 +227,7 @@ impl Stream for Ticker {
209 self.expires_at += dur; 227 self.expires_at += dur;
210 Poll::Ready(Some(())) 228 Poll::Ready(Some(()))
211 } else { 229 } else {
212 schedule_wake(self.expires_at, cx.waker()); 230 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
213 Poll::Pending 231 Poll::Pending
214 } 232 }
215 } 233 }
@@ -221,11 +239,3 @@ impl FusedStream for Ticker {
221 false 239 false
222 } 240 }
223} 241}
224
225extern "Rust" {
226 fn _embassy_time_schedule_wake(at: Instant, waker: &Waker);
227}
228
229fn schedule_wake(at: Instant, waker: &Waker) {
230 unsafe { _embassy_time_schedule_wake(at, waker) }
231}