diff --git a/README.md b/README.md
index eaa1e10ab..4dbbb5f51 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Rust's <a href="https://rust-lang.github.io/async-book/">async/await</a> allows
   - <a href="https://docs.embassy.dev/embassy-nrf/">embassy-nrf</a>, for the Nordic Semiconductor nRF52, nRF53, nRF91 series.
 
 - **Time that Just Works** - 
-No more messing with hardware timers. <a href="https://docs.embassy.dev/embassy/git/thumbv7em-none-eabihf/time/index.html">embassy_executor::time</a> provides Instant, Duration and Timer types that are globally available and never overflow.
+No more messing with hardware timers. <a href="https://docs.embassy.dev/embassy-time">embassy_time</a> provides Instant, Duration and Timer types that are globally available and never overflow.
 
 - **Real-time ready** - 
 Tasks on the same async executor run cooperatively, but you can create multiple executors with different priorities, so that higher priority tasks preempt lower priority ones. See the <a href="https://github.com/embassy-rs/embassy/blob/master/examples/nrf/src/bin/multiprio.rs">example</a>.
@@ -44,8 +44,8 @@ The <a href="https://github.com/embassy-rs/nrf-softdevice">nrf-softdevice</a> cr
 
 ```rust,ignore
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull};
 use embassy_nrf::Peripherals;
 
diff --git a/ci.sh b/ci.sh
index 6ec2410f7..77a8a7e27 100755
--- a/ci.sh
+++ b/ci.sh
@@ -54,25 +54,25 @@ cargo batch  \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits,log \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5ub,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5ub,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
     --- build --release --manifest-path embassy-boot/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840 \
     --- build --release --manifest-path embassy-boot/stm32/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32wl55jc-cm4 \
     --- build --release --manifest-path docs/modules/ROOT/examples/basic/Cargo.toml --target thumbv7em-none-eabi \
diff --git a/ci_stable.sh b/ci_stable.sh
index 7521827d8..d388cfee3 100755
--- a/ci_stable.sh
+++ b/ci_stable.sh
@@ -30,38 +30,38 @@ cargo batch  \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features unstable-traits,defmt \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features unstable-traits,log \
     --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55uc-cm4,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz \
-    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,embassy-executor/time-tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55uc-cm4,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,embassy-time?/tick-32768hz \
+    --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,embassy-time?/tick-32768hz,unstable-traits \
     --- build --release --manifest-path examples/nrf/Cargo.toml --target thumbv7em-none-eabi --no-default-features --out-dir out/examples/nrf --bin raw_spawn \
     --- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --no-default-features --out-dir out/examples/stm32l0 --bin raw_spawn \
diff --git a/docs/modules/ROOT/examples/basic/Cargo.toml b/docs/modules/ROOT/examples/basic/Cargo.toml
index 59e1a437a..ae124a871 100644
--- a/docs/modules/ROOT/examples/basic/Cargo.toml
+++ b/docs/modules/ROOT/examples/basic/Cargo.toml
@@ -6,6 +6,7 @@ version = "0.1.0"
 
 [dependencies]
 embassy-executor = { version = "0.1.0", path = "../../../../../embassy-executor", features = ["defmt", "nightly"] }
+embassy-time = { version = "0.1.0", path = "../../../../../embassy-time", features = ["defmt", "nightly"] }
 embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "nightly"] }
 
 defmt = "0.3"
diff --git a/docs/modules/ROOT/examples/basic/src/main.rs b/docs/modules/ROOT/examples/basic/src/main.rs
index d680dd064..04170db55 100644
--- a/docs/modules/ROOT/examples/basic/src/main.rs
+++ b/docs/modules/ROOT/examples/basic/src/main.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Level, Output, OutputDrive};
 use embassy_nrf::peripherals::P0_13;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _}; // global logger
 
 #[embassy_executor::task]
diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-async/src/main.rs b/docs/modules/ROOT/examples/layer-by-layer/blinky-async/src/main.rs
index 7d62b6107..8df632240 100644
--- a/docs/modules/ROOT/examples/layer-by-layer/blinky-async/src/main.rs
+++ b/docs/modules/ROOT/examples/layer-by-layer/blinky-async/src/main.rs
@@ -2,7 +2,7 @@
 #![no_main]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/embassy-cortex-m/src/executor.rs b/embassy-cortex-m/src/executor.rs
index 4a3fa9903..80c452f84 100644
--- a/embassy-cortex-m/src/executor.rs
+++ b/embassy-cortex-m/src/executor.rs
@@ -1,7 +1,7 @@
 //! Executor specific to cortex-m devices.
 use core::marker::PhantomData;
 
-pub use embassy_executor::executor::*;
+pub use embassy_executor::*;
 
 use crate::interrupt::{Interrupt, InterruptExt};
 
@@ -60,11 +60,11 @@ impl<I: Interrupt> InterruptExecutor<I> {
     /// The executor keeps running in the background through the interrupt.
     ///
     /// This returns a [`SendSpawner`] you can use to spawn tasks on it. A [`SendSpawner`]
-    /// is returned instead of a [`Spawner`](embassy_executor::executor::Spawner) because the executor effectively runs in a
+    /// is returned instead of a [`Spawner`](embassy_executor::Spawner) because the executor effectively runs in a
     /// different "thread" (the interrupt), so spawning tasks on it is effectively
     /// sending them.
     ///
-    /// To obtain a [`Spawner`](embassy_executor::executor::Spawner) for this executor, use [`Spawner::for_current_executor()`](embassy_executor::executor::Spawner::for_current_executor()) from
+    /// To obtain a [`Spawner`](embassy_executor::Spawner) for this executor, use [`Spawner::for_current_executor()`](embassy_executor::Spawner::for_current_executor()) from
     /// a task running in it.
     ///
     /// This function requires `&'static mut self`. This means you have to store the
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml
index 45d0d2de6..25c3f0abd 100644
--- a/embassy-executor/Cargo.toml
+++ b/embassy-executor/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 [package.metadata.embassy_docs]
 src_base = "https://github.com/embassy-rs/embassy/blob/embassy-executor-v$VERSION/embassy-executor/src/"
 src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-executor/src/"
-features = ["nightly", "defmt", "unstable-traits", "time", "time-tick-1mhz"]
+features = ["nightly", "defmt", "unstable-traits"]
 flavors = [
     { name = "std",                       target = "x86_64-unknown-linux-gnu",   features = ["std"] },
     { name = "wasm",                      target = "wasm32-unknown-unknown",     features = ["wasm"] },
@@ -22,49 +22,25 @@ flavors = [
 
 [features]
 default = []
-std = ["time", "time-tick-1mhz", "embassy-macros/std"]
-wasm = ["wasm-bindgen", "js-sys", "embassy-macros/wasm", "wasm-timer", "time", "time-tick-1mhz"]
+std = ["embassy-macros/std"]
+wasm = ["dep:wasm-bindgen", "dep:js-sys", "embassy-macros/wasm"]
 
 # Enable nightly-only features
-nightly = ["embedded-hal-async"]
+nightly = []
 
-# Implement embedded-hal 1.0 alpha and embedded-hal-async traits.
-# Implement embedded-hal-async traits if `nightly` is set as well.
-unstable-traits = ["embedded-hal-1"]
-
-# Display a timestamp of the number of seconds since startup next to defmt log messages
-# To use this you must have a time driver provided.
-defmt-timestamp-uptime = ["defmt"]
-
-# Enable `embassy_executor::time` module. 
-# NOTE: This feature is only intended to be enabled by crates providing the time driver implementation.
-# Enabling it directly without supplying a time driver will fail to link.
-time = []
-
-# Set the `embassy_executor::time` tick rate.
-# NOTE: This feature is only intended to be enabled by crates providing the time driver implementation.
-# If you're not writing your own driver, check the driver documentation to customize the tick rate.
-# If you're writing a driver and your tick rate is not listed here, please add it and send a PR!
-time-tick-32768hz = ["time"]
-time-tick-1000hz = ["time"]
-time-tick-1mhz = ["time"]
-time-tick-16mhz = ["time"]
+integrated-timers = ["dep:embassy-time"]
 
 [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.0-alpha.8", optional = true}
-embedded-hal-async = { version = "0.1.0-alpha.1", optional = true}
-
 futures-util = { version = "0.3.17", default-features = false }
 embassy-macros  = { version = "0.1.0", path = "../embassy-macros"}
+embassy-time  = { version = "0.1.0", path = "../embassy-time", optional = true}
 atomic-polyfill = "1.0.1"
 critical-section = "1.1"
 cfg-if = "1.0.0"
 
 # WASM dependencies
 wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true }
-js-sys = { version = "0.3", optional = true }
-wasm-timer = { version = "0.2.5", optional = true }
\ No newline at end of file
+js-sys = { version = "0.3", optional = true }
\ No newline at end of file
diff --git a/embassy-executor/README.md b/embassy-executor/README.md
new file mode 100644
index 000000000..47d0cb8a2
--- /dev/null
+++ b/embassy-executor/README.md
@@ -0,0 +1,11 @@
+# embassy-executor
+
+An async/await executor designed for embedded usage.
+
+- No `alloc`, no heap needed. Task futures are statically allocated.
+- No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning.
+- Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`.
+- No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`.
+- Efficient polling: a wake will only poll the woken task, not all of them.
+- Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time.
+- Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks.
diff --git a/embassy-executor/src/executor/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs
similarity index 100%
rename from embassy-executor/src/executor/arch/cortex_m.rs
rename to embassy-executor/src/arch/cortex_m.rs
diff --git a/embassy-executor/src/executor/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs
similarity index 100%
rename from embassy-executor/src/executor/arch/riscv32.rs
rename to embassy-executor/src/arch/riscv32.rs
diff --git a/embassy-executor/src/executor/arch/std.rs b/embassy-executor/src/arch/std.rs
similarity index 100%
rename from embassy-executor/src/executor/arch/std.rs
rename to embassy-executor/src/arch/std.rs
diff --git a/embassy-executor/src/executor/arch/wasm.rs b/embassy-executor/src/arch/wasm.rs
similarity index 100%
rename from embassy-executor/src/executor/arch/wasm.rs
rename to embassy-executor/src/arch/wasm.rs
diff --git a/embassy-executor/src/executor/arch/xtensa.rs b/embassy-executor/src/arch/xtensa.rs
similarity index 100%
rename from embassy-executor/src/executor/arch/xtensa.rs
rename to embassy-executor/src/arch/xtensa.rs
diff --git a/embassy-executor/src/executor/mod.rs b/embassy-executor/src/executor/mod.rs
deleted file mode 100644
index 45d00c568..000000000
--- a/embassy-executor/src/executor/mod.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-//! Async task executor.
-//!
-//! This module provides an async/await executor designed for embedded usage.
-//!
-//! - No `alloc`, no heap needed. Task futures are statically allocated.
-//! - No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning.
-//! - Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`.
-//! - No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`.
-//! - Efficient polling: a wake will only poll the woken task, not all of them.
-//! - Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time.
-//! - Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks.
-
-cfg_if::cfg_if! {
-    if #[cfg(cortex_m)] {
-        #[path="arch/cortex_m.rs"]
-        mod arch;
-        pub use arch::*;
-    }
-    else if #[cfg(target_arch="riscv32")] {
-        #[path="arch/riscv32.rs"]
-        mod arch;
-        pub use arch::*;
-    }
-    else if #[cfg(all(target_arch="xtensa", feature = "nightly"))] {
-        #[path="arch/xtensa.rs"]
-        mod arch;
-        pub use arch::*;
-    }
-    else if #[cfg(feature="wasm")] {
-        #[path="arch/wasm.rs"]
-        mod arch;
-        pub use arch::*;
-    }
-    else if #[cfg(feature="std")] {
-        #[path="arch/std.rs"]
-        mod arch;
-        pub use arch::*;
-    }
-}
-
-pub mod raw;
-
-mod spawner;
-pub use spawner::*;
diff --git a/embassy-executor/src/fmt.rs b/embassy-executor/src/fmt.rs
index f8bb0a035..066970813 100644
--- a/embassy-executor/src/fmt.rs
+++ b/embassy-executor/src/fmt.rs
@@ -195,9 +195,6 @@ macro_rules! unwrap {
     }
 }
 
-#[cfg(feature = "defmt-timestamp-uptime")]
-defmt::timestamp! {"{=u64:us}", crate::time::Instant::now().as_micros() }
-
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
 pub struct NoneError;
 
diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs
index 69e4aeb4b..9328a7378 100644
--- a/embassy-executor/src/lib.rs
+++ b/embassy-executor/src/lib.rs
@@ -1,22 +1,44 @@
 #![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)]
-#![cfg_attr(feature = "nightly", feature(generic_associated_types, type_alias_impl_trait))]
 #![cfg_attr(all(feature = "nightly", target_arch = "xtensa"), feature(asm_experimental_arch))]
 #![allow(clippy::new_without_default)]
-#![doc = include_str!("../../README.md")]
+#![doc = include_str!("../README.md")]
 #![warn(missing_docs)]
 
 // This mod MUST go first, so that the others see its macros.
 pub(crate) mod fmt;
 
-pub mod executor;
-#[cfg(feature = "time")]
-pub mod time;
-
 #[cfg(feature = "nightly")]
 pub use embassy_macros::{main, task};
 
-#[doc(hidden)]
-/// Implementation details for embassy macros. DO NOT USE.
-pub mod export {
-    pub use atomic_polyfill as atomic;
+cfg_if::cfg_if! {
+    if #[cfg(cortex_m)] {
+        #[path="arch/cortex_m.rs"]
+        mod arch;
+        pub use arch::*;
+    }
+    else if #[cfg(target_arch="riscv32")] {
+        #[path="arch/riscv32.rs"]
+        mod arch;
+        pub use arch::*;
+    }
+    else if #[cfg(all(target_arch="xtensa", feature = "nightly"))] {
+        #[path="arch/xtensa.rs"]
+        mod arch;
+        pub use arch::*;
+    }
+    else if #[cfg(feature="wasm")] {
+        #[path="arch/wasm.rs"]
+        mod arch;
+        pub use arch::*;
+    }
+    else if #[cfg(feature="std")] {
+        #[path="arch/std.rs"]
+        mod arch;
+        pub use arch::*;
+    }
 }
+
+pub mod raw;
+
+mod spawner;
+pub use spawner::*;
diff --git a/embassy-executor/src/executor/raw/mod.rs b/embassy-executor/src/raw/mod.rs
similarity index 93%
rename from embassy-executor/src/executor/raw/mod.rs
rename to embassy-executor/src/raw/mod.rs
index fb4cc6288..afe67decb 100644
--- a/embassy-executor/src/executor/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -8,7 +8,7 @@
 //! executor wrappers in [`executor`](crate::executor) and the [`embassy_executor::task`](embassy_macros::task) macro, which are fully safe.
 
 mod run_queue;
-#[cfg(feature = "time")]
+#[cfg(feature = "integrated-timers")]
 mod timer_queue;
 pub(crate) mod util;
 mod waker;
@@ -22,22 +22,22 @@ use core::{mem, ptr};
 
 use atomic_polyfill::{AtomicU32, Ordering};
 use critical_section::CriticalSection;
+#[cfg(feature = "integrated-timers")]
+use embassy_time::driver::{self, AlarmHandle};
+#[cfg(feature = "integrated-timers")]
+use embassy_time::Instant;
 
 use self::run_queue::{RunQueue, RunQueueItem};
 use self::util::UninitCell;
 pub use self::waker::task_from_waker;
 use super::SpawnToken;
-#[cfg(feature = "time")]
-use crate::time::driver::{self, AlarmHandle};
-#[cfg(feature = "time")]
-use crate::time::Instant;
 
 /// Task is spawned (has a future)
 pub(crate) const STATE_SPAWNED: u32 = 1 << 0;
 /// Task is in the executor run queue
 pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1;
 /// Task is in the executor timer queue
-#[cfg(feature = "time")]
+#[cfg(feature = "integrated-timers")]
 pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2;
 
 /// Raw task header for use in task pointers.
@@ -50,9 +50,9 @@ pub struct TaskHeader {
     pub(crate) executor: Cell<*const Executor>, // Valid if state != 0
     pub(crate) poll_fn: UninitCell<unsafe fn(NonNull<TaskHeader>)>, // Valid if STATE_SPAWNED
 
-    #[cfg(feature = "time")]
+    #[cfg(feature = "integrated-timers")]
     pub(crate) expires_at: Cell<Instant>,
-    #[cfg(feature = "time")]
+    #[cfg(feature = "integrated-timers")]
     pub(crate) timer_queue_item: timer_queue::TimerQueueItem,
 }
 
