Compare commits

..

14 Commits

Author SHA1 Message Date
c8aa9c3b98 wip 2023-10-11 20:53:33 -05:00
7810ef1c5e wip 2023-10-11 20:22:00 -05:00
c1dc1741f6 wip 2023-10-11 20:21:32 -05:00
6deec1b853 wip 2023-10-11 20:17:47 -05:00
ba5b5e98fe wip 2023-10-11 20:15:43 -05:00
158aeac438 wip 2023-10-11 20:12:13 -05:00
f27c929cb8 wip 2023-10-11 19:59:42 -05:00
0d0fbe957e Merge branch 'rcc-mux' of github.com:xoviat/embassy; branch 'main' of github.com:embassy-rs/embassy into rcc-mux 2023-10-11 19:58:38 -05:00
e1a1c51d00 remove disable variant 2023-10-11 19:35:45 -05:00
e25c7c23d0 wip 2023-10-09 20:49:44 -05:00
4ee39f6dce Merge branch 'main' of github.com:embassy-rs/embassy into rcc-mux 2023-10-09 20:10:16 -05:00
a4b6bc31f8 wip 2023-10-08 18:26:27 -05:00
2ae9d28d47 wip 2023-10-07 09:34:12 -05:00
1457b53e48 wip 2023-10-07 09:31:09 -05:00
351 changed files with 2788 additions and 3023 deletions

View File

@ -62,9 +62,9 @@ async fn blink(pin: AnyPin) {
loop { loop {
// Timekeeping is globally available, no need to mess with hardware timers. // Timekeeping is globally available, no need to mess with hardware timers.
led.set_high(); led.set_high();
Timer::after_millis(150).await; Timer::after(Duration::from_millis(150)).await;
led.set_low(); led.set_low();
Timer::after_millis(150).await; Timer::after(Duration::from_millis(150)).await;
} }
} }

106
ci.sh
View File

@ -69,68 +69,62 @@ cargo batch \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,intrinsics \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,intrinsics \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,qspi-as-gpio \ --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,qspi-as-gpio \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f412zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f415zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f412zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f417zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f423zh,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f415zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f427zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f417zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f423zh,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f437zi,log,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f427zi,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f439zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f446ze,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f437zi,log,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f469zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f439zi,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f479zi,defmt,exti,time-driver-any,unstable-traits,embedded-sdmmc \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f446ze,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f469zi,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f479zi,defmt,exti,time-driver-any,unstable-traits,embedded-sdmmc,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l422cb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l422cb,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l073cz,defmt,exti,time-driver-any,unstable-traits,low-power \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l073cz,defmt,exti,time-driver-any,unstable-traits,low-power,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f378cc,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f378cc,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5jb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32g474pe,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5jb,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32g474pe,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h503rb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h562ag,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h503rb,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h562ag,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \

View File

@ -40,38 +40,33 @@ cargo batch \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --no-default-features --out-dir out/examples/nrf52840 --bin raw_spawn \ --- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --no-default-features --out-dir out/examples/nrf52840 --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 \ --- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --no-default-features --out-dir out/examples/stm32l0 --bin raw_spawn \

View File

@ -11,10 +11,10 @@ log = ["dep:log"]
firmware-logs = [] firmware-logs = []
[dependencies] [dependencies]
embassy-time = { version = "0.1.5", path = "../embassy-time"} embassy-time = { version = "0.1.3", path = "../embassy-time"}
embassy-sync = { version = "0.3.0", path = "../embassy-sync"} embassy-sync = { version = "0.3.0", path = "../embassy-sync"}
embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"}
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"}
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
log = { version = "0.4.17", optional = true } log = { version = "0.4.17", optional = true }

View File

@ -1,5 +1,5 @@
use embassy_futures::yield_now; use embassy_futures::yield_now;
use embassy_time::Timer; use embassy_time::{Duration, Timer};
use embedded_hal_1::digital::OutputPin; use embedded_hal_1::digital::OutputPin;
use futures::FutureExt; use futures::FutureExt;
@ -51,9 +51,9 @@ where
pub async fn init(&mut self) { pub async fn init(&mut self) {
// Reset // Reset
self.pwr.set_low().unwrap(); self.pwr.set_low().unwrap();
Timer::after_millis(20).await; Timer::after(Duration::from_millis(20)).await;
self.pwr.set_high().unwrap(); self.pwr.set_high().unwrap();
Timer::after_millis(250).await; Timer::after(Duration::from_millis(250)).await;
while self while self
.read32_swapped(REG_BUS_TEST_RO) .read32_swapped(REG_BUS_TEST_RO)

View File

@ -2,7 +2,7 @@ use core::cmp::{max, min};
use ch::driver::LinkState; use ch::driver::LinkState;
use embassy_net_driver_channel as ch; use embassy_net_driver_channel as ch;
use embassy_time::Timer; use embassy_time::{Duration, Timer};
pub use crate::bus::SpiBusCyw43; pub use crate::bus::SpiBusCyw43;
use crate::consts::*; use crate::consts::*;
@ -87,22 +87,22 @@ impl<'a> Control<'a> {
self.set_iovar("country", &country_info.to_bytes()).await; self.set_iovar("country", &country_info.to_bytes()).await;
// set country takes some time, next ioctls fail if we don't wait. // set country takes some time, next ioctls fail if we don't wait.
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
// Set antenna to chip antenna // Set antenna to chip antenna
self.ioctl_set_u32(IOCTL_CMD_ANTDIV, 0, 0).await; self.ioctl_set_u32(IOCTL_CMD_ANTDIV, 0, 0).await;
self.set_iovar_u32("bus:txglom", 0).await; self.set_iovar_u32("bus:txglom", 0).await;
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
//self.set_iovar_u32("apsta", 1).await; // this crashes, also we already did it before...?? //self.set_iovar_u32("apsta", 1).await; // this crashes, also we already did it before...??
//Timer::after_millis(100).await; //Timer::after(Duration::from_millis(100)).await;
self.set_iovar_u32("ampdu_ba_wsize", 8).await; self.set_iovar_u32("ampdu_ba_wsize", 8).await;
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
self.set_iovar_u32("ampdu_mpdu", 4).await; self.set_iovar_u32("ampdu_mpdu", 4).await;
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
//self.set_iovar_u32("ampdu_rx_factor", 0).await; // this crashes //self.set_iovar_u32("ampdu_rx_factor", 0).await; // this crashes
//Timer::after_millis(100).await; //Timer::after(Duration::from_millis(100)).await;
// evts // evts
let mut evts = EventMask { let mut evts = EventMask {
@ -121,17 +121,17 @@ impl<'a> Control<'a> {
self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await; self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await;
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
// set wifi up // set wifi up
self.up().await; self.up().await;
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto
self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
self.state_ch.set_ethernet_address(mac_addr); self.state_ch.set_ethernet_address(mac_addr);
@ -185,7 +185,7 @@ impl<'a> Control<'a> {
self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await; self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await;
self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await; self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await;
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
let mut pfi = PassphraseInfo { let mut pfi = PassphraseInfo {
len: passphrase.len() as _, len: passphrase.len() as _,
@ -297,7 +297,7 @@ impl<'a> Control<'a> {
if security != Security::OPEN { if security != Security::OPEN {
self.set_iovar_u32x2("bsscfg:wpa_auth", 0, 0x0084).await; // wpa_auth = WPA2_AUTH_PSK | WPA_AUTH_PSK self.set_iovar_u32x2("bsscfg:wpa_auth", 0, 0x0084).await; // wpa_auth = WPA2_AUTH_PSK | WPA_AUTH_PSK
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
// Set passphrase // Set passphrase
let mut pfi = PassphraseInfo { let mut pfi = PassphraseInfo {

View File

@ -555,14 +555,14 @@ where
self.bus.bp_write8(base + AI_RESETCTRL_OFFSET, 0).await; self.bus.bp_write8(base + AI_RESETCTRL_OFFSET, 0).await;
Timer::after_millis(1).await; Timer::after(Duration::from_millis(1)).await;
self.bus self.bus
.bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN) .bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN)
.await; .await;
let _ = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await; let _ = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await;
Timer::after_millis(1).await; Timer::after(Duration::from_millis(1)).await;
} }
async fn core_is_up(&mut self, core: Core) -> bool { async fn core_is_up(&mut self, core: Core) -> bool {

View File

@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
[dependencies] [dependencies]
embassy-executor = { version = "0.3.0", path = "../../../../../embassy-executor", features = ["defmt", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } embassy-executor = { version = "0.3.0", path = "../../../../../embassy-executor", features = ["defmt", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] }
embassy-time = { version = "0.1.4", path = "../../../../../embassy-time", 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"] } embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "nightly"] }
defmt = "0.3" defmt = "0.3"

View File

@ -6,7 +6,7 @@ The Embassy executor is an async/await executor designed for embedded usage alon
* No `alloc`, no heap needed. Task are statically allocated. * No `alloc`, no heap needed. Task are statically allocated.
* No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. * 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_secs(1).await;`. * 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`. * 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. * 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. * 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.

View File

@ -21,7 +21,7 @@ default = ["time"]
[dependencies] [dependencies]
embassy-futures = { version = "0.1.0", path = "../embassy-futures", optional = true } embassy-futures = { version = "0.1.0", path = "../embassy-futures", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [ embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [
"unproven", "unproven",
] } ] }

View File

@ -76,7 +76,9 @@ where
#[cfg(not(feature = "time"))] #[cfg(not(feature = "time"))]
Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported),
#[cfg(feature = "time")] #[cfg(feature = "time")]
Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await, Operation::DelayUs(us) => {
embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await
}
} }
} }
}; };
@ -141,7 +143,9 @@ where
#[cfg(not(feature = "time"))] #[cfg(not(feature = "time"))]
Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported),
#[cfg(feature = "time")] #[cfg(feature = "time")]
Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await, Operation::DelayUs(us) => {
embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await
}
} }
} }
}; };

View File

@ -59,7 +59,7 @@ rtos-trace = { version = "0.1.2", optional = true }
futures-util = { version = "0.3.17", default-features = false } futures-util = { version = "0.3.17", default-features = false }
embassy-macros = { version = "0.2.1", path = "../embassy-macros" } embassy-macros = { version = "0.2.1", path = "../embassy-macros" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true} embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true}
atomic-polyfill = "1.0.1" atomic-polyfill = "1.0.1"
critical-section = "1.1" critical-section = "1.1"
static_cell = "1.1" static_cell = "1.1"

View File

@ -4,7 +4,7 @@ An async/await executor designed for embedded usage.
- No `alloc`, no heap needed. Task futures are statically allocated. - 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. - 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_secs(1).await;`. - 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`. - 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. - 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. - 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.

View File

@ -1,4 +1,4 @@
# embassy-hal-internal # embassy-macros
An [Embassy](https://embassy.dev) project. An [Embassy](https://embassy.dev) project.

View File

@ -4,7 +4,6 @@ use core::sync::atomic::{compiler_fence, Ordering};
use cortex_m::interrupt::InterruptNumber; use cortex_m::interrupt::InterruptNumber;
use cortex_m::peripheral::NVIC; use cortex_m::peripheral::NVIC;
use critical_section::CriticalSection;
/// Generate a standard `mod interrupt` for a HAL. /// Generate a standard `mod interrupt` for a HAL.
#[macro_export] #[macro_export]
@ -92,12 +91,6 @@ macro_rules! interrupt_mod {
fn set_priority(prio: crate::interrupt::Priority) { fn set_priority(prio: crate::interrupt::Priority) {
Self::IRQ.set_priority(prio) Self::IRQ.set_priority(prio)
} }
/// Set the interrupt priority with an already-acquired critical section
#[inline]
fn set_priority_with_cs(cs: critical_section::CriticalSection, prio: crate::interrupt::Priority) {
Self::IRQ.set_priority_with_cs(cs, prio)
}
} }
$( $(
@ -202,29 +195,10 @@ pub unsafe trait InterruptExt: InterruptNumber + Copy {
/// Set the interrupt priority. /// Set the interrupt priority.
#[inline] #[inline]
fn set_priority(self, prio: Priority) { fn set_priority(self, prio: Priority) {
unsafe { critical_section::with(|_| unsafe {
let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(()); let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
nvic.set_priority(self, prio.into())
// On thumbv6, set_priority must do a RMW to change 8bit in a 32bit reg. })
#[cfg(armv6m)]
critical_section::with(|_| nvic.set_priority(self, prio.into()));
// On thumbv7+, set_priority does an atomic 8bit write, so no CS needed.
#[cfg(not(armv6m))]
nvic.set_priority(self, prio.into());
}
}
/// Set the interrupt priority with an already-acquired critical section
///
/// Equivalent to `set_priority`, except you pass a `CriticalSection` to prove
/// you've already acquired a critical section. This prevents acquiring another
/// one, which saves code size.
#[inline]
fn set_priority_with_cs(self, _cs: CriticalSection, prio: Priority) {
unsafe {
let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
nvic.set_priority(self, prio.into());
}
} }
} }

View File

@ -10,6 +10,7 @@ pub mod drop;
mod macros; mod macros;
mod peripheral; mod peripheral;
pub mod ratio; pub mod ratio;
pub mod ring_buffer;
pub use peripheral::{Peripheral, PeripheralRef}; pub use peripheral::{Peripheral, PeripheralRef};
#[cfg(feature = "cortex-m")] #[cfg(feature = "cortex-m")]

View File

@ -48,23 +48,17 @@ macro_rules! peripherals_struct {
///Returns all the peripherals *once* ///Returns all the peripherals *once*
#[inline] #[inline]
pub(crate) fn take() -> Self { pub(crate) fn take() -> Self {
critical_section::with(Self::take_with_cs)
}
///Returns all the peripherals *once*
#[inline]
pub(crate) fn take_with_cs(_cs: critical_section::CriticalSection) -> Self {
#[no_mangle] #[no_mangle]
static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false; static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false;
// safety: OK because we're inside a CS. critical_section::with(|_| unsafe {
unsafe {
if _EMBASSY_DEVICE_PERIPHERALS { if _EMBASSY_DEVICE_PERIPHERALS {
panic!("init called more than once!") panic!("init called more than once!")
} }
_EMBASSY_DEVICE_PERIPHERALS = true; _EMBASSY_DEVICE_PERIPHERALS = true;
Self::steal() Self::steal()
} })
} }
} }

View File

@ -0,0 +1,136 @@
pub struct RingBuffer<'a> {
buf: &'a mut [u8],
start: usize,
end: usize,
empty: bool,
}
impl<'a> RingBuffer<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
Self {
buf,
start: 0,
end: 0,
empty: true,
}
}
pub fn push_buf(&mut self) -> &mut [u8] {
if self.start == self.end && !self.empty {
trace!(" ringbuf: push_buf empty");
return &mut self.buf[..0];
}
let n = if self.start <= self.end {
self.buf.len() - self.end
} else {
self.start - self.end
};
trace!(" ringbuf: push_buf {:?}..{:?}", self.end, self.end + n);
&mut self.buf[self.end..self.end + n]
}
pub fn push(&mut self, n: usize) {
trace!(" ringbuf: push {:?}", n);
if n == 0 {
return;
}
self.end = self.wrap(self.end + n);
self.empty = false;
}
pub fn pop_buf(&mut self) -> &mut [u8] {
if self.empty {
trace!(" ringbuf: pop_buf empty");
return &mut self.buf[..0];
}
let n = if self.end <= self.start {
self.buf.len() - self.start
} else {
self.end - self.start
};
trace!(" ringbuf: pop_buf {:?}..{:?}", self.start, self.start + n);
&mut self.buf[self.start..self.start + n]
}
pub fn pop(&mut self, n: usize) {
trace!(" ringbuf: pop {:?}", n);
if n == 0 {
return;
}
self.start = self.wrap(self.start + n);
self.empty = self.start == self.end;
}
pub fn is_full(&self) -> bool {
self.start == self.end && !self.empty
}
pub fn is_empty(&self) -> bool {
self.empty
}
pub fn clear(&mut self) {
self.start = 0;
self.end = 0;
self.empty = true;
}
fn wrap(&self, n: usize) -> usize {
assert!(n <= self.buf.len());
if n == self.buf.len() {
0
} else {
n
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn push_pop() {
let mut b = [0; 4];
let mut rb = RingBuffer::new(&mut b);
let buf = rb.push_buf();
assert_eq!(4, buf.len());
buf[0] = 1;
buf[1] = 2;
buf[2] = 3;
buf[3] = 4;
rb.push(4);
let buf = rb.pop_buf();
assert_eq!(4, buf.len());
assert_eq!(1, buf[0]);
rb.pop(1);
let buf = rb.pop_buf();
assert_eq!(3, buf.len());
assert_eq!(2, buf[0]);
rb.pop(1);
let buf = rb.pop_buf();
assert_eq!(2, buf.len());
assert_eq!(3, buf[0]);
rb.pop(1);
let buf = rb.pop_buf();
assert_eq!(1, buf.len());
assert_eq!(4, buf[0]);
rb.pop(1);
let buf = rb.pop_buf();
assert_eq!(0, buf.len());
let buf = rb.push_buf();
assert_eq!(4, buf.len());
}
}

View File

@ -20,7 +20,7 @@ defmt = ["dep:defmt", "lorawan-device/defmt"]
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
embedded-hal-async = { version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" }

View File

@ -34,6 +34,6 @@ impl lorawan_device::async_device::radio::Timer for LoraTimer {
} }
async fn delay_ms(&mut self, millis: u64) { async fn delay_ms(&mut self, millis: u64) {
Timer::after_millis(millis).await Timer::after(Duration::from_millis(millis)).await
} }
} }

View File

