From 15f94fb0fc70463b9a50c997083fee3f5758b17a Mon Sep 17 00:00:00 2001
From: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Date: Thu, 11 Jan 2024 16:38:44 +0100
Subject: [PATCH] time: split driver into a separate embassy-time-driver crate.

---
 ci.sh                                         |  40 +-
 embassy-nrf/Cargo.toml                        |   3 +-
 embassy-nrf/src/time_driver.rs                |   4 +-
 embassy-rp/Cargo.toml                         |   5 +-
 embassy-rp/src/lib.rs                         |   4 +-
 embassy-rp/src/{timer.rs => time_driver.rs}   |   4 +-
 embassy-stm32/Cargo.toml                      |   5 +-
 embassy-stm32/src/time_driver.rs              |   5 +-
 embassy-time-driver/CHANGELOG.md              |  51 +++
 embassy-time-driver/Cargo.toml                | 391 ++++++++++++++++++
 embassy-time-driver/README.md                 |  20 +
 .../build.rs                                  |   0
 .../gen_tick.py                               |  32 +-
 .../src/lib.rs                                |  28 +-
 .../src/tick.rs                               |   0
 embassy-time/Cargo.toml                       | 326 ++++++++-------
 embassy-time/README.md                        |   4 +-
 embassy-time/src/driver_mock.rs               |   2 +-
 embassy-time/src/driver_std.rs                |   2 +-
 embassy-time/src/driver_wasm.rs               |   2 +-
 embassy-time/src/lib.rs                       |  10 +-
 21 files changed, 711 insertions(+), 227 deletions(-)
 rename embassy-rp/src/{timer.rs => time_driver.rs} (97%)
 create mode 100644 embassy-time-driver/CHANGELOG.md
 create mode 100644 embassy-time-driver/Cargo.toml
 create mode 100644 embassy-time-driver/README.md
 rename {embassy-time => embassy-time-driver}/build.rs (100%)
 rename {embassy-time => embassy-time-driver}/gen_tick.py (71%)
 rename embassy-time/src/driver.rs => embassy-time-driver/src/lib.rs (89%)
 rename {embassy-time => embassy-time-driver}/src/tick.rs (100%)

diff --git a/ci.sh b/ci.sh
index 9c6f58f9f..ac0457679 100755
--- a/ci.sh
+++ b/ci.sh
@@ -47,24 +47,30 @@ cargo batch  \
     --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip \
     --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet \
     --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet,medium-ieee802154 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52805,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52810,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52811,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52820,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52832,gpiote,time-driver-rtc1,reset-pin-as-gpio \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52833,gpiote,time-driver-rtc1,nfc-pins-as-gpio \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf9160-s,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf9160-ns,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-s,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-ns,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-net,gpiote,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52805,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52810,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52811,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52820,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52832,gpiote,time,time-driver-rtc1,reset-pin-as-gpio \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52833,gpiote,time,time-driver-rtc1,nfc-pins-as-gpio \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf9160-s,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf9160-ns,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-s,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-ns,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-net,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,time \
     --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,log,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,defmt,gpiote,time-driver-rtc1 \
-    --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features defmt \
-    --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features log \
-    --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features intrinsics \
-    --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features qspi-as-gpio \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,log,time \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,log,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,log,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,defmt,time \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,defmt,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,defmt,time,time-driver-rtc1 \
+    --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features time-driver,defmt \
+    --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features time-driver,log \
+    --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features time-driver,intrinsics \
+    --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features time-driver,qspi-as-gpio \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,time \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,time \
     --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time \
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index 7d7346d92..f62059eb1 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -96,7 +96,7 @@ _nrf5340 = ["_gpio-p1", "_dppi"]
 _nrf9160 = ["nrf9160-pac", "_dppi"]
 _nrf52 = ["_ppi"]
 
-_time-driver = ["dep:embassy-time", "embassy-time?/tick-hz-32_768"]
+_time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-32_768"]
 
 # trustzone state.
 _s = []
@@ -110,6 +110,7 @@ _gpio-p1 = []
 _nrf52832_anomaly_109 = []
 
 [dependencies]
+embassy-time-driver = { version = "0.1", path = "../embassy-time-driver", optional = true }
 embassy-time = { version = "0.2", path = "../embassy-time", optional = true }
 embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
 embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] }
diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs
index f1ab4f8fd..042f7c5f7 100644
--- a/embassy-nrf/src/time_driver.rs
+++ b/embassy-nrf/src/time_driver.rs
@@ -5,7 +5,7 @@ use core::{mem, ptr};
 use critical_section::CriticalSection;
 use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
 use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex;
-use embassy_time::driver::{AlarmHandle, Driver};
+use embassy_time_driver::{AlarmHandle, Driver};
 
 use crate::interrupt::InterruptExt;
 use crate::{interrupt, pac};
@@ -119,7 +119,7 @@ struct RtcDriver {
 }
 
 const ALARM_STATE_NEW: AlarmState = AlarmState::new();
-embassy_time::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
+embassy_time_driver::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
     period: AtomicU32::new(0),
     alarm_count: AtomicU8::new(0),
     alarms: Mutex::const_new(CriticalSectionRawMutex::new(), [ALARM_STATE_NEW; ALARM_COUNT]),
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml
index 8d7a11749..b324eab82 100644
--- a/embassy-rp/Cargo.toml
+++ b/embassy-rp/Cargo.toml
@@ -30,7 +30,7 @@ critical-section-impl = ["critical-section/restore-state-u8"]
 unstable-pac = []
 
 ## Enable the timer for use with `embassy-time` with a 1MHz tick rate
-time-driver = []
+time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-1_000_000"]
 
 ## Enable ROM function cache
 rom-func-cache = []
@@ -67,7 +67,8 @@ boot2-w25x10cl = []
 
 [dependencies]
 embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
-embassy-time = { version = "0.2", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] }
+embassy-time-driver = { version = "0.1", path = "../embassy-time-driver", optional = true }
+embassy-time = { version = "0.2", path = "../embassy-time" }
 embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
 embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
 embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 0a3714777..46973fdc8 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -30,7 +30,7 @@ pub mod rom_data;
 pub mod rtc;
 pub mod spi;
 #[cfg(feature = "time-driver")]
-pub mod timer;
+pub mod time_driver;
 pub mod uart;
 pub mod usb;
 pub mod watchdog;