@@ -64,9 +64,9 @@ impl TaskHeader {
             executor: Cell::new(ptr::null()),
             poll_fn: UninitCell::uninit(),
 
-            #[cfg(feature = "time")]
+            #[cfg(feature = "integrated-timers")]
             expires_at: Cell::new(Instant::from_ticks(0)),
-            #[cfg(feature = "time")]
+            #[cfg(feature = "integrated-timers")]
             timer_queue_item: timer_queue::TimerQueueItem::new(),
         }
     }
@@ -267,9 +267,9 @@ pub struct Executor {
     signal_fn: fn(*mut ()),
     signal_ctx: *mut (),
 
-    #[cfg(feature = "time")]
+    #[cfg(feature = "integrated-timers")]
     pub(crate) timer_queue: timer_queue::TimerQueue,
-    #[cfg(feature = "time")]
+    #[cfg(feature = "integrated-timers")]
     alarm: AlarmHandle,
 }
 
@@ -281,9 +281,9 @@ impl Executor {
     ///
     /// See [`Executor`] docs for details on `signal_fn`.
     pub fn new(signal_fn: fn(*mut ()), signal_ctx: *mut ()) -> Self {
-        #[cfg(feature = "time")]
+        #[cfg(feature = "integrated-timers")]
         let alarm = unsafe { unwrap!(driver::allocate_alarm()) };
-        #[cfg(feature = "time")]
+        #[cfg(feature = "integrated-timers")]
         driver::set_alarm_callback(alarm, signal_fn, signal_ctx);
 
         Self {
@@ -291,9 +291,9 @@ impl Executor {
             signal_fn,
             signal_ctx,
 
-            #[cfg(feature = "time")]
+            #[cfg(feature = "integrated-timers")]
             timer_queue: timer_queue::TimerQueue::new(),
-            #[cfg(feature = "time")]
+            #[cfg(feature = "integrated-timers")]
             alarm,
         }
     }
@@ -346,13 +346,13 @@ impl Executor {
     /// somehow schedule for `poll()` to be called later, at a time you know for sure there's
     /// no `poll()` already running.
     pub unsafe fn poll(&'static self) {
-        #[cfg(feature = "time")]
+        #[cfg(feature = "integrated-timers")]
         self.timer_queue.dequeue_expired(Instant::now(), |task| wake_task(task));
 
         self.run_queue.dequeue_all(|p| {
             let task = p.as_ref();
 
-            #[cfg(feature = "time")]
+            #[cfg(feature = "integrated-timers")]
             task.expires_at.set(Instant::MAX);
 
             let state = task.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel);
@@ -369,11 +369,11 @@ impl Executor {
             task.poll_fn.read()(p as _);
 
             // Enqueue or update into timer_queue
-            #[cfg(feature = "time")]
+            #[cfg(feature = "integrated-timers")]
             self.timer_queue.update(p);
         });
 
-        #[cfg(feature = "time")]
+        #[cfg(feature = "integrated-timers")]
         {
             // If this is already in the past, set_alarm will immediately trigger the alarm.
             // This will cause `signal_fn` to be called, which will cause `poll()` to be called again,
@@ -418,8 +418,9 @@ pub unsafe fn wake_task(task: NonNull<TaskHeader>) {
     })
 }
 
-#[cfg(feature = "time")]
-pub(crate) unsafe fn register_timer(at: Instant, waker: &core::task::Waker) {
+#[cfg(feature = "integrated-timers")]
+#[no_mangle]
+unsafe fn _embassy_time_schedule_wake(at: Instant, waker: &core::task::Waker) {
     let task = waker::task_from_waker(waker);
     let task = task.as_ref();
     let expires_at = task.expires_at.get();
diff --git a/embassy-executor/src/executor/raw/run_queue.rs b/embassy-executor/src/raw/run_queue.rs
similarity index 100%
rename from embassy-executor/src/executor/raw/run_queue.rs
rename to embassy-executor/src/raw/run_queue.rs
diff --git a/embassy-executor/src/executor/raw/timer_queue.rs b/embassy-executor/src/raw/timer_queue.rs
similarity index 98%
rename from embassy-executor/src/executor/raw/timer_queue.rs
rename to embassy-executor/src/raw/timer_queue.rs
index 62fcfc531..24c31892a 100644
--- a/embassy-executor/src/executor/raw/timer_queue.rs
+++ b/embassy-executor/src/raw/timer_queue.rs
@@ -4,9 +4,9 @@ use core::ptr;
 use core::ptr::NonNull;
 
 use atomic_polyfill::Ordering;
+use embassy_time::Instant;
 
 use super::{TaskHeader, STATE_TIMER_QUEUED};
-use crate::time::Instant;
 
 pub(crate) struct TimerQueueItem {
     next: Cell<*mut TaskHeader>,
diff --git a/embassy-executor/src/executor/raw/util.rs b/embassy-executor/src/raw/util.rs
similarity index 100%
rename from embassy-executor/src/executor/raw/util.rs
rename to embassy-executor/src/raw/util.rs
diff --git a/embassy-executor/src/executor/raw/waker.rs b/embassy-executor/src/raw/waker.rs
similarity index 95%
rename from embassy-executor/src/executor/raw/waker.rs
rename to embassy-executor/src/raw/waker.rs
index 6b9c03a62..5765259f2 100644
--- a/embassy-executor/src/executor/raw/waker.rs
+++ b/embassy-executor/src/raw/waker.rs
@@ -40,7 +40,7 @@ pub fn task_from_waker(waker: &Waker) -> NonNull<TaskHeader> {
     // TODO use waker_getters when stable. https://github.com/rust-lang/rust/issues/96992
     let hack: &WakerHack = unsafe { mem::transmute(waker) };
     if hack.vtable != &VTABLE {
-        panic!("Found waker not created by the Embassy executor. `embassy_executor::time::Timer` only works with the Embassy executor.")
+        panic!("Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor.")
     }
 
     // safety: we never create a waker with a null data pointer.
diff --git a/embassy-executor/src/executor/spawner.rs b/embassy-executor/src/spawner.rs
similarity index 100%
rename from embassy-executor/src/executor/spawner.rs
rename to embassy-executor/src/spawner.rs
diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml
index 6c1b01e67..c7435ab3e 100644
--- a/embassy-lora/Cargo.toml
+++ b/embassy-lora/Cargo.toml
@@ -8,8 +8,8 @@ src_base = "https://github.com/embassy-rs/embassy/blob/embassy-lora-v$VERSION/em
 src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-lora/src/"
 features = ["time", "defmt"]
 flavors = [
-    { name = "sx127x",  target = "thumbv7em-none-eabihf", features = ["sx127x", "embassy-stm32/stm32wl55jc-cm4", "embassy-stm32/time-driver-any", "embassy-executor/time-tick-32768hz"] },
-    { name = "stm32wl", target = "thumbv7em-none-eabihf", features = ["stm32wl", "embassy-stm32/stm32wl55jc-cm4", "embassy-stm32/time-driver-any", "embassy-executor/time-tick-32768hz"] },
+    { name = "sx127x",  target = "thumbv7em-none-eabihf", features = ["sx127x", "embassy-stm32/stm32wl55jc-cm4", "embassy-stm32/time-driver-any", "embassy-time/tick-32768hz"] },
+    { name = "stm32wl", target = "thumbv7em-none-eabihf", features = ["stm32wl", "embassy-stm32/stm32wl55jc-cm4", "embassy-stm32/time-driver-any", "embassy-time/tick-32768hz"] },
 ]
 
 [lib]
@@ -24,7 +24,7 @@ time = []
 defmt = { version = "0.3", optional = true }
 log = { version = "0.4.14", optional = true }
 
-embassy-executor = { version = "0.1.0", path = "../embassy-executor" }
+embassy-time = { version = "0.1.0", path = "../embassy-time" }
 embassy-util = { version = "0.1.0", path = "../embassy-util" }
 embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
 embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8" }
diff --git a/embassy-lora/src/lib.rs b/embassy-lora/src/lib.rs
index 29ea45863..1b2dd45c2 100644
--- a/embassy-lora/src/lib.rs
+++ b/embassy-lora/src/lib.rs
@@ -18,6 +18,6 @@ pub struct LoraTimer;
 impl lorawan_device::async_device::radio::Timer for LoraTimer {
     type DelayFuture<'m> = impl core::future::Future<Output = ()> + 'm;
     fn delay_ms<'m>(&'m mut self, millis: u64) -> Self::DelayFuture<'m> {
-        embassy_executor::time::Timer::after(embassy_executor::time::Duration::from_millis(millis))
+        embassy_time::Timer::after(embassy_time::Duration::from_millis(millis))
     }
 }
diff --git a/embassy-lora/src/sx127x/sx127x_lora/mod.rs b/embassy-lora/src/sx127x/sx127x_lora/mod.rs
index b3636d097..aacc9da22 100644
--- a/embassy-lora/src/sx127x/sx127x_lora/mod.rs
+++ b/embassy-lora/src/sx127x/sx127x_lora/mod.rs
@@ -6,7 +6,7 @@
 #![allow(dead_code)]
 
 use bit_field::BitField;
-use embassy_executor::time::{Duration, Timer};
+use embassy_time::{Duration, Timer};
 use embedded_hal::digital::v2::OutputPin;
 use embedded_hal_async::spi::SpiBus;
 
diff --git a/embassy-macros/src/macros/main.rs b/embassy-macros/src/macros/main.rs
index a0cb0f0b3..52987d7d2 100644
--- a/embassy-macros/src/macros/main.rs
+++ b/embassy-macros/src/macros/main.rs
@@ -34,8 +34,8 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, Toke
     let main = quote! {
         #[wasm_bindgen::prelude::wasm_bindgen(start)]
         pub fn main() -> Result<(), wasm_bindgen::JsValue> {
-            static EXECUTOR: ::embassy_util::Forever<::embassy_executor::executor::Executor> = ::embassy_util::Forever::new();
-            let executor = EXECUTOR.put(::embassy_executor::executor::Executor::new());
+            static EXECUTOR: ::embassy_util::Forever<::embassy_executor::Executor> = ::embassy_util::Forever::new();
+            let executor = EXECUTOR.put(::embassy_executor::Executor::new());
 
             executor.start(|spawner| {
                 spawner.spawn(__embassy_main(spawner)).unwrap();
@@ -48,7 +48,7 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, Toke
     #[cfg(all(feature = "std", not(feature = "wasm")))]
     let main = quote! {
         fn main() -> ! {
-            let mut executor = ::embassy_executor::executor::Executor::new();
+            let mut executor = ::embassy_executor::Executor::new();
             let executor = unsafe { __make_static(&mut executor) };
 
             executor.run(|spawner| {
@@ -61,7 +61,7 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, Toke
     let main = quote! {
         #[cortex_m_rt::entry]
         fn main() -> ! {
-            let mut executor = ::embassy_executor::executor::Executor::new();
+            let mut executor = ::embassy_executor::Executor::new();
             let executor = unsafe { __make_static(&mut executor) };
 
             executor.run(|spawner| {
diff --git a/embassy-macros/src/macros/task.rs b/embassy-macros/src/macros/task.rs
index 414e5cb09..573776f8c 100644
--- a/embassy-macros/src/macros/task.rs
+++ b/embassy-macros/src/macros/task.rs
@@ -64,9 +64,9 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, Toke
         // in the user's code.
         #task_inner
 
-        #visibility fn #task_ident(#fargs) -> ::embassy_executor::executor::SpawnToken<impl Sized> {
+        #visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
             type Fut = impl ::core::future::Future + 'static;
-            static POOL: ::embassy_executor::executor::raw::TaskPool<Fut, #pool_size> = ::embassy_executor::executor::raw::TaskPool::new();
+            static POOL: ::embassy_executor::raw::TaskPool<Fut, #pool_size> = ::embassy_executor::raw::TaskPool::new();
             unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#arg_names,)*)) }
         }
     };
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index 11e39a871..1ce4479aa 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 [package.metadata.embassy_docs]
 src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-v$VERSION/embassy-net/src/"
 src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net/src/"
-features = [ "pool-4", "defmt", "tcp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "embassy-executor/time", "embassy-executor/time-tick-1mhz"]
+features = [ "pool-4", "defmt", "tcp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "embassy-time/tick-1mhz"]
 target = "thumbv7em-none-eabi"
 
 [features]
@@ -37,16 +37,16 @@ unstable-traits = []
 defmt = { version = "0.3", optional = true }
 log = { version = "0.4.14", optional = true }
 
-embassy-executor    = { version = "0.1.0", path = "../embassy-executor" }
-embassy-util        = { version = "0.1.0", path = "../embassy-util" }
-embedded-io         = { version = "0.3.0", features = [ "async" ] }
+embassy-time = { version = "0.1.0", path = "../embassy-time" }
+embassy-util = { version = "0.1.0", path = "../embassy-util" }
+embedded-io = { version = "0.3.0", features = [ "async" ] }
 
-managed             = { version = "0.8.0", default-features = false, features = [ "map" ] }
-heapless            = { version = "0.7.5", default-features = false }
-as-slice            = "0.2.1"
-generic-array       = { version = "0.14.4", default-features = false }
-stable_deref_trait  = { version = "1.2.0", default-features = false }
-futures             = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
+managed = { version = "0.8.0", default-features = false, features = [ "map" ] }
+heapless = { version = "0.7.5", default-features = false }
+as-slice = "0.2.1"
+generic-array = { version = "0.14.4", default-features = false }
+stable_deref_trait = { version = "1.2.0", default-features = false }
+futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
 atomic-pool = "0.2.1"
 atomic-polyfill = "0.1.5"
 embedded-nal-async = "0.2.0"
diff --git a/embassy-net/src/stack.rs b/embassy-net/src/stack.rs
index 06bb732ff..4b6a7ae2a 100644
--- a/embassy-net/src/stack.rs
+++ b/embassy-net/src/stack.rs
@@ -2,7 +2,7 @@ use core::cell::UnsafeCell;
 use core::future::Future;
 use core::task::{Context, Poll};
 
-use embassy_executor::time::{Instant, Timer};
+use embassy_time::{Instant, Timer};
 use embassy_util::waitqueue::WakerRegistration;
 use futures::future::poll_fn;
 use futures::pin_mut;
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index 9d6690acb..0ef7f5bbd 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -16,7 +16,7 @@ flavors = [
 
 [features]
 
-time = ["embassy-executor/time"]
+time = ["dep:embassy-time"]
 
 defmt = ["dep:defmt", "embassy-executor/defmt", "embassy-util/defmt", "embassy-usb?/defmt", "embedded-io?/defmt", "embassy-embedded-hal/defmt"]
 
@@ -57,7 +57,7 @@ _nrf5340-net = ["_nrf5340", "nrf5340-net-pac"]
 _nrf5340 = ["_gpio-p1", "_dppi"]
 _nrf9160 = ["nrf9160-pac", "_dppi"]
 
-_time-driver = ["embassy-executor/time-tick-32768hz", "time"]
+_time-driver = ["dep:embassy-time", "embassy-time?/tick-32768hz"]
 
 _ppi = []
 _dppi = []
@@ -65,6 +65,7 @@ _gpio-p1 = []
 
 [dependencies]
 embassy-executor = { version = "0.1.0", path = "../embassy-executor", optional = true }
+embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true }
 embassy-util = { version = "0.1.0", path = "../embassy-util" }
 embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-3"]}
 embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs
index 05fa0aea8..b961d65a0 100644
--- a/embassy-nrf/src/time_driver.rs
+++ b/embassy-nrf/src/time_driver.rs
@@ -3,7 +3,7 @@ use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering};
 use core::{mem, ptr};
 
 use critical_section::CriticalSection;
-use embassy_executor::time::driver::{AlarmHandle, Driver};
+use embassy_time::driver::{AlarmHandle, Driver};
 use embassy_util::blocking_mutex::raw::CriticalSectionRawMutex;
 use embassy_util::blocking_mutex::CriticalSectionMutex as Mutex;
 
@@ -119,7 +119,7 @@ struct RtcDriver {
 }
 
 const ALARM_STATE_NEW: AlarmState = AlarmState::new();
-embassy_executor::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
+embassy_time::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-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index 494abe0cc..9587d1f40 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -12,9 +12,9 @@ use core::sync::atomic::Ordering::SeqCst;
 use core::task::Poll;
 
 use embassy_embedded_hal::SetConfig;
-#[cfg(feature = "time")]
-use embassy_executor::time::{Duration, Instant};
 use embassy_hal_common::{into_ref, PeripheralRef};
+#[cfg(feature = "time")]
+use embassy_time::{Duration, Instant};
 use embassy_util::waitqueue::AtomicWaker;
 use futures::future::poll_fn;
 
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml
index bf4919d5f..aaf4ede13 100644
--- a/embassy-rp/Cargo.toml
+++ b/embassy-rp/Cargo.toml
@@ -28,7 +28,8 @@ unstable-traits = ["embedded-hal-1"]
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../embassy-util" }
-embassy-executor = { version = "0.1.0", path = "../embassy-executor", features = [ "time-tick-1mhz" ] }
+embassy-executor = { version = "0.1.0", path = "../embassy-executor" }
+embassy-time = { version = "0.1.0", path = "../embassy-time", features = [ "tick-1mhz" ] }
 embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-3"]}
 embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
 embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
diff --git a/embassy-rp/src/timer.rs b/embassy-rp/src/timer.rs
index 142fd410d..5bc1f66c8 100644
--- a/embassy-rp/src/timer.rs
+++ b/embassy-rp/src/timer.rs
@@ -2,7 +2,7 @@ use core::cell::Cell;
 
 use atomic_polyfill::{AtomicU8, Ordering};
 use critical_section::CriticalSection;
-use embassy_executor::time::driver::{AlarmHandle, Driver};
+use embassy_time::driver::{AlarmHandle, Driver};
 use embassy_util::blocking_mutex::raw::CriticalSectionRawMutex;
 use embassy_util::blocking_mutex::Mutex;
 
@@ -26,7 +26,7 @@ struct TimerDriver {
     next_alarm: AtomicU8,
 }
 
-embassy_executor::time_driver_impl!(static DRIVER: TimerDriver = TimerDriver{
+embassy_time::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 dea68e440..c47ea0bca 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -10,7 +10,7 @@ src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-stm32
 # TODO: sdmmc
 # TODO: net
 # TODO: subghz
-features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any", "embassy-executor/time-tick-32768hz"]
+features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any", "embassy-time/tick-32768hz"]
 flavors = [
     { regex_feature = "stm32f0.*", target = "thumbv6m-none-eabi" },
     { regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" },
@@ -33,6 +33,7 @@ flavors = [
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../embassy-util" }
 embassy-executor = { version = "0.1.0", path = "../embassy-executor" }
+embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true }
 embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-4"]}
 embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
 embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
@@ -80,7 +81,7 @@ exti = []
 
 # 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 = ["embassy-executor/time"]
+_time-driver = ["dep:embassy-time"]
 time-driver-any = ["_time-driver"]
 time-driver-tim2 = ["_time-driver"]
 time-driver-tim3 = ["_time-driver"]
diff --git a/embassy-stm32/src/subghz/mod.rs b/embassy-stm32/src/subghz/mod.rs
index 4e53efed5..a74f9a6d5 100644
--- a/embassy-stm32/src/subghz/mod.rs
+++ b/embassy-stm32/src/subghz/mod.rs
@@ -504,7 +504,7 @@ impl<'d> SubGhz<'d, NoDma, NoDma> {
     ///
     /// sg.set_standby(StandbyClk::Rc)?;
     /// unsafe { sg.set_sleep(SleepCfg::default())? };
-    /// embassy_executor::time::Timer::after(embassy_executor::time::Duration::from_micros(500)).await;
+    /// embassy_time::Timer::after(embassy_time::Duration::from_micros(500)).await;
     /// unsafe { wakeup() };
     /// # Ok::<(), embassy_stm32::subghz::Error>(())
     /// ```
diff --git a/embassy-stm32/src/subghz/timeout.rs b/embassy-stm32/src/subghz/timeout.rs
index b8d6ad8f9..28b3b0c21 100644
--- a/embassy-stm32/src/subghz/timeout.rs
+++ b/embassy-stm32/src/subghz/timeout.rs
@@ -439,9 +439,9 @@ impl From<Timeout> for [u8; 3] {
     }
 }
 
-impl From<Timeout> for embassy_executor::time::Duration {
+impl From<Timeout> for embassy_time::Duration {
     fn from(to: Timeout) -> Self {
-        embassy_executor::time::Duration::from_micros(to.as_micros().into())
+        embassy_time::Duration::from_micros(to.as_micros().into())
     }
 }
 
diff --git a/embassy-stm32/src/subghz/tx_params.rs b/embassy-stm32/src/subghz/tx_params.rs
index a72c060f3..cede6f2c1 100644
--- a/embassy-stm32/src/subghz/tx_params.rs
+++ b/embassy-stm32/src/subghz/tx_params.rs
@@ -44,17 +44,17 @@ impl From<RampTime> for core::time::Duration {
     }
 }
 
-impl From<RampTime> for embassy_executor::time::Duration {
+impl From<RampTime> for embassy_time::Duration {
     fn from(rt: RampTime) -> Self {
         match rt {
-            RampTime::Micros10 => embassy_executor::time::Duration::from_micros(10),
-            RampTime::Micros20 => embassy_executor::time::Duration::from_micros(20),
-            RampTime::Micros40 => embassy_executor::time::Duration::from_micros(40),
-            RampTime::Micros80 => embassy_executor::time::Duration::from_micros(80),
-            RampTime::Micros200 => embassy_executor::time::Duration::from_micros(200),
-            RampTime::Micros800 => embassy_executor::time::Duration::from_micros(800),
-            RampTime::Micros1700 => embassy_executor::time::Duration::from_micros(1700),
-            RampTime::Micros3400 => embassy_executor::time::Duration::from_micros(3400),
+            RampTime::Micros10 => embassy_time::Duration::from_micros(10),
+            RampTime::Micros20 => embassy_time::Duration::from_micros(20),
+            RampTime::Micros40 => embassy_time::Duration::from_micros(40),
+            RampTime::Micros80 => embassy_time::Duration::from_micros(80),
+            RampTime::Micros200 => embassy_time::Duration::from_micros(200),
+            RampTime::Micros800 => embassy_time::Duration::from_micros(800),
+            RampTime::Micros1700 => embassy_time::Duration::from_micros(1700),
+            RampTime::Micros3400 => embassy_time::Duration::from_micros(3400),
         }
     }
 }
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index 6cea43f18..7f4723162 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -4,8 +4,8 @@ use core::sync::atomic::{compiler_fence, Ordering};
 use core::{mem, ptr};
 
 use atomic_polyfill::{AtomicU32, AtomicU8};
-use embassy_executor::time::driver::{AlarmHandle, Driver};
-use embassy_executor::time::TICKS_PER_SECOND;
+use embassy_time::driver::{AlarmHandle, Driver};
+use embassy_time::TICKS_PER_SECOND;
 use embassy_util::blocking_mutex::raw::CriticalSectionRawMutex;
 use embassy_util::blocking_mutex::Mutex;
 use stm32_metapac::timer::regs;
@@ -133,7 +133,7 @@ struct RtcDriver {
 
 const ALARM_STATE_NEW: AlarmState = AlarmState::new();
 
-embassy_executor::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
+embassy_time::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-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 764b21461..3861e42d0 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -5,8 +5,8 @@ use core::sync::atomic::Ordering;
 use core::task::Poll;
 
 use atomic_polyfill::{AtomicBool, AtomicU8};
-use embassy_executor::time::{block_for, Duration};
 use embassy_hal_common::into_ref;
+use embassy_time::{block_for, Duration};
 use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported};
 use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
 use embassy_util::waitqueue::AtomicWaker;
diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml
new file mode 100644
index 000000000..161c101fe
--- /dev/null
+++ b/embassy-time/Cargo.toml
@@ -0,0 +1,54 @@
+[package]
+name = "embassy-time"
+version = "0.1.0"
+edition = "2021"
+
+
+[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/"
+features = ["nightly", "defmt", "unstable-traits", "std"]
+target = "x86_64-unknown-linux-gnu"
+
+[features]
+std = ["tick-1mhz"]
+wasm = ["dep:wasm-bindgen", "dep:js-sys", "dep:wasm-timer", "tick-1mhz"]
+
+# Enable nightly-only features
+nightly = ["embedded-hal-async"]
+
+# Implement embedded-hal 1.0 alpha and embedded-hal-async traits.
+# Implement embedded-hal-async traits if `nightly` is set as well.
+unstable-traits = ["embedded-hal-1"]
+
+# Display a timestamp of the number of seconds since startup next to defmt log messages
+# To use this you must have a time driver provided.
+defmt-timestamp-uptime = ["defmt"]
+
+# Set the `embassy_time` tick rate.
+# NOTE: This feature is only intended to be enabled by crates providing the time driver implementation.
+# If you're not writing your own driver, check the driver documentation to customize the tick rate.
+# If you're writing a driver and your tick rate is not listed here, please add it and send a PR!
+tick-32768hz = []
+tick-1000hz = []
+tick-1mhz = []
+tick-16mhz = []
+
+[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.0-alpha.8", optional = true}
+embedded-hal-async = { version = "0.1.0-alpha.1", optional = true}
+
+futures-util = { version = "0.3.17", default-features = false }
+embassy-macros  = { version = "0.1.0", path = "../embassy-macros"}
+atomic-polyfill = "1.0.1"
+critical-section = "1.1"
+cfg-if = "1.0.0"
+
+# WASM dependencies
+wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true }
+js-sys = { version = "0.3", optional = true }
+wasm-timer = { version = "0.2.5", optional = true }
\ No newline at end of file
diff --git a/embassy-executor/src/time/delay.rs b/embassy-time/src/delay.rs
similarity index 98%
rename from embassy-executor/src/time/delay.rs
rename to embassy-time/src/delay.rs
index d76ed32eb..d010fff98 100644
--- a/embassy-executor/src/time/delay.rs
+++ b/embassy-time/src/delay.rs
@@ -33,7 +33,7 @@ mod eh1 {
 
 cfg_if::cfg_if! {
     if #[cfg(all(feature = "unstable-traits", feature = "nightly"))] {
-        use crate::time::Timer;
+        use crate::Timer;
         use core::future::Future;
         use futures_util::FutureExt;
 
diff --git a/embassy-executor/src/time/driver.rs b/embassy-time/src/driver.rs
similarity index 83%
rename from embassy-executor/src/time/driver.rs
rename to embassy-time/src/driver.rs
index 48e2f1c7d..216b27408 100644
--- a/embassy-executor/src/time/driver.rs
+++ b/embassy-time/src/driver.rs
@@ -1,17 +1,17 @@
 //! Time driver interface
 //!
-//! This module defines the interface a driver needs to implement to power the `embassy_executor::time` module.
+//! This module defines the interface a driver needs to implement to power the `embassy_time` module.
 //!
 //! # Implementing a driver
 //!
 //! - Define a struct `MyDriver`
 //! - Implement [`Driver`] for it
 //! - Register it as the global driver with [`time_driver_impl`].
-//! - Enable the Cargo features `embassy-executor/time` and one of `embassy-executor/time-tick-*` corresponding to the
+//! - Enable the Cargo features `embassy-executor/time` and one of `embassy-time/tick-*` corresponding to the
 //!   tick rate of your driver.
 //!
 //! If you wish to make the tick rate configurable by the end user, you should do so by exposing your own
-//! Cargo features and having each enable the corresponding `embassy-executor/time-tick-*`.
+//! Cargo features and having each enable the corresponding `embassy-time/tick-*`.
 //!
 //! # Linkage details
 //!
@@ -34,10 +34,10 @@
 //! # Example
 //!
 //! ```
-//! use embassy_executor::time::driver::{Driver, AlarmHandle};
+//! use embassy_time::driver::{Driver, AlarmHandle};
 //!
 //! struct MyDriver{}; // not public!
-//! embassy_executor::time_driver_impl!(static DRIVER: MyDriver = MyDriver{});
+//! embassy_time::time_driver_impl!(static DRIVER: MyDriver = MyDriver{});
 //!
 //! impl Driver for MyDriver {
 //!     fn now(&self) -> u64 {
@@ -121,17 +121,25 @@ extern "Rust" {
     fn _embassy_time_set_alarm(alarm: AlarmHandle, timestamp: u64);
 }
 
-pub(crate) fn now() -> u64 {
+/// See [`Driver::now`]
+pub fn now() -> u64 {
     unsafe { _embassy_time_now() }
 }
+
+/// See [`Driver::allocate_alarm`]
+///
 /// Safety: it is UB to make the alarm fire before setting a callback.
-pub(crate) unsafe fn allocate_alarm() -> Option<AlarmHandle> {
+pub unsafe fn allocate_alarm() -> Option<AlarmHandle> {
     _embassy_time_allocate_alarm()
 }
-pub(crate) fn set_alarm_callback(alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
+
+/// See [`Driver::set_alarm_callback`]
+pub fn set_alarm_callback(alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
     unsafe { _embassy_time_set_alarm_callback(alarm, callback, ctx) }
 }
-pub(crate) fn set_alarm(alarm: AlarmHandle, timestamp: u64) {
+
+/// See [`Driver::set_alarm`]
+pub fn set_alarm(alarm: AlarmHandle, timestamp: u64) {
     unsafe { _embassy_time_set_alarm(alarm, timestamp) }
 }
 
@@ -145,26 +153,22 @@ macro_rules! time_driver_impl {
 
         #[no_mangle]
         fn _embassy_time_now() -> u64 {
-            <$t as $crate::time::driver::Driver>::now(&$name)
+            <$t as $crate::driver::Driver>::now(&$name)
         }
 
         #[no_mangle]
-        unsafe fn _embassy_time_allocate_alarm() -> Option<$crate::time::driver::AlarmHandle> {
-            <$t as $crate::time::driver::Driver>::allocate_alarm(&$name)
+        unsafe fn _embassy_time_allocate_alarm() -> Option<$crate::driver::AlarmHandle> {
+            <$t as $crate::driver::Driver>::allocate_alarm(&$name)
         }
 
         #[no_mangle]
-        fn _embassy_time_set_alarm_callback(
-            alarm: $crate::time::driver::AlarmHandle,
-            callback: fn(*mut ()),
-            ctx: *mut (),
-        ) {
-            <$t as $crate::time::driver::Driver>::set_alarm_callback(&$name, alarm, callback, ctx)
+        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)
         }
 
         #[no_mangle]
-        fn _embassy_time_set_alarm(alarm: $crate::time::driver::AlarmHandle, timestamp: u64) {
-            <$t as $crate::time::driver::Driver>::set_alarm(&$name, alarm, timestamp)
+        fn _embassy_time_set_alarm(alarm: $crate::driver::AlarmHandle, timestamp: u64) {
+            <$t as $crate::driver::Driver>::set_alarm(&$name, alarm, timestamp)
         }
     };
 }
diff --git a/embassy-executor/src/time/driver_std.rs b/embassy-time/src/driver_std.rs
similarity index 99%
rename from embassy-executor/src/time/driver_std.rs
rename to embassy-time/src/driver_std.rs
index cb66f7c19..2ddb2e604 100644
--- a/embassy-executor/src/time/driver_std.rs
+++ b/embassy-time/src/driver_std.rs
@@ -6,7 +6,7 @@ use std::{mem, ptr, thread};
 
 use atomic_polyfill::{AtomicU8, Ordering};
 
-use crate::time::driver::{AlarmHandle, Driver};
+use crate::driver::{AlarmHandle, Driver};
 
 const ALARM_COUNT: usize = 4;
 
diff --git a/embassy-executor/src/time/driver_wasm.rs b/embassy-time/src/driver_wasm.rs
similarity index 98%
rename from embassy-executor/src/time/driver_wasm.rs
rename to embassy-time/src/driver_wasm.rs
index 5f585a19a..e4497e6a2 100644
--- a/embassy-executor/src/time/driver_wasm.rs
+++ b/embassy-time/src/driver_wasm.rs
@@ -7,7 +7,7 @@ use atomic_polyfill::{AtomicU8, Ordering};
 use wasm_bindgen::prelude::*;
 use wasm_timer::Instant as StdInstant;
 
-use crate::time::driver::{AlarmHandle, Driver};
+use crate::driver::{AlarmHandle, Driver};
 
 const ALARM_COUNT: usize = 4;
 
diff --git a/embassy-executor/src/time/duration.rs b/embassy-time/src/duration.rs
similarity index 100%
rename from embassy-executor/src/time/duration.rs
rename to embassy-time/src/duration.rs
diff --git a/embassy-time/src/fmt.rs b/embassy-time/src/fmt.rs
new file mode 100644
index 000000000..066970813
--- /dev/null
+++ b/embassy-time/src/fmt.rs
@@ -0,0 +1,225 @@
+#![macro_use]
+#![allow(unused_macros)]
+
+#[cfg(all(feature = "defmt", feature = "log"))]
+compile_error!("You may not enable both `defmt` and `log` features.");
+
+macro_rules! assert {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::assert!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::assert!($($x)*);
+        }
+    };
+}
+
+macro_rules! assert_eq {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::assert_eq!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::assert_eq!($($x)*);
+        }
+    };
+}
+
+macro_rules! assert_ne {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::assert_ne!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::assert_ne!($($x)*);
+        }
+    };
+}
+
+macro_rules! debug_assert {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::debug_assert!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::debug_assert!($($x)*);
+        }
+    };
+}
+
+macro_rules! debug_assert_eq {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::debug_assert_eq!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::debug_assert_eq!($($x)*);
+        }
+    };
+}
+
+macro_rules! debug_assert_ne {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::debug_assert_ne!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::debug_assert_ne!($($x)*);
+        }
+    };
+}
+
+macro_rules! todo {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::todo!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::todo!($($x)*);
+        }
+    };
+}
+
+macro_rules! unreachable {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::unreachable!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::unreachable!($($x)*);
+        }
+    };
+}
+
+macro_rules! panic {
+    ($($x:tt)*) => {
+        {
+            #[cfg(not(feature = "defmt"))]
+            ::core::panic!($($x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::panic!($($x)*);
+        }
+    };
+}
+
+macro_rules! trace {
+    ($s:literal $(, $x:expr)* $(,)?) => {
+        {
+            #[cfg(feature = "log")]
+            ::log::trace!($s $(, $x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::trace!($s $(, $x)*);
+            #[cfg(not(any(feature = "log", feature="defmt")))]
+            let _ = ($( & $x ),*);
+        }
+    };
+}
+
+macro_rules! debug {
+    ($s:literal $(, $x:expr)* $(,)?) => {
+        {
+            #[cfg(feature = "log")]
+            ::log::debug!($s $(, $x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::debug!($s $(, $x)*);
+            #[cfg(not(any(feature = "log", feature="defmt")))]
+            let _ = ($( & $x ),*);
+        }
+    };
+}
+
+macro_rules! info {
+    ($s:literal $(, $x:expr)* $(,)?) => {
+        {
+            #[cfg(feature = "log")]
+            ::log::info!($s $(, $x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::info!($s $(, $x)*);
+            #[cfg(not(any(feature = "log", feature="defmt")))]
+            let _ = ($( & $x ),*);
+        }
+    };
+}
+
+macro_rules! warn {
+    ($s:literal $(, $x:expr)* $(,)?) => {
+        {
+            #[cfg(feature = "log")]
+            ::log::warn!($s $(, $x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::warn!($s $(, $x)*);
+            #[cfg(not(any(feature = "log", feature="defmt")))]
+            let _ = ($( & $x ),*);
+        }
+    };
+}
+
+macro_rules! error {
+    ($s:literal $(, $x:expr)* $(,)?) => {
+        {
+            #[cfg(feature = "log")]
+            ::log::error!($s $(, $x)*);
+            #[cfg(feature = "defmt")]
+            ::defmt::error!($s $(, $x)*);
+            #[cfg(not(any(feature = "log", feature="defmt")))]
+            let _ = ($( & $x ),*);
+        }
+    };
+}
+
+#[cfg(feature = "defmt")]
+macro_rules! unwrap {
+    ($($x:tt)*) => {
+        ::defmt::unwrap!($($x)*)
+    };
+}
+
+#[cfg(not(feature = "defmt"))]
+macro_rules! unwrap {
+    ($arg:expr) => {
+        match $crate::fmt::Try::into_result($arg) {
+            ::core::result::Result::Ok(t) => t,
+            ::core::result::Result::Err(e) => {
+                ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
+            }
+        }
+    };
+    ($arg:expr, $($msg:expr),+ $(,)? ) => {
+        match $crate::fmt::Try::into_result($arg) {
+            ::core::result::Result::Ok(t) => t,
+            ::core::result::Result::Err(e) => {
+                ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
+            }
+        }
+    }
+}
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct NoneError;
+
+pub trait Try {
+    type Ok;
+    type Error;
+    fn into_result(self) -> Result<Self::Ok, Self::Error>;
+}
+
+impl<T> Try for Option<T> {
+    type Ok = T;
+    type Error = NoneError;
+
+    #[inline]
+    fn into_result(self) -> Result<T, NoneError> {
+        self.ok_or(NoneError)
+    }
+}
+
+impl<T, E> Try for Result<T, E> {
+    type Ok = T;
+    type Error = E;
+
+    #[inline]
+    fn into_result(self) -> Self {
+        self
+    }
+}
diff --git a/embassy-executor/src/time/instant.rs b/embassy-time/src/instant.rs
similarity index 100%
rename from embassy-executor/src/time/instant.rs
rename to embassy-time/src/instant.rs
diff --git a/embassy-executor/src/time/mod.rs b/embassy-time/src/lib.rs
similarity index 75%
rename from embassy-executor/src/time/mod.rs
rename to embassy-time/src/lib.rs
index b787a5cf2..a6454d55e 100644
--- a/embassy-executor/src/time/mod.rs
+++ b/embassy-time/src/lib.rs
@@ -1,3 +1,8 @@
+#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)]
+#![cfg_attr(feature = "nightly", feature(generic_associated_types, type_alias_impl_trait))]
+#![allow(clippy::new_without_default)]
+#![warn(missing_docs)]
+
 //! Timekeeping, delays and timeouts.
 //!
 //! Timekeeping is done with elapsed time since system boot. Time is represented in
@@ -26,7 +31,7 @@
 //! like `2021-08-24 13:33:21`).
 //!
 //! If persistence across reboots is not needed, support can be built on top of
-//! `embassy_executor::time` by storing the offset between "seconds elapsed since boot"
+//! `embassy_time` by storing the offset between "seconds elapsed since boot"
 //! and "seconds since unix epoch".
 //!
 //! # Time driver
@@ -35,12 +40,13 @@
 //! 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_executor::time` in a driver-agnostic way without
+//! possible for libraries to use `embassy_time` in a driver-agnostic way without
 //! requiring generic parameters.
 //!
 //! For more details, check the [`driver`] module.
 
-#![deny(missing_docs)]
+// This mod MUST go first, so that the others see its macros.
+pub(crate) mod fmt;
 
 mod delay;
 pub mod driver;
@@ -50,7 +56,6 @@ mod timer;
 
 #[cfg(feature = "std")]
 mod driver_std;
-
 #[cfg(feature = "wasm")]
 mod driver_wasm;
 
@@ -59,24 +64,24 @@ pub use duration::Duration;
 pub use instant::Instant;
 pub use timer::{with_timeout, Ticker, TimeoutError, Timer};
 
-#[cfg(feature = "time-tick-1000hz")]
+#[cfg(feature = "tick-1000hz")]
 const TPS: u64 = 1_000;
 
-#[cfg(feature = "time-tick-32768hz")]
+#[cfg(feature = "tick-32768hz")]
 const TPS: u64 = 32_768;
 
-#[cfg(feature = "time-tick-1mhz")]
+#[cfg(feature = "tick-1mhz")]
 const TPS: u64 = 1_000_000;
 
-#[cfg(feature = "time-tick-16mhz")]
+#[cfg(feature = "tick-16mhz")]
 const TPS: u64 = 16_000_000;
 
 /// Ticks per second of the global timebase.
 ///
-/// This value is specified by the `time-tick-*` Cargo features, which
+/// This value is specified by the `tick-*` Cargo features, which
 /// should be set by the time driver. Some drivers support a fixed tick rate, others
 /// allow you to choose a tick rate with Cargo features of their own. You should not
-/// set the `time-tick-*` features for embassy yourself as an end user.
+/// set the `tick-*` features for embassy yourself as an end user.
 pub const TICKS_PER_SECOND: u64 = TPS;
 
 const fn gcd(a: u64, b: u64) -> u64 {
@@ -89,3 +94,6 @@ const fn gcd(a: u64, b: u64) -> u64 {
 
 pub(crate) const GCD_1K: u64 = gcd(TICKS_PER_SECOND, 1_000);
 pub(crate) const GCD_1M: u64 = gcd(TICKS_PER_SECOND, 1_000_000);
+
+#[cfg(feature = "defmt-timestamp-uptime")]
+defmt::timestamp! {"{=u64:us}", Instant::now().as_micros() }
diff --git a/embassy-executor/src/time/timer.rs b/embassy-time/src/timer.rs
similarity index 88%
rename from embassy-executor/src/time/timer.rs
rename to embassy-time/src/timer.rs
index b9cdb1be5..bd791b817 100644
--- a/embassy-executor/src/time/timer.rs
+++ b/embassy-time/src/timer.rs
@@ -1,12 +1,11 @@
 use core::future::Future;
 use core::pin::Pin;
-use core::task::{Context, Poll};
+use core::task::{Context, Poll, Waker};
 
 use futures_util::future::{select, Either};
 use futures_util::{pin_mut, Stream};
 
-use crate::executor::raw;
-use crate::time::{Duration, Instant};
+use crate::{Duration, Instant};
 
 /// Error returned by [`with_timeout`] on timeout.
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -49,7 +48,7 @@ impl Timer {
     /// # #![feature(type_alias_impl_trait)]
     /// #
     /// # fn foo() {}
-    /// use embassy_executor::time::{Duration, Timer};
+    /// use embassy_time::{Duration, Timer};
     ///
     /// #[embassy_executor::task]
     /// async fn demo_sleep_seconds() {
@@ -73,7 +72,7 @@ impl Future for Timer {
         if self.yielded_once && self.expires_at <= Instant::now() {
             Poll::Ready(())
         } else {
-            unsafe { raw::register_timer(self.expires_at, cx.waker()) };
+            schedule_wake(self.expires_at, cx.waker());
             self.yielded_once = true;
             Poll::Pending
         }
@@ -88,7 +87,7 @@ impl Future for Timer {
 /// ``` no_run
 /// # #![feature(type_alias_impl_trait)]
 /// #
-/// use embassy_executor::time::{Duration, Timer};
+/// use embassy_time::{Duration, Timer};
 /// # fn foo() {}
 ///
 /// #[embassy_executor::task]
@@ -108,7 +107,7 @@ impl Future for Timer {
 /// ``` no_run
 /// # #![feature(type_alias_impl_trait)]
 /// #
-/// use embassy_executor::time::{Duration, Ticker};
+/// use embassy_time::{Duration, Ticker};
 /// use futures::StreamExt;
 /// # fn foo(){}
 ///
@@ -144,8 +143,16 @@ impl Stream for Ticker {
             self.expires_at += dur;
             Poll::Ready(Some(()))
         } else {
-            unsafe { raw::register_timer(self.expires_at, cx.waker()) };
+            schedule_wake(self.expires_at, cx.waker());
             Poll::Pending
         }
     }
 }
+
+extern "Rust" {
+    fn _embassy_time_schedule_wake(at: Instant, waker: &Waker);
+}
+
+fn schedule_wake(at: Instant, waker: &Waker) {
+    unsafe { _embassy_time_schedule_wake(at, waker) }
+}
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml
index ca4fb984d..ef9346639 100644
--- a/examples/boot/application/nrf/Cargo.toml
+++ b/examples/boot/application/nrf/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../../../embassy-util" }
-embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly"] }
+embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly"] }
 embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly", "nrf52840"] }
 embassy-boot-nrf = { version = "0.1.0", path = "../../../../embassy-boot/nrf" }
 embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
diff --git a/examples/boot/application/nrf/src/bin/a.rs b/examples/boot/application/nrf/src/bin/a.rs
index 6343f5705..bd8fa3246 100644
--- a/examples/boot/application/nrf/src/bin/a.rs
+++ b/examples/boot/application/nrf/src/bin/a.rs
@@ -6,7 +6,7 @@
 
 use embassy_boot_nrf::FirmwareUpdater;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
 use embassy_nrf::nvmc::Nvmc;
 use panic_reset as _;
diff --git a/examples/boot/application/nrf/src/bin/b.rs b/examples/boot/application/nrf/src/bin/b.rs
index ad44804af..5394bf0c7 100644
--- a/examples/boot/application/nrf/src/bin/b.rs
+++ b/examples/boot/application/nrf/src/bin/b.rs
@@ -4,9 +4,9 @@
 #![feature(generic_associated_types)]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Level, Output, OutputDrive};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 #[embassy_executor::main]
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index 17df18169..27eafa653 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" }
 embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs
index d06e6aea2..11eecc5e2 100644
--- a/examples/boot/application/stm32f3/src/bin/a.rs
+++ b/examples/boot/application/stm32f3/src/bin/a.rs
@@ -6,7 +6,7 @@
 use defmt_rtt::*;
 use embassy_boot_stm32::FirmwareUpdater;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::flash::Flash;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
diff --git a/examples/boot/application/stm32f3/src/bin/b.rs b/examples/boot/application/stm32f3/src/bin/b.rs
index 98d6dbdf6..a5862b1b0 100644
--- a/examples/boot/application/stm32f3/src/bin/b.rs
+++ b/examples/boot/application/stm32f3/src/bin/b.rs
@@ -4,9 +4,9 @@
 
 #[cfg(feature = "defmt-rtt")]
 use defmt_rtt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 #[embassy_executor::main]
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index e3a3ff380..7de0b82d7 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" }
 embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs
index 154d62d2b..a3b66e7c9 100644
--- a/examples/boot/application/stm32f7/src/bin/a.rs
+++ b/examples/boot/application/stm32f7/src/bin/a.rs
@@ -6,7 +6,7 @@
 use defmt_rtt::*;
 use embassy_boot_stm32::FirmwareUpdater;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::flash::Flash;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
diff --git a/examples/boot/application/stm32f7/src/bin/b.rs b/examples/boot/application/stm32f7/src/bin/b.rs
index 118836267..16c94d845 100644
--- a/examples/boot/application/stm32f7/src/bin/b.rs
+++ b/examples/boot/application/stm32f7/src/bin/b.rs
@@ -4,9 +4,9 @@
 
 #[cfg(feature = "defmt-rtt")]
 use defmt_rtt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 #[embassy_executor::main]
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index 24dd34106..65d34c70b 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" }
 embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs
index 8407adac3..0ecf60348 100644
--- a/examples/boot/application/stm32h7/src/bin/a.rs
+++ b/examples/boot/application/stm32h7/src/bin/a.rs
@@ -6,7 +6,7 @@
 use defmt_rtt::*;
 use embassy_boot_stm32::FirmwareUpdater;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::flash::Flash;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
diff --git a/examples/boot/application/stm32h7/src/bin/b.rs b/examples/boot/application/stm32h7/src/bin/b.rs
index cc694e843..34799279c 100644
--- a/examples/boot/application/stm32h7/src/bin/b.rs
+++ b/examples/boot/application/stm32h7/src/bin/b.rs
@@ -4,9 +4,9 @@
 
 #[cfg(feature = "defmt-rtt")]
 use defmt_rtt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 #[embassy_executor::main]
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index 48659d801..8f37869e3 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"]  }
 embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" }
 embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs
index 7ec6bb96d..f4f1d7119 100644
--- a/examples/boot/application/stm32l0/src/bin/a.rs
+++ b/examples/boot/application/stm32l0/src/bin/a.rs
@@ -6,11 +6,11 @@
 use defmt_rtt::*;
 use embassy_boot_stm32::FirmwareUpdater;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::flash::Flash;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 static APP_B: &[u8] = include_bytes!("../../b.bin");
diff --git a/examples/boot/application/stm32l0/src/bin/b.rs b/examples/boot/application/stm32l0/src/bin/b.rs
index f1e1eaca3..ee40274ff 100644
--- a/examples/boot/application/stm32l0/src/bin/b.rs
+++ b/examples/boot/application/stm32l0/src/bin/b.rs
@@ -4,9 +4,9 @@
 
 #[cfg(feature = "defmt-rtt")]
 use defmt_rtt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 #[embassy_executor::main]
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index f96933269..6abf1986d 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" }
 embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs
index 7ec6bb96d..f4f1d7119 100644
--- a/examples/boot/application/stm32l1/src/bin/a.rs
+++ b/examples/boot/application/stm32l1/src/bin/a.rs
@@ -6,11 +6,11 @@
 use defmt_rtt::*;
 use embassy_boot_stm32::FirmwareUpdater;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::flash::Flash;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 static APP_B: &[u8] = include_bytes!("../../b.bin");
diff --git a/examples/boot/application/stm32l1/src/bin/b.rs b/examples/boot/application/stm32l1/src/bin/b.rs
index f1e1eaca3..ee40274ff 100644
--- a/examples/boot/application/stm32l1/src/bin/b.rs
+++ b/examples/boot/application/stm32l1/src/bin/b.rs
@@ -4,9 +4,9 @@
 
 #[cfg(feature = "defmt-rtt")]
 use defmt_rtt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 #[embassy_executor::main]
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index f529c871f..6f2d12ff1 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" }
 embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs
index 91d16ea11..178b2e04a 100644
--- a/examples/boot/application/stm32l4/src/bin/a.rs
+++ b/examples/boot/application/stm32l4/src/bin/a.rs
@@ -6,7 +6,7 @@
 use defmt_rtt::*;
 use embassy_boot_stm32::FirmwareUpdater;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::flash::Flash;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
diff --git a/examples/boot/application/stm32l4/src/bin/b.rs b/examples/boot/application/stm32l4/src/bin/b.rs
index 98d6dbdf6..a5862b1b0 100644
--- a/examples/boot/application/stm32l4/src/bin/b.rs
+++ b/examples/boot/application/stm32l4/src/bin/b.rs
@@ -4,9 +4,9 @@
 
 #[cfg(feature = "defmt-rtt")]
 use defmt_rtt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 #[embassy_executor::main]
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index 67973a24e..be97d4ebb 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"]  }
 embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" }
 embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs
index 613694ec2..c71a42654 100644
--- a/examples/boot/application/stm32wl/src/bin/a.rs
+++ b/examples/boot/application/stm32wl/src/bin/a.rs
@@ -6,7 +6,7 @@
 use defmt_rtt::*;
 use embassy_boot_stm32::FirmwareUpdater;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::flash::Flash;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
diff --git a/examples/boot/application/stm32wl/src/bin/b.rs b/examples/boot/application/stm32wl/src/bin/b.rs
index 976198148..f9f0ffc60 100644
--- a/examples/boot/application/stm32wl/src/bin/b.rs
+++ b/examples/boot/application/stm32wl/src/bin/b.rs
@@ -4,9 +4,9 @@
 
 #[cfg(feature = "defmt-rtt")]
 use defmt_rtt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use panic_reset as _;
 
 #[embassy_executor::main]
diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml
index 2d28623ce..2fcc31221 100644
--- a/examples/nrf/Cargo.toml
+++ b/examples/nrf/Cargo.toml
@@ -9,7 +9,8 @@ nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-nrf/unsta
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
 embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
 embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"], optional = true }
 embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true }
diff --git a/examples/nrf/src/bin/awaitable_timer.rs b/examples/nrf/src/bin/awaitable_timer.rs
index a94224800..b32af236c 100644
--- a/examples/nrf/src/bin/awaitable_timer.rs
+++ b/examples/nrf/src/bin/awaitable_timer.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::interrupt;
 use embassy_nrf::timer::Timer;
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/blinky.rs b/examples/nrf/src/bin/blinky.rs
index 5283d7ead..513f6cd82 100644
--- a/examples/nrf/src/bin/blinky.rs
+++ b/examples/nrf/src/bin/blinky.rs
@@ -2,9 +2,9 @@
 #![no_main]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Level, Output, OutputDrive};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/nrf/src/bin/buffered_uart.rs b/examples/nrf/src/bin/buffered_uart.rs
index d2a153972..ea566f4b2 100644
--- a/examples/nrf/src/bin/buffered_uart.rs
+++ b/examples/nrf/src/bin/buffered_uart.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::buffered_uarte::{BufferedUarte, State};
 use embassy_nrf::{interrupt, uarte};
 use embedded_io::asynch::{BufRead, Write};
diff --git a/examples/nrf/src/bin/channel.rs b/examples/nrf/src/bin/channel.rs
index a7ea08d09..195200988 100644
--- a/examples/nrf/src/bin/channel.rs
+++ b/examples/nrf/src/bin/channel.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::unwrap;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Level, Output, OutputDrive};
+use embassy_time::{Duration, Timer};
 use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
 use embassy_util::channel::mpmc::Channel;
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/channel_sender_receiver.rs b/examples/nrf/src/bin/channel_sender_receiver.rs
index ef85e8717..c9c458aec 100644
--- a/examples/nrf/src/bin/channel_sender_receiver.rs
+++ b/examples/nrf/src/bin/channel_sender_receiver.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::unwrap;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin};
+use embassy_time::{Duration, Timer};
 use embassy_util::blocking_mutex::raw::NoopRawMutex;
 use embassy_util::channel::mpmc::{Channel, Receiver, Sender};
 use embassy_util::Forever;
diff --git a/examples/nrf/src/bin/executor_fairness_test.rs b/examples/nrf/src/bin/executor_fairness_test.rs
index 7aaeda543..9ae030d07 100644
--- a/examples/nrf/src/bin/executor_fairness_test.rs
+++ b/examples/nrf/src/bin/executor_fairness_test.rs
@@ -5,8 +5,8 @@
 use core::task::Poll;
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Instant, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Instant, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::task]
diff --git a/examples/nrf/src/bin/gpiote_channel.rs b/examples/nrf/src/bin/gpiote_channel.rs
index f2654cb4e..5bfd02465 100644
--- a/examples/nrf/src/bin/gpiote_channel.rs
+++ b/examples/nrf/src/bin/gpiote_channel.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Input, Pull};
 use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/gpiote_port.rs b/examples/nrf/src/bin/gpiote_port.rs
index 46c260a4f..0155d539e 100644
--- a/examples/nrf/src/bin/gpiote_port.rs
+++ b/examples/nrf/src/bin/gpiote_port.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/nrf/src/bin/multiprio.rs b/examples/nrf/src/bin/multiprio.rs
index 7050da378..b653689a7 100644
--- a/examples/nrf/src/bin/multiprio.rs
+++ b/examples/nrf/src/bin/multiprio.rs
@@ -59,10 +59,10 @@
 
 use cortex_m_rt::entry;
 use defmt::{info, unwrap};
-use embassy_executor::time::{Duration, Instant, Timer};
 use embassy_nrf::executor::{Executor, InterruptExecutor};
 use embassy_nrf::interrupt;
 use embassy_nrf::interrupt::InterruptExt;
+use embassy_time::{Duration, Instant, Timer};
 use embassy_util::Forever;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/nrf/src/bin/mutex.rs b/examples/nrf/src/bin/mutex.rs
index 378a5926b..876297883 100644
--- a/examples/nrf/src/bin/mutex.rs
+++ b/examples/nrf/src/bin/mutex.rs
@@ -3,8 +3,8 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
 use embassy_util::mutex::Mutex;
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/nvmc.rs b/examples/nrf/src/bin/nvmc.rs
index a0b555802..75d090fbb 100644
--- a/examples/nrf/src/bin/nvmc.rs
+++ b/examples/nrf/src/bin/nvmc.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::nvmc::Nvmc;
+use embassy_time::{Duration, Timer};
 use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/nrf/src/bin/ppi.rs b/examples/nrf/src/bin/ppi.rs
index fb2a97f1c..d74ce4064 100644
--- a/examples/nrf/src/bin/ppi.rs
+++ b/examples/nrf/src/bin/ppi.rs
@@ -5,7 +5,7 @@
 use core::future::pending;
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
 use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity};
 use embassy_nrf::ppi::Ppi;
diff --git a/examples/nrf/src/bin/pubsub.rs b/examples/nrf/src/bin/pubsub.rs
index d1441d5c1..1d90217f2 100644
--- a/examples/nrf/src/bin/pubsub.rs
+++ b/examples/nrf/src/bin/pubsub.rs
@@ -3,8 +3,8 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::unwrap;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
 use embassy_util::channel::pubsub::{DynSubscriber, PubSubChannel, Subscriber};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/pwm.rs b/examples/nrf/src/bin/pwm.rs
index dca40fd58..1698c0bc8 100644
--- a/examples/nrf/src/bin/pwm.rs
+++ b/examples/nrf/src/bin/pwm.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::pwm::{Prescaler, SimplePwm};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 // for i in range(1024): print(int((math.sin(i/512*math.pi)*0.4+0.5)**2*32767), ', ', end='')
diff --git a/examples/nrf/src/bin/pwm_double_sequence.rs b/examples/nrf/src/bin/pwm_double_sequence.rs
index 08436c8f5..16e50e909 100644
--- a/examples/nrf/src/bin/pwm_double_sequence.rs
+++ b/examples/nrf/src/bin/pwm_double_sequence.rs
@@ -3,11 +3,11 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::pwm::{
     Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, Sequencer, StartSequence,
 };
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs
index c549b55c6..b9aca9aaa 100644
--- a/examples/nrf/src/bin/pwm_sequence.rs
+++ b/examples/nrf/src/bin/pwm_sequence.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/nrf/src/bin/pwm_sequence_ppi.rs b/examples/nrf/src/bin/pwm_sequence_ppi.rs
index 4131e0841..6594fa348 100644
--- a/examples/nrf/src/bin/pwm_sequence_ppi.rs
+++ b/examples/nrf/src/bin/pwm_sequence_ppi.rs
@@ -5,7 +5,7 @@
 use core::future::pending;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Input, Pull};
 use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
 use embassy_nrf::ppi::Ppi;
diff --git a/examples/nrf/src/bin/pwm_sequence_ws2812b.rs b/examples/nrf/src/bin/pwm_sequence_ws2812b.rs
index de4578229..711c8a17b 100644
--- a/examples/nrf/src/bin/pwm_sequence_ws2812b.rs
+++ b/examples/nrf/src/bin/pwm_sequence_ws2812b.rs
@@ -3,11 +3,11 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::pwm::{
     Config, Prescaler, SequenceConfig, SequenceLoad, SequencePwm, SingleSequenceMode, SingleSequencer,
 };
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 // WS2812B LED light demonstration. Drives just one light.
diff --git a/examples/nrf/src/bin/pwm_servo.rs b/examples/nrf/src/bin/pwm_servo.rs
index 08a7a1fdc..19228f433 100644
--- a/examples/nrf/src/bin/pwm_servo.rs
+++ b/examples/nrf/src/bin/pwm_servo.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::pwm::{Prescaler, SimplePwm};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/nrf/src/bin/qdec.rs b/examples/nrf/src/bin/qdec.rs
index f9565e89c..600bba07a 100644
--- a/examples/nrf/src/bin/qdec.rs
+++ b/examples/nrf/src/bin/qdec.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::interrupt;
 use embassy_nrf::qdec::{self, Qdec};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/qspi.rs b/examples/nrf/src/bin/qspi.rs
index 976673a2f..bdcf710b8 100644
--- a/examples/nrf/src/bin/qspi.rs
+++ b/examples/nrf/src/bin/qspi.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{assert_eq, info, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::{interrupt, qspi};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/nrf/src/bin/qspi_lowpower.rs b/examples/nrf/src/bin/qspi_lowpower.rs
index a83fe3fe9..9341a2376 100644
--- a/examples/nrf/src/bin/qspi_lowpower.rs
+++ b/examples/nrf/src/bin/qspi_lowpower.rs
@@ -5,9 +5,9 @@
 use core::mem;
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::{interrupt, qspi};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 // Workaround for alignment requirements.
diff --git a/examples/nrf/src/bin/raw_spawn.rs b/examples/nrf/src/bin/raw_spawn.rs
index 9199d3aeb..415579be7 100644
--- a/examples/nrf/src/bin/raw_spawn.rs
+++ b/examples/nrf/src/bin/raw_spawn.rs
@@ -5,9 +5,9 @@ use core::mem;
 
 use cortex_m_rt::entry;
 use defmt::{info, unwrap};
-use embassy_executor::executor::raw::TaskStorage;
-use embassy_executor::executor::Executor;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::raw::TaskStorage;
+use embassy_executor::Executor;
+use embassy_time::{Duration, Timer};
 use embassy_util::Forever;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/nrf/src/bin/rng.rs b/examples/nrf/src/bin/rng.rs
index 70ab5c731..647073949 100644
--- a/examples/nrf/src/bin/rng.rs
+++ b/examples/nrf/src/bin/rng.rs
@@ -2,7 +2,7 @@
 #![no_main]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::interrupt;
 use embassy_nrf::rng::Rng;
 use rand::Rng as _;
diff --git a/examples/nrf/src/bin/saadc.rs b/examples/nrf/src/bin/saadc.rs
index e90fc3df0..7cf588090 100644
--- a/examples/nrf/src/bin/saadc.rs
+++ b/examples/nrf/src/bin/saadc.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::interrupt;
 use embassy_nrf::saadc::{ChannelConfig, Config, Saadc};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/nrf/src/bin/saadc_continuous.rs b/examples/nrf/src/bin/saadc_continuous.rs
index 80ecaae7b..bb50ac65e 100644
--- a/examples/nrf/src/bin/saadc_continuous.rs
+++ b/examples/nrf/src/bin/saadc_continuous.rs
@@ -3,11 +3,11 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::Duration;
+use embassy_executor::Spawner;
 use embassy_nrf::interrupt;
 use embassy_nrf::saadc::{ChannelConfig, Config, Saadc, SamplerState};
 use embassy_nrf::timer::Frequency;
+use embassy_time::Duration;
 use {defmt_rtt as _, panic_probe as _};
 
 // Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer
@@ -28,7 +28,7 @@ async fn main(_p: Spawner) {
 
     // This delay demonstrates that starting the timer prior to running
     // the task sampler is benign given the calibration that follows.
-    embassy_executor::time::Timer::after(Duration::from_millis(500)).await;
+    embassy_time::Timer::after(Duration::from_millis(500)).await;
     saadc.calibrate().await;
 
     let mut bufs = [[[0; 3]; 500]; 2];
diff --git a/examples/nrf/src/bin/self_spawn.rs b/examples/nrf/src/bin/self_spawn.rs
index 56539eef6..196255a52 100644
--- a/examples/nrf/src/bin/self_spawn.rs
+++ b/examples/nrf/src/bin/self_spawn.rs
@@ -3,8 +3,8 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::task(pool_size = 2)]
diff --git a/examples/nrf/src/bin/self_spawn_current_executor.rs b/examples/nrf/src/bin/self_spawn_current_executor.rs
index 11fe6fb40..8a179886c 100644
--- a/examples/nrf/src/bin/self_spawn_current_executor.rs
+++ b/examples/nrf/src/bin/self_spawn_current_executor.rs
@@ -3,8 +3,8 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::task(pool_size = 2)]
diff --git a/examples/nrf/src/bin/spim.rs b/examples/nrf/src/bin/spim.rs
index 437a1a805..132e01660 100644
--- a/examples/nrf/src/bin/spim.rs
+++ b/examples/nrf/src/bin/spim.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Level, Output, OutputDrive};
 use embassy_nrf::{interrupt, spim};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/temp.rs b/examples/nrf/src/bin/temp.rs
index a898488f9..b06ac709e 100644
--- a/examples/nrf/src/bin/temp.rs
+++ b/examples/nrf/src/bin/temp.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::interrupt;
 use embassy_nrf::temp::Temp;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/nrf/src/bin/timer.rs b/examples/nrf/src/bin/timer.rs
index de7902336..c22b5acd5 100644
--- a/examples/nrf/src/bin/timer.rs
+++ b/examples/nrf/src/bin/timer.rs
@@ -3,8 +3,8 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::task]
diff --git a/examples/nrf/src/bin/twim.rs b/examples/nrf/src/bin/twim.rs
index a0a6d359b..a027cc1e7 100644
--- a/examples/nrf/src/bin/twim.rs
+++ b/examples/nrf/src/bin/twim.rs
@@ -7,7 +7,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::interrupt;
 use embassy_nrf::twim::{self, Twim};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/nrf/src/bin/twim_lowpower.rs b/examples/nrf/src/bin/twim_lowpower.rs
index 916ac07e3..e30cc9688 100644
--- a/examples/nrf/src/bin/twim_lowpower.rs
+++ b/examples/nrf/src/bin/twim_lowpower.rs
@@ -11,10 +11,10 @@
 use core::mem;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::interrupt;
 use embassy_nrf::twim::{self, Twim};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 const ADDRESS: u8 = 0x50;
diff --git a/examples/nrf/src/bin/uart.rs b/examples/nrf/src/bin/uart.rs
index 011ad2a5d..600f7a6ef 100644
--- a/examples/nrf/src/bin/uart.rs
+++ b/examples/nrf/src/bin/uart.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::{interrupt, uarte};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/nrf/src/bin/uart_idle.rs b/examples/nrf/src/bin/uart_idle.rs
index cf3d99389..09ec624c0 100644
--- a/examples/nrf/src/bin/uart_idle.rs
+++ b/examples/nrf/src/bin/uart_idle.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::{interrupt, uarte};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/nrf/src/bin/uart_split.rs b/examples/nrf/src/bin/uart_split.rs
index 12c21c09f..dab8e475d 100644
--- a/examples/nrf/src/bin/uart_split.rs
+++ b/examples/nrf/src/bin/uart_split.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::peripherals::UARTE0;
 use embassy_nrf::uarte::UarteRx;
 use embassy_nrf::{interrupt, uarte};
diff --git a/examples/nrf/src/bin/usb_ethernet.rs b/examples/nrf/src/bin/usb_ethernet.rs
index 4f8e59cc3..f0a870317 100644
--- a/examples/nrf/src/bin/usb_ethernet.rs
+++ b/examples/nrf/src/bin/usb_ethernet.rs
@@ -8,7 +8,7 @@ use core::sync::atomic::{AtomicBool, Ordering};
 use core::task::Waker;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_net::tcp::TcpSocket;
 use embassy_net::{PacketBox, PacketBoxExt, PacketBuf, Stack, StackResources};
 use embassy_nrf::rng::Rng;
diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs
index 16d1a9a27..cf0078eec 100644
--- a/examples/nrf/src/bin/usb_hid_keyboard.rs
+++ b/examples/nrf/src/bin/usb_hid_keyboard.rs
@@ -7,7 +7,7 @@ use core::mem;
 use core::sync::atomic::{AtomicBool, Ordering};
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Input, Pin, Pull};
 use embassy_nrf::usb::{Driver, PowerUsb};
 use embassy_nrf::{interrupt, pac};
diff --git a/examples/nrf/src/bin/usb_hid_mouse.rs b/examples/nrf/src/bin/usb_hid_mouse.rs
index 0008e0e64..7cd2ece17 100644
--- a/examples/nrf/src/bin/usb_hid_mouse.rs
+++ b/examples/nrf/src/bin/usb_hid_mouse.rs
@@ -6,10 +6,10 @@
 use core::mem;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_nrf::usb::{Driver, PowerUsb};
 use embassy_nrf::{interrupt, pac};
+use embassy_time::{Duration, Timer};
 use embassy_usb::control::OutResponse;
 use embassy_usb::{Builder, Config};
 use embassy_usb_hid::{HidWriter, ReportId, RequestHandler, State};
diff --git a/examples/nrf/src/bin/usb_serial.rs b/examples/nrf/src/bin/usb_serial.rs
index ce11c6cbb..a68edb329 100644
--- a/examples/nrf/src/bin/usb_serial.rs
+++ b/examples/nrf/src/bin/usb_serial.rs
@@ -6,7 +6,7 @@
 use core::mem;
 
 use defmt::{info, panic};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::usb::{Driver, Instance, PowerUsb, UsbSupply};
 use embassy_nrf::{interrupt, pac};
 use embassy_usb::driver::EndpointError;
diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs
index d2f1a9723..4c1a93087 100644
--- a/examples/nrf/src/bin/usb_serial_multitask.rs
+++ b/examples/nrf/src/bin/usb_serial_multitask.rs
@@ -6,7 +6,7 @@
 use core::mem;
 
 use defmt::{info, panic, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::usb::{Driver, PowerUsb};
 use embassy_nrf::{interrupt, pac, peripherals};
 use embassy_usb::driver::EndpointError;
diff --git a/examples/nrf/src/bin/wdt.rs b/examples/nrf/src/bin/wdt.rs
index 47e40b886..b0b9c3b81 100644
--- a/examples/nrf/src/bin/wdt.rs
+++ b/examples/nrf/src/bin/wdt.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Input, Pull};
 use embassy_nrf::wdt::{Config, Watchdog};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index f58ec194f..c2dcf429a 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -6,7 +6,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
 embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac"] }
 
 defmt = "0.3"
diff --git a/examples/rp/src/bin/blinky.rs b/examples/rp/src/bin/blinky.rs
index dade3bf32..7aa36a19f 100644
--- a/examples/rp/src/bin/blinky.rs
+++ b/examples/rp/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_rp::gpio;
+use embassy_time::{Duration, Timer};
 use gpio::{Level, Output};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/rp/src/bin/button.rs b/examples/rp/src/bin/button.rs
index 22793735b..c5422c616 100644
--- a/examples/rp/src/bin/button.rs
+++ b/examples/rp/src/bin/button.rs
@@ -2,7 +2,7 @@
 #![no_main]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_rp::gpio::{Input, Level, Output, Pull};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/rp/src/bin/gpio_async.rs b/examples/rp/src/bin/gpio_async.rs
index c61b87a38..52d13a9d5 100644
--- a/examples/rp/src/bin/gpio_async.rs
+++ b/examples/rp/src/bin/gpio_async.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_rp::gpio;
+use embassy_time::{Duration, Timer};
 use gpio::{Input, Level, Output, Pull};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/rp/src/bin/spi.rs b/examples/rp/src/bin/spi.rs
index 7d3370027..88003ee17 100644
--- a/examples/rp/src/bin/spi.rs
+++ b/examples/rp/src/bin/spi.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_rp::spi::Spi;
 use embassy_rp::{gpio, spi};
 use gpio::{Level, Output};
diff --git a/examples/rp/src/bin/spi_display.rs b/examples/rp/src/bin/spi_display.rs
index 8b46bd070..f0e54d87f 100644
--- a/examples/rp/src/bin/spi_display.rs
+++ b/examples/rp/src/bin/spi_display.rs
@@ -5,11 +5,11 @@
 use core::cell::RefCell;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::Delay;
+use embassy_executor::Spawner;
 use embassy_rp::gpio::{Level, Output};
 use embassy_rp::spi;
 use embassy_rp::spi::Spi;
+use embassy_time::Delay;
 use embedded_graphics::image::{Image, ImageRawLE};
 use embedded_graphics::mono_font::ascii::FONT_10X20;
 use embedded_graphics::mono_font::MonoTextStyle;
diff --git a/examples/rp/src/bin/uart.rs b/examples/rp/src/bin/uart.rs
index 067211464..5fdc3ff77 100644
--- a/examples/rp/src/bin/uart.rs
+++ b/examples/rp/src/bin/uart.rs
@@ -2,7 +2,7 @@
 #![no_main]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_rp::uart;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index 47933894a..b7009017c 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["log"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "time", "nightly"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] }
 embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "tcp", "udp", "dhcpv4", "pool-16"] }
 embedded-io = { version = "0.3.0", features = ["async", "std", "futures"] }
 critical-section = { version = "1.1", features = ["std"] }
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs
index 202585289..528609260 100644
--- a/examples/std/src/bin/net.rs
+++ b/examples/std/src/bin/net.rs
@@ -1,7 +1,7 @@
 #![feature(type_alias_impl_trait)]
 
 use clap::Parser;
-use embassy_executor::executor::{Executor, Spawner};
+use embassy_executor::{Executor, Spawner};
 use embassy_net::tcp::TcpSocket;
 use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, Stack, StackResources};
 use embassy_util::Forever;
diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs
index 7fe36e233..07e11c385 100644
--- a/examples/std/src/bin/net_udp.rs
+++ b/examples/std/src/bin/net_udp.rs
@@ -1,7 +1,7 @@
 #![feature(type_alias_impl_trait)]
 
 use clap::Parser;
-use embassy_executor::executor::{Executor, Spawner};
+use embassy_executor::{Executor, Spawner};
 use embassy_net::udp::UdpSocket;
 use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources};
 use embassy_util::Forever;
diff --git a/examples/std/src/bin/serial.rs b/examples/std/src/bin/serial.rs
index b803d1ef7..35cba4cee 100644
--- a/examples/std/src/bin/serial.rs
+++ b/examples/std/src/bin/serial.rs
@@ -4,7 +4,7 @@
 mod serial_port;
 
 use async_io::Async;
-use embassy_executor::executor::Executor;
+use embassy_executor::Executor;
 use embassy_util::Forever;
 use embedded_io::asynch::Read;
 use log::*;
diff --git a/examples/std/src/bin/tick.rs b/examples/std/src/bin/tick.rs
index 9ca900df8..b9de9d873 100644
--- a/examples/std/src/bin/tick.rs
+++ b/examples/std/src/bin/tick.rs
@@ -1,7 +1,7 @@
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use log::*;
 
 #[embassy_executor::task]
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml
index 27bd8a69c..8476200d4 100644
--- a/examples/stm32f0/Cargo.toml
+++ b/examples/stm32f0/Cargo.toml
@@ -12,6 +12,7 @@ defmt = "0.3"
 defmt-rtt = "0.3"
 panic-probe = "0.3"
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "memory-x", "stm32f030f4", "time-driver-any"] }
 
diff --git a/examples/stm32f0/src/bin/hello.rs b/examples/stm32f0/src/bin/hello.rs
index a0775badb..db78233ea 100644
--- a/examples/stm32f0/src/bin/hello.rs
+++ b/examples/stm32f0/src/bin/hello.rs
@@ -3,8 +3,8 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml
index f0e046f57..fbc96400c 100644
--- a/examples/stm32f1/Cargo.toml
+++ b/examples/stm32f1/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"]  }
 embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] }
diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs
index dae001a8b..2d6b4a0e9 100644
--- a/examples/stm32f1/src/bin/adc.rs
+++ b/examples/stm32f1/src/bin/adc.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Delay, Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::adc::Adc;
+use embassy_time::{Delay, Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f1/src/bin/blinky.rs b/examples/stm32f1/src/bin/blinky.rs
index 74e31cbb3..b9b0ac238 100644
--- a/examples/stm32f1/src/bin/blinky.rs
+++ b/examples/stm32f1/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f1/src/bin/hello.rs b/examples/stm32f1/src/bin/hello.rs
index 57892d3cc..180b6aabd 100644
--- a/examples/stm32f1/src/bin/hello.rs
+++ b/examples/stm32f1/src/bin/hello.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::time::Hertz;
 use embassy_stm32::Config;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs
index 2301c51b6..a9c46068f 100644
--- a/examples/stm32f1/src/bin/usb_serial.rs
+++ b/examples/stm32f1/src/bin/usb_serial.rs
@@ -3,12 +3,12 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{panic, *};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
 use embassy_stm32::time::Hertz;
 use embassy_stm32::usb::{Driver, Instance};
 use embassy_stm32::{interrupt, Config};
+use embassy_time::{Duration, Timer};
 use embassy_usb::driver::EndpointError;
 use embassy_usb::Builder;
 use embassy_usb_serial::{CdcAcmClass, State};
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml
index 0825f6180..27894df50 100644
--- a/examples/stm32f2/Cargo.toml
+++ b/examples/stm32f2/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"]  }
 
 defmt = "0.3"
diff --git a/examples/stm32f2/src/bin/blinky.rs b/examples/stm32f2/src/bin/blinky.rs
index 2afdeeb35..d8c89a519 100644
--- a/examples/stm32f2/src/bin/blinky.rs
+++ b/examples/stm32f2/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs
index 6fce7a716..17f09538c 100644
--- a/examples/stm32f2/src/bin/pll.rs
+++ b/examples/stm32f2/src/bin/pll.rs
@@ -5,13 +5,13 @@
 use core::convert::TryFrom;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::rcc::{
     APBPrescaler, ClockSrc, HSEConfig, HSESrc, PLL48Div, PLLConfig, PLLMainDiv, PLLMul, PLLPreDiv, PLLSrc,
 };
 use embassy_stm32::time::Hertz;
 use embassy_stm32::Config;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml
index b7f70b117..b5ea28bb6 100644
--- a/examples/stm32f3/Cargo.toml
+++ b/examples/stm32f3/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"]  }
 embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] }
diff --git a/examples/stm32f3/src/bin/blinky.rs b/examples/stm32f3/src/bin/blinky.rs
index 84d7c50a6..185785ceb 100644
--- a/examples/stm32f3/src/bin/blinky.rs
+++ b/examples/stm32f3/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs
index 404946f2a..61fc6dcab 100644
--- a/examples/stm32f3/src/bin/button_events.rs
+++ b/examples/stm32f3/src/bin/button_events.rs
@@ -11,11 +11,11 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{with_timeout, Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed};
 use embassy_stm32::peripherals::PA0;
+use embassy_time::{with_timeout, Duration, Timer};
 use embassy_util::blocking_mutex::raw::ThreadModeRawMutex;
 use embassy_util::channel::mpmc::Channel;
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32f3/src/bin/button_exti.rs b/examples/stm32f3/src/bin/button_exti.rs
index b770b338b..1266778c1 100644
--- a/examples/stm32f3/src/bin/button_exti.rs
+++ b/examples/stm32f3/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32f3/src/bin/flash.rs b/examples/stm32f3/src/bin/flash.rs
index c7982884f..2cf24dbd3 100644
--- a/examples/stm32f3/src/bin/flash.rs
+++ b/examples/stm32f3/src/bin/flash.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::flash::Flash;
 use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32f3/src/bin/hello.rs b/examples/stm32f3/src/bin/hello.rs
index cd59f7409..65773210d 100644
--- a/examples/stm32f3/src/bin/hello.rs
+++ b/examples/stm32f3/src/bin/hello.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::time::Hertz;
 use embassy_stm32::Config;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f3/src/bin/multiprio.rs b/examples/stm32f3/src/bin/multiprio.rs
index fba5b286e..e96c31249 100644
--- a/examples/stm32f3/src/bin/multiprio.rs
+++ b/examples/stm32f3/src/bin/multiprio.rs
@@ -59,10 +59,10 @@
 
 use cortex_m_rt::entry;
 use defmt::*;
-use embassy_executor::time::{Duration, Instant, Timer};
 use embassy_stm32::executor::{Executor, InterruptExecutor};
 use embassy_stm32::interrupt;
 use embassy_stm32::interrupt::InterruptExt;
+use embassy_time::{Duration, Instant, Timer};
 use embassy_util::Forever;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32f3/src/bin/spi_dma.rs b/examples/stm32f3/src/bin/spi_dma.rs
index 7f874bb66..95b2b6865 100644
--- a/examples/stm32f3/src/bin/spi_dma.rs
+++ b/examples/stm32f3/src/bin/spi_dma.rs
@@ -6,7 +6,7 @@ use core::fmt::Write;
 use core::str::from_utf8;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::spi::{Config, Spi};
 use embassy_stm32::time::Hertz;
 use heapless::String;
diff --git a/examples/stm32f3/src/bin/usart_dma.rs b/examples/stm32f3/src/bin/usart_dma.rs
index 2b27a8daa..3bc5a287f 100644
--- a/examples/stm32f3/src/bin/usart_dma.rs
+++ b/examples/stm32f3/src/bin/usart_dma.rs
@@ -5,7 +5,7 @@
 use core::fmt::Write;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::usart::{Config, Uart};
 use heapless::String;
diff --git a/examples/stm32f3/src/bin/usb_serial.rs b/examples/stm32f3/src/bin/usb_serial.rs
index 757643ea5..d3702fc35 100644
--- a/examples/stm32f3/src/bin/usb_serial.rs
+++ b/examples/stm32f3/src/bin/usb_serial.rs
@@ -3,12 +3,12 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{panic, *};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
 use embassy_stm32::time::mhz;
 use embassy_stm32::usb::{Driver, Instance};
 use embassy_stm32::{interrupt, Config};
+use embassy_time::{Duration, Timer};
 use embassy_usb::driver::EndpointError;
 use embassy_usb::Builder;
 use embassy_usb_serial::{CdcAcmClass, State};
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index e69974c59..04a217aff 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -6,7 +6,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti"]  }
 
 defmt = "0.3"
diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs
index 1dc01edd3..871185074 100644
--- a/examples/stm32f4/src/bin/adc.rs
+++ b/examples/stm32f4/src/bin/adc.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Delay, Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::adc::Adc;
+use embassy_time::{Delay, Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f4/src/bin/blinky.rs b/examples/stm32f4/src/bin/blinky.rs
index 249bbd88f..b27bee4ce 100644
--- a/examples/stm32f4/src/bin/blinky.rs
+++ b/examples/stm32f4/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f4/src/bin/button_exti.rs b/examples/stm32f4/src/bin/button_exti.rs
index 25d3bb9c2..dfe587d41 100644
--- a/examples/stm32f4/src/bin/button_exti.rs
+++ b/examples/stm32f4/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs
index 9098a9715..d97ae7082 100644
--- a/examples/stm32f4/src/bin/dac.rs
+++ b/examples/stm32f4/src/bin/dac.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dac::{Channel, Dac, Value};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32f4/src/bin/flash.rs b/examples/stm32f4/src/bin/flash.rs
index 0d96efb67..393d61e86 100644
--- a/examples/stm32f4/src/bin/flash.rs
+++ b/examples/stm32f4/src/bin/flash.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::flash::Flash;
 use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32f4/src/bin/hello.rs b/examples/stm32f4/src/bin/hello.rs
index 26d3555a2..c409703f5 100644
--- a/examples/stm32f4/src/bin/hello.rs
+++ b/examples/stm32f4/src/bin/hello.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::time::Hertz;
 use embassy_stm32::Config;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f4/src/bin/multiprio.rs b/examples/stm32f4/src/bin/multiprio.rs
index fba5b286e..e96c31249 100644
--- a/examples/stm32f4/src/bin/multiprio.rs
+++ b/examples/stm32f4/src/bin/multiprio.rs
@@ -59,10 +59,10 @@
 
 use cortex_m_rt::entry;
 use defmt::*;
-use embassy_executor::time::{Duration, Instant, Timer};
 use embassy_stm32::executor::{Executor, InterruptExecutor};
 use embassy_stm32::interrupt;
 use embassy_stm32::interrupt::InterruptExt;
+use embassy_time::{Duration, Instant, Timer};
 use embassy_util::Forever;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs
index 1d4f426b8..7c5902052 100644
--- a/examples/stm32f4/src/bin/pwm.rs
+++ b/examples/stm32f4/src/bin/pwm.rs
@@ -3,11 +3,11 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
 use embassy_stm32::pwm::Channel;
 use embassy_stm32::time::khz;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs
index b8e56d2e1..0edd8a61a 100644
--- a/examples/stm32f4/src/bin/sdmmc.rs
+++ b/examples/stm32f4/src/bin/sdmmc.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::sdmmc::Sdmmc;
 use embassy_stm32::time::mhz;
 use embassy_stm32::{interrupt, Config};
diff --git a/examples/stm32f4/src/bin/spi_dma.rs b/examples/stm32f4/src/bin/spi_dma.rs
index f871c1d3e..3d2a1a1ae 100644
--- a/examples/stm32f4/src/bin/spi_dma.rs
+++ b/examples/stm32f4/src/bin/spi_dma.rs
@@ -6,7 +6,7 @@ use core::fmt::Write;
 use core::str::from_utf8;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::spi::{Config, Spi};
 use embassy_stm32::time::Hertz;
 use heapless::String;
diff --git a/examples/stm32f4/src/bin/usart_buffered.rs b/examples/stm32f4/src/bin/usart_buffered.rs
index 9c269ae27..7bcecbd26 100644
--- a/examples/stm32f4/src/bin/usart_buffered.rs
+++ b/examples/stm32f4/src/bin/usart_buffered.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::interrupt;
 use embassy_stm32::usart::{BufferedUart, Config, State, Uart};
diff --git a/examples/stm32f4/src/bin/usart_dma.rs b/examples/stm32f4/src/bin/usart_dma.rs
index febdec6b6..bb41b8b4f 100644
--- a/examples/stm32f4/src/bin/usart_dma.rs
+++ b/examples/stm32f4/src/bin/usart_dma.rs
@@ -5,7 +5,7 @@
 use core::fmt::Write;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::usart::{Config, Uart};
 use heapless::String;
diff --git a/examples/stm32f4/src/bin/wdt.rs b/examples/stm32f4/src/bin/wdt.rs
index a51285257..b2c587fa1 100644
--- a/examples/stm32f4/src/bin/wdt.rs
+++ b/examples/stm32f4/src/bin/wdt.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
 use embassy_stm32::wdg::IndependentWatchdog;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index 8dde9d4f0..29d6da4d8 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "net", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"]  }
 embassy-net = { path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] }
 embedded-io = { version = "0.3.0", features = ["async"] }
diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs
index a0b9bc578..80fad8c41 100644
--- a/examples/stm32f7/src/bin/adc.rs
+++ b/examples/stm32f7/src/bin/adc.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Delay, Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::adc::Adc;
+use embassy_time::{Delay, Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f7/src/bin/blinky.rs b/examples/stm32f7/src/bin/blinky.rs
index 249bbd88f..b27bee4ce 100644
--- a/examples/stm32f7/src/bin/blinky.rs
+++ b/examples/stm32f7/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f7/src/bin/button_exti.rs b/examples/stm32f7/src/bin/button_exti.rs
index 25d3bb9c2..dfe587d41 100644
--- a/examples/stm32f7/src/bin/button_exti.rs
+++ b/examples/stm32f7/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index 1ec30353d..bdffabcb3 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -3,8 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_net::tcp::TcpSocket;
 use embassy_net::{Ipv4Address, Stack, StackResources};
 use embassy_stm32::eth::generic_smi::GenericSMI;
@@ -13,6 +12,7 @@ use embassy_stm32::peripherals::ETH;
 use embassy_stm32::rng::Rng;
 use embassy_stm32::time::mhz;
 use embassy_stm32::{interrupt, Config};
+use embassy_time::{Duration, Timer};
 use embassy_util::Forever;
 use embedded_io::asynch::Write;
 use rand_core::RngCore;
diff --git a/examples/stm32f7/src/bin/flash.rs b/examples/stm32f7/src/bin/flash.rs
index f4d8a1c51..c10781d0c 100644
--- a/examples/stm32f7/src/bin/flash.rs
+++ b/examples/stm32f7/src/bin/flash.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::flash::Flash;
+use embassy_time::{Duration, Timer};
 use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32f7/src/bin/hello.rs b/examples/stm32f7/src/bin/hello.rs
index 26d3555a2..c409703f5 100644
--- a/examples/stm32f7/src/bin/hello.rs
+++ b/examples/stm32f7/src/bin/hello.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::info;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::time::Hertz;
 use embassy_stm32::Config;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs
index 9d97a1de4..3bf427eca 100644
--- a/examples/stm32f7/src/bin/sdmmc.rs
+++ b/examples/stm32f7/src/bin/sdmmc.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::sdmmc::Sdmmc;
 use embassy_stm32::time::mhz;
 use embassy_stm32::{interrupt, Config};
diff --git a/examples/stm32f7/src/bin/usart_dma.rs b/examples/stm32f7/src/bin/usart_dma.rs
index 27da10efd..07270479c 100644
--- a/examples/stm32f7/src/bin/usart_dma.rs
+++ b/examples/stm32f7/src/bin/usart_dma.rs
@@ -5,7 +5,7 @@
 use core::fmt::Write;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::usart::{Config, Uart};
 use heapless::String;
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml
index ab5567bb7..5c80d43eb 100644
--- a/examples/stm32g0/Cargo.toml
+++ b/examples/stm32g0/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"]  }
 
 defmt = "0.3"
diff --git a/examples/stm32g0/src/bin/blinky.rs b/examples/stm32g0/src/bin/blinky.rs
index 249bbd88f..b27bee4ce 100644
--- a/examples/stm32g0/src/bin/blinky.rs
+++ b/examples/stm32g0/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32g0/src/bin/button_exti.rs b/examples/stm32g0/src/bin/button_exti.rs
index 8909a1fea..ef32d4c4a 100644
--- a/examples/stm32g0/src/bin/button_exti.rs
+++ b/examples/stm32g0/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml
index 61150a4e2..74c645cf5 100644
--- a/examples/stm32g4/Cargo.toml
+++ b/examples/stm32g4/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"]  }
 embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" }
 
diff --git a/examples/stm32g4/src/bin/blinky.rs b/examples/stm32g4/src/bin/blinky.rs
index e905a311d..8a65b0692 100644
--- a/examples/stm32g4/src/bin/blinky.rs
+++ b/examples/stm32g4/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32g4/src/bin/button_exti.rs b/examples/stm32g4/src/bin/button_exti.rs
index 25d3bb9c2..dfe587d41 100644
--- a/examples/stm32g4/src/bin/button_exti.rs
+++ b/examples/stm32g4/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs
index f10da3d6e..017e89e41 100644
--- a/examples/stm32g4/src/bin/pwm.rs
+++ b/examples/stm32g4/src/bin/pwm.rs
@@ -3,11 +3,11 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
 use embassy_stm32::pwm::Channel;
 use embassy_stm32::time::khz;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 70038d157..a416796ea 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
 embassy-net = { path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16", "unstable-traits"] }
 embedded-io = { version = "0.3.0", features = ["async"] }
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index 0715a0f62..0e1e28c72 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -3,12 +3,12 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Delay, Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::adc::{Adc, SampleTime};
 use embassy_stm32::rcc::AdcClockSource;
 use embassy_stm32::time::mhz;
 use embassy_stm32::Config;
+use embassy_time::{Delay, Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32h7/src/bin/blinky.rs b/examples/stm32h7/src/bin/blinky.rs
index be2fa64cc..12f08c0fd 100644
--- a/examples/stm32h7/src/bin/blinky.rs
+++ b/examples/stm32h7/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32h7/src/bin/button_exti.rs b/examples/stm32h7/src/bin/button_exti.rs
index 25d3bb9c2..dfe587d41 100644
--- a/examples/stm32h7/src/bin/button_exti.rs
+++ b/examples/stm32h7/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs
index a281e75c9..9c443b83a 100644
--- a/examples/stm32h7/src/bin/camera.rs
+++ b/examples/stm32h7/src/bin/camera.rs
@@ -2,14 +2,14 @@
 #![no_main]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::dcmi::{self, *};
 use embassy_stm32::gpio::{Level, Output, Speed};
 use embassy_stm32::i2c::I2c;
 use embassy_stm32::rcc::{Mco, Mco1Source, McoClock};
 use embassy_stm32::time::{khz, mhz};
 use embassy_stm32::{interrupt, Config};
+use embassy_time::{Duration, Timer};
 use ov7725::*;
 use {defmt_rtt as _, panic_probe as _};
 
@@ -83,8 +83,8 @@ mod ov7725 {
     use core::marker::PhantomData;
 
     use defmt::Format;
-    use embassy_executor::time::{Duration, Timer};
     use embassy_stm32::rcc::{Mco, McoInstance};
+    use embassy_time::{Duration, Timer};
     use embedded_hal_async::i2c::I2c;
 
     #[repr(u8)]
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index 9039b7ee7..83210bcb5 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -3,8 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_net::tcp::TcpSocket;
 use embassy_net::{Ipv4Address, Stack, StackResources};
 use embassy_stm32::eth::generic_smi::GenericSMI;
@@ -13,6 +12,7 @@ use embassy_stm32::peripherals::ETH;
 use embassy_stm32::rng::Rng;
 use embassy_stm32::time::mhz;
 use embassy_stm32::{interrupt, Config};
+use embassy_time::{Duration, Timer};
 use embassy_util::Forever;
 use embedded_io::asynch::Write;
 use rand_core::RngCore;
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index 25e75d71e..99946f504 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -3,8 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_net::tcp::client::{TcpClient, TcpClientState};
 use embassy_net::{Stack, StackResources};
 use embassy_stm32::eth::generic_smi::GenericSMI;
@@ -13,6 +12,7 @@ use embassy_stm32::peripherals::ETH;
 use embassy_stm32::rng::Rng;
 use embassy_stm32::time::mhz;
 use embassy_stm32::{interrupt, Config};
+use embassy_time::{Duration, Timer};
 use embassy_util::Forever;
 use embedded_io::asynch::Write;
 use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
diff --git a/examples/stm32h7/src/bin/flash.rs b/examples/stm32h7/src/bin/flash.rs
index 2d6f3a163..6682c64d5 100644
--- a/examples/stm32h7/src/bin/flash.rs
+++ b/examples/stm32h7/src/bin/flash.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::flash::Flash;
+use embassy_time::{Duration, Timer};
 use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs
index 1a0d073d0..85c690fe6 100644
--- a/examples/stm32h7/src/bin/fmc.rs
+++ b/examples/stm32h7/src/bin/fmc.rs
@@ -3,11 +3,11 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Delay, Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::fmc::Fmc;
 use embassy_stm32::time::mhz;
 use embassy_stm32::Config;
+use embassy_time::{Delay, Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index 59648d4b4..1972f8ff2 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -3,13 +3,13 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::low_level::AFType;
 use embassy_stm32::gpio::Speed;
 use embassy_stm32::pwm::*;
 use embassy_stm32::time::{khz, mhz, Hertz};
 use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32h7/src/bin/mco.rs b/examples/stm32h7/src/bin/mco.rs
index 31aa3f330..036455d5e 100644
--- a/examples/stm32h7/src/bin/mco.rs
+++ b/examples/stm32h7/src/bin/mco.rs
@@ -3,10 +3,10 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
 use embassy_stm32::rcc::{Mco, Mco1Source, McoClock};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs
index b225d66e3..c5c0dd290 100644
--- a/examples/stm32h7/src/bin/pwm.rs
+++ b/examples/stm32h7/src/bin/pwm.rs
@@ -3,12 +3,12 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
 use embassy_stm32::pwm::Channel;
 use embassy_stm32::time::{khz, mhz};
 use embassy_stm32::Config;
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32h7/src/bin/rng.rs b/examples/stm32h7/src/bin/rng.rs
index 2c52f4a02..af9be0b62 100644
--- a/examples/stm32h7/src/bin/rng.rs
+++ b/examples/stm32h7/src/bin/rng.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::rng::Rng;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs
index f44d88aca..26d1db01e 100644
--- a/examples/stm32h7/src/bin/sdmmc.rs
+++ b/examples/stm32h7/src/bin/sdmmc.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::sdmmc::Sdmmc;
 use embassy_stm32::time::mhz;
 use embassy_stm32::{interrupt, Config};
diff --git a/examples/stm32h7/src/bin/signal.rs b/examples/stm32h7/src/bin/signal.rs
index c4ec2b609..be2ac268e 100644
--- a/examples/stm32h7/src/bin/signal.rs
+++ b/examples/stm32h7/src/bin/signal.rs
@@ -3,8 +3,8 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 use embassy_util::channel::signal::Signal;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs
index 8f6f14850..c28f937a8 100644
--- a/examples/stm32h7/src/bin/spi.rs
+++ b/examples/stm32h7/src/bin/spi.rs
@@ -7,7 +7,7 @@ use core::str::from_utf8;
 
 use cortex_m_rt::entry;
 use defmt::*;
-use embassy_executor::executor::Executor;
+use embassy_executor::Executor;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::peripherals::SPI3;
 use embassy_stm32::time::mhz;
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs
index d4c91a8e3..6c78c194f 100644
--- a/examples/stm32h7/src/bin/spi_dma.rs
+++ b/examples/stm32h7/src/bin/spi_dma.rs
@@ -7,7 +7,7 @@ use core::str::from_utf8;
 
 use cortex_m_rt::entry;
 use defmt::*;
-use embassy_executor::executor::Executor;
+use embassy_executor::Executor;
 use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3};
 use embassy_stm32::time::mhz;
 use embassy_stm32::{spi, Config};
diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs
index e491fb39d..1384d54c6 100644
--- a/examples/stm32h7/src/bin/usart.rs
+++ b/examples/stm32h7/src/bin/usart.rs
@@ -4,7 +4,7 @@
 
 use cortex_m_rt::entry;
 use defmt::*;
-use embassy_executor::executor::Executor;
+use embassy_executor::Executor;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::usart::{Config, Uart};
 use embassy_util::Forever;
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs
index aacda45bc..f8d58bb84 100644
--- a/examples/stm32h7/src/bin/usart_dma.rs
+++ b/examples/stm32h7/src/bin/usart_dma.rs
@@ -6,7 +6,7 @@ use core::fmt::Write;
 
 use cortex_m_rt::entry;
 use defmt::*;
-use embassy_executor::executor::Executor;
+use embassy_executor::Executor;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::usart::{Config, Uart};
 use embassy_util::Forever;
diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs
index 7447319ed..64080ec45 100644
--- a/examples/stm32h7/src/bin/usart_split.rs
+++ b/examples/stm32h7/src/bin/usart_split.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::peripherals::{DMA1_CH1, UART7};
 use embassy_stm32::usart::{Config, Uart, UartRx};
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index 367b89db5..fdb716d15 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -9,7 +9,8 @@ nightly = ["embassy-stm32/nightly", "embassy-lora", "lorawan-device", "lorawan",
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"]  }
 embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"], optional = true}
 
diff --git a/examples/stm32l0/src/bin/blinky.rs b/examples/stm32l0/src/bin/blinky.rs
index 06aad4d90..07fad07c6 100644
--- a/examples/stm32l0/src/bin/blinky.rs
+++ b/examples/stm32l0/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32l0/src/bin/button.rs b/examples/stm32l0/src/bin/button.rs
index 14200334d..9d194471e 100644
--- a/examples/stm32l0/src/bin/button.rs
+++ b/examples/stm32l0/src/bin/button.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs
index bdd2fa3c1..af82b9955 100644
--- a/examples/stm32l0/src/bin/button_exti.rs
+++ b/examples/stm32l0/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use embassy_stm32::Config;
diff --git a/examples/stm32l0/src/bin/flash.rs b/examples/stm32l0/src/bin/flash.rs
index f33bd9bbd..867cb4d3e 100644
--- a/examples/stm32l0/src/bin/flash.rs
+++ b/examples/stm32l0/src/bin/flash.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::flash::Flash;
 use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32l0/src/bin/lorawan.rs b/examples/stm32l0/src/bin/lorawan.rs
index 9497cad72..303558b96 100644
--- a/examples/stm32l0/src/bin/lorawan.rs
+++ b/examples/stm32l0/src/bin/lorawan.rs
@@ -6,7 +6,7 @@
 #![feature(generic_associated_types)]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_lora::sx127x::*;
 use embassy_lora::LoraTimer;
 use embassy_stm32::exti::ExtiInput;
diff --git a/examples/stm32l0/src/bin/raw_spawn.rs b/examples/stm32l0/src/bin/raw_spawn.rs
index cd711a430..bd87e62a4 100644
--- a/examples/stm32l0/src/bin/raw_spawn.rs
+++ b/examples/stm32l0/src/bin/raw_spawn.rs
@@ -5,9 +5,9 @@ use core::mem;
 
 use cortex_m_rt::entry;
 use defmt::*;
-use embassy_executor::executor::raw::TaskStorage;
-use embassy_executor::executor::Executor;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::raw::TaskStorage;
+use embassy_executor::Executor;
+use embassy_time::{Duration, Timer};
 use embassy_util::Forever;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32l0/src/bin/spi.rs b/examples/stm32l0/src/bin/spi.rs
index e61c642b8..9b5b3e27d 100644
--- a/examples/stm32l0/src/bin/spi.rs
+++ b/examples/stm32l0/src/bin/spi.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::gpio::{Level, Output, Speed};
 use embassy_stm32::spi::{Config, Spi};
diff --git a/examples/stm32l0/src/bin/usart_dma.rs b/examples/stm32l0/src/bin/usart_dma.rs
index b686c410e..66657d0f0 100644
--- a/examples/stm32l0/src/bin/usart_dma.rs
+++ b/examples/stm32l0/src/bin/usart_dma.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::usart::{Config, Uart};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/examples/stm32l0/src/bin/usart_irq.rs b/examples/stm32l0/src/bin/usart_irq.rs
index f6d998368..0e2237388 100644
--- a/examples/stm32l0/src/bin/usart_irq.rs
+++ b/examples/stm32l0/src/bin/usart_irq.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::interrupt;
 use embassy_stm32::usart::{BufferedUart, Config, State, Uart};
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml
index dba1dd7d6..43f844b67 100644
--- a/examples/stm32l1/Cargo.toml
+++ b/examples/stm32l1/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"]  }
 
 defmt = "0.3"
diff --git a/examples/stm32l1/src/bin/blinky.rs b/examples/stm32l1/src/bin/blinky.rs
index 8ecdb7bb9..8a345d235 100644
--- a/examples/stm32l1/src/bin/blinky.rs
+++ b/examples/stm32l1/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32l1/src/bin/flash.rs b/examples/stm32l1/src/bin/flash.rs
index 399b09f98..a76b9879f 100644
--- a/examples/stm32l1/src/bin/flash.rs
+++ b/examples/stm32l1/src/bin/flash.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::flash::Flash;
 use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32l1/src/bin/spi.rs b/examples/stm32l1/src/bin/spi.rs
index 424416156..0a532e8e3 100644
--- a/examples/stm32l1/src/bin/spi.rs
+++ b/examples/stm32l1/src/bin/spi.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::gpio::{Level, Output, Speed};
 use embassy_stm32::spi::{Config, Spi};
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index 1d9c21a05..eaffa253e 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -7,7 +7,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits"]  }
 
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs
index 93a20d5ea..281346e5f 100644
--- a/examples/stm32l4/src/bin/adc.rs
+++ b/examples/stm32l4/src/bin/adc.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::time::Delay;
 use embassy_stm32::adc::{Adc, Resolution};
 use embassy_stm32::pac;
+use embassy_time::Delay;
 use {defmt_rtt as _, panic_probe as _};
 
 #[cortex_m_rt::entry]
diff --git a/examples/stm32l4/src/bin/blinky.rs b/examples/stm32l4/src/bin/blinky.rs
index 8e3601496..033292fff 100644
--- a/examples/stm32l4/src/bin/blinky.rs
+++ b/examples/stm32l4/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32l4/src/bin/button_exti.rs b/examples/stm32l4/src/bin/button_exti.rs
index 8909a1fea..ef32d4c4a 100644
--- a/examples/stm32l4/src/bin/button_exti.rs
+++ b/examples/stm32l4/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs
index 177f6baf7..d54c080c7 100644
--- a/examples/stm32l4/src/bin/i2c.rs
+++ b/examples/stm32l4/src/bin/i2c.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::i2c::I2c;
 use embassy_stm32::interrupt;
diff --git a/examples/stm32l4/src/bin/i2c_blocking_async.rs b/examples/stm32l4/src/bin/i2c_blocking_async.rs
index 8cc069d0e..35a86660d 100644
--- a/examples/stm32l4/src/bin/i2c_blocking_async.rs
+++ b/examples/stm32l4/src/bin/i2c_blocking_async.rs
@@ -4,7 +4,7 @@
 
 use defmt::*;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::i2c::I2c;
 use embassy_stm32::interrupt;
diff --git a/examples/stm32l4/src/bin/i2c_dma.rs b/examples/stm32l4/src/bin/i2c_dma.rs
index 9323fd53f..3ce9398a4 100644
--- a/examples/stm32l4/src/bin/i2c_dma.rs
+++ b/examples/stm32l4/src/bin/i2c_dma.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::i2c::I2c;
 use embassy_stm32::interrupt;
 use embassy_stm32::time::Hertz;
diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs
index c90515626..c9302bb99 100644
--- a/examples/stm32l4/src/bin/rng.rs
+++ b/examples/stm32l4/src/bin/rng.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv};
 use embassy_stm32::rng::Rng;
 use embassy_stm32::Config;
diff --git a/examples/stm32l4/src/bin/spi_blocking_async.rs b/examples/stm32l4/src/bin/spi_blocking_async.rs
index a893cef6d..62ef0130e 100644
--- a/examples/stm32l4/src/bin/spi_blocking_async.rs
+++ b/examples/stm32l4/src/bin/spi_blocking_async.rs
@@ -4,7 +4,7 @@
 
 use defmt::*;
 use embassy_embedded_hal::adapter::BlockingAsync;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 use embassy_stm32::spi::{Config, Spi};
diff --git a/examples/stm32l4/src/bin/spi_dma.rs b/examples/stm32l4/src/bin/spi_dma.rs
index 5b19433cc..89471db5a 100644
--- a/examples/stm32l4/src/bin/spi_dma.rs
+++ b/examples/stm32l4/src/bin/spi_dma.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
 use embassy_stm32::spi::{Config, Spi};
 use embassy_stm32::time::Hertz;
diff --git a/examples/stm32l4/src/bin/usart_dma.rs b/examples/stm32l4/src/bin/usart_dma.rs
index 4b3a9b23c..728906897 100644
--- a/examples/stm32l4/src/bin/usart_dma.rs
+++ b/examples/stm32l4/src/bin/usart_dma.rs
@@ -5,7 +5,7 @@
 use core::fmt::Write;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::usart::{Config, Uart};
 use heapless::String;
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index 3e3a11d08..4d96d31fc 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -7,7 +7,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"]  }
 embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
 embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] }
diff --git a/examples/stm32l5/src/bin/button_exti.rs b/examples/stm32l5/src/bin/button_exti.rs
index ac3942521..e80ad2b3a 100644
--- a/examples/stm32l5/src/bin/button_exti.rs
+++ b/examples/stm32l5/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs
index cec9078e6..d359847e8 100644
--- a/examples/stm32l5/src/bin/rng.rs
+++ b/examples/stm32l5/src/bin/rng.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv};
 use embassy_stm32::rng::Rng;
 use embassy_stm32::Config;
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs
index 769b67a2b..7c53d03cc 100644
--- a/examples/stm32l5/src/bin/usb_ethernet.rs
+++ b/examples/stm32l5/src/bin/usb_ethernet.rs
@@ -7,7 +7,7 @@ use core::sync::atomic::{AtomicBool, Ordering};
 use core::task::Waker;
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_net::tcp::TcpSocket;
 use embassy_net::{PacketBox, PacketBoxExt, PacketBuf, Stack, StackResources};
 use embassy_stm32::rcc::*;
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs
index ef0a20a42..f7e3d93e3 100644
--- a/examples/stm32l5/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs
@@ -4,12 +4,12 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::rcc::*;
 use embassy_stm32::time::Hertz;
 use embassy_stm32::usb::Driver;
 use embassy_stm32::{interrupt, Config, Peripherals};
+use embassy_time::{Duration, Timer};
 use embassy_usb::control::OutResponse;
 use embassy_usb::Builder;
 use embassy_usb_hid::{HidWriter, ReportId, RequestHandler, State};
diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs
index a763a0b56..323db6557 100644
--- a/examples/stm32l5/src/bin/usb_serial.rs
+++ b/examples/stm32l5/src/bin/usb_serial.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{panic, *};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::rcc::*;
 use embassy_stm32::time::Hertz;
 use embassy_stm32::usb::{Driver, Instance};
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml
index d80260f04..48833664a 100644
--- a/examples/stm32u5/Cargo.toml
+++ b/examples/stm32u5/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ]  }
 
 defmt = "0.3"
diff --git a/examples/stm32u5/src/bin/blinky.rs b/examples/stm32u5/src/bin/blinky.rs
index 400542952..976fb0b9a 100644
--- a/examples/stm32u5/src/bin/blinky.rs
+++ b/examples/stm32u5/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index 59f9401bf..b46300764 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55cc", "time-driver-any", "exti"]  }
 
 defmt = "0.3"
diff --git a/examples/stm32wb/src/bin/blinky.rs b/examples/stm32wb/src/bin/blinky.rs
index 47f126e8d..f9bf90d2e 100644
--- a/examples/stm32wb/src/bin/blinky.rs
+++ b/examples/stm32wb/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32wb/src/bin/button_exti.rs b/examples/stm32wb/src/bin/button_exti.rs
index d2816950b..3648db6ff 100644
--- a/examples/stm32wb/src/bin/button_exti.rs
+++ b/examples/stm32wb/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml
index f886fae7d..ae33478af 100644
--- a/examples/stm32wl/Cargo.toml
+++ b/examples/stm32wl/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "subghz", "unstable-pac", "exti"]  }
 embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time", "defmt"] }
 
diff --git a/examples/stm32wl/src/bin/blinky.rs b/examples/stm32wl/src/bin/blinky.rs
index 4b8588bbc..6af5099ce 100644
--- a/examples/stm32wl/src/bin/blinky.rs
+++ b/examples/stm32wl/src/bin/blinky.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Level, Output, Speed};
+use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::main]
diff --git a/examples/stm32wl/src/bin/button_exti.rs b/examples/stm32wl/src/bin/button_exti.rs
index ebc255626..1f02db5cf 100644
--- a/examples/stm32wl/src/bin/button_exti.rs
+++ b/examples/stm32wl/src/bin/button_exti.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32wl/src/bin/flash.rs b/examples/stm32wl/src/bin/flash.rs
index 3c4da1e9b..eb7489760 100644
--- a/examples/stm32wl/src/bin/flash.rs
+++ b/examples/stm32wl/src/bin/flash.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{info, unwrap};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::flash::Flash;
 use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
 use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32wl/src/bin/lorawan.rs b/examples/stm32wl/src/bin/lorawan.rs
index b6a3ca905..7e8a8946d 100644
--- a/examples/stm32wl/src/bin/lorawan.rs
+++ b/examples/stm32wl/src/bin/lorawan.rs
@@ -5,7 +5,7 @@
 #![feature(generic_associated_types)]
 #![feature(type_alias_impl_trait)]
 
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_lora::stm32wl::*;
 use embassy_lora::LoraTimer;
 use embassy_stm32::dma::NoDma;
diff --git a/examples/stm32wl/src/bin/subghz.rs b/examples/stm32wl/src/bin/subghz.rs
index 1b096514b..d16e3f5e4 100644
--- a/examples/stm32wl/src/bin/subghz.rs
+++ b/examples/stm32wl/src/bin/subghz.rs
@@ -6,7 +6,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::*;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::exti::ExtiInput;
 use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index 20433689e..c7f980366 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -8,7 +8,8 @@ crate-type = ["cdylib"]
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["log"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "wasm", "nightly"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "wasm", "nightly", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "wasm", "nightly"] }
 
 wasm-logger = "0.2.0"
 wasm-bindgen = "0.2"
diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs
index 2e961e65a..d44c020b6 100644
--- a/examples/wasm/src/lib.rs
+++ b/examples/wasm/src/lib.rs
@@ -1,8 +1,8 @@
 #![feature(type_alias_impl_trait)]
 #![allow(incomplete_features)]
 
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Timer};
 
 #[embassy_executor::task]
 async fn ticker() {
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index d105f0e6e..8740cc488 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -5,7 +5,8 @@ version = "0.1.0"
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] }
 embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits"]  }
 
 defmt = "0.3.0"