@ -16,8 +16,8 @@ log = { version = "0.4", default-features = false, optional = true }
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" }
embedded-hal-async = { version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" }
embedded-hal-bus = { version = "=0.1.0-rc.1", features = ["async"] } embedded-hal-bus = { version = "=0.1.0-rc.1", features = ["async"] }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" }
embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-time = { version = "0.1.3" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
bitfield = "0.14.0" bitfield = "0.14.0"

View File

@ -20,7 +20,7 @@ pub use crc32::ETH_FCS;
use crc8::crc8; use crc8::crc8;
use embassy_futures::select::{select, Either}; use embassy_futures::select::{select, Either};
use embassy_net_driver_channel as ch; use embassy_net_driver_channel as ch;
use embassy_time::Timer; use embassy_time::{Duration, Timer};
use embedded_hal_1::digital::OutputPin; use embedded_hal_1::digital::OutputPin;
use embedded_hal_async::digital::Wait; use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::{Error, Operation, SpiDevice}; use embedded_hal_async::spi::{Error, Operation, SpiDevice};
@ -609,12 +609,12 @@ pub async fn new<const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT: Wait
reset.set_low().unwrap(); reset.set_low().unwrap();
// Wait t1: 20-43mS // Wait t1: 20-43mS
Timer::after_millis(30).await; Timer::after(Duration::from_millis(30)).await;
reset.set_high().unwrap(); reset.set_high().unwrap();
// Wait t3: 50mS // Wait t3: 50mS
Timer::after_millis(50).await; Timer::after(Duration::from_millis(50)).await;
// Create device // Create device
let mut mac = ADIN1110::new(spi_dev, spi_crc, append_fcs_on_tx); let mut mac = ADIN1110::new(spi_dev, spi_crc, append_fcs_on_tx);

View File

@ -1,18 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.2.0 - 2023-10-15
- Update embassy-net-driver
- `Runner::new` now takes an `embassy_net_driver::HardwareAddress` parameter
- Added `Runner::set_ieee802154_address`, `Runner::ieee802154_address`
## 0.1.0 - 2023-06-29
- First release

View File

@ -1,6 +1,6 @@
[package] [package]
name = "embassy-net-driver-channel" name = "embassy-net-driver-channel"
version = "0.2.0" version = "0.1.0"
edition = "2021" edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "High-level channel-based driver for the `embassy-net` async TCP/IP network stack." description = "High-level channel-based driver for the `embassy-net` async TCP/IP network stack."
@ -26,4 +26,4 @@ log = { version = "0.4.14", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }

View File

@ -1,17 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.2.0 - 2023-10-15
- Added `Driver::ieee802154_address`
- Added `Medium::Ieee802154`
## 0.1.0 - 2023-06-29
- First release

View File

@ -1,6 +1,6 @@
[package] [package]
name = "embassy-net-driver" name = "embassy-net-driver"
version = "0.2.0" version = "0.1.0"
edition = "2021" edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "Driver trait for the `embassy-net` async TCP/IP network stack." description = "Driver trait for the `embassy-net` async TCP/IP network stack."

View File

@ -10,8 +10,8 @@ edition = "2021"
[dependencies] [dependencies]
embedded-hal = { version = "1.0.0-rc.1" } embedded-hal = { version = "1.0.0-rc.1" }
embedded-hal-async = { version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-time = { version = "0.1.3", path = "../embassy-time" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }

View File

@ -7,10 +7,10 @@ edition = "2021"
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }
embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-time = { version = "0.1.3", path = "../embassy-time" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync"} embassy-sync = { version = "0.3.0", path = "../embassy-sync"}
embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"}
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"}
embedded-hal = { version = "1.0.0-rc.1" } embedded-hal = { version = "1.0.0-rc.1" }
embedded-hal-async = { version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" }

View File

@ -169,9 +169,9 @@ where
pub async fn run(mut self) -> ! { pub async fn run(mut self) -> ! {
debug!("resetting..."); debug!("resetting...");
self.reset.set_low().unwrap(); self.reset.set_low().unwrap();
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
self.reset.set_high().unwrap(); self.reset.set_high().unwrap();
Timer::after_millis(1000).await; Timer::after(Duration::from_millis(1000)).await;
let mut tx_buf = [0u8; MAX_SPI_BUFFER_SIZE]; let mut tx_buf = [0u8; MAX_SPI_BUFFER_SIZE];
let mut rx_buf = [0u8; MAX_SPI_BUFFER_SIZE]; let mut rx_buf = [0u8; MAX_SPI_BUFFER_SIZE];

View File

@ -16,7 +16,7 @@ defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }
embedded-io-async = { version = "0.6.0" } embedded-io-async = { version = "0.6.0" }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
ppproto = { version = "0.1.2"} ppproto = { version = "0.1.2"}
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }

View File

@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
async-io = "1.6.0" async-io = "1.6.0"
log = "0.4.14" log = "0.4.14"
libc = "0.2.101" libc = "0.2.101"

View File

@ -10,8 +10,8 @@ edition = "2021"
[dependencies] [dependencies]
embedded-hal = { version = "1.0.0-rc.1" } embedded-hal = { version = "1.0.0-rc.1" }
embedded-hal-async = { version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" }
embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-time = { version = "0.1.3", path = "../embassy-time" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }

View File

@ -8,7 +8,7 @@ mod device;
use embassy_futures::select::{select, Either}; use embassy_futures::select::{select, Either};
use embassy_net_driver_channel as ch; use embassy_net_driver_channel as ch;
use embassy_net_driver_channel::driver::LinkState; use embassy_net_driver_channel::driver::LinkState;
use embassy_time::Timer; use embassy_time::{Duration, Timer};
use embedded_hal::digital::OutputPin; use embedded_hal::digital::OutputPin;
use embedded_hal_async::digital::Wait; use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::SpiDevice; use embedded_hal_async::spi::SpiDevice;
@ -95,12 +95,12 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevi
// Reset the chip. // Reset the chip.
reset.set_low().ok(); reset.set_low().ok();
// Ensure the reset is registered. // Ensure the reset is registered.
Timer::after_millis(1).await; Timer::after(Duration::from_millis(1)).await;
reset.set_high().ok(); reset.set_high().ok();
// Wait for PLL lock. Some chips are slower than others. // Wait for PLL lock. Some chips are slower than others.
// Slowest is w5100s which is 100ms, so let's just wait that. // Slowest is w5100s which is 100ms, so let's just wait that.
Timer::after_millis(100).await; Timer::after(Duration::from_millis(100)).await;
let mac = WiznetDevice::new(spi_dev, mac_addr).await.unwrap(); let mac = WiznetDevice::new(spi_dev, mac_addr).await.unwrap();

View File

@ -1,31 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.2.0 - 2023-10-15
- Re-export `smoltcp::wire::IpEndpoint`
- Add poll functions on UdpSocket
- Make dual-stack work in embassy-net
- Fix multicast support
- Allow ethernet and 802.15.4 to coexist
- Add IEEE802.15.4 address to embassy net Stack
- Use HardwareAddress in Driver
- Add async versions of smoltcp's `send` and `recv` closure based API
- add error translation to tcp errors
- Forward TCP/UDP socket capacity impls
- allow changing IP config at runtime
- allow non-'static drivers
- Remove impl_trait_projections
- update embedded-io, embedded-nal-async
- add support for dhcp hostname option
- Wake stack's task after queueing a DNS query
## 0.1.0 - 2023-06-29
- First release

View File

@ -1,6 +1,6 @@
[package] [package]
name = "embassy-net" name = "embassy-net"
version = "0.2.0" version = "0.1.0"
edition = "2021" edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "Async TCP/IP network stack for embedded systems" description = "Async TCP/IP network stack for embedded systems"
@ -51,8 +51,8 @@ smoltcp = { version = "0.10.0", default-features = false, features = [
"async", "async",
] } ] }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-time = { version = "0.1.3", path = "../embassy-time" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embedded-io-async = { version = "0.6.0", optional = true } embedded-io-async = { version = "0.6.0", optional = true }

View File

@ -509,10 +509,7 @@ impl<D: Driver> Stack<D> {
self.with_mut(|s, i| { self.with_mut(|s, i| {
let socket = s.sockets.get_mut::<dns::Socket>(i.dns_socket); let socket = s.sockets.get_mut::<dns::Socket>(i.dns_socket);
match socket.start_query(s.iface.context(), name, qtype) { match socket.start_query(s.iface.context(), name, qtype) {
Ok(handle) => { Ok(handle) => Poll::Ready(Ok(handle)),
s.waker.wake();
Poll::Ready(Ok(handle))
}
Err(dns::StartQueryError::NoFreeSlot) => { Err(dns::StartQueryError::NoFreeSlot) => {
i.dns_waker.register(cx.waker()); i.dns_waker.register(cx.waker());
Poll::Pending Poll::Pending

View File

@ -94,7 +94,7 @@ _gpio-p1 = []
_nrf52832_anomaly_109 = [] _nrf52832_anomaly_109 = []
[dependencies] [dependencies]
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }

View File

@ -6,13 +6,10 @@ pub mod pac {
// To avoid cfg spam, we remove _ns or _s suffixes here. // To avoid cfg spam, we remove _ns or _s suffixes here.
pub use nrf5340_app_pac::NVIC_PRIO_BITS; pub use nrf5340_app_pac::NVIC_PRIO_BITS;
#[cfg(feature="rt")]
#[doc(no_inline)]
pub use nrf5340_app_pac::interrupt;
#[doc(no_inline)] #[doc(no_inline)]
pub use nrf5340_app_pac::{ pub use nrf5340_app_pac::{
interrupt,
Interrupt, Interrupt,
Peripherals, Peripherals,
@ -63,167 +60,156 @@ pub mod pac {
wdt0_ns as wdt0, wdt0_ns as wdt0,
}; };
/// Non-Secure mode (NS) peripherals #[cfg(feature = "nrf5340-app-ns")]
pub mod ns { #[doc(no_inline)]
#[cfg(feature = "nrf5340-app-ns")] pub use nrf5340_app_pac::{
#[doc(no_inline)] CLOCK_NS as CLOCK,
pub use nrf5340_app_pac::{ COMP_NS as COMP,
CLOCK_NS as CLOCK, CTRLAP_NS as CTRLAP,
COMP_NS as COMP, DCNF_NS as DCNF,
CTRLAP_NS as CTRLAP, DPPIC_NS as DPPIC,
DCNF_NS as DCNF, EGU0_NS as EGU0,
DPPIC_NS as DPPIC, EGU1_NS as EGU1,
EGU0_NS as EGU0, EGU2_NS as EGU2,
EGU1_NS as EGU1, EGU3_NS as EGU3,
EGU2_NS as EGU2, EGU4_NS as EGU4,
EGU3_NS as EGU3, EGU5_NS as EGU5,
EGU4_NS as EGU4, FPU_NS as FPU,
EGU5_NS as EGU5, GPIOTE1_NS as GPIOTE1,
FPU_NS as FPU, I2S0_NS as I2S0,
GPIOTE1_NS as GPIOTE1, IPC_NS as IPC,
I2S0_NS as I2S0, KMU_NS as KMU,
IPC_NS as IPC, LPCOMP_NS as LPCOMP,
KMU_NS as KMU, MUTEX_NS as MUTEX,
LPCOMP_NS as LPCOMP, NFCT_NS as NFCT,
MUTEX_NS as MUTEX, NVMC_NS as NVMC,
NFCT_NS as NFCT, OSCILLATORS_NS as OSCILLATORS,
NVMC_NS as NVMC, P0_NS as P0,
OSCILLATORS_NS as OSCILLATORS, P1_NS as P1,
P0_NS as P0, PDM0_NS as PDM0,
P1_NS as P1, POWER_NS as POWER,
PDM0_NS as PDM0, PWM0_NS as PWM0,
POWER_NS as POWER, PWM1_NS as PWM1,
PWM0_NS as PWM0, PWM2_NS as PWM2,
PWM1_NS as PWM1, PWM3_NS as PWM3,
PWM2_NS as PWM2, QDEC0_NS as QDEC0,
PWM3_NS as PWM3, QDEC1_NS as QDEC1,
QDEC0_NS as QDEC0, QSPI_NS as QSPI,
QDEC1_NS as QDEC1, REGULATORS_NS as REGULATORS,
QSPI_NS as QSPI, RESET_NS as RESET,
REGULATORS_NS as REGULATORS, RTC0_NS as RTC0,
RESET_NS as RESET, RTC1_NS as RTC1,
RTC0_NS as RTC0, SAADC_NS as SAADC,
RTC1_NS as RTC1, SPIM0_NS as SPIM0,
SAADC_NS as SAADC, SPIM1_NS as SPIM1,
SPIM0_NS as SPIM0, SPIM2_NS as SPIM2,
SPIM1_NS as SPIM1, SPIM3_NS as SPIM3,
SPIM2_NS as SPIM2, SPIM4_NS as SPIM4,
SPIM3_NS as SPIM3, SPIS0_NS as SPIS0,
SPIM4_NS as SPIM4, SPIS1_NS as SPIS1,
SPIS0_NS as SPIS0, SPIS2_NS as SPIS2,
SPIS1_NS as SPIS1, SPIS3_NS as SPIS3,
SPIS2_NS as SPIS2, TIMER0_NS as TIMER0,
SPIS3_NS as SPIS3, TIMER1_NS as TIMER1,
TIMER0_NS as TIMER0, TIMER2_NS as TIMER2,
TIMER1_NS as TIMER1, TWIM0_NS as TWIM0,
TIMER2_NS as TIMER2, TWIM1_NS as TWIM1,
TWIM0_NS as TWIM0, TWIM2_NS as TWIM2,
TWIM1_NS as TWIM1, TWIM3_NS as TWIM3,
TWIM2_NS as TWIM2, TWIS0_NS as TWIS0,
TWIM3_NS as TWIM3, TWIS1_NS as TWIS1,
TWIS0_NS as TWIS0, TWIS2_NS as TWIS2,
TWIS1_NS as TWIS1, TWIS3_NS as TWIS3,
TWIS2_NS as TWIS2, UARTE0_NS as UARTE0,
TWIS3_NS as TWIS3, UARTE1_NS as UARTE1,
UARTE0_NS as UARTE0, UARTE2_NS as UARTE2,
UARTE1_NS as UARTE1, UARTE3_NS as UARTE3,
UARTE2_NS as UARTE2, USBD_NS as USBD,
UARTE3_NS as UARTE3, USBREGULATOR_NS as USBREGULATOR,
USBD_NS as USBD, VMC_NS as VMC,
USBREGULATOR_NS as USBREGULATOR, WDT0_NS as WDT0,
VMC_NS as VMC, WDT1_NS as WDT1,
WDT0_NS as WDT0, };
WDT1_NS as WDT1,
};
}
/// Secure mode (S) peripherals #[cfg(feature = "nrf5340-app-s")]
pub mod s { #[doc(no_inline)]
#[cfg(feature = "nrf5340-app-s")] pub use nrf5340_app_pac::{
#[doc(no_inline)] CACHEDATA_S as CACHEDATA,
pub use nrf5340_app_pac::{ CACHEINFO_S as CACHEINFO,
CACHEDATA_S as CACHEDATA, CACHE_S as CACHE,
CACHEINFO_S as CACHEINFO, CLOCK_S as CLOCK,
CACHE_S as CACHE, COMP_S as COMP,
CLOCK_S as CLOCK, CRYPTOCELL_S as CRYPTOCELL,
COMP_S as COMP, CTI_S as CTI,
CRYPTOCELL_S as CRYPTOCELL, CTRLAP_S as CTRLAP,
CTI_S as CTI, DCNF_S as DCNF,
CTRLAP_S as CTRLAP, DPPIC_S as DPPIC,
DCNF_S as DCNF, EGU0_S as EGU0,
DPPIC_S as DPPIC, EGU1_S as EGU1,
EGU0_S as EGU0, EGU2_S as EGU2,
EGU1_S as EGU1, EGU3_S as EGU3,
EGU2_S as EGU2, EGU4_S as EGU4,
EGU3_S as EGU3, EGU5_S as EGU5,
EGU4_S as EGU4, FICR_S as FICR,
EGU5_S as EGU5, FPU_S as FPU,
FICR_S as FICR, GPIOTE0_S as GPIOTE0,
FPU_S as FPU, I2S0_S as I2S0,
GPIOTE0_S as GPIOTE0, IPC_S as IPC,
I2S0_S as I2S0, KMU_S as KMU,
IPC_S as IPC, LPCOMP_S as LPCOMP,
KMU_S as KMU, MUTEX_S as MUTEX,
LPCOMP_S as LPCOMP, NFCT_S as NFCT,
MUTEX_S as MUTEX, NVMC_S as NVMC,
NFCT_S as NFCT, OSCILLATORS_S as OSCILLATORS,
NVMC_S as NVMC, P0_S as P0,
OSCILLATORS_S as OSCILLATORS, P1_S as P1,
P0_S as P0, PDM0_S as PDM0,
P1_S as P1, POWER_S as POWER,
PDM0_S as PDM0, PWM0_S as PWM0,
POWER_S as POWER, PWM1_S as PWM1,
PWM0_S as PWM0, PWM2_S as PWM2,
PWM1_S as PWM1, PWM3_S as PWM3,
PWM2_S as PWM2, QDEC0_S as QDEC0,
PWM3_S as PWM3, QDEC1_S as QDEC1,
QDEC0_S as QDEC0, QSPI_S as QSPI,
QDEC1_S as QDEC1, REGULATORS_S as REGULATORS,
QSPI_S as QSPI, RESET_S as RESET,
REGULATORS_S as REGULATORS, RTC0_S as RTC0,
RESET_S as RESET, RTC1_S as RTC1,
RTC0_S as RTC0, SAADC_S as SAADC,
RTC1_S as RTC1, SPIM0_S as SPIM0,
SAADC_S as SAADC, SPIM1_S as SPIM1,
SPIM0_S as SPIM0, SPIM2_S as SPIM2,
SPIM1_S as SPIM1, SPIM3_S as SPIM3,
SPIM2_S as SPIM2, SPIM4_S as SPIM4,
SPIM3_S as SPIM3, SPIS0_S as SPIS0,
SPIM4_S as SPIM4, SPIS1_S as SPIS1,
SPIS0_S as SPIS0, SPIS2_S as SPIS2,
SPIS1_S as SPIS1, SPIS3_S as SPIS3,
SPIS2_S as SPIS2, SPU_S as SPU,
SPIS3_S as SPIS3, TAD_S as TAD,
SPU_S as SPU, TIMER0_S as TIMER0,
TAD_S as TAD, TIMER1_S as TIMER1,
TIMER0_S as TIMER0, TIMER2_S as TIMER2,
TIMER1_S as TIMER1, TWIM0_S as TWIM0,
TIMER2_S as TIMER2, TWIM1_S as TWIM1,
TWIM0_S as TWIM0, TWIM2_S as TWIM2,
TWIM1_S as TWIM1, TWIM3_S as TWIM3,
TWIM2_S as TWIM2, TWIS0_S as TWIS0,
TWIM3_S as TWIM3, TWIS1_S as TWIS1,
TWIS0_S as TWIS0, TWIS2_S as TWIS2,
TWIS1_S as TWIS1, TWIS3_S as TWIS3,
TWIS2_S as TWIS2, UARTE0_S as UARTE0,
TWIS3_S as TWIS3, UARTE1_S as UARTE1,
UARTE0_S as UARTE0, UARTE2_S as UARTE2,
UARTE1_S as UARTE1, UARTE3_S as UARTE3,
UARTE2_S as UARTE2, UICR_S as UICR,
UARTE3_S as UARTE3, USBD_S as USBD,
UICR_S as UICR, USBREGULATOR_S as USBREGULATOR,
USBD_S as USBD, VMC_S as VMC,
USBREGULATOR_S as USBREGULATOR, WDT0_S as WDT0,
VMC_S as VMC, WDT1_S as WDT1,
WDT0_S as WDT0, };
WDT1_S as WDT1,
};
}
#[cfg(feature = "_ns")]
pub use ns::*;
#[cfg(feature = "_s")]
pub use s::*;
} }
/// The maximum buffer size that the EasyDMA can send/recv in one operation. /// The maximum buffer size that the EasyDMA can send/recv in one operation.

View File

@ -7,12 +7,9 @@ pub mod pac {
pub use nrf5340_net_pac::NVIC_PRIO_BITS; pub use nrf5340_net_pac::NVIC_PRIO_BITS;
#[cfg(feature="rt")]
#[doc(no_inline)]
pub use nrf5340_net_pac::interrupt;
#[doc(no_inline)] #[doc(no_inline)]
pub use nrf5340_net_pac::{ pub use nrf5340_net_pac::{
interrupt,
Interrupt, Interrupt,
Peripherals, Peripherals,

View File

@ -7,12 +7,9 @@ pub mod pac {
pub use nrf9160_pac::NVIC_PRIO_BITS; pub use nrf9160_pac::NVIC_PRIO_BITS;
#[cfg(feature="rt")]
#[doc(no_inline)]
pub use nrf9160_pac::interrupt;
#[doc(no_inline)] #[doc(no_inline)]
pub use nrf9160_pac::{ pub use nrf9160_pac::{
interrupt,
Interrupt, Interrupt,
cc_host_rgf_s as cc_host_rgf, cc_host_rgf_s as cc_host_rgf,
@ -48,131 +45,122 @@ pub mod pac {
wdt_ns as wdt, wdt_ns as wdt,
}; };
/// Non-Secure mode (NS) peripherals #[cfg(feature = "nrf9160-ns")]
pub mod ns { #[doc(no_inline)]
#[doc(no_inline)] pub use nrf9160_pac::{
pub use nrf9160_pac::{ CLOCK_NS as CLOCK,
CLOCK_NS as CLOCK, DPPIC_NS as DPPIC,
DPPIC_NS as DPPIC, EGU0_NS as EGU0,
EGU0_NS as EGU0, EGU1_NS as EGU1,
EGU1_NS as EGU1, EGU2_NS as EGU2,
EGU2_NS as EGU2, EGU3_NS as EGU3,
EGU3_NS as EGU3, EGU4_NS as EGU4,
EGU4_NS as EGU4, EGU5_NS as EGU5,
EGU5_NS as EGU5, FPU_NS as FPU,
FPU_NS as FPU, GPIOTE1_NS as GPIOTE1,
GPIOTE1_NS as GPIOTE1, I2S_NS as I2S,
I2S_NS as I2S, IPC_NS as IPC,
IPC_NS as IPC, KMU_NS as KMU,
KMU_NS as KMU, NVMC_NS as NVMC,
NVMC_NS as NVMC, P0_NS as P0,
P0_NS as P0, PDM_NS as PDM,
PDM_NS as PDM, POWER_NS as POWER,
POWER_NS as POWER, PWM0_NS as PWM0,
PWM0_NS as PWM0, PWM1_NS as PWM1,
PWM1_NS as PWM1, PWM2_NS as PWM2,
PWM2_NS as PWM2, PWM3_NS as PWM3,
PWM3_NS as PWM3, REGULATORS_NS as REGULATORS,
REGULATORS_NS as REGULATORS, RTC0_NS as RTC0,
RTC0_NS as RTC0, RTC1_NS as RTC1,
RTC1_NS as RTC1, SAADC_NS as SAADC,
SAADC_NS as SAADC, SPIM0_NS as SPIM0,
SPIM0_NS as SPIM0, SPIM1_NS as SPIM1,
SPIM1_NS as SPIM1, SPIM2_NS as SPIM2,
SPIM2_NS as SPIM2, SPIM3_NS as SPIM3,
SPIM3_NS as SPIM3, SPIS0_NS as SPIS0,
SPIS0_NS as SPIS0, SPIS1_NS as SPIS1,
SPIS1_NS as SPIS1, SPIS2_NS as SPIS2,
SPIS2_NS as SPIS2, SPIS3_NS as SPIS3,
SPIS3_NS as SPIS3, TIMER0_NS as TIMER0,
TIMER0_NS as TIMER0, TIMER1_NS as TIMER1,
TIMER1_NS as TIMER1, TIMER2_NS as TIMER2,
TIMER2_NS as TIMER2, TWIM0_NS as TWIM0,
TWIM0_NS as TWIM0, TWIM1_NS as TWIM1,
TWIM1_NS as TWIM1, TWIM2_NS as TWIM2,
TWIM2_NS as TWIM2, TWIM3_NS as TWIM3,
TWIM3_NS as TWIM3, TWIS0_NS as TWIS0,
TWIS0_NS as TWIS0, TWIS1_NS as TWIS1,
TWIS1_NS as TWIS1, TWIS2_NS as TWIS2,
TWIS2_NS as TWIS2, TWIS3_NS as TWIS3,
TWIS3_NS as TWIS3, UARTE0_NS as UARTE0,
UARTE0_NS as UARTE0, UARTE1_NS as UARTE1,
UARTE1_NS as UARTE1, UARTE2_NS as UARTE2,
UARTE2_NS as UARTE2, UARTE3_NS as UARTE3,
UARTE3_NS as UARTE3, VMC_NS as VMC,
VMC_NS as VMC, WDT_NS as WDT,
WDT_NS as WDT, };
};
}
/// Secure mode (S) peripherals #[cfg(feature = "nrf9160-s")]
pub mod s { #[doc(no_inline)]
#[doc(no_inline)] pub use nrf9160_pac::{
pub use nrf9160_pac::{ CC_HOST_RGF_S as CC_HOST_RGF,
CC_HOST_RGF_S as CC_HOST_RGF, CLOCK_S as CLOCK,
CLOCK_S as CLOCK, CRYPTOCELL_S as CRYPTOCELL,
CRYPTOCELL_S as CRYPTOCELL, CTRL_AP_PERI_S as CTRL_AP_PERI,
CTRL_AP_PERI_S as CTRL_AP_PERI, DPPIC_S as DPPIC,
DPPIC_S as DPPIC, EGU0_S as EGU0,
EGU0_S as EGU0, EGU1_S as EGU1,
EGU1_S as EGU1, EGU2_S as EGU2,
EGU2_S as EGU2, EGU3_S as EGU3,
EGU3_S as EGU3, EGU4_S as EGU4,
EGU4_S as EGU4, EGU5_S as EGU5,
EGU5_S as EGU5, FICR_S as FICR,
FICR_S as FICR, FPU_S as FPU,
FPU_S as FPU, GPIOTE0_S as GPIOTE0,
GPIOTE0_S as GPIOTE0, I2S_S as I2S,
I2S_S as I2S, IPC_S as IPC,
IPC_S as IPC, KMU_S as KMU,
KMU_S as KMU, NVMC_S as NVMC,
NVMC_S as NVMC, P0_S as P0,
P0_S as P0, PDM_S as PDM,
PDM_S as PDM, POWER_S as POWER,
POWER_S as POWER, PWM0_S as PWM0,
PWM0_S as PWM0, PWM1_S as PWM1,
PWM1_S as PWM1, PWM2_S as PWM2,
PWM2_S as PWM2, PWM3_S as PWM3,
PWM3_S as PWM3, REGULATORS_S as REGULATORS,
REGULATORS_S as REGULATORS, RTC0_S as RTC0,
RTC0_S as RTC0, RTC1_S as RTC1,
RTC1_S as RTC1, SAADC_S as SAADC,
SAADC_S as SAADC, SPIM0_S as SPIM0,
SPIM0_S as SPIM0, SPIM1_S as SPIM1,
SPIM1_S as SPIM1, SPIM2_S as SPIM2,
SPIM2_S as SPIM2, SPIM3_S as SPIM3,
SPIM3_S as SPIM3, SPIS0_S as SPIS0,
SPIS0_S as SPIS0, SPIS1_S as SPIS1,
SPIS1_S as SPIS1, SPIS2_S as SPIS2,
SPIS2_S as SPIS2, SPIS3_S as SPIS3,
SPIS3_S as SPIS3, SPU_S as SPU,
SPU_S as SPU, TAD_S as TAD,
TAD_S as TAD, TIMER0_S as TIMER0,
TIMER0_S as TIMER0, TIMER1_S as TIMER1,
TIMER1_S as TIMER1, TIMER2_S as TIMER2,
TIMER2_S as TIMER2, TWIM0_S as TWIM0,
TWIM0_S as TWIM0, TWIM1_S as TWIM1,
TWIM1_S as TWIM1, TWIM2_S as TWIM2,
TWIM2_S as TWIM2, TWIM3_S as TWIM3,
TWIM3_S as TWIM3, TWIS0_S as TWIS0,
TWIS0_S as TWIS0, TWIS1_S as TWIS1,
TWIS1_S as TWIS1, TWIS2_S as TWIS2,
TWIS2_S as TWIS2, TWIS3_S as TWIS3,
TWIS3_S as TWIS3, UARTE0_S as UARTE0,
UARTE0_S as UARTE0, UARTE1_S as UARTE1,
UARTE1_S as UARTE1, UARTE2_S as UARTE2,
UARTE2_S as UARTE2, UARTE3_S as UARTE3,
UARTE3_S as UARTE3, UICR_S as UICR,
UICR_S as UICR, VMC_S as VMC,
VMC_S as VMC, WDT_S as WDT,
WDT_S as WDT, };
};
}
#[cfg(feature = "_ns")]
pub use ns::*;
#[cfg(feature = "_s")]
pub use s::*;
} }
/// The maximum buffer size that the EasyDMA can send/recv in one operation. /// The maximum buffer size that the EasyDMA can send/recv in one operation.

View File

@ -60,7 +60,7 @@ unstable-traits = ["embedded-hal-1", "embedded-hal-nb"]
[dependencies] [dependencies]
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } embassy-time = { version = "0.1.3", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }

View File

@ -5,7 +5,7 @@ use core::task::Poll;
use atomic_polyfill::{AtomicU8, Ordering}; use atomic_polyfill::{AtomicU8, Ordering};
use embassy_hal_internal::atomic_ring_buffer::RingBuffer; use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embassy_time::Timer; use embassy_time::{Duration, Timer};
use super::*; use super::*;
use crate::clocks::clk_peri_freq; use crate::clocks::clk_peri_freq;
@ -435,7 +435,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
Self::flush().await.unwrap(); Self::flush().await.unwrap();
while self.busy() {} while self.busy() {}
regs.uartlcr_h().write_set(|w| w.set_brk(true)); regs.uartlcr_h().write_set(|w| w.set_brk(true));
Timer::after_micros(wait_usecs).await; Timer::after(Duration::from_micros(wait_usecs)).await;
regs.uartlcr_h().write_clear(|w| w.set_brk(true)); regs.uartlcr_h().write_clear(|w| w.set_brk(true));
} }
} }

View File

@ -6,7 +6,7 @@ use atomic_polyfill::{AtomicU16, Ordering};
use embassy_futures::select::{select, Either}; use embassy_futures::select::{select, Either};
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embassy_time::Timer; use embassy_time::{Duration, Timer};
use pac::uart::regs::Uartris; use pac::uart::regs::Uartris;
use crate::clocks::clk_peri_freq; use crate::clocks::clk_peri_freq;
@ -187,7 +187,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
self.blocking_flush().unwrap(); self.blocking_flush().unwrap();
while self.busy() {} while self.busy() {}
regs.uartlcr_h().write_set(|w| w.set_brk(true)); regs.uartlcr_h().write_set(|w| w.set_brk(true));
Timer::after_micros(wait_usecs).await; Timer::after(Duration::from_micros(wait_usecs)).await;
regs.uartlcr_h().write_clear(|w| w.set_brk(true)); regs.uartlcr_h().write_clear(|w| w.set_brk(true));
} }
} }

View File

@ -13,11 +13,11 @@ features = ["stm32wb55rg"]
[dependencies] [dependencies]
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" } embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" }
embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver", optional=true } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true }
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
cortex-m = "0.7.6" cortex-m = "0.7.6"

View File

@ -33,11 +33,11 @@ flavors = [
[dependencies] [dependencies]
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
embassy-executor = { version = "0.3.0", path = "../embassy-executor", optional = true } embassy-executor = { version = "0.3.0", path = "../embassy-executor", optional = true }
@ -58,7 +58,7 @@ rand_core = "0.6.3"
sdio-host = "0.5.0" sdio-host = "0.5.0"
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
critical-section = "1.1" critical-section = "1.1"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c20cbde88fdfaef4645361d09df0cb63a4dc6462" } stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c" }
vcell = "0.1.3" vcell = "0.1.3"
bxcan = "0.7.0" bxcan = "0.7.0"
nb = "1.0.0" nb = "1.0.0"
@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] }
[build-dependencies] [build-dependencies]
proc-macro2 = "1.0.36" proc-macro2 = "1.0.36"
quote = "1.0.15" quote = "1.0.15"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c20cbde88fdfaef4645361d09df0cb63a4dc6462", default-features = false, features = ["metadata"]} stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c", default-features = false, features = ["metadata"]}
[features] [features]