@@ -344,7 +344,7 @@ pub fn init(config: config::Config) -> Peripherals {
     unsafe {
         clocks::init(config.clocks);
         #[cfg(feature = "time-driver")]
-        timer::init();
+        time_driver::init();
         dma::init();
         gpio::init();
     }
diff --git a/embassy-rp/src/timer.rs b/embassy-rp/src/time_driver.rs
similarity index 97%
rename from embassy-rp/src/timer.rs
rename to embassy-rp/src/time_driver.rs
index 69c0c85b1..bab1044cb 100644
--- a/embassy-rp/src/timer.rs
+++ b/embassy-rp/src/time_driver.rs
@@ -5,7 +5,7 @@ use atomic_polyfill::{AtomicU8, Ordering};
 use critical_section::CriticalSection;
 use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
 use embassy_sync::blocking_mutex::Mutex;
-use embassy_time::driver::{AlarmHandle, Driver};
+use embassy_time_driver::{AlarmHandle, Driver};
 
 use crate::interrupt::InterruptExt;
 use crate::{interrupt, pac};
@@ -27,7 +27,7 @@ struct TimerDriver {
     next_alarm: AtomicU8,
 }
 
-embassy_time::time_driver_impl!(static DRIVER: TimerDriver = TimerDriver{
+embassy_time_driver::time_driver_impl!(static DRIVER: TimerDriver = TimerDriver{
     alarms:  Mutex::const_new(CriticalSectionRawMutex::new(), [DUMMY_ALARM; ALARM_COUNT]),
     next_alarm: AtomicU8::new(0),
 });
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index a798a8c5f..60fc86135 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -34,6 +34,7 @@ flavors = [
 [dependencies]
 embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
 embassy-time = { version = "0.2", path = "../embassy-time", optional = true }
+embassy-time-driver = { version = "0.1", path = "../embassy-time-driver", optional = true }
 embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
 embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] }
 embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
@@ -88,7 +89,7 @@ rt = ["stm32-metapac/rt"]
 defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async/defmt-03", "embassy-usb-driver/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"]
 
 exti = []
-low-power = [ "dep:embassy-executor", "embassy-executor?/arch-cortex-m" ]
+low-power = [ "dep:embassy-executor", "embassy-executor?/arch-cortex-m", "time" ]
 low-power-debug-with-sleep = []
 
 ## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/)
@@ -107,7 +108,7 @@ time = ["dep:embassy-time"]
 
 # Features starting with `_` are for internal use only. They're not intended
 # to be enabled by other crates, and are not covered by semver guarantees.
-_time-driver = ["time"]
+_time-driver = ["dep:embassy-time-driver", "time"]
 
 ## Use any time driver
 time-driver-any = ["_time-driver"]
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index 9981800b2..0dbadce0c 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -6,8 +6,7 @@ use core::{mem, ptr};
 use critical_section::CriticalSection;
 use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
 use embassy_sync::blocking_mutex::Mutex;
-use embassy_time::driver::{AlarmHandle, Driver};
-use embassy_time::TICK_HZ;
+use embassy_time_driver::{AlarmHandle, Driver, TICK_HZ};
 use stm32_metapac::timer::regs;
 
 use crate::interrupt::typelevel::Interrupt;
@@ -173,7 +172,7 @@ pub(crate) struct RtcDriver {
 
 const ALARM_STATE_NEW: AlarmState = AlarmState::new();
 
-embassy_time::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
+embassy_time_driver::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
     period: AtomicU32::new(0),
     alarm_count: AtomicU8::new(0),
     alarms: Mutex::const_new(CriticalSectionRawMutex::new(), [ALARM_STATE_NEW; ALARM_COUNT]),
diff --git a/embassy-time-driver/CHANGELOG.md b/embassy-time-driver/CHANGELOG.md
new file mode 100644
index 000000000..d8c0c7d08
--- /dev/null
+++ b/embassy-time-driver/CHANGELOG.md
@@ -0,0 +1,51 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.2.0 - 2023-12-04
+
+- Added tick rates in multiples of 10 kHz
+- Remove nightly and unstable-traits features in preparation for 1.75.
+- Update heapless to 0.8.
+
+## 0.1.5 - 2023-10-16
+
+- Added `links` key to Cargo.toml, to prevent multiple copies of this crate in the same binary.
+  Needed because different copies might get different tick rates, causing
+  wrong delays if the time driver is using one copy and user code is using another.
+  This is especially common when mixing crates from crates.io and git.
+
+## 0.1.4 - 2023-10-12
+
+- Added more tick rates
+
+## 0.1.3 - 2023-08-28
+
+- Update `embedded-hal-async` to `1.0.0-rc.2`
+- Update `embedded-hal v1` to `1.0.0-rc.2`
+
+## 0.1.2 - 2023-07-05
+
+- Update `embedded-hal-async` to `0.2.0-alpha.2`.
+- Update `embedded-hal v1` to `1.0.0-alpha.11`. (Note: v0.2 support is kept unchanged).
+
+## 0.1.1 - 2023-04-13
+
+- Update `embedded-hal-async` to `0.2.0-alpha.1` (uses `async fn` in traits).
+- Update `embedded-hal v1` to `1.0.0-alpha.10`. (Note: v0.2 support is kept unchanged).
+- Remove dep on `embassy-sync`.
+- Fix reentrancy issues in the `std` time driver (#1177)
+- Add `Duration::from_hz()`.
+- impl `From` conversions to/from `core::time::Duration`.
+- Add `#[must_use]` to all futures.
+- Add inherent `async fn tick()` to `Ticker`, so you can use it directly without the `Stream` trait.
+- Add more tick rates.
+- impl `Default` for `Signal`
+- Remove unnecessary uses of `atomic-polyfill`
+
+## 0.1.0 - 2022-08-26
+
+- First release
diff --git a/embassy-time-driver/Cargo.toml b/embassy-time-driver/Cargo.toml
new file mode 100644
index 000000000..2ed250d4d
--- /dev/null
+++ b/embassy-time-driver/Cargo.toml
@@ -0,0 +1,391 @@
+[package]
+name = "embassy-time-driver"
+version = "0.1.0"
+edition = "2021"
+description = "Driver trait for embassy-time"
+repository = "https://github.com/embassy-rs/embassy"
+readme = "README.md"
+license = "MIT OR Apache-2.0"
+categories = [
+    "embedded",
+    "no-std",
+    "concurrency",
+    "asynchronous",
+]
+
+# Prevent multiple copies of this crate in the same binary.
+# Needed because different copies might get different tick rates, causing
+# wrong delays if the time driver is using one copy and user code is using another.
+# This is especially common when mixing crates from crates.io and git.
+links = "embassy-time"
+
+[package.metadata.embassy_docs]
+src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-driver-v$VERSION/embassy-time-driver/src/"
+src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time-driver/src/"
+target = "x86_64-unknown-linux-gnu"
+
+[features]
+#! ### Tick Rate
+#!
+#! At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used.
+#! 
+#! If the time driver in use supports using arbitrary tick rates, you can enable one `tick-*`
+#! feature from your binary crate to set the tick rate. The driver will use configured tick rate.
+#! If the time driver supports a fixed tick rate, it will enable one feature itself, so you should
+#! not enable one. Check the time driver documentation for details.
+#!
+#! When using embassy-time from libraries, you should *not* enable any `tick-*` feature, to allow the
+#! end user or the driver to pick.
+#! <details>
+#!   <summary>Available tick rates:</summary>
+#! <!-- Next line must be left empty for the features to render correctly! -->
+#! 
+
+# BEGIN TICKS
+# Generated by gen_tick.py. DO NOT EDIT.
+## 1Hz Tick Rate
+tick-hz-1 = []
+## 2Hz Tick Rate
+tick-hz-2 = []
+## 4Hz Tick Rate
+tick-hz-4 = []
+## 8Hz Tick Rate
+tick-hz-8 = []
+## 10Hz Tick Rate
+tick-hz-10 = []
+## 16Hz Tick Rate
+tick-hz-16 = []
+## 32Hz Tick Rate
+tick-hz-32 = []
+## 64Hz Tick Rate
+tick-hz-64 = []
+## 100Hz Tick Rate
+tick-hz-100 = []
+## 128Hz Tick Rate
+tick-hz-128 = []
+## 256Hz Tick Rate
+tick-hz-256 = []
+## 512Hz Tick Rate
+tick-hz-512 = []
+## 1.0kHz Tick Rate
+tick-hz-1_000 = []
+## 1.024kHz Tick Rate
+tick-hz-1_024 = []
+## 2.0kHz Tick Rate
+tick-hz-2_000 = []
+## 2.048kHz Tick Rate
+tick-hz-2_048 = []
+## 4.0kHz Tick Rate
+tick-hz-4_000 = []
+## 4.096kHz Tick Rate
+tick-hz-4_096 = []
+## 8.0kHz Tick Rate
+tick-hz-8_000 = []
+## 8.192kHz Tick Rate
+tick-hz-8_192 = []
+## 10.0kHz Tick Rate
+tick-hz-10_000 = []
+## 16.0kHz Tick Rate
+tick-hz-16_000 = []
+## 16.384kHz Tick Rate
+tick-hz-16_384 = []
+## 20.0kHz Tick Rate
+tick-hz-20_000 = []
+## 32.0kHz Tick Rate
+tick-hz-32_000 = []
+## 32.768kHz Tick Rate
+tick-hz-32_768 = []
+## 40.0kHz Tick Rate
+tick-hz-40_000 = []
+## 64.0kHz Tick Rate
+tick-hz-64_000 = []
+## 65.536kHz Tick Rate
+tick-hz-65_536 = []
+## 80.0kHz Tick Rate
+tick-hz-80_000 = []
+## 100.0kHz Tick Rate
+tick-hz-100_000 = []
+## 128.0kHz Tick Rate
+tick-hz-128_000 = []
+## 131.072kHz Tick Rate
+tick-hz-131_072 = []
+## 160.0kHz Tick Rate
+tick-hz-160_000 = []
+## 256.0kHz Tick Rate
+tick-hz-256_000 = []
+## 262.144kHz Tick Rate
+tick-hz-262_144 = []
+## 320.0kHz Tick Rate
+tick-hz-320_000 = []
+## 512.0kHz Tick Rate
+tick-hz-512_000 = []
+## 524.288kHz Tick Rate
+tick-hz-524_288 = []
+## 640.0kHz Tick Rate
+tick-hz-640_000 = []
+## 1.0MHz Tick Rate
+tick-hz-1_000_000 = []
+## 1.024MHz Tick Rate
+tick-hz-1_024_000 = []
+## 1.048576MHz Tick Rate
+tick-hz-1_048_576 = []
+## 1.28MHz Tick Rate
+tick-hz-1_280_000 = []
+## 2.0MHz Tick Rate
+tick-hz-2_000_000 = []
+## 2.048MHz Tick Rate
+tick-hz-2_048_000 = []
+## 2.097152MHz Tick Rate
+tick-hz-2_097_152 = []
+## 2.56MHz Tick Rate
+tick-hz-2_560_000 = []
+## 3.0MHz Tick Rate
+tick-hz-3_000_000 = []
+## 4.0MHz Tick Rate
+tick-hz-4_000_000 = []
+## 4.096MHz Tick Rate
+tick-hz-4_096_000 = []
+## 4.194304MHz Tick Rate
+tick-hz-4_194_304 = []
+## 5.12MHz Tick Rate
+tick-hz-5_120_000 = []
+## 6.0MHz Tick Rate
+tick-hz-6_000_000 = []
+## 8.0MHz Tick Rate
+tick-hz-8_000_000 = []
+## 8.192MHz Tick Rate
+tick-hz-8_192_000 = []
+## 8.388608MHz Tick Rate
+tick-hz-8_388_608 = []
+## 9.0MHz Tick Rate
+tick-hz-9_000_000 = []
+## 10.0MHz Tick Rate
+tick-hz-10_000_000 = []
+## 10.24MHz Tick Rate
+tick-hz-10_240_000 = []
+## 12.0MHz Tick Rate
+tick-hz-12_000_000 = []
+## 16.0MHz Tick Rate
+tick-hz-16_000_000 = []
+## 16.384MHz Tick Rate
+tick-hz-16_384_000 = []
+## 16.777216MHz Tick Rate
+tick-hz-16_777_216 = []
+## 18.0MHz Tick Rate
+tick-hz-18_000_000 = []
+## 20.0MHz Tick Rate
+tick-hz-20_000_000 = []
+## 20.48MHz Tick Rate
+tick-hz-20_480_000 = []
+## 24.0MHz Tick Rate
+tick-hz-24_000_000 = []
+## 30.0MHz Tick Rate
+tick-hz-30_000_000 = []
+## 32.0MHz Tick Rate
+tick-hz-32_000_000 = []
+## 32.768MHz Tick Rate
+tick-hz-32_768_000 = []
+## 36.0MHz Tick Rate
+tick-hz-36_000_000 = []
+## 40.0MHz Tick Rate
+tick-hz-40_000_000 = []
+## 40.96MHz Tick Rate
+tick-hz-40_960_000 = []
+## 48.0MHz Tick Rate
+tick-hz-48_000_000 = []
+## 50.0MHz Tick Rate
+tick-hz-50_000_000 = []
+## 60.0MHz Tick Rate
+tick-hz-60_000_000 = []
+## 64.0MHz Tick Rate
+tick-hz-64_000_000 = []
+## 65.536MHz Tick Rate
+tick-hz-65_536_000 = []
+## 70.0MHz Tick Rate
+tick-hz-70_000_000 = []
+## 72.0MHz Tick Rate
+tick-hz-72_000_000 = []
+## 80.0MHz Tick Rate
+tick-hz-80_000_000 = []
+## 81.92MHz Tick Rate
+tick-hz-81_920_000 = []
+## 90.0MHz Tick Rate
+tick-hz-90_000_000 = []
+## 96.0MHz Tick Rate
+tick-hz-96_000_000 = []
+## 100.0MHz Tick Rate
+tick-hz-100_000_000 = []
+## 110.0MHz Tick Rate
+tick-hz-110_000_000 = []
+## 120.0MHz Tick Rate
+tick-hz-120_000_000 = []
+## 128.0MHz Tick Rate
+tick-hz-128_000_000 = []
+## 130.0MHz Tick Rate
+tick-hz-130_000_000 = []
+## 131.072MHz Tick Rate
+tick-hz-131_072_000 = []
+## 140.0MHz Tick Rate
+tick-hz-140_000_000 = []
+## 144.0MHz Tick Rate
+tick-hz-144_000_000 = []
+## 150.0MHz Tick Rate
+tick-hz-150_000_000 = []
+## 160.0MHz Tick Rate
+tick-hz-160_000_000 = []
+## 163.84MHz Tick Rate
+tick-hz-163_840_000 = []
+## 170.0MHz Tick Rate
+tick-hz-170_000_000 = []
+## 180.0MHz Tick Rate
+tick-hz-180_000_000 = []
+## 190.0MHz Tick Rate
+tick-hz-190_000_000 = []
+## 192.0MHz Tick Rate
+tick-hz-192_000_000 = []
+## 200.0MHz Tick Rate
+tick-hz-200_000_000 = []
+## 210.0MHz Tick Rate
+tick-hz-210_000_000 = []
+## 220.0MHz Tick Rate
+tick-hz-220_000_000 = []
+## 230.0MHz Tick Rate
+tick-hz-230_000_000 = []
+## 240.0MHz Tick Rate
+tick-hz-240_000_000 = []
+## 250.0MHz Tick Rate
+tick-hz-250_000_000 = []
+## 256.0MHz Tick Rate
+tick-hz-256_000_000 = []
+## 260.0MHz Tick Rate
+tick-hz-260_000_000 = []
+## 262.144MHz Tick Rate
+tick-hz-262_144_000 = []
+## 270.0MHz Tick Rate
+tick-hz-270_000_000 = []
+## 280.0MHz Tick Rate
+tick-hz-280_000_000 = []
+## 288.0MHz Tick Rate
+tick-hz-288_000_000 = []
+## 290.0MHz Tick Rate
+tick-hz-290_000_000 = []
+## 300.0MHz Tick Rate
+tick-hz-300_000_000 = []
+## 320.0MHz Tick Rate
+tick-hz-320_000_000 = []
+## 327.68MHz Tick Rate
+tick-hz-327_680_000 = []
+## 340.0MHz Tick Rate
+tick-hz-340_000_000 = []
+## 360.0MHz Tick Rate
+tick-hz-360_000_000 = []
+## 380.0MHz Tick Rate
+tick-hz-380_000_000 = []
+## 384.0MHz Tick Rate
+tick-hz-384_000_000 = []
+## 400.0MHz Tick Rate
+tick-hz-400_000_000 = []
+## 420.0MHz Tick Rate
+tick-hz-420_000_000 = []
+## 440.0MHz Tick Rate
+tick-hz-440_000_000 = []
+## 460.0MHz Tick Rate
+tick-hz-460_000_000 = []
+## 480.0MHz Tick Rate
+tick-hz-480_000_000 = []
+## 500.0MHz Tick Rate
+tick-hz-500_000_000 = []
+## 512.0MHz Tick Rate
+tick-hz-512_000_000 = []
+## 520.0MHz Tick Rate
+tick-hz-520_000_000 = []
+## 524.288MHz Tick Rate
+tick-hz-524_288_000 = []
+## 540.0MHz Tick Rate
+tick-hz-540_000_000 = []
+## 560.0MHz Tick Rate
+tick-hz-560_000_000 = []
+## 576.0MHz Tick Rate
+tick-hz-576_000_000 = []
+## 580.0MHz Tick Rate
+tick-hz-580_000_000 = []
+## 600.0MHz Tick Rate
+tick-hz-600_000_000 = []
+## 620.0MHz Tick Rate
+tick-hz-620_000_000 = []
+## 640.0MHz Tick Rate
+tick-hz-640_000_000 = []
+## 655.36MHz Tick Rate
+tick-hz-655_360_000 = []
+## 660.0MHz Tick Rate
+tick-hz-660_000_000 = []
+## 680.0MHz Tick Rate
+tick-hz-680_000_000 = []
+## 700.0MHz Tick Rate
+tick-hz-700_000_000 = []
+## 720.0MHz Tick Rate
+tick-hz-720_000_000 = []
+## 740.0MHz Tick Rate
+tick-hz-740_000_000 = []
+## 760.0MHz Tick Rate
+tick-hz-760_000_000 = []
+## 768.0MHz Tick Rate
+tick-hz-768_000_000 = []
+## 780.0MHz Tick Rate
+tick-hz-780_000_000 = []
+## 800.0MHz Tick Rate
+tick-hz-800_000_000 = []
+## 820.0MHz Tick Rate
+tick-hz-820_000_000 = []
+## 840.0MHz Tick Rate
+tick-hz-840_000_000 = []
+## 860.0MHz Tick Rate
+tick-hz-860_000_000 = []
+## 880.0MHz Tick Rate
+tick-hz-880_000_000 = []
+## 900.0MHz Tick Rate
+tick-hz-900_000_000 = []
+## 920.0MHz Tick Rate
+tick-hz-920_000_000 = []
+## 940.0MHz Tick Rate
+tick-hz-940_000_000 = []
+## 960.0MHz Tick Rate
+tick-hz-960_000_000 = []
+## 980.0MHz Tick Rate
+tick-hz-980_000_000 = []
+## 1.0GHz Tick Rate
+tick-hz-1_000_000_000 = []
+## 1.31072GHz Tick Rate
+tick-hz-1_310_720_000 = []
+## 2.62144GHz Tick Rate
+tick-hz-2_621_440_000 = []
+## 5.24288GHz Tick Rate
+tick-hz-5_242_880_000 = []
+# END TICKS
+
+#! </details>
+
+[dependencies]
+defmt = { version = "0.3", optional = true }
+log = { version = "0.4.14", optional = true }
+
+embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
+embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
+embedded-hal-async = { version = "1.0" }
+
+futures-util = { version = "0.3.17", default-features = false }
+critical-section = "1.1"
+cfg-if = "1.0.0"
+heapless = "0.8"
+
+document-features = "0.2.7"
+
+# WASM dependencies
+wasm-bindgen = { version = "0.2.81", optional = true }
+js-sys = { version = "0.3", optional = true }
+wasm-timer = { version = "0.2.5", optional = true }
+
+[dev-dependencies]
+serial_test = "0.9"
+critical-section = { version = "1.1", features = ["std"] }
+embassy-executor = { version = "0.4.0", path = "../embassy-executor" }
diff --git a/embassy-time-driver/README.md b/embassy-time-driver/README.md
new file mode 100644
index 000000000..74a5b7876
--- /dev/null
+++ b/embassy-time-driver/README.md
@@ -0,0 +1,20 @@
+# embassy-time-driver
+
+
+This crate contains the driver trait necessary for adding [`embassy-time`](https://crates.io/crates/embassy-time) support
+for a new hardware platform.
+
+If you want to *use* `embassy-time` with already made drivers, you should depend on the main `embassy-time` crate, not on this crate.
+
+If you are writing a driver, you  should depend only on this crate, not on the main `embassy-time` crate.
+This will allow your driver to continue working for newer `embassy-time` major versions, without needing an update,
+if the driver trait has not had breaking changes.
+
+## How it works
+
+`embassy-time` module is backed by a global "time driver" specified at build time.
+Only one driver can be active in a program.
+
+All methods and structs transparently call into the active driver. This makes it
+possible for libraries to use `embassy-time` in a driver-agnostic way without
+requiring generic parameters.
diff --git a/embassy-time/build.rs b/embassy-time-driver/build.rs
similarity index 100%
rename from embassy-time/build.rs
rename to embassy-time-driver/build.rs
diff --git a/embassy-time/gen_tick.py b/embassy-time-driver/gen_tick.py
similarity index 71%
rename from embassy-time/gen_tick.py
rename to embassy-time-driver/gen_tick.py
index 8961fb7e6..af194c31f 100644
--- a/embassy-time/gen_tick.py
+++ b/embassy-time-driver/gen_tick.py
@@ -28,18 +28,14 @@ ticks = sorted([x for x in ticks if not (x in seen or seen.add(x))])
 
 # ========= Update Cargo.toml
 
-things = [(hz, f'tick-hz-{hz:_}') for hz in ticks]
-
 SEPARATOR_START = '# BEGIN TICKS\n'
 SEPARATOR_END = '# END TICKS\n'
 HELP = '# Generated by gen_tick.py. DO NOT EDIT.\n'
-with open('Cargo.toml', 'r') as f:
-    data = f.read()
-before, data = data.split(SEPARATOR_START, maxsplit=1)
-_, after = data.split(SEPARATOR_END, maxsplit=1)
 
-data = before + SEPARATOR_START + HELP
-for freq, feature in things:
+feats_time = ''
+feats_driver = ''
+for freq in ticks:
+    feature = f'tick-hz-{freq:_}'
     if freq >= 1_000_000_000:
         freq_human = f"{freq / 1_000_000_000}GHz"
     elif freq >= 1_000_000:
@@ -49,12 +45,24 @@ for freq, feature in things:
     else:
         freq_human = f"{freq}Hz"
 
-    data += f"## {freq_human} Tick Rate\n"
-    data += f"{feature} = []\n"
-data += SEPARATOR_END + after
+    feats_time += f"## {freq_human} Tick Rate\n"
+    feats_time += f"{feature} = [\"embassy-time-driver/{feature}\"]\n"
+    feats_driver += f"## {freq_human} Tick Rate\n"
+    feats_driver += f"{feature} = []\n"
 
+with open('Cargo.toml', 'r') as f:
+    data = f.read()
+before, data = data.split(SEPARATOR_START, maxsplit=1)
+_, after = data.split(SEPARATOR_END, maxsplit=1)
 with open('Cargo.toml', 'w') as f:
-    f.write(data)
+    f.write(before + SEPARATOR_START + HELP + feats_driver + SEPARATOR_END + after)
+
+with open('../embassy-time/Cargo.toml', 'r') as f:
+    data = f.read()
+before, data = data.split(SEPARATOR_START, maxsplit=1)
+_, after = data.split(SEPARATOR_END, maxsplit=1)
+with open('../embassy-time/Cargo.toml', 'w') as f:
+    f.write(before + SEPARATOR_START + HELP + feats_time + SEPARATOR_END + after)
 
 # ========= Update src/tick.rs
 
diff --git a/embassy-time/src/driver.rs b/embassy-time-driver/src/lib.rs
similarity index 89%
rename from embassy-time/src/driver.rs
rename to embassy-time-driver/src/lib.rs
index f966386b7..39a772aa5 100644
--- a/embassy-time/src/driver.rs
+++ b/embassy-time-driver/src/lib.rs
@@ -1,3 +1,7 @@
+#![no_std]
+#![doc = include_str!("../README.md")]
+#![warn(missing_docs)]
+
 //! Time driver interface
 //!
 //! This module defines the interface a driver needs to implement to power the `embassy_time` module.
@@ -62,6 +66,16 @@
 //! embassy_time::time_driver_impl!(static DRIVER: MyDriver = MyDriver{});
 //! ```
 
+//! ## Feature flags
+#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
+
+mod tick;
+
+/// Ticks per second of the global timebase.
+///
+/// This value is specified by the [`tick-*` Cargo features](crate#tick-rate)
+pub const TICK_HZ: u64 = tick::TICK_HZ;
+
 /// Alarm handle, assigned by the driver.
 #[derive(Clone, Copy)]
 pub struct AlarmHandle {
@@ -165,22 +179,22 @@ macro_rules! time_driver_impl {
 
         #[no_mangle]
         fn _embassy_time_now() -> u64 {
-            <$t as $crate::driver::Driver>::now(&$name)
+            <$t as $crate::Driver>::now(&$name)
         }
 
         #[no_mangle]
-        unsafe fn _embassy_time_allocate_alarm() -> Option<$crate::driver::AlarmHandle> {
-            <$t as $crate::driver::Driver>::allocate_alarm(&$name)
+        unsafe fn _embassy_time_allocate_alarm() -> Option<$crate::AlarmHandle> {
+            <$t as $crate::Driver>::allocate_alarm(&$name)
         }
 
         #[no_mangle]
-        fn _embassy_time_set_alarm_callback(alarm: $crate::driver::AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
-            <$t as $crate::driver::Driver>::set_alarm_callback(&$name, alarm, callback, ctx)
+        fn _embassy_time_set_alarm_callback(alarm: $crate::AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
+            <$t as $crate::Driver>::set_alarm_callback(&$name, alarm, callback, ctx)
         }
 
         #[no_mangle]
-        fn _embassy_time_set_alarm(alarm: $crate::driver::AlarmHandle, timestamp: u64) -> bool {
-            <$t as $crate::driver::Driver>::set_alarm(&$name, alarm, timestamp)
+        fn _embassy_time_set_alarm(alarm: $crate::AlarmHandle, timestamp: u64) -> bool {
+            <$t as $crate::Driver>::set_alarm(&$name, alarm, timestamp)
         }
     };
 }
diff --git a/embassy-time/src/tick.rs b/embassy-time-driver/src/tick.rs
similarity index 100%
rename from embassy-time/src/tick.rs
rename to embassy-time-driver/src/tick.rs
diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml
index 2beefac83..729a2bd4f 100644
--- a/embassy-time/Cargo.toml
+++ b/embassy-time/Cargo.toml
@@ -13,12 +13,6 @@ categories = [
     "asynchronous",
 ]
 
-# Prevent multiple copies of this crate in the same binary.
-# Needed because different copies might get different tick rates, causing
-# wrong delays if the time driver is using one copy and user code is using another.
-# This is especially common when mixing crates from crates.io and git.
-links = "embassy-time"
-
 [package.metadata.embassy_docs]
 src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-v$VERSION/embassy-time/src/"
 src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time/src/"
@@ -81,328 +75,330 @@ generic-queue-128 = ["generic-queue"]
 # BEGIN TICKS
 # Generated by gen_tick.py. DO NOT EDIT.
 ## 1Hz Tick Rate
-tick-hz-1 = []
+tick-hz-1 = ["embassy-time-driver/tick-hz-1"]
 ## 2Hz Tick Rate
-tick-hz-2 = []
+tick-hz-2 = ["embassy-time-driver/tick-hz-2"]
 ## 4Hz Tick Rate
-tick-hz-4 = []
+tick-hz-4 = ["embassy-time-driver/tick-hz-4"]
 ## 8Hz Tick Rate
-tick-hz-8 = []
+tick-hz-8 = ["embassy-time-driver/tick-hz-8"]
 ## 10Hz Tick Rate
-tick-hz-10 = []
+tick-hz-10 = ["embassy-time-driver/tick-hz-10"]
 ## 16Hz Tick Rate
-tick-hz-16 = []
+tick-hz-16 = ["embassy-time-driver/tick-hz-16"]
 ## 32Hz Tick Rate
-tick-hz-32 = []
+tick-hz-32 = ["embassy-time-driver/tick-hz-32"]
 ## 64Hz Tick Rate
-tick-hz-64 = []
+tick-hz-64 = ["embassy-time-driver/tick-hz-64"]
 ## 100Hz Tick Rate
-tick-hz-100 = []
+tick-hz-100 = ["embassy-time-driver/tick-hz-100"]
 ## 128Hz Tick Rate
-tick-hz-128 = []
+tick-hz-128 = ["embassy-time-driver/tick-hz-128"]
 ## 256Hz Tick Rate
-tick-hz-256 = []
+tick-hz-256 = ["embassy-time-driver/tick-hz-256"]
 ## 512Hz Tick Rate
-tick-hz-512 = []
+tick-hz-512 = ["embassy-time-driver/tick-hz-512"]
 ## 1.0kHz Tick Rate
-tick-hz-1_000 = []
+tick-hz-1_000 = ["embassy-time-driver/tick-hz-1_000"]
 ## 1.024kHz Tick Rate
-tick-hz-1_024 = []
+tick-hz-1_024 = ["embassy-time-driver/tick-hz-1_024"]
 ## 2.0kHz Tick Rate
-tick-hz-2_000 = []
+tick-hz-2_000 = ["embassy-time-driver/tick-hz-2_000"]
 ## 2.048kHz Tick Rate
-tick-hz-2_048 = []
+tick-hz-2_048 = ["embassy-time-driver/tick-hz-2_048"]
 ## 4.0kHz Tick Rate
-tick-hz-4_000 = []
+tick-hz-4_000 = ["embassy-time-driver/tick-hz-4_000"]
 ## 4.096kHz Tick Rate
-tick-hz-4_096 = []
+tick-hz-4_096 = ["embassy-time-driver/tick-hz-4_096"]
 ## 8.0kHz Tick Rate
-tick-hz-8_000 = []
+tick-hz-8_000 = ["embassy-time-driver/tick-hz-8_000"]
 ## 8.192kHz Tick Rate
-tick-hz-8_192 = []
+tick-hz-8_192 = ["embassy-time-driver/tick-hz-8_192"]
 ## 10.0kHz Tick Rate
-tick-hz-10_000 = []
+tick-hz-10_000 = ["embassy-time-driver/tick-hz-10_000"]
 ## 16.0kHz Tick Rate
-tick-hz-16_000 = []
+tick-hz-16_000 = ["embassy-time-driver/tick-hz-16_000"]
 ## 16.384kHz Tick Rate
-tick-hz-16_384 = []
+tick-hz-16_384 = ["embassy-time-driver/tick-hz-16_384"]
 ## 20.0kHz Tick Rate
-tick-hz-20_000 = []
+tick-hz-20_000 = ["embassy-time-driver/tick-hz-20_000"]
 ## 32.0kHz Tick Rate
-tick-hz-32_000 = []
+tick-hz-32_000 = ["embassy-time-driver/tick-hz-32_000"]
 ## 32.768kHz Tick Rate
-tick-hz-32_768 = []
+tick-hz-32_768 = ["embassy-time-driver/tick-hz-32_768"]
 ## 40.0kHz Tick Rate
-tick-hz-40_000 = []
+tick-hz-40_000 = ["embassy-time-driver/tick-hz-40_000"]
 ## 64.0kHz Tick Rate
-tick-hz-64_000 = []
+tick-hz-64_000 = ["embassy-time-driver/tick-hz-64_000"]
 ## 65.536kHz Tick Rate
-tick-hz-65_536 = []
+tick-hz-65_536 = ["embassy-time-driver/tick-hz-65_536"]
 ## 80.0kHz Tick Rate
-tick-hz-80_000 = []
+tick-hz-80_000 = ["embassy-time-driver/tick-hz-80_000"]
 ## 100.0kHz Tick Rate
-tick-hz-100_000 = []
+tick-hz-100_000 = ["embassy-time-driver/tick-hz-100_000"]
 ## 128.0kHz Tick Rate
-tick-hz-128_000 = []
+tick-hz-128_000 = ["embassy-time-driver/tick-hz-128_000"]
 ## 131.072kHz Tick Rate
-tick-hz-131_072 = []
+tick-hz-131_072 = ["embassy-time-driver/tick-hz-131_072"]
 ## 160.0kHz Tick Rate
-tick-hz-160_000 = []
+tick-hz-160_000 = ["embassy-time-driver/tick-hz-160_000"]
 ## 256.0kHz Tick Rate
-tick-hz-256_000 = []
+tick-hz-256_000 = ["embassy-time-driver/tick-hz-256_000"]
 ## 262.144kHz Tick Rate
-tick-hz-262_144 = []
+tick-hz-262_144 = ["embassy-time-driver/tick-hz-262_144"]
 ## 320.0kHz Tick Rate
-tick-hz-320_000 = []
+tick-hz-320_000 = ["embassy-time-driver/tick-hz-320_000"]
 ## 512.0kHz Tick Rate
-tick-hz-512_000 = []
+tick-hz-512_000 = ["embassy-time-driver/tick-hz-512_000"]
 ## 524.288kHz Tick Rate
-tick-hz-524_288 = []
+tick-hz-524_288 = ["embassy-time-driver/tick-hz-524_288"]
 ## 640.0kHz Tick Rate
-tick-hz-640_000 = []
+tick-hz-640_000 = ["embassy-time-driver/tick-hz-640_000"]
 ## 1.0MHz Tick Rate
-tick-hz-1_000_000 = []
+tick-hz-1_000_000 = ["embassy-time-driver/tick-hz-1_000_000"]
 ## 1.024MHz Tick Rate
-tick-hz-1_024_000 = []
+tick-hz-1_024_000 = ["embassy-time-driver/tick-hz-1_024_000"]
 ## 1.048576MHz Tick Rate
-tick-hz-1_048_576 = []
+tick-hz-1_048_576 = ["embassy-time-driver/tick-hz-1_048_576"]
 ## 1.28MHz Tick Rate
-tick-hz-1_280_000 = []
+tick-hz-1_280_000 = ["embassy-time-driver/tick-hz-1_280_000"]
 ## 2.0MHz Tick Rate
-tick-hz-2_000_000 = []
+tick-hz-2_000_000 = ["embassy-time-driver/tick-hz-2_000_000"]
 ## 2.048MHz Tick Rate
-tick-hz-2_048_000 = []
+tick-hz-2_048_000 = ["embassy-time-driver/tick-hz-2_048_000"]
 ## 2.097152MHz Tick Rate
-tick-hz-2_097_152 = []
+tick-hz-2_097_152 = ["embassy-time-driver/tick-hz-2_097_152"]
 ## 2.56MHz Tick Rate
-tick-hz-2_560_000 = []
+tick-hz-2_560_000 = ["embassy-time-driver/tick-hz-2_560_000"]
 ## 3.0MHz Tick Rate
-tick-hz-3_000_000 = []
+tick-hz-3_000_000 = ["embassy-time-driver/tick-hz-3_000_000"]
 ## 4.0MHz Tick Rate
-tick-hz-4_000_000 = []
+tick-hz-4_000_000 = ["embassy-time-driver/tick-hz-4_000_000"]
 ## 4.096MHz Tick Rate
-tick-hz-4_096_000 = []
+tick-hz-4_096_000 = ["embassy-time-driver/tick-hz-4_096_000"]
 ## 4.194304MHz Tick Rate
-tick-hz-4_194_304 = []
+tick-hz-4_194_304 = ["embassy-time-driver/tick-hz-4_194_304"]
 ## 5.12MHz Tick Rate
-tick-hz-5_120_000 = []
+tick-hz-5_120_000 = ["embassy-time-driver/tick-hz-5_120_000"]
 ## 6.0MHz Tick Rate
-tick-hz-6_000_000 = []
+tick-hz-6_000_000 = ["embassy-time-driver/tick-hz-6_000_000"]
 ## 8.0MHz Tick Rate
-tick-hz-8_000_000 = []
+tick-hz-8_000_000 = ["embassy-time-driver/tick-hz-8_000_000"]
 ## 8.192MHz Tick Rate
-tick-hz-8_192_000 = []
+tick-hz-8_192_000 = ["embassy-time-driver/tick-hz-8_192_000"]
 ## 8.388608MHz Tick Rate
-tick-hz-8_388_608 = []
+tick-hz-8_388_608 = ["embassy-time-driver/tick-hz-8_388_608"]
 ## 9.0MHz Tick Rate
-tick-hz-9_000_000 = []
+tick-hz-9_000_000 = ["embassy-time-driver/tick-hz-9_000_000"]
 ## 10.0MHz Tick Rate
-tick-hz-10_000_000 = []
+tick-hz-10_000_000 = ["embassy-time-driver/tick-hz-10_000_000"]
 ## 10.24MHz Tick Rate
-tick-hz-10_240_000 = []
+tick-hz-10_240_000 = ["embassy-time-driver/tick-hz-10_240_000"]
 ## 12.0MHz Tick Rate
-tick-hz-12_000_000 = []
+tick-hz-12_000_000 = ["embassy-time-driver/tick-hz-12_000_000"]
 ## 16.0MHz Tick Rate
-tick-hz-16_000_000 = []
+tick-hz-16_000_000 = ["embassy-time-driver/tick-hz-16_000_000"]
 ## 16.384MHz Tick Rate
-tick-hz-16_384_000 = []
+tick-hz-16_384_000 = ["embassy-time-driver/tick-hz-16_384_000"]
 ## 16.777216MHz Tick Rate
-tick-hz-16_777_216 = []
+tick-hz-16_777_216 = ["embassy-time-driver/tick-hz-16_777_216"]
 ## 18.0MHz Tick Rate
-tick-hz-18_000_000 = []
+tick-hz-18_000_000 = ["embassy-time-driver/tick-hz-18_000_000"]
 ## 20.0MHz Tick Rate
-tick-hz-20_000_000 = []
+tick-hz-20_000_000 = ["embassy-time-driver/tick-hz-20_000_000"]
 ## 20.48MHz Tick Rate
-tick-hz-20_480_000 = []
+tick-hz-20_480_000 = ["embassy-time-driver/tick-hz-20_480_000"]
 ## 24.0MHz Tick Rate
-tick-hz-24_000_000 = []
+tick-hz-24_000_000 = ["embassy-time-driver/tick-hz-24_000_000"]
 ## 30.0MHz Tick Rate
-tick-hz-30_000_000 = []
+tick-hz-30_000_000 = ["embassy-time-driver/tick-hz-30_000_000"]
 ## 32.0MHz Tick Rate
-tick-hz-32_000_000 = []
+tick-hz-32_000_000 = ["embassy-time-driver/tick-hz-32_000_000"]
 ## 32.768MHz Tick Rate
-tick-hz-32_768_000 = []
+tick-hz-32_768_000 = ["embassy-time-driver/tick-hz-32_768_000"]
 ## 36.0MHz Tick Rate
-tick-hz-36_000_000 = []
+tick-hz-36_000_000 = ["embassy-time-driver/tick-hz-36_000_000"]
 ## 40.0MHz Tick Rate
-tick-hz-40_000_000 = []
+tick-hz-40_000_000 = ["embassy-time-driver/tick-hz-40_000_000"]
 ## 40.96MHz Tick Rate
-tick-hz-40_960_000 = []
+tick-hz-40_960_000 = ["embassy-time-driver/tick-hz-40_960_000"]
 ## 48.0MHz Tick Rate
-tick-hz-48_000_000 = []
+tick-hz-48_000_000 = ["embassy-time-driver/tick-hz-48_000_000"]
 ## 50.0MHz Tick Rate
-tick-hz-50_000_000 = []
+tick-hz-50_000_000 = ["embassy-time-driver/tick-hz-50_000_000"]
 ## 60.0MHz Tick Rate
-tick-hz-60_000_000 = []
+tick-hz-60_000_000 = ["embassy-time-driver/tick-hz-60_000_000"]
 ## 64.0MHz Tick Rate
-tick-hz-64_000_000 = []
+tick-hz-64_000_000 = ["embassy-time-driver/tick-hz-64_000_000"]
 ## 65.536MHz Tick Rate
-tick-hz-65_536_000 = []
+tick-hz-65_536_000 = ["embassy-time-driver/tick-hz-65_536_000"]
 ## 70.0MHz Tick Rate
-tick-hz-70_000_000 = []
+tick-hz-70_000_000 = ["embassy-time-driver/tick-hz-70_000_000"]
 ## 72.0MHz Tick Rate
-tick-hz-72_000_000 = []
+tick-hz-72_000_000 = ["embassy-time-driver/tick-hz-72_000_000"]
 ## 80.0MHz Tick Rate
-tick-hz-80_000_000 = []
+tick-hz-80_000_000 = ["embassy-time-driver/tick-hz-80_000_000"]
 ## 81.92MHz Tick Rate
-tick-hz-81_920_000 = []
+tick-hz-81_920_000 = ["embassy-time-driver/tick-hz-81_920_000"]
 ## 90.0MHz Tick Rate
-tick-hz-90_000_000 = []
+tick-hz-90_000_000 = ["embassy-time-driver/tick-hz-90_000_000"]
 ## 96.0MHz Tick Rate
-tick-hz-96_000_000 = []
+tick-hz-96_000_000 = ["embassy-time-driver/tick-hz-96_000_000"]
 ## 100.0MHz Tick Rate
-tick-hz-100_000_000 = []
+tick-hz-100_000_000 = ["embassy-time-driver/tick-hz-100_000_000"]
 ## 110.0MHz Tick Rate
-tick-hz-110_000_000 = []
+tick-hz-110_000_000 = ["embassy-time-driver/tick-hz-110_000_000"]
 ## 120.0MHz Tick Rate
-tick-hz-120_000_000 = []
+tick-hz-120_000_000 = ["embassy-time-driver/tick-hz-120_000_000"]
 ## 128.0MHz Tick Rate
-tick-hz-128_000_000 = []
+tick-hz-128_000_000 = ["embassy-time-driver/tick-hz-128_000_000"]
 ## 130.0MHz Tick Rate
-tick-hz-130_000_000 = []
+tick-hz-130_000_000 = ["embassy-time-driver/tick-hz-130_000_000"]
 ## 131.072MHz Tick Rate
-tick-hz-131_072_000 = []
+tick-hz-131_072_000 = ["embassy-time-driver/tick-hz-131_072_000"]
 ## 140.0MHz Tick Rate
-tick-hz-140_000_000 = []
+tick-hz-140_000_000 = ["embassy-time-driver/tick-hz-140_000_000"]
 ## 144.0MHz Tick Rate
-tick-hz-144_000_000 = []
+tick-hz-144_000_000 = ["embassy-time-driver/tick-hz-144_000_000"]
 ## 150.0MHz Tick Rate
-tick-hz-150_000_000 = []
+tick-hz-150_000_000 = ["embassy-time-driver/tick-hz-150_000_000"]
 ## 160.0MHz Tick Rate
-tick-hz-160_000_000 = []
+tick-hz-160_000_000 = ["embassy-time-driver/tick-hz-160_000_000"]
 ## 163.84MHz Tick Rate
-tick-hz-163_840_000 = []
+tick-hz-163_840_000 = ["embassy-time-driver/tick-hz-163_840_000"]
 ## 170.0MHz Tick Rate
-tick-hz-170_000_000 = []
+tick-hz-170_000_000 = ["embassy-time-driver/tick-hz-170_000_000"]
 ## 180.0MHz Tick Rate
-tick-hz-180_000_000 = []
+tick-hz-180_000_000 = ["embassy-time-driver/tick-hz-180_000_000"]
 ## 190.0MHz Tick Rate
-tick-hz-190_000_000 = []
+tick-hz-190_000_000 = ["embassy-time-driver/tick-hz-190_000_000"]
 ## 192.0MHz Tick Rate
-tick-hz-192_000_000 = []
+tick-hz-192_000_000 = ["embassy-time-driver/tick-hz-192_000_000"]
 ## 200.0MHz Tick Rate
-tick-hz-200_000_000 = []
+tick-hz-200_000_000 = ["embassy-time-driver/tick-hz-200_000_000"]
 ## 210.0MHz Tick Rate
-tick-hz-210_000_000 = []
+tick-hz-210_000_000 = ["embassy-time-driver/tick-hz-210_000_000"]
 ## 220.0MHz Tick Rate
-tick-hz-220_000_000 = []
+tick-hz-220_000_000 = ["embassy-time-driver/tick-hz-220_000_000"]
 ## 230.0MHz Tick Rate
-tick-hz-230_000_000 = []
+tick-hz-230_000_000 = ["embassy-time-driver/tick-hz-230_000_000"]
 ## 240.0MHz Tick Rate
-tick-hz-240_000_000 = []
+tick-hz-240_000_000 = ["embassy-time-driver/tick-hz-240_000_000"]
 ## 250.0MHz Tick Rate
-tick-hz-250_000_000 = []
+tick-hz-250_000_000 = ["embassy-time-driver/tick-hz-250_000_000"]
 ## 256.0MHz Tick Rate
-tick-hz-256_000_000 = []
+tick-hz-256_000_000 = ["embassy-time-driver/tick-hz-256_000_000"]
 ## 260.0MHz Tick Rate
-tick-hz-260_000_000 = []
+tick-hz-260_000_000 = ["embassy-time-driver/tick-hz-260_000_000"]
 ## 262.144MHz Tick Rate
-tick-hz-262_144_000 = []
+tick-hz-262_144_000 = ["embassy-time-driver/tick-hz-262_144_000"]
 ## 270.0MHz Tick Rate
-tick-hz-270_000_000 = []
+tick-hz-270_000_000 = ["embassy-time-driver/tick-hz-270_000_000"]
 ## 280.0MHz Tick Rate
-tick-hz-280_000_000 = []
+tick-hz-280_000_000 = ["embassy-time-driver/tick-hz-280_000_000"]
 ## 288.0MHz Tick Rate
-tick-hz-288_000_000 = []
+tick-hz-288_000_000 = ["embassy-time-driver/tick-hz-288_000_000"]
 ## 290.0MHz Tick Rate
-tick-hz-290_000_000 = []
+tick-hz-290_000_000 = ["embassy-time-driver/tick-hz-290_000_000"]
 ## 300.0MHz Tick Rate
-tick-hz-300_000_000 = []
+tick-hz-300_000_000 = ["embassy-time-driver/tick-hz-300_000_000"]
 ## 320.0MHz Tick Rate
-tick-hz-320_000_000 = []
+tick-hz-320_000_000 = ["embassy-time-driver/tick-hz-320_000_000"]
 ## 327.68MHz Tick Rate
-tick-hz-327_680_000 = []
+tick-hz-327_680_000 = ["embassy-time-driver/tick-hz-327_680_000"]
 ## 340.0MHz Tick Rate
-tick-hz-340_000_000 = []
+tick-hz-340_000_000 = ["embassy-time-driver/tick-hz-340_000_000"]
 ## 360.0MHz Tick Rate
-tick-hz-360_000_000 = []
+tick-hz-360_000_000 = ["embassy-time-driver/tick-hz-360_000_000"]
 ## 380.0MHz Tick Rate
-tick-hz-380_000_000 = []
+tick-hz-380_000_000 = ["embassy-time-driver/tick-hz-380_000_000"]
 ## 384.0MHz Tick Rate
-tick-hz-384_000_000 = []
+tick-hz-384_000_000 = ["embassy-time-driver/tick-hz-384_000_000"]
 ## 400.0MHz Tick Rate
-tick-hz-400_000_000 = []
+tick-hz-400_000_000 = ["embassy-time-driver/tick-hz-400_000_000"]
 ## 420.0MHz Tick Rate
-tick-hz-420_000_000 = []
+tick-hz-420_000_000 = ["embassy-time-driver/tick-hz-420_000_000"]
 ## 440.0MHz Tick Rate
-tick-hz-440_000_000 = []
+tick-hz-440_000_000 = ["embassy-time-driver/tick-hz-440_000_000"]
 ## 460.0MHz Tick Rate
-tick-hz-460_000_000 = []
+tick-hz-460_000_000 = ["embassy-time-driver/tick-hz-460_000_000"]
 ## 480.0MHz Tick Rate
-tick-hz-480_000_000 = []
+tick-hz-480_000_000 = ["embassy-time-driver/tick-hz-480_000_000"]
 ## 500.0MHz Tick Rate
-tick-hz-500_000_000 = []
+tick-hz-500_000_000 = ["embassy-time-driver/tick-hz-500_000_000"]
 ## 512.0MHz Tick Rate
-tick-hz-512_000_000 = []
+tick-hz-512_000_000 = ["embassy-time-driver/tick-hz-512_000_000"]
 ## 520.0MHz Tick Rate
-tick-hz-520_000_000 = []
+tick-hz-520_000_000 = ["embassy-time-driver/tick-hz-520_000_000"]
 ## 524.288MHz Tick Rate
-tick-hz-524_288_000 = []
+tick-hz-524_288_000 = ["embassy-time-driver/tick-hz-524_288_000"]
 ## 540.0MHz Tick Rate
-tick-hz-540_000_000 = []
+tick-hz-540_000_000 = ["embassy-time-driver/tick-hz-540_000_000"]
 ## 560.0MHz Tick Rate
-tick-hz-560_000_000 = []
+tick-hz-560_000_000 = ["embassy-time-driver/tick-hz-560_000_000"]
 ## 576.0MHz Tick Rate
-tick-hz-576_000_000 = []
+tick-hz-576_000_000 = ["embassy-time-driver/tick-hz-576_000_000"]
 ## 580.0MHz Tick Rate
-tick-hz-580_000_000 = []
+tick-hz-580_000_000 = ["embassy-time-driver/tick-hz-580_000_000"]
 ## 600.0MHz Tick Rate
-tick-hz-600_000_000 = []
+tick-hz-600_000_000 = ["embassy-time-driver/tick-hz-600_000_000"]
 ## 620.0MHz Tick Rate
-tick-hz-620_000_000 = []
+tick-hz-620_000_000 = ["embassy-time-driver/tick-hz-620_000_000"]
 ## 640.0MHz Tick Rate
-tick-hz-640_000_000 = []
+tick-hz-640_000_000 = ["embassy-time-driver/tick-hz-640_000_000"]
 ## 655.36MHz Tick Rate
-tick-hz-655_360_000 = []
+tick-hz-655_360_000 = ["embassy-time-driver/tick-hz-655_360_000"]
 ## 660.0MHz Tick Rate
-tick-hz-660_000_000 = []
+tick-hz-660_000_000 = ["embassy-time-driver/tick-hz-660_000_000"]
 ## 680.0MHz Tick Rate
-tick-hz-680_000_000 = []
+tick-hz-680_000_000 = ["embassy-time-driver/tick-hz-680_000_000"]
 ## 700.0MHz Tick Rate
-tick-hz-700_000_000 = []
+tick-hz-700_000_000 = ["embassy-time-driver/tick-hz-700_000_000"]
 ## 720.0MHz Tick Rate
-tick-hz-720_000_000 = []
+tick-hz-720_000_000 = ["embassy-time-driver/tick-hz-720_000_000"]
 ## 740.0MHz Tick Rate
-tick-hz-740_000_000 = []
+tick-hz-740_000_000 = ["embassy-time-driver/tick-hz-740_000_000"]
 ## 760.0MHz Tick Rate
-tick-hz-760_000_000 = []
+tick-hz-760_000_000 = ["embassy-time-driver/tick-hz-760_000_000"]
 ## 768.0MHz Tick Rate
-tick-hz-768_000_000 = []
+tick-hz-768_000_000 = ["embassy-time-driver/tick-hz-768_000_000"]
 ## 780.0MHz Tick Rate
-tick-hz-780_000_000 = []
+tick-hz-780_000_000 = ["embassy-time-driver/tick-hz-780_000_000"]
 ## 800.0MHz Tick Rate
-tick-hz-800_000_000 = []
+tick-hz-800_000_000 = ["embassy-time-driver/tick-hz-800_000_000"]
 ## 820.0MHz Tick Rate
-tick-hz-820_000_000 = []
+tick-hz-820_000_000 = ["embassy-time-driver/tick-hz-820_000_000"]
 ## 840.0MHz Tick Rate
-tick-hz-840_000_000 = []
+tick-hz-840_000_000 = ["embassy-time-driver/tick-hz-840_000_000"]
 ## 860.0MHz Tick Rate
-tick-hz-860_000_000 = []
+tick-hz-860_000_000 = ["embassy-time-driver/tick-hz-860_000_000"]
 ## 880.0MHz Tick Rate
-tick-hz-880_000_000 = []
+tick-hz-880_000_000 = ["embassy-time-driver/tick-hz-880_000_000"]
 ## 900.0MHz Tick Rate
-tick-hz-900_000_000 = []
+tick-hz-900_000_000 = ["embassy-time-driver/tick-hz-900_000_000"]
 ## 920.0MHz Tick Rate
-tick-hz-920_000_000 = []
+tick-hz-920_000_000 = ["embassy-time-driver/tick-hz-920_000_000"]
 ## 940.0MHz Tick Rate
-tick-hz-940_000_000 = []
+tick-hz-940_000_000 = ["embassy-time-driver/tick-hz-940_000_000"]
 ## 960.0MHz Tick Rate
-tick-hz-960_000_000 = []
+tick-hz-960_000_000 = ["embassy-time-driver/tick-hz-960_000_000"]
 ## 980.0MHz Tick Rate
-tick-hz-980_000_000 = []
+tick-hz-980_000_000 = ["embassy-time-driver/tick-hz-980_000_000"]
 ## 1.0GHz Tick Rate
-tick-hz-1_000_000_000 = []
+tick-hz-1_000_000_000 = ["embassy-time-driver/tick-hz-1_000_000_000"]
 ## 1.31072GHz Tick Rate
-tick-hz-1_310_720_000 = []
+tick-hz-1_310_720_000 = ["embassy-time-driver/tick-hz-1_310_720_000"]
 ## 2.62144GHz Tick Rate
-tick-hz-2_621_440_000 = []
+tick-hz-2_621_440_000 = ["embassy-time-driver/tick-hz-2_621_440_000"]
 ## 5.24288GHz Tick Rate
-tick-hz-5_242_880_000 = []
+tick-hz-5_242_880_000 = ["embassy-time-driver/tick-hz-5_242_880_000"]
 # END TICKS
 
 #! </details>
 
 [dependencies]
+embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver" }
+
 defmt = { version = "0.3", optional = true }
 log = { version = "0.4.14", optional = true }
 
diff --git a/embassy-time/README.md b/embassy-time/README.md
index a4e150c14..20772f1d8 100644
--- a/embassy-time/README.md
+++ b/embassy-time/README.md
@@ -12,7 +12,7 @@ Tick counts are 64 bits. The default tick rate of 1Mhz supports
 representing time spans of up to ~584558 years, which is big enough for all practical
 purposes and allows not having to worry about overflows.
 
-## Time driver
+## Global time driver
 
 The `time` module is backed by a global "time driver" specified at build time.
 Only one driver can be active in a program.
@@ -21,7 +21,7 @@ All methods and structs transparently call into the active driver. This makes it
 possible for libraries to use `embassy_time` in a driver-agnostic way without
 requiring generic parameters.
 
-For more details, check the [`driver`] module.
+For more details, check the [`embassy_time_driver`] crate.
 
 ## Instants and Durations
 
diff --git a/embassy-time/src/driver_mock.rs b/embassy-time/src/driver_mock.rs
index 7533d51e5..7abc2bd70 100644
--- a/embassy-time/src/driver_mock.rs
+++ b/embassy-time/src/driver_mock.rs
@@ -28,7 +28,7 @@ use crate::{Duration, Instant};
 /// ```
 pub struct MockDriver(CsMutex<RefCell<InnerMockDriver>>);
 
-crate::time_driver_impl!(static DRIVER: MockDriver = MockDriver::new());
+crate::driver::time_driver_impl!(static DRIVER: MockDriver = MockDriver::new());
 
 impl MockDriver {
     /// Creates a new mock driver.
diff --git a/embassy-time/src/driver_std.rs b/embassy-time/src/driver_std.rs
index 32db47a37..3b5524f9e 100644
--- a/embassy-time/src/driver_std.rs
+++ b/embassy-time/src/driver_std.rs
@@ -45,7 +45,7 @@ struct TimeDriver {
 }
 
 const ALARM_NEW: AlarmState = AlarmState::new();
-crate::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
+crate::driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
     alarm_count: AtomicU8::new(0),
 
     once: Once::new(),
diff --git a/embassy-time/src/driver_wasm.rs b/embassy-time/src/driver_wasm.rs
index 0f672dc75..d75856c26 100644
--- a/embassy-time/src/driver_wasm.rs
+++ b/embassy-time/src/driver_wasm.rs
@@ -42,7 +42,7 @@ struct TimeDriver {
 }
 
 const ALARM_NEW: AlarmState = AlarmState::new();
-crate::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
+crate::driver::time_driver_impl!(static DRIVER: TimeDriver = TimeDriver {
     alarm_count: AtomicU8::new(0),
     once: Once::new(),
     alarms: UninitCell::uninit(),
diff --git a/embassy-time/src/lib.rs b/embassy-time/src/lib.rs
index 7e2546f68..3f8c09f1a 100644
--- a/embassy-time/src/lib.rs
+++ b/embassy-time/src/lib.rs
@@ -10,12 +10,12 @@
 // This mod MUST go first, so that the others see its macros.
 pub(crate) mod fmt;
 
+pub use embassy_time_driver as driver;
+
 mod delay;
-pub mod driver;
 mod duration;
 mod instant;
 pub mod queue;
-mod tick;
 mod timer;
 
 #[cfg(feature = "mock-driver")]
@@ -32,15 +32,11 @@ mod driver_wasm;
 mod queue_generic;
 
 pub use delay::{block_for, Delay};
+pub use driver::TICK_HZ;
 pub use duration::Duration;
 pub use instant::Instant;
 pub use timer::{with_timeout, Ticker, TimeoutError, Timer};
 
-/// Ticks per second of the global timebase.
-///
-/// This value is specified by the [`tick-*` Cargo features](crate#tick-rate)
-pub const TICK_HZ: u64 = tick::TICK_HZ;
-
 const fn gcd(a: u64, b: u64) -> u64 {
     if b == 0 {
         a