Compare commits
14 Commits
comment-me
...
rcc-mux
Author | SHA1 | Date | |
---|---|---|---|
c8aa9c3b98 | |||
7810ef1c5e | |||
c1dc1741f6 | |||
6deec1b853 | |||
ba5b5e98fe | |||
158aeac438 | |||
f27c929cb8 | |||
0d0fbe957e | |||
e1a1c51d00 | |||
e25c7c23d0 | |||
4ee39f6dce | |||
a4b6bc31f8 | |||
2ae9d28d47 | |||
1457b53e48 |
@ -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
106
ci.sh
@ -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' \
|
||||||
|
61
ci_stable.sh
61
ci_stable.sh
@ -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 \
|
||||||
|
@ -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 }
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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"
|
||||||
|
@ -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.
|
||||||
|
@ -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",
|
||||||
] }
|
] }
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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"
|
||||||
|
@ -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.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# embassy-hal-internal
|
# embassy-macros
|
||||||
|
|
||||||
An [Embassy](https://embassy.dev) project.
|
An [Embassy](https://embassy.dev) project.
|
||||||
|
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")]
|
||||||
|
@ -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()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
136
embassy-hal-internal/src/ring_buffer.rs
Normal file
136
embassy-hal-internal/src/ring_buffer.rs
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
@ -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" }
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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" }
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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."
|
||||||
|
@ -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 }
|
||||||
|
@ -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" }
|
||||||
|
@ -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];
|
||||||
|
@ -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" }
|
||||||
|
@ -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"
|
||||||
|
@ -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 }
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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 }
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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" }
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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" }
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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]
|
||||||
|
@ -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,
|
||||||
|
@ -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’)
|
||||||
|
@ -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));
|
||||||
|
@ -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> {}
|
||||||
|
@ -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.
|
||||||
//
|
//
|
||||||
|
@ -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()));
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
|
|
||||||
|
@ -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};
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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)]
|
||||||
|
209
embassy-stm32/src/i2c/timeout.rs
Normal file
209
embassy-stm32/src/i2c/timeout.rs
Normal 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!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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(),
|
||||||
|
@ -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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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() {}
|
||||||
|
|
||||||
|
@ -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.");
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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))]
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
296
embassy-stm32/src/rcc/l4.rs
Normal 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!(),
|
||||||
|
}
|
||||||
|
}
|
@ -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
291
embassy-stm32/src/rcc/l5.rs
Normal 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!(),
|
||||||
|
}
|
||||||
|
}
|
@ -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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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")]
|
||||||
|
@ -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
Reference in New Issue
Block a user