View File

@ -5,7 +5,7 @@ use std::{env, fs};
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use stm32_metapac::metadata::ir::{BlockItemInner, Enum, FieldSet}; use stm32_metapac::metadata::ir::{BlockItemInner, Enum};
use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA}; use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA};
fn main() { fn main() {
@ -388,37 +388,41 @@ fn main() {
}); });
} }
// ========
// Extract the rcc registers
let rcc_registers = METADATA
.peripherals
.iter()
.filter_map(|p| p.registers.as_ref())
.find(|r| r.kind == "rcc")
.unwrap();
// ======== // ========
// Generate rcc fieldset and enum maps // Generate rcc fieldset and enum maps
let rcc_enum_map: HashMap<&str, HashMap<&str, &Enum>> = { let rcc_enum_map: HashMap<&str, HashMap<&str, &Enum>> = {
let rcc_blocks = rcc_registers.ir.blocks.iter().find(|b| b.name == "Rcc").unwrap().items; let rcc_registers = METADATA
let rcc_fieldsets: HashMap<&str, &FieldSet> = rcc_registers.ir.fieldsets.iter().map(|f| (f.name, f)).collect(); .peripherals
let rcc_enums: HashMap<&str, &Enum> = rcc_registers.ir.enums.iter().map(|e| (e.name, e)).collect(); .iter()
.filter_map(|p| p.registers.as_ref())
.find(|r| r.kind == "rcc")
.unwrap()
.ir;
rcc_blocks let rcc_blocks = rcc_registers.blocks.iter().find(|b| b.name == "Rcc").unwrap().items;
let rcc_block_item_map: HashMap<&str, &str> = rcc_blocks
.iter() .iter()
.filter_map(|b| match &b.inner { .filter_map(|b| match &b.inner {
BlockItemInner::Register(register) => register.fieldset.map(|f| (b.name, f)), BlockItemInner::Register(register) => register.fieldset.map(|f| (f, b.name)),
_ => None, _ => None,
}) })
.filter_map(|(b, f)| { .collect();
rcc_fieldsets.get(f).map(|f| {
let rcc_enum_map: HashMap<&str, &Enum> = rcc_registers.enums.iter().map(|e| (e.name, e)).collect();
rcc_registers
.fieldsets
.iter()
.filter_map(|f| {
rcc_block_item_map.get(f.name).map(|b| {
( (
b, *b,
f.fields f.fields
.iter() .iter()
.filter_map(|f| { .filter_map(|f| {
let enumm = f.enumm?; let enumm = f.enumm?;
let enumm = rcc_enums.get(enumm)?; let enumm = rcc_enum_map.get(enumm)?;
Some((f.name, *enumm)) Some((f.name, *enumm))
}) })
@ -448,8 +452,10 @@ fn main() {
let rst_reg = format_ident!("{}", rst.register.to_ascii_lowercase()); let rst_reg = format_ident!("{}", rst.register.to_ascii_lowercase());
let set_rst_field = format_ident!("set_{}", rst.field.to_ascii_lowercase()); let set_rst_field = format_ident!("set_{}", rst.field.to_ascii_lowercase());
quote! { quote! {
crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(true)); critical_section::with(|_| {
crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(false)); crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(true));
crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(false));
});
} }
} }
None => TokenStream::new(), None => TokenStream::new(),
@ -466,9 +472,9 @@ fn main() {
let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" }; let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" };
let pname = format_ident!("{}", p.name); let pname = format_ident!("{}", p.name);
let clk = format_ident!("{}", rcc.clock); let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase());
let en_reg = format_ident!("{}", en.register); let en_reg = format_ident!("{}", en.register.to_ascii_lowercase());
let set_en_field = format_ident!("set_{}", en.field); let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase());
let (before_enable, before_disable) = if refcounted_peripherals.contains(ptype) { let (before_enable, before_disable) = if refcounted_peripherals.contains(ptype) {
let refcount_static = let refcount_static =
@ -494,11 +500,9 @@ fn main() {
(TokenStream::new(), TokenStream::new()) (TokenStream::new(), TokenStream::new())
}; };
let mux_supported = HashSet::from(["c0", "h5", "h50", "h7", "h7ab", "h7rm0433", "g4", "l4"])
.contains(rcc_registers.version);
let mux_for = |mux: Option<&'static PeripheralRccRegister>| { let mux_for = |mux: Option<&'static PeripheralRccRegister>| {
// restrict mux implementation to supported versions // temporary hack to restrict the scope of the implementation to h5
if !mux_supported { if !&chip_name.starts_with("stm32h5") {
return None; return None;
} }
@ -521,16 +525,12 @@ fn main() {
.filter(|v| v.name != "DISABLE") .filter(|v| v.name != "DISABLE")
.map(|v| { .map(|v| {
let variant_name = format_ident!("{}", v.name); let variant_name = format_ident!("{}", v.name);
let clock_name = format_ident!("{}", v.name.to_ascii_lowercase());
if v.name.starts_with("HCLK") || v.name.starts_with("PCLK") || v.name == "SYS" { // temporary hack to restrict the scope of the implementation until clock names can be stabilized
quote! { let clock_name = format_ident!("mux_{}", v.name.to_ascii_lowercase());
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name },
} quote! {
} else { #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
quote! {
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
}
} }
}) })
.collect(); .collect();
@ -556,19 +556,25 @@ fn main() {
fn frequency() -> crate::time::Hertz { fn frequency() -> crate::time::Hertz {
#clock_frequency #clock_frequency
} }
fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { fn enable() {
#before_enable critical_section::with(|_cs| {
#[cfg(feature = "low-power")] #before_enable
crate::rcc::clock_refcount_add(_cs); #[cfg(feature = "low-power")]
crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); crate::rcc::clock_refcount_add(_cs);
#after_enable crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true));
#rst #after_enable
})
} }
fn disable_with_cs(_cs: critical_section::CriticalSection) { fn disable() {
#before_disable critical_section::with(|_cs| {
crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); #before_disable
#[cfg(feature = "low-power")] crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false));
crate::rcc::clock_refcount_sub(_cs); #[cfg(feature = "low-power")]
crate::rcc::clock_refcount_sub(_cs);
})
}
fn reset() {
#rst
} }
} }
@ -1014,7 +1020,15 @@ fn main() {
// ======== // ========
// Generate Div/Mul impls for RCC prescalers/dividers/multipliers. // Generate Div/Mul impls for RCC prescalers/dividers/multipliers.
for e in rcc_registers.ir.enums { let rcc_registers = METADATA
.peripherals
.iter()
.filter_map(|p| p.registers.as_ref())
.find(|r| r.kind == "rcc")
.unwrap()
.ir;
for e in rcc_registers.enums {
fn is_rcc_name(e: &str) -> bool { fn is_rcc_name(e: &str) -> bool {
match e { match e {
"Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true, "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true,

View File

@ -51,7 +51,8 @@ impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
into_ref!(adc); into_ref!(adc);
T::enable_and_reset(); T::enable();
T::reset();
T::regs().cr2().modify(|reg| reg.set_adon(true)); T::regs().cr2().modify(|reg| reg.set_adon(true));
// 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = 1) // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = 1)

View File

@ -64,7 +64,8 @@ impl<'d, T: Instance> Adc<'d, T> {
into_ref!(adc); into_ref!(adc);
T::enable_and_reset(); T::enable();
T::reset();
// Enable the adc regulator // Enable the adc regulator
T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE)); T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE));

View File

@ -74,9 +74,9 @@ pub(crate) mod sealed {
} }
} }
#[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_g0)))] #[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v4, adc_f3)))]
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {}
#[cfg(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_g0))] #[cfg(any(adc_f1, adc_v1, adc_v2, adc_v4, adc_f3))]
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {}
pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}

View File