diff --git a/tests/rp/src/bin/gpio.rs b/tests/rp/src/bin/gpio.rs
index 2d1a2ee51..af22fe27d 100644
--- a/tests/rp/src/bin/gpio.rs
+++ b/tests/rp/src/bin/gpio.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{assert, *};
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_rp::gpio::{Flex, Input, Level, Output, OutputOpenDrain, Pull};
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/tests/rp/src/bin/gpio_async.rs b/tests/rp/src/bin/gpio_async.rs
index d88786876..1eeaac1f6 100644
--- a/tests/rp/src/bin/gpio_async.rs
+++ b/tests/rp/src/bin/gpio_async.rs
@@ -3,9 +3,9 @@
 #![feature(type_alias_impl_trait)]
 
 use defmt::{assert, *};
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Instant, Timer};
+use embassy_executor::Spawner;
 use embassy_rp::gpio::{Input, Level, Output, Pull};
+use embassy_time::{Duration, Instant, Timer};
 use futures::future::join;
 use {defmt_rtt as _, panic_probe as _};
 
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 5fc67e130..1d12995a2 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -14,7 +14,8 @@ stm32u585ai = ["embassy-stm32/stm32u585ai"]     # IoT board
 
 [dependencies]
 embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
-embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "time-tick-32768hz"] }
+embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] }
+embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "tick-32768hz"] }
 embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-tim2"]  }
 
 defmt = "0.3.0"
diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs
index dc7223c67..18fd85d44 100644
--- a/tests/stm32/src/bin/gpio.rs
+++ b/tests/stm32/src/bin/gpio.rs
@@ -5,7 +5,7 @@
 #[path = "../example_common.rs"]
 mod example_common;
 use defmt::assert;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::gpio::{Flex, Input, Level, Output, OutputOpenDrain, Pull, Speed};
 use example_common::*;
 
diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs
index 2c0b7fc44..1c5dc87c0 100644
--- a/tests/stm32/src/bin/spi.rs
+++ b/tests/stm32/src/bin/spi.rs
@@ -5,7 +5,7 @@
 #[path = "../example_common.rs"]
 mod example_common;
 use defmt::assert_eq;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::spi::{self, Spi};
 use embassy_stm32::time::Hertz;
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs
index af1118b59..cb2152e0b 100644
--- a/tests/stm32/src/bin/spi_dma.rs
+++ b/tests/stm32/src/bin/spi_dma.rs
@@ -5,7 +5,7 @@
 #[path = "../example_common.rs"]
 mod example_common;
 use defmt::assert_eq;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::spi::{self, Spi};
 use embassy_stm32::time::Hertz;
 use example_common::*;
diff --git a/tests/stm32/src/bin/timer.rs b/tests/stm32/src/bin/timer.rs
index 34903084c..e00e43bf1 100644
--- a/tests/stm32/src/bin/timer.rs
+++ b/tests/stm32/src/bin/timer.rs
@@ -5,8 +5,8 @@
 #[path = "../example_common.rs"]
 mod example_common;
 use defmt::assert;
-use embassy_executor::executor::Spawner;
-use embassy_executor::time::{Duration, Instant, Timer};
+use embassy_executor::Spawner;
+use embassy_time::{Duration, Instant, Timer};
 use example_common::*;
 
 #[embassy_executor::main]
diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs
index f454c1f70..fb4b3fcca 100644
--- a/tests/stm32/src/bin/usart.rs
+++ b/tests/stm32/src/bin/usart.rs
@@ -5,7 +5,7 @@
 #[path = "../example_common.rs"]
 mod example_common;
 use defmt::assert_eq;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::dma::NoDma;
 use embassy_stm32::usart::{Config, Uart};
 use example_common::*;
diff --git a/tests/stm32/src/bin/usart_dma.rs b/tests/stm32/src/bin/usart_dma.rs
index fbaccd174..09382a022 100644
--- a/tests/stm32/src/bin/usart_dma.rs
+++ b/tests/stm32/src/bin/usart_dma.rs
@@ -5,7 +5,7 @@
 #[path = "../example_common.rs"]
 mod example_common;
 use defmt::assert_eq;
-use embassy_executor::executor::Spawner;
+use embassy_executor::Spawner;
 use embassy_stm32::usart::{Config, Uart};
 use example_common::*;