@ -61,7 +61,8 @@ impl<'d, T: Instance> Adc<'d, T> {
delay: &mut impl DelayUs<u32>, delay: &mut impl DelayUs<u32>,
) -> Self { ) -> Self {
into_ref!(adc); into_ref!(adc);
T::enable_and_reset(); T::enable();
T::reset();
// Delay 1μs when using HSI14 as the ADC clock. // Delay 1μs when using HSI14 as the ADC clock.
// //

View File

@ -95,7 +95,8 @@ where
{ {
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
into_ref!(adc); into_ref!(adc);
T::enable_and_reset(); T::enable();
T::reset();
let presc = Prescaler::from_pclk2(T::frequency()); let presc = Prescaler::from_pclk2(T::frequency());
T::common_regs().ccr().modify(|w| w.set_adcpre(presc.adcpre())); T::common_regs().ccr().modify(|w| w.set_adcpre(presc.adcpre()));

View File

@ -9,6 +9,19 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
/// VREF voltage used for factory calibration of VREFINTCAL register. /// VREF voltage used for factory calibration of VREFINTCAL register.
pub const VREF_CALIB_MV: u32 = 3000; pub const VREF_CALIB_MV: u32 = 3000;
/// Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent ADC clock
/// configuration.
fn enable() {
critical_section::with(|_| {
#[cfg(any(stm32h7, stm32wl))]
crate::pac::RCC.apb2enr().modify(|w| w.set_adcen(true));
#[cfg(stm32g0)]
crate::pac::RCC.apbenr2().modify(|w| w.set_adcen(true));
#[cfg(any(stm32l4, stm32l5, stm32wb))]
crate::pac::RCC.ahb2enr().modify(|w| w.set_adcen(true));
});
}
pub struct VrefInt; pub struct VrefInt;
impl<T: Instance> AdcPin<T> for VrefInt {} impl<T: Instance> AdcPin<T> for VrefInt {}
impl<T: Instance> super::sealed::AdcPin<T> for VrefInt { impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
@ -48,7 +61,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Vbat {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
into_ref!(adc); into_ref!(adc);
T::enable_and_reset(); enable();
T::regs().cr().modify(|reg| { T::regs().cr().modify(|reg| {
#[cfg(not(adc_g0))] #[cfg(not(adc_g0))]
reg.set_deeppwd(false); reg.set_deeppwd(false);

View File

@ -127,7 +127,8 @@ impl Prescaler {
impl<'d, T: Instance> Adc<'d, T> { impl<'d, T: Instance> Adc<'d, T> {
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self { pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
embassy_hal_internal::into_ref!(adc); embassy_hal_internal::into_ref!(adc);
T::enable_and_reset(); T::enable();
T::reset();
let prescaler = Prescaler::from_ker_ck(T::frequency()); let prescaler = Prescaler::from_ker_ck(T::frequency());

View File

@ -136,7 +136,8 @@ impl<'d, T: Instance> Can<'d, T> {
rx.set_as_af(rx.af_num(), AFType::Input); rx.set_as_af(rx.af_num(), AFType::Input);
tx.set_as_af(tx.af_num(), AFType::OutputPushPull); tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
T::enable_and_reset(); T::enable();
T::reset();
{ {
use crate::pac::can::vals::{Errie, Fmpie, Tmeie}; use crate::pac::can::vals::{Errie, Fmpie, Tmeie};

View File

@ -16,7 +16,9 @@ impl<'d> Crc<'d> {
// Note: enable and reset come from RccPeripheral. // Note: enable and reset come from RccPeripheral.
// enable CRC clock in RCC. // enable CRC clock in RCC.
CRC::enable_and_reset(); CRC::enable();
// Reset CRC to default values.
CRC::reset();
// Peripheral the peripheral // Peripheral the peripheral
let mut instance = Self { _peri: peripheral }; let mut instance = Self { _peri: peripheral };
instance.reset(); instance.reset();

View File

@ -69,13 +69,16 @@ impl<'d> Crc<'d> {
/// Instantiates the CRC32 peripheral and initializes it to default values. /// Instantiates the CRC32 peripheral and initializes it to default values.
pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self { pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self {
// Note: enable and reset come from RccPeripheral. // Note: enable and reset come from RccPeripheral.
// reset to default values and enable CRC clock in RCC. // enable CRC clock in RCC.
CRC::enable_and_reset(); CRC::enable();
// Reset CRC to default values.
CRC::reset();
into_ref!(peripheral); into_ref!(peripheral);
let mut instance = Self { let mut instance = Self {
_peripheral: peripheral, _peripheral: peripheral,
_config: config, _config: config,
}; };
CRC::reset();
instance.reconfigure(); instance.reconfigure();
instance.reset(); instance.reset();
instance instance

View File

@ -255,7 +255,8 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> {
) -> Self { ) -> Self {
pin.set_as_analog(); pin.set_as_analog();
into_ref!(peri, dma); into_ref!(peri, dma);
T::enable_and_reset(); T::enable();
T::reset();
let mut dac = Self { _peri: peri, dma }; let mut dac = Self { _peri: peri, dma };
@ -365,7 +366,8 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> {
) -> Self { ) -> Self {
pin.set_as_analog(); pin.set_as_analog();
into_ref!(_peri, dma); into_ref!(_peri, dma);
T::enable_and_reset(); T::enable();
T::reset();
let mut dac = Self { let mut dac = Self {
phantom: PhantomData, phantom: PhantomData,
@ -481,7 +483,8 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> {
pin_ch1.set_as_analog(); pin_ch1.set_as_analog();
pin_ch2.set_as_analog(); pin_ch2.set_as_analog();
into_ref!(peri, dma_ch1, dma_ch2); into_ref!(peri, dma_ch1, dma_ch2);
T::enable_and_reset(); T::enable();
T::reset();
let mut dac_ch1 = DacCh1 { let mut dac_ch1 = DacCh1 {
_peri: peri, _peri: peri,
@ -560,26 +563,35 @@ pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {}
foreach_peripheral!( foreach_peripheral!(
(dac, $inst:ident) => { (dac, $inst:ident) => {
// H7 uses single bit for both DAC1 and DAC2, this is a hack until a proper fix is implemented // H7 uses single bit for both DAC1 and DAC2, this is a hack until a proper fix is implemented
#[cfg(any(rcc_h7, rcc_h7rm0433))] #[cfg(any(rcc_h7, rcc_h7rm0433))]
impl crate::rcc::sealed::RccPeripheral for peripherals::$inst { impl crate::rcc::sealed::RccPeripheral for peripherals::$inst {
fn frequency() -> crate::time::Hertz { fn frequency() -> crate::time::Hertz {
critical_section::with(|_| unsafe { crate::rcc::get_freqs().pclk1 }) critical_section::with(|_| unsafe { crate::rcc::get_freqs().apb1 })
} }
fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { fn reset() {
crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); critical_section::with(|_| {
crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true));
crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false));
} })
}
fn disable_with_cs(_cs: critical_section::CriticalSection) { fn enable() {
crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)) critical_section::with(|_| {
} crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true));
} })
}
#[cfg(any(rcc_h7, rcc_h7rm0433))] fn disable() {
impl crate::rcc::RccPeripheral for peripherals::$inst {} critical_section::with(|_| {
crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false))
})
}
}
#[cfg(any(rcc_h7, rcc_h7rm0433))]
impl crate::rcc::RccPeripheral for peripherals::$inst {}
impl crate::dac::sealed::Instance for peripherals::$inst { impl crate::dac::sealed::Instance for peripherals::$inst {
fn regs() -> &'static crate::pac::dac::Dac { fn regs() -> &'static crate::pac::dac::Dac {

View File

@ -330,7 +330,8 @@ where
use_embedded_synchronization: bool, use_embedded_synchronization: bool,
edm: u8, edm: u8,
) -> Self { ) -> Self {
T::enable_and_reset(); T::reset();
T::enable();
peri.regs().cr().modify(|r| { peri.regs().cr().modify(|r| {
r.set_cm(true); // disable continuous mode (snapshot mode) r.set_cm(true); // disable continuous mode (snapshot mode)

View File

@ -77,10 +77,10 @@ impl State {
static STATE: State = State::new(); static STATE: State = State::new();
/// safety: must be called only once /// safety: must be called only once
pub(crate) unsafe fn init(cs: critical_section::CriticalSection, irq_priority: Priority) { pub(crate) unsafe fn init(irq_priority: Priority) {
foreach_interrupt! { foreach_interrupt! {
($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => { ($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => {
crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, irq_priority); crate::interrupt::typelevel::$irq::set_priority(irq_priority);
crate::interrupt::typelevel::$irq::enable(); crate::interrupt::typelevel::$irq::enable();
}; };
} }

View File

@ -154,10 +154,10 @@ impl State {
static STATE: State = State::new(); static STATE: State = State::new();
/// safety: must be called only once /// safety: must be called only once
pub(crate) unsafe fn init(cs: critical_section::CriticalSection, irq_priority: Priority) { pub(crate) unsafe fn init(irq_priority: Priority) {
foreach_interrupt! { foreach_interrupt! {
($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => { ($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => {
interrupt::typelevel::$irq::set_priority_with_cs(cs, irq_priority); interrupt::typelevel::$irq::set_priority(irq_priority);
interrupt::typelevel::$irq::enable(); interrupt::typelevel::$irq::enable();
}; };
} }

View File

@ -47,6 +47,6 @@ foreach_dma_channel! {
} }
/// safety: must be called only once /// safety: must be called only once
pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) { pub(crate) unsafe fn init() {
crate::_generated::init_dmamux(); crate::_generated::init_dmamux();
} }

View File

@ -53,10 +53,10 @@ impl State {
static STATE: State = State::new(); static STATE: State = State::new();
/// safety: must be called only once /// safety: must be called only once
pub(crate) unsafe fn init(cs: critical_section::CriticalSection, irq_priority: Priority) { pub(crate) unsafe fn init(irq_priority: Priority) {
foreach_interrupt! { foreach_interrupt! {
($peri:ident, gpdma, $block:ident, $signal_name:ident, $irq:ident) => { ($peri:ident, gpdma, $block:ident, $signal_name:ident, $irq:ident) => {
crate::interrupt::typelevel::$irq::set_priority_with_cs(cs, irq_priority); crate::interrupt::typelevel::$irq::set_priority(irq_priority);
crate::interrupt::typelevel::$irq::enable(); crate::interrupt::typelevel::$irq::enable();
}; };
} }

View File

@ -56,17 +56,16 @@ pub(crate) fn slice_ptr_parts_mut<T>(slice: *mut [T]) -> (usize, usize) {
// safety: must be called only once at startup // safety: must be called only once at startup
pub(crate) unsafe fn init( pub(crate) unsafe fn init(
cs: critical_section::CriticalSection,
#[cfg(bdma)] bdma_priority: Priority, #[cfg(bdma)] bdma_priority: Priority,
#[cfg(dma)] dma_priority: Priority, #[cfg(dma)] dma_priority: Priority,
#[cfg(gpdma)] gpdma_priority: Priority, #[cfg(gpdma)] gpdma_priority: Priority,
) { ) {
#[cfg(bdma)] #[cfg(bdma)]
bdma::init(cs, bdma_priority); bdma::init(bdma_priority);
#[cfg(dma)] #[cfg(dma)]
dma::init(cs, dma_priority); dma::init(dma_priority);
#[cfg(gpdma)] #[cfg(gpdma)]
gpdma::init(cs, gpdma_priority); gpdma::init(gpdma_priority);
#[cfg(dmamux)] #[cfg(dmamux)]
dmamux::init(cs); dmamux::init();
} }

View File

@ -191,7 +191,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
// TODO MTU size setting not found for v1 ethernet, check if correct // TODO MTU size setting not found for v1 ethernet, check if correct
// NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called // NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called
let hclk = unsafe { crate::rcc::get_freqs() }.hclk1; let hclk = unsafe { crate::rcc::get_freqs() }.ahb1;
let hclk_mhz = hclk.0 / 1_000_000; let hclk_mhz = hclk.0 / 1_000_000;
// Set the MDC clock frequency in the range 1MHz - 2.5MHz // Set the MDC clock frequency in the range 1MHz - 2.5MHz

View File

@ -164,7 +164,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
}); });
// NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called // NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called
let hclk = unsafe { crate::rcc::get_freqs() }.hclk1; let hclk = unsafe { crate::rcc::get_freqs() }.ahb1;
let hclk_mhz = hclk.0 / 1_000_000; let hclk_mhz = hclk.0 / 1_000_000;
// Set the MDC clock frequency in the range 1MHz - 2.5MHz // Set the MDC clock frequency in the range 1MHz - 2.5MHz

View File

@ -367,7 +367,7 @@ macro_rules! enable_irq {
} }
/// safety: must be called only once /// safety: must be called only once
pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) { pub(crate) unsafe fn init() {
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
foreach_exti_irq!(enable_irq); foreach_exti_irq!(enable_irq);

View File

@ -19,7 +19,8 @@ where
const REGISTERS: *const () = T::REGS.as_ptr() as *const _; const REGISTERS: *const () = T::REGS.as_ptr() as *const _;
fn enable(&mut self) { fn enable(&mut self) {
T::enable_and_reset(); <T as crate::rcc::sealed::RccPeripheral>::enable();
<T as crate::rcc::sealed::RccPeripheral>::reset();
} }
fn memory_controller_enable(&mut self) { fn memory_controller_enable(&mut self) {

View File

@ -1,7 +1,6 @@
#![macro_use] #![macro_use]
use core::convert::Infallible; use core::convert::Infallible;
use critical_section::CriticalSection;
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
use crate::pac::gpio::{self, vals}; use crate::pac::gpio::{self, vals};
@ -758,9 +757,9 @@ foreach_pin!(
}; };
); );
pub(crate) unsafe fn init(_cs: CriticalSection) { pub(crate) unsafe fn init() {
#[cfg(afio)] #[cfg(afio)]
<crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(_cs); <crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable();
crate::_generated::init_gpio(); crate::_generated::init_gpio();
} }

View File

@ -157,7 +157,8 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> {
fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self { fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self {
into_ref!(tim); into_ref!(tim);
T::enable_and_reset(); T::enable();
<T as crate::rcc::sealed::RccPeripheral>::reset();
#[cfg(stm32f334)] #[cfg(stm32f334)]
if unsafe { get_freqs() }.hrtim.is_some() { if unsafe { get_freqs() }.hrtim.is_some() {

View File

@ -7,6 +7,11 @@ use crate::interrupt;
mod _version; mod _version;
pub use _version::*; pub use _version::*;
#[cfg(feature = "time")]
mod timeout;
#[cfg(feature = "time")]
pub use timeout::*;
use crate::peripherals; use crate::peripherals;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]

View File

@ -0,0 +1,209 @@
use embassy_time::{Duration, Instant};
use super::{Error, I2c, Instance};
/// An I2C wrapper, which provides `embassy-time` based timeouts for all `embedded-hal` trait methods.
///
/// This is useful for recovering from a shorted bus or a device stuck in a clock stretching state.
/// A regular [I2c] would freeze until condition is removed.
pub struct TimeoutI2c<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> {
i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>,
timeout: Duration,
}
fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> {
let deadline = Instant::now() + timeout;
move || {
if Instant::now() > deadline {
Err(Error::Timeout)
} else {
Ok(())
}
}
}
impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
pub fn new(i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self {
Self { i2c, timeout }
}
// =========================
// Async public API
#[cfg(i2c_v2)]
pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error>
where
TXDMA: crate::i2c::TxDma<T>,
{
self.write_timeout(address, write, self.timeout).await
}
#[cfg(i2c_v2)]
pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error>
where
TXDMA: crate::i2c::TxDma<T>,
{
self.i2c.write_timeout(address, write, timeout_fn(timeout)).await
}
#[cfg(i2c_v2)]
pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error>
where
TXDMA: crate::i2c::TxDma<T>,
{
self.write_vectored_timeout(address, write, self.timeout).await
}
#[cfg(i2c_v2)]
pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error>
where
TXDMA: crate::i2c::TxDma<T>,
{
self.i2c
.write_vectored_timeout(address, write, timeout_fn(timeout))
.await
}
#[cfg(i2c_v2)]
pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error>
where
RXDMA: crate::i2c::RxDma<T>,
{
self.read_timeout(address, buffer, self.timeout).await
}
#[cfg(i2c_v2)]
pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error>
where
RXDMA: crate::i2c::RxDma<T>,
{
self.i2c.read_timeout(address, buffer, timeout_fn(timeout)).await
}
#[cfg(i2c_v2)]
pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error>
where
TXDMA: super::TxDma<T>,
RXDMA: super::RxDma<T>,
{
self.write_read_timeout(address, write, read, self.timeout).await
}
#[cfg(i2c_v2)]
pub async fn write_read_timeout(
&mut self,
address: u8,
write: &[u8],
read: &mut [u8],
timeout: Duration,
) -> Result<(), Error>
where
TXDMA: super::TxDma<T>,
RXDMA: super::RxDma<T>,
{
self.i2c
.write_read_timeout(address, write, read, timeout_fn(timeout))
.await
}
// =========================
// Blocking public API
/// Blocking read with a custom timeout
pub fn blocking_read_timeout(&mut self, addr: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> {
self.i2c.blocking_read_timeout(addr, read, timeout_fn(timeout))
}
/// Blocking read with default timeout, provided in [`TimeoutI2c::new()`]
pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> {
self.blocking_read_timeout(addr, read, self.timeout)
}
/// Blocking write with a custom timeout
pub fn blocking_write_timeout(&mut self, addr: u8, write: &[u8], timeout: Duration) -> Result<(), Error> {
self.i2c.blocking_write_timeout(addr, write, timeout_fn(timeout))
}
/// Blocking write with default timeout, provided in [`TimeoutI2c::new()`]
pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> {
self.blocking_write_timeout(addr, write, self.timeout)
}
/// Blocking write-read with a custom timeout
pub fn blocking_write_read_timeout(
&mut self,
addr: u8,
write: &[u8],
read: &mut [u8],
timeout: Duration,
) -> Result<(), Error> {
self.i2c
.blocking_write_read_timeout(addr, write, read, timeout_fn(timeout))
}
/// Blocking write-read with default timeout, provided in [`TimeoutI2c::new()`]
pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
self.blocking_write_read_timeout(addr, write, read, self.timeout)
}
}
impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read
for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
{
type Error = Error;
fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_read(addr, read)
}
}
impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write
for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
{
type Error = Error;
fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> {
self.blocking_write(addr, write)
}
}
impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead
for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
{
type Error = Error;
fn write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_write_read(addr, write, read)
}
}
#[cfg(feature = "unstable-traits")]
mod eh1 {
use super::*;
impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
type Error = Error;
}
impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_read(address, read)
}
fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
self.blocking_write(address, write)
}
fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_write_read(address, write, read)
}
fn transaction(
&mut self,
_address: u8,
_operations: &mut [embedded_hal_1::i2c::Operation<'_>],
) -> Result<(), Self::Error> {
todo!();
}
}
}

View File

@ -56,7 +56,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
) -> Self { ) -> Self {
into_ref!(scl, sda, tx_dma, rx_dma); into_ref!(scl, sda, tx_dma, rx_dma);
T::enable_and_reset(); T::enable();
T::reset();
scl.set_as_af_pull( scl.set_as_af_pull(
scl.af_num(), scl.af_num(),

View File

@ -1,21 +1,14 @@
use core::cmp; use core::cmp;
#[cfg(feature = "time")]
use core::future::poll_fn; use core::future::poll_fn;
use core::marker::PhantomData; use core::marker::PhantomData;
#[cfg(feature = "time")]
use core::task::Poll; use core::task::Poll;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
#[cfg(feature = "time")]
use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
#[cfg(feature = "time")]
use embassy_time::{Duration, Instant};
use crate::dma::NoDma; use crate::dma::{NoDma, Transfer};
#[cfg(feature = "time")]
use crate::dma::Transfer;
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::gpio::Pull; use crate::gpio::Pull;
use crate::i2c::{Error, Instance, SclPin, SdaPin}; use crate::i2c::{Error, Instance, SclPin, SdaPin};
@ -50,8 +43,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
pub struct Config { pub struct Config {
pub sda_pullup: bool, pub sda_pullup: bool,
pub scl_pullup: bool, pub scl_pullup: bool,
#[cfg(feature = "time")]
pub transaction_timeout: Duration,
} }
impl Default for Config { impl Default for Config {
@ -59,8 +50,6 @@ impl Default for Config {
Self { Self {
sda_pullup: false, sda_pullup: false,
scl_pullup: false, scl_pullup: false,
#[cfg(feature = "time")]
transaction_timeout: Duration::from_millis(100),
} }
} }
} }
@ -79,12 +68,9 @@ impl State {
pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> {
_peri: PeripheralRef<'d, T>, _peri: PeripheralRef<'d, T>,
#[allow(dead_code)]
tx_dma: PeripheralRef<'d, TXDMA>, tx_dma: PeripheralRef<'d, TXDMA>,
#[allow(dead_code)] #[allow(dead_code)]
rx_dma: PeripheralRef<'d, RXDMA>, rx_dma: PeripheralRef<'d, RXDMA>,
#[cfg(feature = "time")]
timeout: Duration,
} }
impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
@ -100,7 +86,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
) -> Self { ) -> Self {
into_ref!(peri, scl, sda, tx_dma, rx_dma); into_ref!(peri, scl, sda, tx_dma, rx_dma);
T::enable_and_reset(); T::enable();
T::reset();
scl.set_as_af_pull( scl.set_as_af_pull(
scl.af_num(), scl.af_num(),
@ -145,8 +132,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
_peri: peri, _peri: peri,
tx_dma, tx_dma,
rx_dma, rx_dma,
#[cfg(feature = "time")]
timeout: config.transaction_timeout,
} }
} }
@ -437,7 +422,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
result result
} }
#[cfg(feature = "time")]
async fn write_dma_internal( async fn write_dma_internal(
&mut self, &mut self,
address: u8, address: u8,
@ -528,7 +512,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
Ok(()) Ok(())
} }
#[cfg(feature = "time")]
async fn read_dma_internal( async fn read_dma_internal(
&mut self, &mut self,
address: u8, address: u8,
@ -611,41 +594,42 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
// ========================= // =========================
// Async public API // Async public API
#[cfg(feature = "time")]
pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error>
where where
TXDMA: crate::i2c::TxDma<T>, TXDMA: crate::i2c::TxDma<T>,
{ {
self.write_timeout(address, write, self.timeout).await self.write_timeout(address, write, || Ok(())).await
} }
#[cfg(feature = "time")] pub async fn write_timeout(
pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> &mut self,
address: u8,
write: &[u8],
check_timeout: impl Fn() -> Result<(), Error>,
) -> Result<(), Error>
where where
TXDMA: crate::i2c::TxDma<T>, TXDMA: crate::i2c::TxDma<T>,
{ {
if write.is_empty() { if write.is_empty() {
self.write_internal(address, write, true, timeout_fn(timeout)) self.write_internal(address, write, true, check_timeout)
} else { } else {
embassy_time::with_timeout( self.write_dma_internal(address, write, true, true, check_timeout).await
timeout,
self.write_dma_internal(address, write, true, true, timeout_fn(timeout)),
)
.await
.unwrap_or(Err(Error::Timeout))
} }
} }
#[cfg(feature = "time")]
pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error>
where where
TXDMA: crate::i2c::TxDma<T>, TXDMA: crate::i2c::TxDma<T>,
{ {
self.write_vectored_timeout(address, write, self.timeout).await self.write_vectored_timeout(address, write, || Ok(())).await
} }
#[cfg(feature = "time")] pub async fn write_vectored_timeout(
pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error> &mut self,
address: u8,
write: &[&[u8]],
check_timeout: impl Fn() -> Result<(), Error>,
) -> Result<(), Error>
where where
TXDMA: crate::i2c::TxDma<T>, TXDMA: crate::i2c::TxDma<T>,
{ {
@ -660,88 +644,67 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
let next = iter.next(); let next = iter.next();
let is_last = next.is_none(); let is_last = next.is_none();
embassy_time::with_timeout( self.write_dma_internal(address, c, first, is_last, || check_timeout())
timeout, .await?;
self.write_dma_internal(address, c, first, is_last, timeout_fn(timeout)),
)
.await
.unwrap_or(Err(Error::Timeout))?;
first = false; first = false;
current = next; current = next;
} }
Ok(()) Ok(())
} }
#[cfg(feature = "time")]
pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error>
where where
RXDMA: crate::i2c::RxDma<T>, RXDMA: crate::i2c::RxDma<T>,
{ {
self.read_timeout(address, buffer, self.timeout).await self.read_timeout(address, buffer, || Ok(())).await
} }
#[cfg(feature = "time")] pub async fn read_timeout(
pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> &mut self,
address: u8,
buffer: &mut [u8],
check_timeout: impl Fn() -> Result<(), Error>,
) -> Result<(), Error>
where where
RXDMA: crate::i2c::RxDma<T>, RXDMA: crate::i2c::RxDma<T>,
{ {
if buffer.is_empty() { if buffer.is_empty() {
self.read_internal(address, buffer, false, timeout_fn(timeout)) self.read_internal(address, buffer, false, check_timeout)
} else { } else {
embassy_time::with_timeout( self.read_dma_internal(address, buffer, false, check_timeout).await
timeout,
self.read_dma_internal(address, buffer, false, timeout_fn(timeout)),
)
.await
.unwrap_or(Err(Error::Timeout))
} }
} }
#[cfg(feature = "time")]
pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error>
where where
TXDMA: super::TxDma<T>, TXDMA: super::TxDma<T>,
RXDMA: super::RxDma<T>, RXDMA: super::RxDma<T>,
{ {
self.write_read_timeout(address, write, read, self.timeout).await self.write_read_timeout(address, write, read, || Ok(())).await
} }
#[cfg(feature = "time")]
pub async fn write_read_timeout( pub async fn write_read_timeout(
&mut self, &mut self,
address: u8, address: u8,
write: &[u8], write: &[u8],
read: &mut [u8], read: &mut [u8],
timeout: Duration, check_timeout: impl Fn() -> Result<(), Error>,
) -> Result<(), Error> ) -> Result<(), Error>
where where
TXDMA: super::TxDma<T>, TXDMA: super::TxDma<T>,
RXDMA: super::RxDma<T>, RXDMA: super::RxDma<T>,
{ {
let start_instant = Instant::now();
let check_timeout = timeout_fn(timeout);
if write.is_empty() { if write.is_empty() {
self.write_internal(address, write, false, &check_timeout)?; self.write_internal(address, write, false, || check_timeout())?;
} else { } else {
embassy_time::with_timeout( self.write_dma_internal(address, write, true, true, || check_timeout())
timeout, .await?;
self.write_dma_internal(address, write, true, true, &check_timeout),
)
.await
.unwrap_or(Err(Error::Timeout))?;
} }
let time_left_until_timeout = timeout - Instant::now().duration_since(start_instant);
if read.is_empty() { if read.is_empty() {
self.read_internal(address, read, true, &check_timeout)?; self.read_internal(address, read, true, check_timeout)?;
} else { } else {
embassy_time::with_timeout( self.read_dma_internal(address, read, true, check_timeout).await?;
time_left_until_timeout,
self.read_dma_internal(address, read, true, &check_timeout),
)
.await
.unwrap_or(Err(Error::Timeout))?;
} }
Ok(()) Ok(())
@ -750,73 +713,33 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
// ========================= // =========================
// Blocking public API // Blocking public API
#[cfg(feature = "time")]
pub fn blocking_read_timeout(&mut self, address: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> {
self.read_internal(address, read, false, timeout_fn(timeout))
// Automatic Stop
}
#[cfg(not(feature = "time"))]
pub fn blocking_read_timeout( pub fn blocking_read_timeout(
&mut self, &mut self,
address: u8, address: u8,
read: &mut [u8], read: &mut [u8],
check_timeout: impl Fn() -> Result<(), Error>, check_timeout: impl Fn() -> Result<(), Error>,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.read_internal(address, read, false, check_timeout) self.read_internal(address, read, false, &check_timeout)
// Automatic Stop // Automatic Stop
} }
#[cfg(feature = "time")]
pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
self.blocking_read_timeout(address, read, self.timeout)
}
#[cfg(not(feature = "time"))]
pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
self.blocking_read_timeout(address, read, || Ok(())) self.blocking_read_timeout(address, read, || Ok(()))
} }
#[cfg(feature = "time")]
pub fn blocking_write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error> {
self.write_internal(address, write, true, timeout_fn(timeout))
}
#[cfg(not(feature = "time"))]
pub fn blocking_write_timeout( pub fn blocking_write_timeout(
&mut self, &mut self,
address: u8, address: u8,
write: &[u8], write: &[u8],
check_timeout: impl Fn() -> Result<(), Error>, check_timeout: impl Fn() -> Result<(), Error>,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.write_internal(address, write, true, check_timeout) self.write_internal(address, write, true, &check_timeout)
} }
#[cfg(feature = "time")]
pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
self.blocking_write_timeout(address, write, self.timeout)
}
#[cfg(not(feature = "time"))]
pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
self.blocking_write_timeout(address, write, || Ok(())) self.blocking_write_timeout(address, write, || Ok(()))
} }
#[cfg(feature = "time")]
pub fn blocking_write_read_timeout(
&mut self,
address: u8,
write: &[u8],
read: &mut [u8],
timeout: Duration,
) -> Result<(), Error> {
let check_timeout = timeout_fn(timeout);
self.write_internal(address, write, false, &check_timeout)?;
self.read_internal(address, read, true, &check_timeout)
// Automatic Stop
}
#[cfg(not(feature = "time"))]
pub fn blocking_write_read_timeout( pub fn blocking_write_read_timeout(
&mut self, &mut self,
address: u8, address: u8,
@ -829,17 +752,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
// Automatic Stop // Automatic Stop
} }
#[cfg(feature = "time")]
pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
self.blocking_write_read_timeout(address, write, read, self.timeout)
}
#[cfg(not(feature = "time"))]
pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
self.blocking_write_read_timeout(address, write, read, || Ok(())) self.blocking_write_read_timeout(address, write, read, || Ok(()))
} }
fn blocking_write_vectored_with_timeout( pub fn blocking_write_vectored_timeout(
&mut self, &mut self,
address: u8, address: u8,
write: &[&[u8]], write: &[&[u8]],
@ -848,7 +765,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
if write.is_empty() { if write.is_empty() {
return Err(Error::ZeroLengthTransfer); return Err(Error::ZeroLengthTransfer);
} }
let first_length = write[0].len(); let first_length = write[0].len();
let last_slice_index = write.len() - 1; let last_slice_index = write.len() - 1;
@ -917,33 +833,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
result result
} }
#[cfg(feature = "time")]
pub fn blocking_write_vectored_timeout(
&mut self,
address: u8,
write: &[&[u8]],
timeout: Duration,
) -> Result<(), Error> {
let check_timeout = timeout_fn(timeout);
self.blocking_write_vectored_with_timeout(address, write, check_timeout)
}
#[cfg(not(feature = "time"))]
pub fn blocking_write_vectored_timeout(
&mut self,
address: u8,
write: &[&[u8]],
check_timeout: impl Fn() -> Result<(), Error>,
) -> Result<(), Error> {
self.blocking_write_vectored_with_timeout(address, write, check_timeout)
}
#[cfg(feature = "time")]
pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
self.blocking_write_vectored_timeout(address, write, self.timeout)
}
#[cfg(not(feature = "time"))]
pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
self.blocking_write_vectored_timeout(address, write, || Ok(())) self.blocking_write_vectored_timeout(address, write, || Ok(()))
} }
@ -955,7 +844,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> {
} }
} }
#[cfg(feature = "time")]
mod eh02 { mod eh02 {
use super::*; use super::*;
@ -1155,7 +1043,7 @@ mod eh1 {
} }
} }
#[cfg(all(feature = "unstable-traits", feature = "nightly", feature = "time"))] #[cfg(all(feature = "unstable-traits", feature = "nightly"))]
mod eha { mod eha {
use super::super::{RxDma, TxDma}; use super::super::{RxDma, TxDma};
use super::*; use super::*;
@ -1201,15 +1089,3 @@ impl<'d, T: Instance> SetConfig for I2c<'d, T> {
Ok(()) Ok(())
} }
} }
#[cfg(feature = "time")]
fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> {
let deadline = Instant::now() + timeout;
move || {
if Instant::now() > deadline {
Err(Error::Timeout)
} else {
Ok(())
}
}
}

View File

@ -170,7 +170,7 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> {
let spi = Spi::new_internal(peri, txdma, rxdma, spi_cfg); let spi = Spi::new_internal(peri, txdma, rxdma, spi_cfg);
#[cfg(all(rcc_f4, not(stm32f410)))] #[cfg(all(rcc_f4, not(stm32f410)))]
let pclk = unsafe { get_freqs() }.plli2s1_q.unwrap(); let pclk = unsafe { get_freqs() }.plli2s.unwrap();
#[cfg(stm32f410)] #[cfg(stm32f410)]
let pclk = T::frequency(); let pclk = T::frequency();

View File

@ -93,7 +93,8 @@ pub struct Ipcc;
impl Ipcc { impl Ipcc {
pub fn enable(_config: Config) { pub fn enable(_config: Config) {
IPCC::enable_and_reset(); IPCC::enable();
IPCC::reset();
IPCC::set_cpu2(true); IPCC::set_cpu2(true);
_configure_pwr(); _configure_pwr();

View File

@ -155,82 +155,81 @@ impl Default for Config {
/// Initialize embassy. /// Initialize embassy.
pub fn init(config: Config) -> Peripherals { pub fn init(config: Config) -> Peripherals {
critical_section::with(|cs| { let p = Peripherals::take();
let p = Peripherals::take_with_cs(cs);
#[cfg(dbgmcu)] #[cfg(dbgmcu)]
if config.enable_debug_during_sleep { if config.enable_debug_during_sleep {
crate::pac::DBGMCU.cr().modify(|cr| { crate::pac::DBGMCU.cr().modify(|cr| {
#[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba))] #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba))]
{ {
cr.set_dbg_stop(true); cr.set_dbg_stop(true);
cr.set_dbg_standby(true); cr.set_dbg_standby(true);
}
#[cfg(any(
dbgmcu_f1, dbgmcu_f2, dbgmcu_f3, dbgmcu_f4, dbgmcu_f7, dbgmcu_g4, dbgmcu_f7, dbgmcu_l0, dbgmcu_l1,
dbgmcu_l4, dbgmcu_wb, dbgmcu_wl
))]
{
cr.set_dbg_sleep(true);
cr.set_dbg_stop(true);
cr.set_dbg_standby(true);
}
#[cfg(dbgmcu_h7)]
{
cr.set_d1dbgcken(true);
cr.set_d3dbgcken(true);
cr.set_dbgsleep_d1(true);
cr.set_dbgstby_d1(true);
cr.set_dbgstop_d1(true);
}
});
}
#[cfg(not(any(stm32f1, stm32wb, stm32wl)))]
peripherals::SYSCFG::enable_and_reset_with_cs(cs);
#[cfg(not(any(stm32h5, stm32h7, stm32wb, stm32wl)))]
peripherals::PWR::enable_and_reset_with_cs(cs);
#[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7)))]
peripherals::FLASH::enable_and_reset_with_cs(cs);
unsafe {
#[cfg(feature = "_split-pins-enabled")]
crate::pac::SYSCFG.pmcr().modify(|pmcr| {
#[cfg(feature = "split-pa0")]
pmcr.set_pa0so(true);
#[cfg(feature = "split-pa1")]
pmcr.set_pa1so(true);
#[cfg(feature = "split-pc2")]
pmcr.set_pc2so(true);
#[cfg(feature = "split-pc3")]
pmcr.set_pc3so(true);
});
gpio::init(cs);
dma::init(
cs,
#[cfg(bdma)]
config.bdma_interrupt_priority,
#[cfg(dma)]
config.dma_interrupt_priority,
#[cfg(gpdma)]
config.gpdma_interrupt_priority,
);
#[cfg(feature = "exti")]
exti::init(cs);
rcc::init(config.rcc);
// must be after rcc init
#[cfg(feature = "_time-driver")]
time_driver::init(cs);
#[cfg(feature = "low-power")]
while !crate::rcc::low_power_ready() {
crate::rcc::clock_refcount_sub(cs);
} }
} #[cfg(any(
dbgmcu_f1, dbgmcu_f2, dbgmcu_f3, dbgmcu_f4, dbgmcu_f7, dbgmcu_g4, dbgmcu_f7, dbgmcu_l0, dbgmcu_l1,
dbgmcu_l4, dbgmcu_wb, dbgmcu_wl
))]
{
cr.set_dbg_sleep(true);
cr.set_dbg_stop(true);
cr.set_dbg_standby(true);
}
#[cfg(dbgmcu_h7)]
{
cr.set_d1dbgcken(true);
cr.set_d3dbgcken(true);
cr.set_dbgsleep_d1(true);
cr.set_dbgstby_d1(true);
cr.set_dbgstop_d1(true);
}
});
}
p #[cfg(not(any(stm32f1, stm32wb, stm32wl)))]
}) peripherals::SYSCFG::enable();
#[cfg(not(any(stm32h5, stm32h7, stm32wb, stm32wl)))]
peripherals::PWR::enable();
#[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7)))]
peripherals::FLASH::enable();
unsafe {
#[cfg(feature = "_split-pins-enabled")]
crate::pac::SYSCFG.pmcr().modify(|pmcr| {
#[cfg(feature = "split-pa0")]
pmcr.set_pa0so(true);
#[cfg(feature = "split-pa1")]
pmcr.set_pa1so(true);
#[cfg(feature = "split-pc2")]
pmcr.set_pc2so(true);
#[cfg(feature = "split-pc3")]
pmcr.set_pc3so(true);
});
gpio::init();
dma::init(
#[cfg(bdma)]
config.bdma_interrupt_priority,
#[cfg(dma)]
config.dma_interrupt_priority,
#[cfg(gpdma)]
config.gpdma_interrupt_priority,
);
#[cfg(feature = "exti")]
exti::init();
rcc::init(config.rcc);
// must be after rcc init
#[cfg(feature = "_time-driver")]
time_driver::init();
#[cfg(feature = "low-power")]
while !crate::rcc::low_power_ready() {
critical_section::with(|cs| {
crate::rcc::clock_refcount_sub(cs);
});
}
}
p
} }

View File

@ -177,7 +177,8 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
) -> Self { ) -> Self {
into_ref!(peri, dma); into_ref!(peri, dma);
T::enable_and_reset(); T::enable();
T::reset();
while T::REGS.sr().read().busy() {} while T::REGS.sr().read().busy() {}

View File

@ -106,7 +106,7 @@ impl LsConfig {
pub const fn off() -> Self { pub const fn off() -> Self {
Self { Self {
rtc: RtcClockSource::DISABLE, rtc: RtcClockSource::NOCLOCK,
lsi: false, lsi: false,
lse: None, lse: None,
} }
@ -133,7 +133,7 @@ impl LsConfig {
Some(LSI_FREQ) Some(LSI_FREQ)
} }
RtcClockSource::LSE => Some(self.lse.as_ref().unwrap().frequency), RtcClockSource::LSE => Some(self.lse.as_ref().unwrap().frequency),
RtcClockSource::DISABLE => None, RtcClockSource::NOCLOCK => None,
_ => todo!(), _ => todo!(),
}; };
@ -180,7 +180,7 @@ impl LsConfig {
ok &= reg.rtcsel() == self.rtc; ok &= reg.rtcsel() == self.rtc;
#[cfg(not(rcc_wba))] #[cfg(not(rcc_wba))]
{ {
ok &= reg.rtcen() == (self.rtc != RtcClockSource::DISABLE); ok &= reg.rtcen() == (self.rtc != RtcClockSource::NOCLOCK);
} }
ok &= reg.lseon() == lse_en; ok &= reg.lseon() == lse_en;
ok &= reg.lsebyp() == lse_byp; ok &= reg.lsebyp() == lse_byp;
@ -225,7 +225,7 @@ impl LsConfig {
while !bdcr().read().lserdy() {} while !bdcr().read().lserdy() {}
} }
if self.rtc != RtcClockSource::DISABLE { if self.rtc != RtcClockSource::NOCLOCK {
bdcr().modify(|w| { bdcr().modify(|w| {
#[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet."); assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet.");

View File

@ -134,12 +134,10 @@ pub(crate) unsafe fn init(config: Config) {
}; };
set_freqs(Clocks { set_freqs(Clocks {
hsi: None,
lse: None,
sys: sys_clk, sys: sys_clk,
hclk1: ahb_freq, ahb1: ahb_freq,
pclk1: apb_freq, apb1: apb_freq,
pclk1_tim: apb_tim_freq, apb1_tim: apb_tim_freq,
rtc, rtc,
}); });
} }

View File

@ -162,11 +162,11 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: Hertz(real_sysclk), sys: Hertz(real_sysclk),
pclk1: Hertz(pclk), apb1: Hertz(pclk),
pclk2: Hertz(pclk), apb2: Hertz(pclk),
pclk1_tim: Hertz(pclk * timer_mul), apb1_tim: Hertz(pclk * timer_mul),
pclk2_tim: Hertz(pclk * timer_mul), apb2_tim: Hertz(pclk * timer_mul),
hclk1: Hertz(hclk), ahb1: Hertz(hclk),
rtc, rtc,
}); });
} }

View File

@ -102,6 +102,7 @@ pub(crate) unsafe fn init(config: Config) {
assert!(pclk2 <= 72_000_000); assert!(pclk2 <= 72_000_000);
// Only needed for stm32f103?
FLASH.acr().write(|w| { FLASH.acr().write(|w| {
w.set_latency(if real_sysclk <= 24_000_000 { w.set_latency(if real_sysclk <= 24_000_000 {
Latency::WS0 Latency::WS0
@ -110,8 +111,6 @@ pub(crate) unsafe fn init(config: Config) {
} else { } else {
Latency::WS2 Latency::WS2
}); });
// the prefetch buffer is enabled by default, let's keep it enabled
w.set_prftbe(true);
}); });
// the USB clock is only valid if an external crystal is used, the PLL is enabled, and the // the USB clock is only valid if an external crystal is used, the PLL is enabled, and the
@ -181,11 +180,11 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: Hertz(real_sysclk), sys: Hertz(real_sysclk),
pclk1: Hertz(pclk1), apb1: Hertz(pclk1),
pclk2: Hertz(pclk2), apb2: Hertz(pclk2),
pclk1_tim: Hertz(pclk1 * timer_mul1), apb1_tim: Hertz(pclk1 * timer_mul1),
pclk2_tim: Hertz(pclk2 * timer_mul2), apb2_tim: Hertz(pclk2 * timer_mul2),
hclk1: Hertz(hclk), ahb1: Hertz(hclk),
adc: Some(Hertz(adcclk)), adc: Some(Hertz(adcclk)),
rtc, rtc,
}); });

View File

@ -307,14 +307,14 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
hclk1: ahb_freq, ahb1: ahb_freq,
hclk2: ahb_freq, ahb2: ahb_freq,
hclk3: ahb_freq, ahb3: ahb_freq,
pclk1: apb1_freq, apb1: apb1_freq,
pclk1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
pclk2: apb2_freq, apb2: apb2_freq,
pclk2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
pll1_q: Some(pll_clocks.pll48_freq), pll48: Some(pll_clocks.pll48_freq),
rtc, rtc,
}); });
} }

View File

@ -281,11 +281,11 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sysclk, sys: sysclk,
pclk1: pclk1, apb1: pclk1,
pclk2: pclk2, apb2: pclk2,
pclk1_tim: pclk1 * timer_mul1, apb1_tim: pclk1 * timer_mul1,
pclk2_tim: pclk2 * timer_mul2, apb2_tim: pclk2 * timer_mul2,
hclk1: hclk, ahb1: hclk,
#[cfg(rcc_f3)] #[cfg(rcc_f3)]
adc: adc, adc: adc,
#[cfg(all(rcc_f3, adc3_common))] #[cfg(all(rcc_f3, adc3_common))]

View File

@ -340,27 +340,23 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: Hertz(sysclk), sys: Hertz(sysclk),
pclk1: Hertz(pclk1), apb1: Hertz(pclk1),
pclk2: Hertz(pclk2), apb2: Hertz(pclk2),
pclk1_tim: Hertz(pclk1 * timer_mul1), apb1_tim: Hertz(pclk1 * timer_mul1),
pclk2_tim: Hertz(pclk2 * timer_mul2), apb2_tim: Hertz(pclk2 * timer_mul2),
hclk1: Hertz(hclk), ahb1: Hertz(hclk),
hclk2: Hertz(hclk), ahb2: Hertz(hclk),
hclk3: Hertz(hclk), ahb3: Hertz(hclk),
pll1_q: plls.pll48clk.map(Hertz), pll48: plls.pll48clk.map(Hertz),
#[cfg(not(stm32f410))] #[cfg(not(stm32f410))]
plli2s1_q: plls.plli2sclk.map(Hertz), plli2s: plls.plli2sclk.map(Hertz),
#[cfg(not(stm32f410))]
plli2s1_r: None,
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pllsai1_q: plls.pllsaiclk.map(Hertz), pllsai: plls.pllsaiclk.map(Hertz),
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pllsai1_r: None,
rtc, rtc,
}); });

View File

@ -259,17 +259,17 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: Hertz(sysclk), sys: Hertz(sysclk),
pclk1: Hertz(pclk1), apb1: Hertz(pclk1),
pclk2: Hertz(pclk2), apb2: Hertz(pclk2),
pclk1_tim: Hertz(pclk1 * timer_mul1), apb1_tim: Hertz(pclk1 * timer_mul1),
pclk2_tim: Hertz(pclk2 * timer_mul2), apb2_tim: Hertz(pclk2 * timer_mul2),
hclk1: Hertz(hclk), ahb1: Hertz(hclk),
hclk2: Hertz(hclk), ahb2: Hertz(hclk),
hclk3: Hertz(hclk), ahb3: Hertz(hclk),
pll1_q: plls.pll48clk.map(Hertz), pll48: plls.pll48clk.map(Hertz),
rtc, rtc,
}); });

View File

@ -89,7 +89,7 @@ impl Default for Config {
impl PllConfig { impl PllConfig {
pub(crate) fn init(self) -> Hertz { pub(crate) fn init(self) -> Hertz {
let (src, input_freq) = match self.source { let (src, input_freq) = match self.source {
PllSrc::HSI16 => (vals::Pllsrc::HSI, HSI_FREQ), PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ),
PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq), PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq),
}; };
@ -186,7 +186,7 @@ pub(crate) unsafe fn init(config: Config) {
} }
ClockSrc::PLL(pll) => { ClockSrc::PLL(pll) => {
let freq = pll.init(); let freq = pll.init();
(freq, Sw::PLL1_R) (freq, Sw::PLLRCLK)
} }
ClockSrc::LSI => { ClockSrc::LSI => {
// Enable LSI // Enable LSI
@ -275,9 +275,9 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
hclk1: ahb_freq, ahb1: ahb_freq,
pclk1: apb_freq, apb1: apb_freq,
pclk1_tim: apb_tim_freq, apb1_tim: apb_tim_freq,
rtc, rtc,
}); });
} }

View File

@ -33,7 +33,7 @@ impl Into<Pllsrc> for PllSrc {
fn into(self) -> Pllsrc { fn into(self) -> Pllsrc {
match self { match self {
PllSrc::HSE(..) => Pllsrc::HSE, PllSrc::HSE(..) => Pllsrc::HSE,
PllSrc::HSI16 => Pllsrc::HSI, PllSrc::HSI16 => Pllsrc::HSI16,
} }
} }
} }
@ -118,9 +118,9 @@ impl Default for Config {
apb2_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1,
low_power_run: false, low_power_run: false,
pll: None, pll: None,
clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(None)), clock_48mhz_src: None,
adc12_clock_source: Adcsel::DISABLE, adc12_clock_source: Adcsel::NOCLK,
adc345_clock_source: Adcsel::DISABLE, adc345_clock_source: Adcsel::NOCLK,
ls: Default::default(), ls: Default::default(),
} }
} }
@ -201,7 +201,7 @@ pub(crate) unsafe fn init(config: Config) {
RCC.cr().write(|w| w.set_hsion(true)); RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {} while !RCC.cr().read().hsirdy() {}
(HSI_FREQ, Sw::HSI) (HSI_FREQ, Sw::HSI16)
} }
ClockSrc::HSE(freq) => { ClockSrc::HSE(freq) => {
// Enable HSE // Enable HSE
@ -249,7 +249,7 @@ pub(crate) unsafe fn init(config: Config) {
} }
} }
(Hertz(freq), Sw::PLL1_R) (Hertz(freq), Sw::PLLRCLK)
} }
}; };
@ -286,7 +286,7 @@ pub(crate) unsafe fn init(config: Config) {
let pllq_freq = pll_freq.as_ref().and_then(|f| f.pll_q); let pllq_freq = pll_freq.as_ref().and_then(|f| f.pll_q);
assert!(pllq_freq.is_some() && pllq_freq.unwrap().0 == 48_000_000); assert!(pllq_freq.is_some() && pllq_freq.unwrap().0 == 48_000_000);
crate::pac::rcc::vals::Clk48sel::PLL1_Q crate::pac::rcc::vals::Clk48sel::PLLQCLK
} }
Clock48MhzSrc::Hsi48(crs_config) => { Clock48MhzSrc::Hsi48(crs_config) => {
// Enable HSI48 // Enable HSI48
@ -296,7 +296,7 @@ pub(crate) unsafe fn init(config: Config) {
// Enable and setup CRS if needed // Enable and setup CRS if needed
if let Some(crs_config) = crs_config { if let Some(crs_config) = crs_config {
crate::peripherals::CRS::enable_and_reset(); crate::peripherals::CRS::enable();
let sync_src = match crs_config.sync_src { let sync_src = match crs_config.sync_src {
CrsSyncSource::Gpio => crate::pac::crs::vals::Syncsrc::GPIO, CrsSyncSource::Gpio => crate::pac::crs::vals::Syncsrc::GPIO,
@ -326,16 +326,16 @@ pub(crate) unsafe fn init(config: Config) {
RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source)); RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source));
let adc12_ck = match config.adc12_clock_source { let adc12_ck = match config.adc12_clock_source {
AdcClockSource::DISABLE => None, AdcClockSource::NOCLK => None,
AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p, AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p,
AdcClockSource::SYS => Some(sys_clk), AdcClockSource::SYSCLK => Some(sys_clk),
_ => unreachable!(), _ => unreachable!(),
}; };
let adc345_ck = match config.adc345_clock_source { let adc345_ck = match config.adc345_clock_source {
AdcClockSource::DISABLE => None, AdcClockSource::NOCLK => None,
AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p, AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p,
AdcClockSource::SYS => Some(sys_clk), AdcClockSource::SYSCLK => Some(sys_clk),
_ => unreachable!(), _ => unreachable!(),
}; };
@ -348,15 +348,14 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
hclk1: ahb_freq, ahb1: ahb_freq,
hclk2: ahb_freq, ahb2: ahb_freq,
pclk1: apb1_freq, apb1: apb1_freq,
pclk1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
pclk2: apb2_freq, apb2: apb2_freq,
pclk2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
adc: adc12_ck, adc: adc12_ck,
adc34: adc345_ck, adc34: adc345_ck,
pll1_p: None,
rtc, rtc,
}); });
} }

View File

@ -163,6 +163,10 @@ impl From<TimerPrescaler> for Timpre {
pub struct Config { pub struct Config {
pub hsi: Option<Hsi>, pub hsi: Option<Hsi>,
pub hse: Option<Hse>, pub hse: Option<Hse>,
#[cfg(stm32h7)]
pub lse: Option<Lse>,
#[cfg(stm32h7)]
pub lsi: bool,
pub csi: bool, pub csi: bool,
pub hsi48: bool, pub hsi48: bool,
pub sys: Sysclk, pub sys: Sysclk,
@ -195,6 +199,10 @@ impl Default for Config {
Self { Self {
hsi: Some(Hsi::Mhz64), hsi: Some(Hsi::Mhz64),
hse: None, hse: None,
#[cfg(stm32h7)]
lse: None,
#[cfg(stm32h7)]
lsi: false,
csi: false, csi: false,
hsi48: false, hsi48: false,
sys: Sysclk::HSI, sys: Sysclk::HSI,
@ -387,7 +395,7 @@ pub(crate) unsafe fn init(config: Config) {
Sysclk::HSI => (unwrap!(hsi), Sw::HSI), Sysclk::HSI => (unwrap!(hsi), Sw::HSI),
Sysclk::HSE => (unwrap!(hse), Sw::HSE), Sysclk::HSE => (unwrap!(hse), Sw::HSE),
Sysclk::CSI => (unwrap!(csi), Sw::CSI), Sysclk::CSI => (unwrap!(csi), Sw::CSI),
Sysclk::Pll1P => (unwrap!(pll1.p), Sw::PLL1_P), Sysclk::Pll1P => (unwrap!(pll1.p), Sw::PLL1),
}; };
// Check limits. // Check limits.
@ -445,12 +453,12 @@ pub(crate) unsafe fn init(config: Config) {
}; };
#[cfg(stm32h5)] #[cfg(stm32h5)]
let adc = match config.adc_clock_source { let adc = match config.adc_clock_source {
AdcClockSource::HCLK1 => Some(hclk), AdcClockSource::HCLK => Some(hclk),
AdcClockSource::SYS => Some(sys), AdcClockSource::SYSCLK => Some(sys),
AdcClockSource::PLL2_R => pll2.r, AdcClockSource::PLL2_R => pll2.r,
AdcClockSource::HSE => hse, AdcClockSource::HSE => hse,
AdcClockSource::HSI => hsi, AdcClockSource::HSI_KER => hsi,
AdcClockSource::CSI => csi, AdcClockSource::CSI_KER => csi,
_ => unreachable!(), _ => unreachable!(),
}; };
@ -524,65 +532,66 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys, sys,
hclk1: hclk, ahb1: hclk,
hclk2: hclk, ahb2: hclk,
hclk3: hclk, ahb3: hclk,
hclk4: hclk, ahb4: hclk,
pclk1: apb1, apb1,
pclk2: apb2, apb2,
pclk3: apb3, apb3,
#[cfg(stm32h7)] #[cfg(stm32h7)]
pclk4: apb4, apb4,
#[cfg(stm32h5)] apb1_tim,
pclk4: Hertz(1), apb2_tim,
pclk1_tim: apb1_tim,
pclk2_tim: apb2_tim,
adc, adc,
rtc, rtc,
#[cfg(any(stm32h5, stm32h7))]
hsi: None,
#[cfg(stm32h5)] #[cfg(stm32h5)]
hsi48: None, mux_rcc_pclk1: Some(apb1),
#[cfg(stm32h5)] #[cfg(stm32h5)]
lsi: None, mux_pll2_q: None,
#[cfg(any(stm32h5, stm32h7))] #[cfg(stm32h5)]
csi: None, mux_pll3_q: None,
#[cfg(stm32h5)]
mux_hsi_ker: None,
#[cfg(stm32h5)]
mux_csi_ker: None,
#[cfg(stm32h5)]
mux_lse: None,
#[cfg(stm32h5)]
mux_pll1_q: pll1.q,
#[cfg(stm32h5)]
mux_pll2_p: pll2.p,
#[cfg(rcc_h5)]
mux_pll3_p: pll3.p,
#[cfg(stm32h5)]
mux_audioclk: None,
#[cfg(stm32h5)]
mux_per: None,
#[cfg(any(stm32h5, stm32h7))] #[cfg(rcc_h5)]
lse: None, mux_pll3_r: pll3.r,
#[cfg(any(stm32h5, stm32h7))] #[cfg(all(not(rcc_h5), stm32h5))]
hse: None, mux_pll3_r: None,
#[cfg(stm32h5)]
#[cfg(any(stm32h5, stm32h7))] mux_rcc_pclk3: Some(apb3),
pll1_q: pll1.q, #[cfg(stm32h5)]
#[cfg(any(stm32h5, stm32h7))] mux_pll3_1: None,
pll2_p: pll2.p, #[cfg(stm32h5)]
#[cfg(any(stm32h5, stm32h7))] mux_hsi48_ker: None,
pll2_q: pll2.q, #[cfg(stm32h5)]
#[cfg(any(stm32h5, stm32h7))] mux_lsi_ker: None,
pll2_r: pll2.r, #[cfg(stm32h5)]
#[cfg(any(rcc_h5, stm32h7))] mux_pll2_r: pll2.r,
pll3_p: pll3.p, #[cfg(stm32h5)]
#[cfg(any(rcc_h5, stm32h7))] mux_rcc_pclk2: Some(apb2),
pll3_q: pll3.q, #[cfg(stm32h5)]
#[cfg(any(rcc_h5, stm32h7))] mux_rcc_pclk4: None,
pll3_r: pll3.r, #[cfg(stm32h5)]
mux_hse: hse,
#[cfg(rcc_h50)]
pll3_p: None,
#[cfg(rcc_h50)]
pll3_q: None,
#[cfg(rcc_h50)]
pll3_r: None,
#[cfg(stm32h5)] #[cfg(stm32h5)]
audioclk: None, mux_hsi48: None,
#[cfg(any(stm32h5, stm32h7))]
per: None,
#[cfg(stm32h7)]
rcc_pclk_d3: None,
}); });
} }

View File

@ -31,7 +31,7 @@ pub enum PLLSource {
impl From<PLLSource> for Pllsrc { impl From<PLLSource> for Pllsrc {
fn from(val: PLLSource) -> Pllsrc { fn from(val: PLLSource) -> Pllsrc {
match val { match val {
PLLSource::HSI16 => Pllsrc::HSI, PLLSource::HSI16 => Pllsrc::HSI16,
PLLSource::HSE(_) => Pllsrc::HSE, PLLSource::HSE(_) => Pllsrc::HSE,
} }
} }
@ -88,7 +88,7 @@ pub(crate) unsafe fn init(config: Config) {
RCC.cr().write(|w| w.set_hsi16on(true)); RCC.cr().write(|w| w.set_hsi16on(true));
while !RCC.cr().read().hsi16rdy() {} while !RCC.cr().read().hsi16rdy() {}
(HSI_FREQ, Sw::HSI) (HSI_FREQ, Sw::HSI16)
} }
ClockSrc::HSE(freq) => { ClockSrc::HSE(freq) => {
// Enable HSE // Enable HSE
@ -209,11 +209,11 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
hclk1: ahb_freq, ahb1: ahb_freq,
pclk1: apb1_freq, apb1: apb1_freq,
pclk2: apb2_freq, apb2: apb2_freq,
pclk1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
pclk2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc, rtc,
}); });
} }

296
embassy-stm32/src/rcc/l4.rs Normal file
View File

@ -0,0 +1,296 @@
use crate::pac::rcc::regs::Cfgr;
pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv,
Pllr as PllRDiv, Ppre as APBPrescaler,
};
use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// System clock mux source
#[derive(Clone, Copy)]
pub enum ClockSrc {
MSI(MSIRange),
PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option<PllQDiv>),
HSE(Hertz),
HSI16,
}
/// PLL clock input source
#[derive(Clone, Copy)]
pub enum PLLSource {
HSI16,
HSE(Hertz),
MSI(MSIRange),
}
impl From<PLLSource> for Pllsrc {
fn from(val: PLLSource) -> Pllsrc {
match val {
PLLSource::HSI16 => Pllsrc::HSI16,
PLLSource::HSE(_) => Pllsrc::HSE,
PLLSource::MSI(_) => Pllsrc::MSI,
}
}
}
/// Clocks configutation
pub struct Config {
pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler,
pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
pub hsi48: bool,
pub ls: super::LsConfig,
}
impl Default for Config {
#[inline]
fn default() -> Config {
Config {
mux: ClockSrc::MSI(MSIRange::RANGE4M),
ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
pllsai1: None,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
hsi48: false,
ls: Default::default(),
}
}
}
pub(crate) unsafe fn init(config: Config) {
// Switch to MSI to prevent problems with PLL configuration.
if !RCC.cr().read().msion() {
// Turn on MSI and configure it to 4MHz.
RCC.cr().modify(|w| {
w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0].
w.set_msirange(MSIRange::RANGE4M);
w.set_msipllen(false);
w.set_msion(true)
});
// Wait until MSI is running
while !RCC.cr().read().msirdy() {}
}
if RCC.cfgr().read().sws() != Sw::MSI {
// Set MSI as a clock source, reset prescalers.
RCC.cfgr().write_value(Cfgr::default());
// Wait for clock switch status bits to change.
while RCC.cfgr().read().sws() != Sw::MSI {}
}
let rtc = config.ls.init();
let (sys_clk, sw) = match config.mux {
ClockSrc::MSI(range) => {
// Enable MSI
RCC.cr().write(|w| {
w.set_msirange(range);
w.set_msirgsel(true);
w.set_msion(true);
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(config.ls.lse.is_some());
});
while !RCC.cr().read().msirdy() {}
// Enable as clock source for USB, RNG if running at 48 MHz
if range == MSIRange::RANGE48M {
RCC.ccipr().modify(|w| {
w.set_clk48sel(0b11);
});
}
(msirange_to_hertz(range), Sw::MSI)
}
ClockSrc::HSI16 => {
// Enable HSI16
RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
(HSI_FREQ, Sw::HSI16)
}
ClockSrc::HSE(freq) => {
// Enable HSE
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
(freq, Sw::HSE)
}
ClockSrc::PLL(src, divr, prediv, mul, divq) => {
let src_freq = match src {
PLLSource::HSE(freq) => {
// Enable HSE
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
freq
}
PLLSource::HSI16 => {
// Enable HSI
RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
HSI_FREQ
}
PLLSource::MSI(range) => {
// Enable MSI
RCC.cr().write(|w| {
w.set_msirange(range);
w.set_msipllen(false); // should be turned on if LSE is started
w.set_msirgsel(true);
w.set_msion(true);
});
while !RCC.cr().read().msirdy() {}
msirange_to_hertz(range)
}
};
// Disable PLL
RCC.cr().modify(|w| w.set_pllon(false));
while RCC.cr().read().pllrdy() {}
let freq = src_freq / prediv * mul / divr;
#[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))]
assert!(freq.0 <= 120_000_000);
#[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))]
assert!(freq.0 <= 80_000_000);
RCC.pllcfgr().write(move |w| {
w.set_plln(mul);
w.set_pllm(prediv);
w.set_pllr(divr);
if let Some(divq) = divq {
w.set_pllq(divq);
w.set_pllqen(true);
}
w.set_pllsrc(src.into());
});
// Enable as clock source for USB, RNG if PLL48 divisor is provided
if let Some(divq) = divq {
let freq = src_freq / prediv * mul / divq;
assert!(freq.0 == 48_000_000);
RCC.ccipr().modify(|w| {
w.set_clk48sel(0b10);
});
}
if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 {
RCC.pllsai1cfgr().write(move |w| {
w.set_plln(mul);
w.set_pllm(prediv);
if let Some(r_div) = r_div {
w.set_pllr(r_div);
w.set_pllren(true);
}
if let Some(q_div) = q_div {
w.set_pllq(q_div);
w.set_pllqen(true);
let freq = src_freq / prediv * mul / q_div;
if freq.0 == 48_000_000 {
RCC.ccipr().modify(|w| {
w.set_clk48sel(0b1);
});
}
}
if let Some(p_div) = p_div {
w.set_pllp(p_div);
w.set_pllpen(true);
}
});
RCC.cr().modify(|w| w.set_pllsai1on(true));
}
// Enable PLL
RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {}
RCC.pllcfgr().modify(|w| w.set_pllren(true));
(freq, Sw::PLL)
}
};
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
if config.hsi48 {
RCC.crrcr().modify(|w| w.set_hsi48on(true));
while !RCC.crrcr().read().hsi48rdy() {}
// Enable as clock source for USB, RNG and SDMMC
RCC.ccipr().modify(|w| w.set_clk48sel(0));
}
// Set flash wait states
FLASH.acr().modify(|w| {
w.set_latency(match sys_clk.0 {
0..=16_000_000 => 0,
0..=32_000_000 => 1,
0..=48_000_000 => 2,
0..=64_000_000 => 3,
_ => 4,
})
});
RCC.cfgr().modify(|w| {
w.set_sw(sw);
w.set_hpre(config.ahb_pre);
w.set_ppre1(config.apb1_pre);
w.set_ppre2(config.apb2_pre);
});
let ahb_freq = sys_clk / config.ahb_pre;
let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
pre => {
let freq = ahb_freq / pre;
(freq, freq * 2u32)
}
};
let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
pre => {
let freq = ahb_freq / pre;
(freq, freq * 2u32)
}
};
set_freqs(Clocks {
sys: sys_clk,
ahb1: ahb_freq,
ahb2: ahb_freq,
ahb3: ahb_freq,
apb1: apb1_freq,
apb2: apb2_freq,
apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq,
rtc,
});
}
fn msirange_to_hertz(range: Msirange) -> Hertz {
match range {
MSIRange::RANGE100K => Hertz(100_000),
MSIRange::RANGE200K => Hertz(200_000),
MSIRange::RANGE400K => Hertz(400_000),
MSIRange::RANGE800K => Hertz(800_000),
MSIRange::RANGE1M => Hertz(1_000_000),
MSIRange::RANGE2M => Hertz(2_000_000),
MSIRange::RANGE4M => Hertz(4_000_000),
MSIRange::RANGE8M => Hertz(8_000_000),
MSIRange::RANGE16M => Hertz(16_000_000),
MSIRange::RANGE24M => Hertz(24_000_000),
MSIRange::RANGE32M => Hertz(32_000_000),
MSIRange::RANGE48M => Hertz(48_000_000),
_ => unreachable!(),
}
}

View File

@ -1,446 +0,0 @@
use crate::pac::rcc::regs::Cfgr;
use crate::pac::rcc::vals::Msirgsel;
pub use crate::pac::rcc::vals::{
Clk48sel as Clk48Src, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul,
Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc,
};
use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
#[derive(Clone, Copy)]
pub struct Pll {
/// PLL source
pub source: PLLSource,
/// PLL pre-divider (DIVM).
pub prediv: PllPreDiv,
/// PLL multiplication factor.
pub mul: PllMul,
/// PLL P division factor. If None, PLL P output is disabled.
pub divp: Option<PllPDiv>,
/// PLL Q division factor. If None, PLL Q output is disabled.
pub divq: Option<PllQDiv>,
/// PLL R division factor. If None, PLL R output is disabled.
pub divr: Option<PllRDiv>,
}
/// Clocks configutation
pub struct Config {
// base clock sources
pub msi: Option<MSIRange>,
pub hsi16: bool,
pub hse: Option<Hertz>,
#[cfg(not(any(stm32l47x, stm32l48x)))]
pub hsi48: bool,
// pll
pub pll: Option<Pll>,
pub pllsai1: Option<Pll>,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
pub pllsai2: Option<Pll>,
// sysclk, buses.
pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler,
// muxes
pub clk48_src: Clk48Src,
// low speed LSI/LSE/RTC
pub ls: super::LsConfig,
}
impl Default for Config {
#[inline]
fn default() -> Config {
Config {
hse: None,
hsi16: false,
msi: Some(MSIRange::RANGE4M),
mux: ClockSrc::MSI,
ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
pll: None,
pllsai1: None,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
pllsai2: None,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
hsi48: true,
clk48_src: Clk48Src::HSI48,
ls: Default::default(),
}
}
}
pub(crate) unsafe fn init(config: Config) {
// Switch to MSI to prevent problems with PLL configuration.
if !RCC.cr().read().msion() {
// Turn on MSI and configure it to 4MHz.
RCC.cr().modify(|w| {
w.set_msirgsel(Msirgsel::CR);
w.set_msirange(MSIRange::RANGE4M);
w.set_msipllen(false);
w.set_msion(true)
});
// Wait until MSI is running
while !RCC.cr().read().msirdy() {}
}
if RCC.cfgr().read().sws() != ClockSrc::MSI {
// Set MSI as a clock source, reset prescalers.
RCC.cfgr().write_value(Cfgr::default());
// Wait for clock switch status bits to change.
while RCC.cfgr().read().sws() != ClockSrc::MSI {}
}
#[cfg(stm32l5)]
crate::pac::PWR.cr1().modify(|w| {
w.set_vos(crate::pac::pwr::vals::Vos::RANGE0);
});
let rtc = config.ls.init();
let msi = config.msi.map(|range| {
// Enable MSI
RCC.cr().write(|w| {
w.set_msirange(range);
w.set_msirgsel(Msirgsel::CR);
w.set_msion(true);
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(config.ls.lse.is_some());
});
while !RCC.cr().read().msirdy() {}
// Enable as clock source for USB, RNG if running at 48 MHz
if range == MSIRange::RANGE48M {}
msirange_to_hertz(range)
});
let hsi16 = config.hsi16.then(|| {
RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
HSI_FREQ
});
let hse = config.hse.map(|freq| {
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
freq
});
#[cfg(not(any(stm32l47x, stm32l48x)))]
let hsi48 = config.hsi48.then(|| {
RCC.crrcr().modify(|w| w.set_hsi48on(true));
while !RCC.crrcr().read().hsi48rdy() {}
Hertz(48_000_000)
});
#[cfg(any(stm32l47x, stm32l48x))]
let hsi48 = None;
let _plls = [
&config.pll,
&config.pllsai1,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
&config.pllsai2,
];
// L4 has shared PLLSRC, PLLM, check it's equal in all PLLs.
#[cfg(all(stm32l4, not(rcc_l4plus)))]
match get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) {
Err(()) => panic!("Source must be equal across all enabled PLLs."),
Ok(None) => {}
Ok(Some((source, prediv))) => RCC.pllcfgr().write(|w| {
w.set_pllm(prediv);
w.set_pllsrc(source);
}),
};
// L4+ has shared PLLSRC, check it's equal in all PLLs.
#[cfg(any(rcc_l4plus))]
match get_equal(_plls.into_iter().flatten().map(|p| p.source)) {
Err(()) => panic!("Source must be equal across all enabled PLLs."),
Ok(None) => {}
Ok(Some(source)) => RCC.pllcfgr().write(|w| {
w.set_pllsrc(source);
}),
};
let pll_input = PllInput { hse, hsi16, msi };
let pll = init_pll(PllInstance::Pll, config.pll, &pll_input);
let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input);
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input);
let sys_clk = match config.mux {
ClockSrc::HSE => hse.unwrap(),
#[cfg(rcc_l5)]
ClockSrc::HSI16 => hsi16.unwrap(),
#[cfg(not(rcc_l5))]
ClockSrc::HSI => hsi16.unwrap(),
ClockSrc::MSI => msi.unwrap(),
ClockSrc::PLL => pll._r.unwrap(),
};
#[cfg(stm32l4)]
RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src));
#[cfg(stm32l5)]
RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src));
let _clk48 = match config.clk48_src {
Clk48Src::HSI48 => hsi48,
Clk48Src::MSI => msi,
Clk48Src::PLLSAI1_Q => pllsai1._q,
#[cfg(rcc_l5)]
Clk48Src::PLL_Q => pll._q,
#[cfg(not(rcc_l5))]
Clk48Src::PLL1_Q => pll._q,
};
#[cfg(rcc_l4plus)]
assert!(sys_clk.0 <= 120_000_000);
#[cfg(all(stm32l4, not(rcc_l4plus)))]
assert!(sys_clk.0 <= 80_000_000);
// Set flash wait states
#[cfg(stm32l4)]
FLASH.acr().modify(|w| {
w.set_latency(match sys_clk.0 {
0..=16_000_000 => 0,
0..=32_000_000 => 1,
0..=48_000_000 => 2,
0..=64_000_000 => 3,
_ => 4,
})
});
// VCORE Range 0 (performance), others TODO
#[cfg(stm32l5)]
FLASH.acr().modify(|w| {
w.set_latency(match sys_clk.0 {
0..=20_000_000 => 0,
0..=40_000_000 => 1,
0..=60_000_000 => 2,
0..=80_000_000 => 3,
0..=100_000_000 => 4,
_ => 5,
})
});
RCC.cfgr().modify(|w| {
w.set_sw(config.mux);
w.set_hpre(config.ahb_pre);
w.set_ppre1(config.apb1_pre);
w.set_ppre2(config.apb2_pre);
});
let ahb_freq = sys_clk / config.ahb_pre;
let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
pre => {
let freq = ahb_freq / pre;
(freq, freq * 2u32)
}
};
let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
pre => {
let freq = ahb_freq / pre;
(freq, freq * 2u32)
}
};
set_freqs(Clocks {
sys: sys_clk,
hclk1: ahb_freq,
hclk2: ahb_freq,
hclk3: ahb_freq,
pclk1: apb1_freq,
pclk2: apb2_freq,
pclk1_tim: apb1_tim_freq,
pclk2_tim: apb2_tim_freq,
#[cfg(rcc_l4)]
hsi: None,
#[cfg(rcc_l4)]
lse: None,
#[cfg(rcc_l4)]
pllsai1_p: None,
#[cfg(rcc_l4)]
pllsai2_p: None,
#[cfg(rcc_l4)]
pll1_p: None,
#[cfg(rcc_l4)]
pll1_q: None,
#[cfg(rcc_l4)]
sai1_extclk: None,
#[cfg(rcc_l4)]
sai2_extclk: None,
rtc,
});
}
fn msirange_to_hertz(range: MSIRange) -> Hertz {
match range {
MSIRange::RANGE100K => Hertz(100_000),
MSIRange::RANGE200K => Hertz(200_000),
MSIRange::RANGE400K => Hertz(400_000),
MSIRange::RANGE800K => Hertz(800_000),
MSIRange::RANGE1M => Hertz(1_000_000),
MSIRange::RANGE2M => Hertz(2_000_000),
MSIRange::RANGE4M => Hertz(4_000_000),
MSIRange::RANGE8M => Hertz(8_000_000),
MSIRange::RANGE16M => Hertz(16_000_000),
MSIRange::RANGE24M => Hertz(24_000_000),
MSIRange::RANGE32M => Hertz(32_000_000),
MSIRange::RANGE48M => Hertz(48_000_000),
_ => unreachable!(),
}
}
#[allow(unused)]
fn get_equal<T: Eq>(mut iter: impl Iterator<Item = T>) -> Result<Option<T>, ()> {
let Some(x) = iter.next() else { return Ok(None) };
if !iter.all(|y| y == x) {
return Err(());
}
return Ok(Some(x));
}
struct PllInput {
hsi16: Option<Hertz>,
hse: Option<Hertz>,
msi: Option<Hertz>,
}
#[derive(Default)]
struct PllOutput {
_p: Option<Hertz>,
_q: Option<Hertz>,
_r: Option<Hertz>,
}
#[derive(PartialEq, Eq, Clone, Copy)]
enum PllInstance {
Pll,
Pllsai1,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
Pllsai2,
}
fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> PllOutput {
// Disable PLL
match instance {
PllInstance::Pll => {
RCC.cr().modify(|w| w.set_pllon(false));
while RCC.cr().read().pllrdy() {}
}
PllInstance::Pllsai1 => {
RCC.cr().modify(|w| w.set_pllsai1on(false));
while RCC.cr().read().pllsai1rdy() {}
}
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
PllInstance::Pllsai2 => {
RCC.cr().modify(|w| w.set_pllsai2on(false));
while RCC.cr().read().pllsai2rdy() {}
}
}
let Some(pll) = config else { return PllOutput::default() };
let pll_src = match pll.source {
PLLSource::NONE => panic!("must not select PLL source as NONE"),
PLLSource::HSE => input.hse,
#[cfg(rcc_l5)]
PLLSource::HSI16 => input.hsi16,
#[cfg(not(rcc_l5))]
PLLSource::HSI => input.hsi16,
PLLSource::MSI => input.msi,
};
let pll_src = pll_src.unwrap();
let vco_freq = pll_src / pll.prediv * pll.mul;
let p = pll.divp.map(|div| vco_freq / div);
let q = pll.divq.map(|div| vco_freq / div);
let r = pll.divr.map(|div| vco_freq / div);
#[cfg(stm32l5)]
if instance == PllInstance::Pllsai2 {
assert!(q.is_none(), "PLLSAI2_Q is not available on L5");
assert!(r.is_none(), "PLLSAI2_R is not available on L5");
}
macro_rules! write_fields {
($w:ident) => {
$w.set_plln(pll.mul);
if let Some(divp) = pll.divp {
$w.set_pllp(divp);
$w.set_pllpen(true);
}
if let Some(divq) = pll.divq {
$w.set_pllq(divq);
$w.set_pllqen(true);
}
if let Some(divr) = pll.divr {
$w.set_pllr(divr);
$w.set_pllren(true);
}
};
}
match instance {
PllInstance::Pll => RCC.pllcfgr().write(|w| {
w.set_pllm(pll.prediv);
w.set_pllsrc(pll.source);
write_fields!(w);
}),
PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| {
#[cfg(any(rcc_l4plus, stm32l5))]
w.set_pllm(pll.prediv);
#[cfg(stm32l5)]
w.set_pllsrc(pll.source);
write_fields!(w);
}),
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| {
#[cfg(any(rcc_l4plus, stm32l5))]
w.set_pllm(pll.prediv);
#[cfg(stm32l5)]
w.set_pllsrc(pll.source);
write_fields!(w);
}),
}
// Enable PLL
match instance {
PllInstance::Pll => {
RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {}
}
PllInstance::Pllsai1 => {
RCC.cr().modify(|w| w.set_pllsai1on(true));
while !RCC.cr().read().pllsai1rdy() {}
}
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
PllInstance::Pllsai2 => {
RCC.cr().modify(|w| w.set_pllsai2on(true));
while !RCC.cr().read().pllsai2rdy() {}
}
}
PllOutput { _p: p, _q: q, _r: r }
}

291
embassy-stm32/src/rcc/l5.rs Normal file
View File

@ -0,0 +1,291 @@
use crate::pac::rcc::regs::Cfgr;
pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv,
Pllr as PllRDiv, Ppre as APBPrescaler,
};
use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// System clock mux source
#[derive(Clone, Copy)]
pub enum ClockSrc {
MSI(MSIRange),
PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option<PllQDiv>),
HSE(Hertz),
HSI16,
}
/// PLL clock input source
#[derive(Clone, Copy)]
pub enum PLLSource {
HSI16,
HSE(Hertz),
MSI(MSIRange),
}
impl From<PLLSource> for Pllsrc {
fn from(val: PLLSource) -> Pllsrc {
match val {
PLLSource::HSI16 => Pllsrc::HSI16,
PLLSource::HSE(_) => Pllsrc::HSE,
PLLSource::MSI(_) => Pllsrc::MSI,
}
}
}
/// Clocks configutation
pub struct Config {
pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler,
pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
pub hsi48: bool,
pub ls: super::LsConfig,
}
impl Default for Config {
#[inline]
fn default() -> Config {
Config {
mux: ClockSrc::MSI(MSIRange::RANGE4M),
ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
pllsai1: None,
hsi48: false,
ls: Default::default(),
}
}
}
pub(crate) unsafe fn init(config: Config) {
// Switch to MSI to prevent problems with PLL configuration.
if !RCC.cr().read().msion() {
// Turn on MSI and configure it to 4MHz.
RCC.cr().modify(|w| {
w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0].
w.set_msirange(MSIRange::RANGE4M);
w.set_msipllen(false);
w.set_msion(true)
});
// Wait until MSI is running
while !RCC.cr().read().msirdy() {}
}
if RCC.cfgr().read().sws() != Sw::MSI {
// Set MSI as a clock source, reset prescalers.
RCC.cfgr().write_value(Cfgr::default());
// Wait for clock switch status bits to change.
while RCC.cfgr().read().sws() != Sw::MSI {}
}
let rtc = config.ls.init();
PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0));
let (sys_clk, sw) = match config.mux {
ClockSrc::MSI(range) => {
// Enable MSI
RCC.cr().write(|w| {
w.set_msirange(range);
w.set_msirgsel(true);
w.set_msion(true);
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(config.ls.lse.is_some());
});
while !RCC.cr().read().msirdy() {}
// Enable as clock source for USB, RNG if running at 48 MHz
if range == MSIRange::RANGE48M {
RCC.ccipr1().modify(|w| {
w.set_clk48msel(0b11);
});
}
(msirange_to_hertz(range), Sw::MSI)
}
ClockSrc::HSI16 => {
// Enable HSI16
RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
(HSI_FREQ, Sw::HSI16)
}
ClockSrc::HSE(freq) => {
// Enable HSE
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
(freq, Sw::HSE)
}
ClockSrc::PLL(src, divr, prediv, mul, divq) => {
let src_freq = match src {
PLLSource::HSE(freq) => {
// Enable HSE
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
freq
}
PLLSource::HSI16 => {
// Enable HSI
RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
HSI_FREQ
}
PLLSource::MSI(range) => {
// Enable MSI
RCC.cr().write(|w| {
w.set_msirange(range);
w.set_msipllen(false); // should be turned on if LSE is started
w.set_msirgsel(true);
w.set_msion(true);
});
while !RCC.cr().read().msirdy() {}
msirange_to_hertz(range)
}
};
// Disable PLL
RCC.cr().modify(|w| w.set_pllon(false));
while RCC.cr().read().pllrdy() {}
let freq = src_freq / prediv * mul / divr;
RCC.pllcfgr().write(move |w| {
w.set_plln(mul);
w.set_pllm(prediv);
w.set_pllr(divr);
if let Some(divq) = divq {
w.set_pllq(divq);
w.set_pllqen(true);
}
w.set_pllsrc(src.into());
});
// Enable as clock source for USB, RNG if PLL48 divisor is provided
if let Some(divq) = divq {
let freq = src_freq / prediv * mul / divq;
assert!(freq.0 == 48_000_000);
RCC.ccipr1().modify(|w| {
w.set_clk48msel(0b10);
});
}
if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 {
RCC.pllsai1cfgr().write(move |w| {
w.set_plln(mul);
w.set_pllm(prediv);
if let Some(r_div) = r_div {
w.set_pllr(r_div);
w.set_pllren(true);
}
if let Some(q_div) = q_div {
w.set_pllq(q_div);
w.set_pllqen(true);
let freq = src_freq / prediv * mul / q_div;
if freq.0 == 48_000_000 {
RCC.ccipr1().modify(|w| {
w.set_clk48msel(0b1);
});
}
}
if let Some(p_div) = p_div {
w.set_pllp(p_div);
w.set_pllpen(true);
}
});
RCC.cr().modify(|w| w.set_pllsai1on(true));
}
// Enable PLL
RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {}
RCC.pllcfgr().modify(|w| w.set_pllren(true));
(freq, Sw::PLL)
}
};
if config.hsi48 {
RCC.crrcr().modify(|w| w.set_hsi48on(true));
while !RCC.crrcr().read().hsi48rdy() {}
// Enable as clock source for USB, RNG and SDMMC
RCC.ccipr1().modify(|w| w.set_clk48msel(0));
}
// Set flash wait states
// VCORE Range 0 (performance), others TODO
FLASH.acr().modify(|w| {
w.set_latency(match sys_clk.0 {
0..=20_000_000 => 0,
0..=40_000_000 => 1,
0..=60_000_000 => 2,
0..=80_000_000 => 3,
0..=100_000_000 => 4,
_ => 5,
})
});
RCC.cfgr().modify(|w| {
w.set_sw(sw);
w.set_hpre(config.ahb_pre);
w.set_ppre1(config.apb1_pre);
w.set_ppre2(config.apb2_pre);
});
let ahb_freq = sys_clk / config.ahb_pre;
let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
pre => {
let freq = ahb_freq / pre;
(freq, freq * 2u32)
}
};
let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
pre => {
let freq = ahb_freq / pre;
(freq, freq * 2u32)
}
};
set_freqs(Clocks {
sys: sys_clk,
ahb1: ahb_freq,
ahb2: ahb_freq,
ahb3: ahb_freq,
apb1: apb1_freq,
apb2: apb2_freq,
apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq,
rtc,
});
}
fn msirange_to_hertz(range: Msirange) -> Hertz {
match range {
MSIRange::RANGE100K => Hertz(100_000),
MSIRange::RANGE200K => Hertz(200_000),
MSIRange::RANGE400K => Hertz(400_000),
MSIRange::RANGE800K => Hertz(800_000),
MSIRange::RANGE1M => Hertz(1_000_000),
MSIRange::RANGE2M => Hertz(2_000_000),
MSIRange::RANGE4M => Hertz(4_000_000),
MSIRange::RANGE8M => Hertz(8_000_000),
MSIRange::RANGE16M => Hertz(16_000_000),
MSIRange::RANGE24M => Hertz(24_000_000),
MSIRange::RANGE32M => Hertz(32_000_000),
MSIRange::RANGE48M => Hertz(48_000_000),
_ => unreachable!(),
}
}

View File

@ -20,7 +20,8 @@ pub use mco::*;
#[cfg_attr(rcc_g4, path = "g4.rs")] #[cfg_attr(rcc_g4, path = "g4.rs")]
#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] #[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")]
#[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] #[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")]
#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5), path = "l4l5.rs")] #[cfg_attr(rcc_l4, path = "l4.rs")]
#[cfg_attr(rcc_l5, path = "l5.rs")]
#[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")]
#[cfg_attr(rcc_wb, path = "wb.rs")] #[cfg_attr(rcc_wb, path = "wb.rs")]
#[cfg_attr(rcc_wba, path = "wba.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")]
@ -47,24 +48,23 @@ pub struct Clocks {
pub sys: Hertz, pub sys: Hertz,
// APB // APB
pub pclk1: Hertz, pub apb1: Hertz,
pub pclk1_tim: Hertz, pub apb1_tim: Hertz,
#[cfg(not(any(rcc_c0, rcc_g0)))] #[cfg(not(any(rcc_c0, rcc_g0)))]
pub pclk2: Hertz, pub apb2: Hertz,
#[cfg(not(any(rcc_c0, rcc_g0)))] #[cfg(not(any(rcc_c0, rcc_g0)))]
pub pclk2_tim: Hertz, pub apb2_tim: Hertz,
#[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_u5))] #[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_u5))]
pub pclk3: Hertz, pub apb3: Hertz,
#[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab, stm32h5))] #[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab))]
pub pclk4: Hertz, pub apb4: Hertz,
#[cfg(any(rcc_wba))] #[cfg(any(rcc_wba))]
pub pclk7: Hertz, pub apb7: Hertz,
// AHB // AHB
pub hclk1: Hertz, pub ahb1: Hertz,
#[cfg(any( #[cfg(any(
rcc_l4, rcc_l4,
rcc_l4plus,
rcc_l5, rcc_l5,
rcc_f2, rcc_f2,
rcc_f4, rcc_f4,
@ -82,10 +82,9 @@ pub struct Clocks {
rcc_wl5, rcc_wl5,
rcc_wle rcc_wle
))] ))]
pub hclk2: Hertz, pub ahb2: Hertz,
#[cfg(any( #[cfg(any(
rcc_l4, rcc_l4,
rcc_l4plus,
rcc_l5, rcc_l5,
rcc_f2, rcc_f2,
rcc_f4, rcc_f4,
@ -101,40 +100,18 @@ pub struct Clocks {
rcc_wl5, rcc_wl5,
rcc_wle rcc_wle
))] ))]
pub hclk3: Hertz, pub ahb3: Hertz,
#[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_wba))] #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_wba))]
pub hclk4: Hertz, pub ahb4: Hertz,
#[cfg(any(rcc_f2, rcc_f4, rcc_f410, rcc_f7))]
pub pll48: Option<Hertz>,
#[cfg(all(rcc_f4, not(stm32f410)))] #[cfg(all(rcc_f4, not(stm32f410)))]
pub plli2s1_q: Option<Hertz>, pub plli2s: Option<Hertz>,
#[cfg(all(rcc_f4, not(stm32f410)))]
pub plli2s1_r: Option<Hertz>,
#[cfg(rcc_l4)]
pub pllsai1_p: Option<Hertz>,
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pub pllsai1_q: Option<Hertz>, pub pllsai: Option<Hertz>,
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pub pllsai1_r: Option<Hertz>,
#[cfg(rcc_l4)]
pub pllsai2_p: Option<Hertz>,
#[cfg(any(stm32g4, rcc_l4))]
pub pll1_p: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_l4))]
pub pll1_q: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll2_p: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll2_q: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll2_r: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll3_p: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll3_q: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll3_r: Option<Hertz>,
#[cfg(any( #[cfg(any(
rcc_f1, rcc_f1,
@ -158,31 +135,51 @@ pub struct Clocks {
pub rtc: Option<Hertz>, pub rtc: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))]
pub hsi: Option<Hertz>,
#[cfg(stm32h5)] #[cfg(stm32h5)]
pub hsi48: Option<Hertz>, pub mux_rcc_pclk1: Option<Hertz>,
#[cfg(stm32h5)] #[cfg(stm32h5)]
pub lsi: Option<Hertz>, pub mux_pll2_q: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))] #[cfg(stm32h5)]
pub csi: Option<Hertz>, pub mux_pll3_q: Option<Hertz>,
#[cfg(stm32h5)]
#[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))] pub mux_hsi_ker: Option<Hertz>,
pub lse: Option<Hertz>, #[cfg(stm32h5)]
#[cfg(any(stm32h5, stm32h7))] pub mux_csi_ker: Option<Hertz>,
pub hse: Option<Hertz>, #[cfg(stm32h5)]
pub mux_lse: Option<Hertz>,
#[cfg(stm32h5)] #[cfg(stm32h5)]
pub audioclk: Option<Hertz>, pub mux_pll1_q: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))] #[cfg(stm32h5)]
pub per: Option<Hertz>, pub mux_pll2_p: Option<Hertz>,
#[cfg(rcc_h5)]
pub mux_pll3_p: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_audioclk: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_per: Option<Hertz>,
#[cfg(stm32h7)] #[cfg(stm32h5)]
pub rcc_pclk_d3: Option<Hertz>, pub mux_pll3_r: Option<Hertz>,
#[cfg(rcc_l4)] #[cfg(stm32h5)]
pub sai1_extclk: Option<Hertz>, pub mux_rcc_pclk3: Option<Hertz>,
#[cfg(rcc_l4)] #[cfg(stm32h5)]
pub sai2_extclk: Option<Hertz>, pub mux_pll3_1: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_hsi48_ker: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_lsi_ker: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_pll2_r: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_rcc_pclk2: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_rcc_pclk4: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_hse: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_hsi48: Option<Hertz>,
} }
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]
@ -232,19 +229,11 @@ pub mod low_level {
} }
pub(crate) mod sealed { pub(crate) mod sealed {
use critical_section::CriticalSection;
pub trait RccPeripheral { pub trait RccPeripheral {
fn frequency() -> crate::time::Hertz; fn frequency() -> crate::time::Hertz;
fn enable_and_reset_with_cs(cs: CriticalSection); fn reset();
fn disable_with_cs(cs: CriticalSection); fn enable();
fn disable();
fn enable_and_reset() {
critical_section::with(|cs| Self::enable_and_reset_with_cs(cs))
}
fn disable() {
critical_section::with(|cs| Self::disable_with_cs(cs))
}
} }
} }

View File

@ -188,7 +188,7 @@ impl Default for Config {
apb1_pre: APBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1,
apb3_pre: APBPrescaler::DIV1, apb3_pre: APBPrescaler::DIV1,
hsi48: true, hsi48: false,
voltage_range: VoltageScale::RANGE3, voltage_range: VoltageScale::RANGE3,
ls: Default::default(), ls: Default::default(),
} }
@ -436,14 +436,14 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
hclk1: ahb_freq, ahb1: ahb_freq,
hclk2: ahb_freq, ahb2: ahb_freq,
hclk3: ahb_freq, ahb3: ahb_freq,
pclk1: apb1_freq, apb1: apb1_freq,
pclk2: apb2_freq, apb2: apb2_freq,
pclk3: apb3_freq, apb3: apb3_freq,
pclk1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
pclk2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc, rtc,
}); });
} }

View File

@ -40,7 +40,6 @@ pub struct Config {
pub hse: Option<Hse>, pub hse: Option<Hse>,
pub sys: Sysclk, pub sys: Sysclk,
pub mux: Option<PllMux>, pub mux: Option<PllMux>,
pub hsi48: bool,
pub pll: Option<Pll>, pub pll: Option<Pll>,
pub pllsai: Option<Pll>, pub pllsai: Option<Pll>,
@ -64,7 +63,6 @@ pub const WPAN_DEFAULT: Config = Config {
source: PllSource::HSE, source: PllSource::HSE,
prediv: Pllm::DIV2, prediv: Pllm::DIV2,
}), }),
hsi48: true,
ls: super::LsConfig::default_lse(), ls: super::LsConfig::default_lse(),
@ -92,7 +90,6 @@ impl Default for Config {
mux: None, mux: None,
pll: None, pll: None,
pllsai: None, pllsai: None,
hsi48: true,
ls: Default::default(), ls: Default::default(),
@ -225,13 +222,6 @@ pub(crate) unsafe fn init(config: Config) {
_ => {} _ => {}
} }
let _hsi48 = config.hsi48.then(|| {
rcc.crrcr().modify(|w| w.set_hsi48on(true));
while !rcc.crrcr().read().hsi48rdy() {}
Hertz(48_000_000)
});
rcc.cfgr().modify(|w| { rcc.cfgr().modify(|w| {
w.set_sw(config.sys.into()); w.set_sw(config.sys.into());
w.set_hpre(config.ahb1_pre); w.set_hpre(config.ahb1_pre);
@ -246,13 +236,13 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
hclk1: ahb1_clk, ahb1: ahb1_clk,
hclk2: ahb2_clk, ahb2: ahb2_clk,
hclk3: ahb3_clk, ahb3: ahb3_clk,
pclk1: apb1_clk, apb1: apb1_clk,
pclk2: apb2_clk, apb2: apb2_clk,
pclk1_tim: apb1_tim_clk, apb1_tim: apb1_tim_clk,
pclk2_tim: apb2_tim_clk, apb2_tim: apb2_tim_clk,
rtc, rtc,
}) })
} }

View File

@ -142,14 +142,14 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
hclk1: ahb_freq, ahb1: ahb_freq,
hclk2: ahb_freq, ahb2: ahb_freq,
hclk4: ahb_freq, ahb4: ahb_freq,
pclk1: apb1_freq, apb1: apb1_freq,
pclk2: apb2_freq, apb2: apb2_freq,
pclk7: apb7_freq, apb7: apb7_freq,
pclk1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
pclk2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc, rtc,
}); });
} }

View File

@ -145,14 +145,14 @@ pub(crate) unsafe fn init(config: Config) {
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
hclk1: ahb_freq, ahb1: ahb_freq,
hclk2: ahb_freq, ahb2: ahb_freq,
hclk3: shd_ahb_freq, ahb3: shd_ahb_freq,
pclk1: apb1_freq, apb1: apb1_freq,
pclk2: apb2_freq, apb2: apb2_freq,
pclk3: shd_ahb_freq, apb3: shd_ahb_freq,
pclk1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
pclk2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc, rtc,
}); });
} }

View File

@ -43,7 +43,8 @@ impl<'d, T: Instance> Rng<'d, T> {
inner: impl Peripheral<P = T> + 'd, inner: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
T::enable_and_reset(); T::enable();
T::reset();
into_ref!(inner); into_ref!(inner);
let mut random = Self { _inner: inner }; let mut random = Self { _inner: inner };
random.reset(); random.reset();
@ -85,7 +86,7 @@ impl<'d, T: Instance> Rng<'d, T> {
reg.set_ie(false); reg.set_ie(false);
reg.set_rngen(true); reg.set_rngen(true);
}); });
T::regs().cr().modify(|reg| { T::regs().cr().write(|reg| {
reg.set_ced(false); reg.set_ced(false);
}); });
// wait for CONDRST to be set // wait for CONDRST to be set

View File

@ -184,7 +184,7 @@ impl Default for RtcCalibrationCyclePeriod {
impl Rtc { impl Rtc {
pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
#[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
<RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset(); <RTC as crate::rcc::sealed::RccPeripheral>::enable();
let mut this = Self { let mut this = Self {
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]

View File

@ -531,13 +531,10 @@ pub struct SubBlock<'d, T: Instance, C: Channel, W: word::Word> {
pub struct SubBlockA {} pub struct SubBlockA {}
pub struct SubBlockB {} pub struct SubBlockB {}
pub struct SubBlockAPeripheral<'d, T>(PeripheralRef<'d, T>);
pub struct SubBlockBPeripheral<'d, T>(PeripheralRef<'d, T>);
pub struct Sai<'d, T: Instance> { pub struct Sai<'d, T: Instance> {
_peri: PeripheralRef<'d, T>, _peri: PeripheralRef<'d, T>,
sub_block_a_peri: Option<SubBlockAPeripheral<'d, T>>, sub_block_a_peri: Option<PeripheralRef<'d, T>>,
sub_block_b_peri: Option<SubBlockBPeripheral<'d, T>>, sub_block_b_peri: Option<PeripheralRef<'d, T>>,
} }
// return the type for (sd, sck) // return the type for (sd, sck)
@ -580,16 +577,17 @@ fn get_ring_buffer<'d, T: Instance, C: Channel, W: word::Word>(
impl<'d, T: Instance> Sai<'d, T> { impl<'d, T: Instance> Sai<'d, T> {
pub fn new(peri: impl Peripheral<P = T> + 'd) -> Self { pub fn new(peri: impl Peripheral<P = T> + 'd) -> Self {
T::enable_and_reset(); T::enable();
T::reset();
Self { Self {
_peri: unsafe { peri.clone_unchecked().into_ref() }, _peri: unsafe { peri.clone_unchecked().into_ref() },
sub_block_a_peri: Some(SubBlockAPeripheral(unsafe { peri.clone_unchecked().into_ref() })), sub_block_a_peri: Some(unsafe { peri.clone_unchecked().into_ref() }),
sub_block_b_peri: Some(SubBlockBPeripheral(peri.into_ref())), sub_block_b_peri: Some(peri.into_ref()),
} }
} }
pub fn take_sub_block_a(self: &mut Self) -> Option<SubBlockAPeripheral<'d, T>> { pub fn take_sub_block_a(self: &mut Self) -> Option<PeripheralRef<'d, T>> {
if self.sub_block_a_peri.is_some() { if self.sub_block_a_peri.is_some() {
self.sub_block_a_peri.take() self.sub_block_a_peri.take()
} else { } else {
@ -597,7 +595,7 @@ impl<'d, T: Instance> Sai<'d, T> {
} }
} }
pub fn take_sub_block_b(self: &mut Self) -> Option<SubBlockBPeripheral<'d, T>> { pub fn take_sub_block_b(self: &mut Self) -> Option<PeripheralRef<'d, T>> {
if self.sub_block_b_peri.is_some() { if self.sub_block_b_peri.is_some() {
self.sub_block_b_peri.take() self.sub_block_b_peri.take()
} else { } else {
@ -625,7 +623,7 @@ fn update_synchronous_config(config: &mut Config) {
impl SubBlockA { impl SubBlockA {
pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>( pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>(
peri: SubBlockAPeripheral<'d, T>, peri: impl Peripheral<P = T> + 'd,
sck: impl Peripheral<P = impl SckAPin<T>> + 'd, sck: impl Peripheral<P = impl SckAPin<T>> + 'd,
sd: impl Peripheral<P = impl SdAPin<T>> + 'd, sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
fs: impl Peripheral<P = impl FsAPin<T>> + 'd, fs: impl Peripheral<P = impl FsAPin<T>> + 'd,
@ -633,7 +631,7 @@ impl SubBlockA {
dma: impl Peripheral<P = C> + 'd, dma: impl Peripheral<P = C> + 'd,
dma_buf: &'d mut [W], dma_buf: &'d mut [W],
mut config: Config, mut config: Config,
) -> SubBlock<'d, T, C, W> ) -> SubBlock<T, C, W>
where where
C: Channel + DmaA<T>, C: Channel + DmaA<T>,
{ {
@ -652,18 +650,17 @@ impl SubBlockA {
} }
pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>( pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>(
peri: SubBlockAPeripheral<'d, T>, peri: impl Peripheral<P = T> + 'd,
sck: impl Peripheral<P = impl SckAPin<T>> + 'd, sck: impl Peripheral<P = impl SckAPin<T>> + 'd,
sd: impl Peripheral<P = impl SdAPin<T>> + 'd, sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
fs: impl Peripheral<P = impl FsAPin<T>> + 'd, fs: impl Peripheral<P = impl FsAPin<T>> + 'd,
dma: impl Peripheral<P = C> + 'd, dma: impl Peripheral<P = C> + 'd,
dma_buf: &'d mut [W], dma_buf: &'d mut [W],
config: Config, config: Config,
) -> SubBlock<'d, T, C, W> ) -> SubBlock<T, C, W>
where where
C: Channel + DmaA<T>, C: Channel + DmaA<T>,
{ {
let peri = peri.0;
into_ref!(peri, dma, sck, sd, fs); into_ref!(peri, dma, sck, sd, fs);
let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
@ -691,18 +688,17 @@ impl SubBlockA {
} }
pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>( pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>(
peri: SubBlockAPeripheral<'d, T>, peri: impl Peripheral<P = T> + 'd,
sd: impl Peripheral<P = impl SdAPin<T>> + 'd, sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
dma: impl Peripheral<P = C> + 'd, dma: impl Peripheral<P = C> + 'd,
dma_buf: &'d mut [W], dma_buf: &'d mut [W],
mut config: Config, mut config: Config,
) -> SubBlock<'d, T, C, W> ) -> SubBlock<T, C, W>
where where
C: Channel + DmaA<T>, C: Channel + DmaA<T>,
{ {
update_synchronous_config(&mut config); update_synchronous_config(&mut config);
let peri = peri.0;
into_ref!(dma, peri, sd); into_ref!(dma, peri, sd);
let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
@ -728,7 +724,7 @@ impl SubBlockA {
impl SubBlockB { impl SubBlockB {
pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>( pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>(
peri: SubBlockBPeripheral<'d, T>, peri: impl Peripheral<P = T> + 'd,
sck: impl Peripheral<P = impl SckBPin<T>> + 'd, sck: impl Peripheral<P = impl SckBPin<T>> + 'd,
sd: impl Peripheral<P = impl SdBPin<T>> + 'd, sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
fs: impl Peripheral<P = impl FsBPin<T>> + 'd, fs: impl Peripheral<P = impl FsBPin<T>> + 'd,
@ -736,7 +732,7 @@ impl SubBlockB {
dma: impl Peripheral<P = C> + 'd, dma: impl Peripheral<P = C> + 'd,
dma_buf: &'d mut [W], dma_buf: &'d mut [W],
mut config: Config, mut config: Config,
) -> SubBlock<'d, T, C, W> ) -> SubBlock<T, C, W>
where where
C: Channel + DmaB<T>, C: Channel + DmaB<T>,
{ {
@ -755,18 +751,17 @@ impl SubBlockB {
} }
pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>( pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>(
peri: SubBlockBPeripheral<'d, T>, peri: impl Peripheral<P = T> + 'd,
sck: impl Peripheral<P = impl SckBPin<T>> + 'd, sck: impl Peripheral<P = impl SckBPin<T>> + 'd,
sd: impl Peripheral<P = impl SdBPin<T>> + 'd, sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
fs: impl Peripheral<P = impl FsBPin<T>> + 'd, fs: impl Peripheral<P = impl FsBPin<T>> + 'd,
dma: impl Peripheral<P = C> + 'd, dma: impl Peripheral<P = C> + 'd,
dma_buf: &'d mut [W], dma_buf: &'d mut [W],
config: Config, config: Config,
) -> SubBlock<'d, T, C, W> ) -> SubBlock<T, C, W>
where where
C: Channel + DmaB<T>, C: Channel + DmaB<T>,
{ {
let peri = peri.0;
into_ref!(dma, peri, sck, sd, fs); into_ref!(dma, peri, sck, sd, fs);
let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
@ -795,17 +790,17 @@ impl SubBlockB {
} }
pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>( pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>(
peri: SubBlockBPeripheral<'d, T>, peri: impl Peripheral<P = T> + 'd,
sd: impl Peripheral<P = impl SdBPin<T>> + 'd, sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
dma: impl Peripheral<P = C> + 'd, dma: impl Peripheral<P = C> + 'd,
dma_buf: &'d mut [W], dma_buf: &'d mut [W],
mut config: Config, mut config: Config,
) -> SubBlock<'d, T, C, W> ) -> SubBlock<T, C, W>
where where
C: Channel + DmaB<T>, C: Channel + DmaB<T>,
{ {
update_synchronous_config(&mut config); update_synchronous_config(&mut config);
let peri = peri.0;
into_ref!(dma, peri, sd); into_ref!(dma, peri, sd);
let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
@ -858,6 +853,10 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
ring_buffer: RingBuffer<'d, C, W>, ring_buffer: RingBuffer<'d, C, W>,
config: Config, config: Config,
) -> Self { ) -> Self {
T::enable();
// can't reset here because the other sub-block might be in use
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
{ {
let ch = T::REGS.ch(sub_block as usize); let ch = T::REGS.ch(sub_block as usize);
@ -960,7 +959,8 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
} }
pub fn reset() { pub fn reset() {
T::enable_and_reset(); T::enable();
T::reset();
} }
pub fn flush(&mut self) { pub fn flush(&mut self) {

Some files were not shown because too many files have changed in this diff Show More