Compare commits

..

6 Commits

Author SHA1 Message Date
3b7fec6efc wip 2023-10-03 17:59:49 -05:00
731df8be49 wip 2023-10-03 17:58:44 -05:00
2849bfcc6b wip 2023-10-03 17:57:12 -05:00
a4b20fc943 wip 2023-10-03 17:49:18 -05:00
8bb48f3083 wip 2023-10-03 17:47:41 -05:00
d7ce823d79 wpan: fix ipcc delay 2023-10-03 17:47:29 -05:00
390 changed files with 6179 additions and 5333 deletions

View File

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

385
ci.sh
View File

@ -1,12 +1,9 @@
#!/bin/bash #!/bin/bash
set -eo pipefail set -euo pipefail
export RUSTFLAGS=-Dwarnings export RUSTFLAGS=-Dwarnings
export DEFMT_LOG=trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info export DEFMT_LOG=trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info
if [[ -z "${CARGO_TARGET_DIR}" ]]; then
export CARGO_TARGET_DIR=target_ci
fi
TARGET=$(rustc -vV | sed -n 's|host: ||p') TARGET=$(rustc -vV | sed -n 's|host: ||p')
@ -18,202 +15,194 @@ fi
find . -name '*.rs' -not -path '*target*' | xargs rustfmt --check --skip-children --unstable-features --edition 2021 find . -name '*.rs' -not -path '*target*' | xargs rustfmt --check --skip-children --unstable-features --edition 2021
cargo batch \ cargo batch \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55rg --out-dir out/tests/stm32wb55rg # \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,log \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,defmt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,arch-cortex-m,executor-thread,executor-interrupt,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-interrupt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-interrupt,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,executor-interrupt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,executor-interrupt,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32 \
--- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,executor-thread \
--- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,executor-thread,integrated-timers \
--- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \
--- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly,dhcpv4-hostname \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ieee802154 \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,medium-ieee802154 \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet,medium-ieee802154,nightly \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52805,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52820,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52832,gpiote,time-driver-rtc1,reset-pin-as-gpio \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52833,gpiote,time-driver-rtc1,unstable-traits,nfc-pins-as-gpio \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf9160-s,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf9160-ns,gpiote,time-driver-rtc1,unstable-traits \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf5340-app-s,gpiote,time-driver-rtc1,unstable-traits \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf5340-app-ns,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf5340-net,gpiote,time-driver-rtc1,unstable-traits \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52840,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52840,log,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52840,defmt,gpiote,time-driver-rtc1,unstable-traits \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits,defmt \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits,log \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \
--- build --release --manifest-path embassy-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-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,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits,time \
--- 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,unstable-traits,time \
--- 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,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,time \
--- 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,unstable-traits,time \
--- 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,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 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,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,stm32f405zg,defmt,exti,time-driver-any,unstable-traits,time \
--- 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,stm32f410tb,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,time \
--- 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,stm32f413vh,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,time \
--- 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,stm32f423zh,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,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,time \
--- 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,stm32f439zi,defmt,exti,time-driver-any,unstable-traits,time \
--- 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,stm32f469zi,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,time \
--- 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,stm32h753zi,defmt,exti,time-driver-any,unstable-traits,time \
--- 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,stm32h755zi-cm7,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,time \
--- 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 thumbv7em-none-eabi --features nightly,stm32l422cb,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,time \
--- 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 thumbv6m-none-eabi --features nightly,stm32l041f6,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,time \
--- 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 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,stm32f378cc,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,time \
--- 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 thumbv8m.main-none-eabihf --features nightly,stm32l552ze,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,time \
--- 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 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,stm32f107vc,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,time \
--- 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 '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 'log,firmware-logs' \
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt,firmware-logs' \
--- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features '' \
--- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'overclock' \
--- build --release --manifest-path embassy-boot/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,nightly \
--- build --release --manifest-path embassy-boot/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,nightly \
--- build --release --manifest-path embassy-boot/rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \
--- build --release --manifest-path embassy-boot/stm32/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32wl55jc-cm4,nightly \
--- build --release --manifest-path docs/modules/ROOT/examples/basic/Cargo.toml --target thumbv7em-none-eabi \
--- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-pac/Cargo.toml --target thumbv7em-none-eabi \
--- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-hal/Cargo.toml --target thumbv7em-none-eabi \
--- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-irq/Cargo.toml --target thumbv7em-none-eabi \
--- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml --target thumbv7em-none-eabi \
--- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840 \
--- build --release --manifest-path examples/nrf52840-rtic/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840-rtic \
--- build --release --manifest-path examples/nrf5340/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf5340 \
--- build --release --manifest-path examples/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/rp \
--- build --release --manifest-path examples/stm32f0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32f0 \
--- build --release --manifest-path examples/stm32f1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f1 \
--- build --release --manifest-path examples/stm32f2/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f2 \
--- build --release --manifest-path examples/stm32f3/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f3 \
--- build --release --manifest-path examples/stm32f334/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f334 \
--- build --release --manifest-path examples/stm32f4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f4 \
--- build --release --manifest-path examples/stm32f7/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f7 \
--- build --release --manifest-path examples/stm32c0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32c0 \
--- build --release --manifest-path examples/stm32g0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32g0 \
--- build --release --manifest-path examples/stm32g4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32g4 \
--- build --release --manifest-path examples/stm32h5/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32h5 \
--- build --release --manifest-path examples/stm32h7/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32h7 \
--- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32l0 \
--- build --release --manifest-path examples/stm32l1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32l1 \
--- build --release --manifest-path examples/stm32l4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32l4 \
--- build --release --manifest-path examples/stm32l5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32l5 \
--- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \
--- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wb \
--- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32wba \
--- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wl \
--- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --out-dir out/examples/boot/nrf52840 \
--- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --out-dir out/examples/boot/nrf9160 \
--- build --release --manifest-path examples/boot/application/rp/Cargo.toml --target thumbv6m-none-eabi --features skip-include --out-dir out/examples/boot/rp \
--- build --release --manifest-path examples/boot/application/stm32f3/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32f3 \
--- build --release --manifest-path examples/boot/application/stm32f7/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32f7 \
--- build --release --manifest-path examples/boot/application/stm32h7/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32h7 \
--- build --release --manifest-path examples/boot/application/stm32l0/Cargo.toml --target thumbv6m-none-eabi --features skip-include --out-dir out/examples/boot/stm32l0 \
--- build --release --manifest-path examples/boot/application/stm32l1/Cargo.toml --target thumbv7m-none-eabi --features skip-include --out-dir out/examples/boot/stm32l1 \
--- build --release --manifest-path examples/boot/application/stm32l4/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32l4 \
--- build --release --manifest-path examples/boot/application/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --features skip-include --out-dir out/examples/boot/stm32wl \
--- build --release --manifest-path examples/boot/bootloader/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840 \
--- build --release --manifest-path examples/boot/bootloader/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns \
--- build --release --manifest-path examples/boot/bootloader/rp/Cargo.toml --target thumbv6m-none-eabi \
--- build --release --manifest-path examples/boot/bootloader/stm32/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32wl55jc-cm4 \
--- build --release --manifest-path examples/wasm/Cargo.toml --target wasm32-unknown-unknown --out-dir out/examples/wasm \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f103c8 --out-dir out/tests/stm32f103c8 \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi --out-dir out/tests/stm32f429zi \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re --out-dir out/tests/stm32g491re \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32g071rb --out-dir out/tests/stm32g071rb \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32c031c6 --out-dir out/tests/stm32c031c6 \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi --out-dir out/tests/stm32h755zi \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55rg --out-dir out/tests/stm32wb55rg \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h563zi --out-dir out/tests/stm32h563zi \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585ai --out-dir out/tests/stm32u585ai \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l073rz --out-dir out/tests/stm32l073rz \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l152re --out-dir out/tests/stm32l152re \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4a6zg --out-dir out/tests/stm32l4a6zg \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r5zi --out-dir out/tests/stm32l4r5zi \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze --out-dir out/tests/stm32l552ze \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f767zi --out-dir out/tests/stm32f767zi \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f207zg --out-dir out/tests/stm32f207zg \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303ze --out-dir out/tests/stm32f303ze \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l496zg --out-dir out/tests/stm32l496zg \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55jc --out-dir out/tests/stm32wl55jc \
--- build --release --manifest-path tests/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/tests/rpi-pico \
--- build --release --manifest-path tests/nrf/Cargo.toml --target thumbv7em-none-eabi --out-dir out/tests/nrf52840-dk \
--- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \
$BUILD_EXTRA
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,log \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,defmt \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,arch-cortex-m,executor-thread,executor-interrupt,integrated-timers \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,integrated-timers \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,integrated-timers \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-interrupt \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-interrupt,integrated-timers \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,executor-interrupt \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,executor-interrupt,integrated-timers \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32 \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,integrated-timers \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,executor-thread \
# --- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,executor-thread,integrated-timers \
# --- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \
# --- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ieee802154 \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,medium-ieee802154 \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,nightly \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,nightly \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,nightly \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet,nightly \
# --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet,medium-ieee802154,nightly \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52805,gpiote,time-driver-rtc1 \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52820,gpiote,time-driver-rtc1 \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52832,gpiote,time-driver-rtc1,reset-pin-as-gpio \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52833,gpiote,time-driver-rtc1,unstable-traits,nfc-pins-as-gpio \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf9160-s,gpiote,time-driver-rtc1 \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf9160-ns,gpiote,time-driver-rtc1,unstable-traits \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf5340-app-s,gpiote,time-driver-rtc1,unstable-traits \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf5340-app-ns,gpiote,time-driver-rtc1 \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,nrf5340-net,gpiote,time-driver-rtc1,unstable-traits \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52840,gpiote,time-driver-rtc1 \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52840,log,gpiote,time-driver-rtc1 \
# --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52840,defmt,gpiote,time-driver-rtc1,unstable-traits \
# --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits,defmt \
# --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits,log \
# --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits \
# --- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \
# --- build --release --manifest-path embassy-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-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 \
# --- 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 \
# --- 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 \
# --- 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 \
# --- 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 \
# --- 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 \
# --- 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 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,stm32f407zg,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 \
# --- 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,stm32f412zg,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 \
# --- 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,stm32f417zg,defmt,exti,time-driver-any,unstable-traits \
# --- 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,stm32f427zi,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 \
# --- 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,stm32f439zi,defmt,exti,time-driver-any,unstable-traits \
# --- 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,stm32f469zi,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 \
# --- 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,stm32h753zi,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 \
# --- 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,stm32h7b3ai,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 \
# --- 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,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits \
# --- 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 thumbv6m-none-eabi --features nightly,stm32l041f6,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 \
# --- 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 thumbv7m-none-eabi --features nightly,stm32f398ve,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 \
# --- 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,stm32f217zg,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 \
# --- 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 thumbv7em-none-eabi --features nightly,stm32wle5jb,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 \
# --- 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 thumbv7m-none-eabi --features nightly,stm32f103re,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 \
# --- 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,stm32h562ag,defmt,exti,time-driver-any,unstable-traits \
# --- 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 'defmt' \
# --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log,firmware-logs' \
# --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt,firmware-logs' \
# --- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features '' \
# --- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'overclock' \
# --- build --release --manifest-path embassy-boot/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,nightly \
# --- build --release --manifest-path embassy-boot/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,nightly \
# --- build --release --manifest-path embassy-boot/rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \
# --- build --release --manifest-path embassy-boot/stm32/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32wl55jc-cm4,nightly \
# --- build --release --manifest-path docs/modules/ROOT/examples/basic/Cargo.toml --target thumbv7em-none-eabi \
# --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-pac/Cargo.toml --target thumbv7em-none-eabi \
# --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-hal/Cargo.toml --target thumbv7em-none-eabi \
# --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-irq/Cargo.toml --target thumbv7em-none-eabi \
# --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml --target thumbv7em-none-eabi \
# --- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840 \
# --- build --release --manifest-path examples/nrf52840-rtic/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840-rtic \
# --- build --release --manifest-path examples/nrf5340/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf5340 \
# --- build --release --manifest-path examples/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/rp \
# --- build --release --manifest-path examples/stm32f0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32f0 \
# --- build --release --manifest-path examples/stm32f1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f1 \
# --- build --release --manifest-path examples/stm32f2/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f2 \
# --- build --release --manifest-path examples/stm32f3/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f3 \
# --- build --release --manifest-path examples/stm32f334/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f334 \
# --- build --release --manifest-path examples/stm32f4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f4 \
# --- build --release --manifest-path examples/stm32f7/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f7 \
# --- build --release --manifest-path examples/stm32c0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32c0 \
# --- build --release --manifest-path examples/stm32g0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32g0 \
# --- build --release --manifest-path examples/stm32g4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32g4 \
# --- build --release --manifest-path examples/stm32h5/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32h5 \
# --- build --release --manifest-path examples/stm32h7/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32h7 \
# --- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32l0 \
# --- build --release --manifest-path examples/stm32l1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32l1 \
# --- build --release --manifest-path examples/stm32l4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32l4 \
# --- build --release --manifest-path examples/stm32l5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32l5 \
# --- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \
# --- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wb \
# --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32wba \
# --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wl \
# --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --out-dir out/examples/boot/nrf52840 \
# --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --out-dir out/examples/boot/nrf9160 \
# --- build --release --manifest-path examples/boot/application/rp/Cargo.toml --target thumbv6m-none-eabi --features skip-include --out-dir out/examples/boot/rp \
# --- build --release --manifest-path examples/boot/application/stm32f3/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32f3 \
# --- build --release --manifest-path examples/boot/application/stm32f7/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32f7 \
# --- build --release --manifest-path examples/boot/application/stm32h7/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32h7 \
# --- build --release --manifest-path examples/boot/application/stm32l0/Cargo.toml --target thumbv6m-none-eabi --features skip-include --out-dir out/examples/boot/stm32l0 \
# --- build --release --manifest-path examples/boot/application/stm32l1/Cargo.toml --target thumbv7m-none-eabi --features skip-include --out-dir out/examples/boot/stm32l1 \
# --- build --release --manifest-path examples/boot/application/stm32l4/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32l4 \
# --- build --release --manifest-path examples/boot/application/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --features skip-include --out-dir out/examples/boot/stm32wl \
# --- build --release --manifest-path examples/boot/bootloader/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840 \
# --- build --release --manifest-path examples/boot/bootloader/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns \
# --- build --release --manifest-path examples/boot/bootloader/rp/Cargo.toml --target thumbv6m-none-eabi \
# --- build --release --manifest-path examples/boot/bootloader/stm32/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32wl55jc-cm4 \
# --- build --release --manifest-path examples/wasm/Cargo.toml --target wasm32-unknown-unknown --out-dir out/examples/wasm \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f103c8 --out-dir out/tests/stm32f103c8 \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi --out-dir out/tests/stm32f429zi \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re --out-dir out/tests/stm32g491re \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32g071rb --out-dir out/tests/stm32g071rb \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32c031c6 --out-dir out/tests/stm32c031c6 \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi --out-dir out/tests/stm32h755zi \
#
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h563zi --out-dir out/tests/stm32h563zi \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585ai --out-dir out/tests/stm32u585ai \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l073rz --out-dir out/tests/stm32l073rz \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l152re --out-dir out/tests/stm32l152re \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4a6zg --out-dir out/tests/stm32l4a6zg \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r5zi --out-dir out/tests/stm32l4r5zi \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze --out-dir out/tests/stm32l552ze \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f767zi --out-dir out/tests/stm32f767zi \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f207zg --out-dir out/tests/stm32f207zg \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303ze --out-dir out/tests/stm32f303ze \
# --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l496zg --out-dir out/tests/stm32l496zg \
# --- build --release --manifest-path tests/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/tests/rpi-pico \
# --- build --release --manifest-path tests/nrf/Cargo.toml --target thumbv7em-none-eabi --out-dir out/tests/nrf52840-dk \
# --- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \
# $BUILD_EXTRA
rm out/tests/stm32wb55rg/wpan_mac rm /ci/cache/teleprobe_cache.json
rm out/tests/stm32wb55rg/wpan_ble
rm out/tests/stm32f207zg/eth
if [[ -z "${TELEPROBE_TOKEN-}" ]]; then if [[ -z "${TELEPROBE_TOKEN-}" ]]; then
echo No teleprobe token found, skipping running HIL tests echo No teleprobe token found, skipping running HIL tests

View File

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

View File

@ -11,10 +11,11 @@ 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"}
atomic-polyfill = "0.1.5"
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
log = { version = "0.4.17", optional = true } log = { version = "0.4.17", optional = true }

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ The Embassy executor is an async/await executor designed for embedded usage alon
* No `alloc`, no heap needed. Task are statically allocated. * No `alloc`, no heap needed. Task are statically allocated.
* No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. * No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning.
* Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. * Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`.
* No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`. * No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`.
* Efficient polling: a wake will only poll the woken task, not all of them. * Efficient polling: a wake will only poll the woken task, not all of them.
* Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time. * Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time.

View File

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

View File

@ -11,7 +11,7 @@ pub use asynch::Partition;
pub use blocking::BlockingPartition; pub use blocking::BlockingPartition;
/// Partition error /// Partition error
#[derive(Debug, PartialEq, Eq)] #[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error<T> { pub enum Error<T> {
/// The requested flash area is outside the partition /// The requested flash area is outside the partition

View File

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

View File

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

View File

@ -4,7 +4,7 @@ An async/await executor designed for embedded usage.
- No `alloc`, no heap needed. Task futures are statically allocated. - No `alloc`, no heap needed. Task futures are statically allocated.
- No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. - No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning.
- Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. - Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`.
- No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`. - No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`.
- Efficient polling: a wake will only poll the woken task, not all of them. - Efficient polling: a wake will only poll the woken task, not all of them.
- Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time. - Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,8 +15,8 @@ log = ["dep:log", "ppproto/log"]
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 }
embedded-io-async = { version = "0.6.0" } embedded-io-async = { version = "0.5.0" }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
ppproto = { version = "0.1.2"} ppproto = { version = "0.1.2"}
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }

View File

@ -11,7 +11,7 @@ use core::mem::MaybeUninit;
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 embedded_io_async::{BufRead, Write}; use embedded_io_async::{BufRead, Write, WriteAllError};
use ppproto::pppos::{BufferFullError, PPPoS, PPPoSAction}; use ppproto::pppos::{BufferFullError, PPPoS, PPPoSAction};
pub use ppproto::{Config, Ipv4Status}; pub use ppproto::{Config, Ipv4Status};
@ -49,12 +49,23 @@ pub enum RunError<E> {
Read(E), Read(E),
/// Writing to the serial port failed. /// Writing to the serial port failed.
Write(E), Write(E),
/// Writing to the serial port wrote zero bytes, indicating it can't accept more data.
WriteZero,
/// Writing to the serial got EOF. /// Writing to the serial got EOF.
Eof, Eof,
/// PPP protocol was terminated by the peer /// PPP protocol was terminated by the peer
Terminated, Terminated,
} }
impl<E> From<WriteAllError<E>> for RunError<E> {
fn from(value: WriteAllError<E>) -> Self {
match value {
WriteAllError::Other(e) => Self::Write(e),
WriteAllError::WriteZero => Self::WriteZero,
}
}
}
impl<'d> Runner<'d> { impl<'d> Runner<'d> {
/// You must call this in a background task for the driver to operate. /// You must call this in a background task for the driver to operate.
/// ///
@ -114,7 +125,7 @@ impl<'d> Runner<'d> {
buf[..pkt.len()].copy_from_slice(pkt); buf[..pkt.len()].copy_from_slice(pkt);
rx_chan.rx_done(pkt.len()); rx_chan.rx_done(pkt.len());
} }
PPPoSAction::Transmit(n) => rw.write_all(&tx_buf[..n]).await.map_err(RunError::Write)?, PPPoSAction::Transmit(n) => rw.write_all(&tx_buf[..n]).await?,
} }
let status = ppp.status(); let status = ppp.status();
@ -137,7 +148,7 @@ impl<'d> Runner<'d> {
} }
Either::Second(pkt) => { Either::Second(pkt) => {
match ppp.send(pkt, &mut tx_buf) { match ppp.send(pkt, &mut tx_buf) {
Ok(n) => rw.write_all(&tx_buf[..n]).await.map_err(RunError::Write)?, Ok(n) => rw.write_all(&tx_buf[..n]).await?,
Err(BufferFullError) => unreachable!(), Err(BufferFullError) => unreachable!(),
} }
tx_chan.tx_done(); tx_chan.tx_done();

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
[package] [package]
name = "embassy-net" name = "embassy-net"
version = "0.2.0" version = "0.1.0"
edition = "2021" edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "Async TCP/IP network stack for embedded systems" description = "Async TCP/IP network stack for embedded systems"
@ -33,7 +33,6 @@ udp = ["smoltcp/socket-udp"]
tcp = ["smoltcp/socket-tcp"] tcp = ["smoltcp/socket-tcp"]
dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"] dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"]
dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"] dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"]
dhcpv4-hostname = ["dhcpv4"]
proto-ipv4 = ["smoltcp/proto-ipv4"] proto-ipv4 = ["smoltcp/proto-ipv4"]
proto-ipv6 = ["smoltcp/proto-ipv6"] proto-ipv6 = ["smoltcp/proto-ipv6"]
medium-ethernet = ["smoltcp/medium-ethernet"] medium-ethernet = ["smoltcp/medium-ethernet"]
@ -51,10 +50,10 @@ 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.5.0", optional = true }
managed = { version = "0.8.0", default-features = false, features = [ "map" ] } managed = { version = "0.8.0", default-features = false, features = [ "map" ] }
heapless = { version = "0.7.5", default-features = false } heapless = { version = "0.7.5", default-features = false }
@ -63,4 +62,5 @@ generic-array = { version = "0.14.4", default-features = false }
stable_deref_trait = { version = "1.2.0", default-features = false } stable_deref_trait = { version = "1.2.0", default-features = false }
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
atomic-pool = "1.0" atomic-pool = "1.0"
embedded-nal-async = { version = "0.6.0", optional = true } embedded-nal-async = { version = "0.5.0", optional = true }
atomic-polyfill = { version = "1.0" }

View File

@ -39,7 +39,7 @@ use smoltcp::socket::dhcpv4::{self, RetryConfig};
pub use smoltcp::wire::EthernetAddress; pub use smoltcp::wire::EthernetAddress;
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154", feature = "medium-ip"))] #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154", feature = "medium-ip"))]
pub use smoltcp::wire::HardwareAddress; pub use smoltcp::wire::HardwareAddress;
#[cfg(any(feature = "udp", feature = "tcp"))] #[cfg(feature = "udp")]
pub use smoltcp::wire::IpListenEndpoint; pub use smoltcp::wire::IpListenEndpoint;
#[cfg(feature = "medium-ieee802154")] #[cfg(feature = "medium-ieee802154")]
pub use smoltcp::wire::{Ieee802154Address, Ieee802154Frame}; pub use smoltcp::wire::{Ieee802154Address, Ieee802154Frame};
@ -56,22 +56,12 @@ const LOCAL_PORT_MIN: u16 = 1025;
const LOCAL_PORT_MAX: u16 = 65535; const LOCAL_PORT_MAX: u16 = 65535;
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
const MAX_QUERIES: usize = 4; const MAX_QUERIES: usize = 4;
#[cfg(feature = "dhcpv4-hostname")]
const MAX_HOSTNAME_LEN: usize = 32;
/// Memory resources needed for a network stack. /// Memory resources needed for a network stack.
pub struct StackResources<const SOCK: usize> { pub struct StackResources<const SOCK: usize> {
sockets: [SocketStorage<'static>; SOCK], sockets: [SocketStorage<'static>; SOCK],
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
queries: [Option<dns::DnsQuery>; MAX_QUERIES], queries: [Option<dns::DnsQuery>; MAX_QUERIES],
#[cfg(feature = "dhcpv4-hostname")]
hostname: core::cell::UnsafeCell<HostnameResources>,
}
#[cfg(feature = "dhcpv4-hostname")]
struct HostnameResources {
option: smoltcp::wire::DhcpOption<'static>,
data: [u8; MAX_HOSTNAME_LEN],
} }
impl<const SOCK: usize> StackResources<SOCK> { impl<const SOCK: usize> StackResources<SOCK> {
@ -83,11 +73,6 @@ impl<const SOCK: usize> StackResources<SOCK> {
sockets: [SocketStorage::EMPTY; SOCK], sockets: [SocketStorage::EMPTY; SOCK],
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
queries: [INIT; MAX_QUERIES], queries: [INIT; MAX_QUERIES],
#[cfg(feature = "dhcpv4-hostname")]
hostname: core::cell::UnsafeCell::new(HostnameResources {
option: smoltcp::wire::DhcpOption { kind: 0, data: &[] },
data: [0; MAX_HOSTNAME_LEN],
}),
} }
} }
} }
@ -119,7 +104,6 @@ pub struct StaticConfigV6 {
/// DHCP configuration. /// DHCP configuration.
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct DhcpConfig { pub struct DhcpConfig {
/// Maximum lease duration. /// Maximum lease duration.
/// ///
@ -136,9 +120,6 @@ pub struct DhcpConfig {
pub server_port: u16, pub server_port: u16,
/// Client port. This is almost always 68. Do not change unless you know what you're doing. /// Client port. This is almost always 68. Do not change unless you know what you're doing.
pub client_port: u16, pub client_port: u16,
/// Our hostname. This will be sent to the DHCP server as Option 12.
#[cfg(feature = "dhcpv4-hostname")]
pub hostname: Option<heapless::String<MAX_HOSTNAME_LEN>>,
} }
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
@ -150,8 +131,6 @@ impl Default for DhcpConfig {
ignore_naks: Default::default(), ignore_naks: Default::default(),
server_port: smoltcp::wire::DHCP_SERVER_PORT, server_port: smoltcp::wire::DHCP_SERVER_PORT,
client_port: smoltcp::wire::DHCP_CLIENT_PORT, client_port: smoltcp::wire::DHCP_CLIENT_PORT,
#[cfg(feature = "dhcpv4-hostname")]
hostname: None,
} }
} }
} }
@ -253,8 +232,6 @@ struct Inner<D: Driver> {
dns_socket: SocketHandle, dns_socket: SocketHandle,
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
dns_waker: WakerRegistration, dns_waker: WakerRegistration,
#[cfg(feature = "dhcpv4-hostname")]
hostname: &'static mut core::cell::UnsafeCell<HostnameResources>,
} }
pub(crate) struct SocketStack { pub(crate) struct SocketStack {
@ -330,8 +307,6 @@ impl<D: Driver> Stack<D> {
)), )),
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
dns_waker: WakerRegistration::new(), dns_waker: WakerRegistration::new(),
#[cfg(feature = "dhcpv4-hostname")]
hostname: &mut resources.hostname,
}; };
#[cfg(feature = "proto-ipv4")] #[cfg(feature = "proto-ipv4")]
@ -509,10 +484,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
@ -701,25 +673,6 @@ impl<D: Driver> Inner<D> {
socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp)); socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp));
socket.set_ports(c.server_port, c.client_port); socket.set_ports(c.server_port, c.client_port);
socket.set_retry_config(c.retry_config); socket.set_retry_config(c.retry_config);
socket.set_outgoing_options(&[]);
#[cfg(feature = "dhcpv4-hostname")]
if let Some(h) = c.hostname {
// safety: we just did set_outgoing_options([]) so we know the socket is no longer holding a reference.
let hostname = unsafe { &mut *self.hostname.get() };
// create data
// safety: we know the buffer lives forever, new borrows the StackResources for 'static.
// also we won't modify it until next call to this function.
hostname.data[..h.len()].copy_from_slice(h.as_bytes());
let data: &[u8] = &hostname.data[..h.len()];
let data: &'static [u8] = unsafe { core::mem::transmute(data) };
// set the option.
hostname.option = smoltcp::wire::DhcpOption { data, kind: 12 };
socket.set_outgoing_options(core::slice::from_ref(&hostname.option));
}
socket.reset(); socket.reset();
} }
_ => { _ => {

View File

@ -579,10 +579,11 @@ mod embedded_io_impls {
/// TCP client compatible with `embedded-nal-async` traits. /// TCP client compatible with `embedded-nal-async` traits.
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
pub mod client { pub mod client {
use core::cell::{Cell, UnsafeCell}; use core::cell::UnsafeCell;
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use core::ptr::NonNull; use core::ptr::NonNull;
use atomic_polyfill::{AtomicBool, Ordering};
use embedded_nal_async::IpAddr; use embedded_nal_async::IpAddr;
use super::*; use super::*;
@ -701,13 +702,15 @@ pub mod client {
} }
} }
unsafe impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize> Sync for TcpClientState<N, TX_SZ, RX_SZ> {}
struct Pool<T, const N: usize> { struct Pool<T, const N: usize> {
used: [Cell<bool>; N], used: [AtomicBool; N],
data: [UnsafeCell<MaybeUninit<T>>; N], data: [UnsafeCell<MaybeUninit<T>>; N],
} }
impl<T, const N: usize> Pool<T, N> { impl<T, const N: usize> Pool<T, N> {
const VALUE: Cell<bool> = Cell::new(false); const VALUE: AtomicBool = AtomicBool::new(false);
const UNINIT: UnsafeCell<MaybeUninit<T>> = UnsafeCell::new(MaybeUninit::uninit()); const UNINIT: UnsafeCell<MaybeUninit<T>> = UnsafeCell::new(MaybeUninit::uninit());
const fn new() -> Self { const fn new() -> Self {
@ -721,9 +724,7 @@ pub mod client {
impl<T, const N: usize> Pool<T, N> { impl<T, const N: usize> Pool<T, N> {
fn alloc(&self) -> Option<NonNull<T>> { fn alloc(&self) -> Option<NonNull<T>> {
for n in 0..N { for n in 0..N {
// this can't race because Pool is not Sync. if self.used[n].swap(true, Ordering::SeqCst) == false {
if !self.used[n].get() {
self.used[n].set(true);
let p = self.data[n].get() as *mut T; let p = self.data[n].get() as *mut T;
return Some(unsafe { NonNull::new_unchecked(p) }); return Some(unsafe { NonNull::new_unchecked(p) });
} }
@ -737,7 +738,7 @@ pub mod client {
let n = p.as_ptr().offset_from(origin); let n = p.as_ptr().offset_from(origin);
assert!(n >= 0); assert!(n >= 0);
assert!((n as usize) < N); assert!((n as usize) < N);
self.used[n as usize].set(false); self.used[n as usize].store(false, Ordering::SeqCst);
} }
} }
} }

View File

@ -94,7 +94,7 @@ _gpio-p1 = []
_nrf52832_anomaly_109 = [] _nrf52832_anomaly_109 = []
[dependencies] [dependencies]
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
@ -103,8 +103,8 @@ embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optiona
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = true} embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = true}
embedded-hal-async = { version = "=1.0.0-rc.1", optional = true} embedded-hal-async = { version = "=1.0.0-rc.1", optional = true}
embedded-io = { version = "0.6.0" } embedded-io = { version = "0.5.0" }
embedded-io-async = { version = "0.6.0", optional = true } embedded-io-async = { version = "0.5.0", optional = true }
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 }

View File

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

View File

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

View File

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

View File

@ -60,7 +60,7 @@ unstable-traits = ["embedded-hal-1", "embedded-hal-nb"]
[dependencies] [dependencies]
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } embassy-time = { version = "0.1.3", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
@ -75,8 +75,8 @@ cortex-m = "0.7.6"
critical-section = "1.1" critical-section = "1.1"
futures = { version = "0.3.17", default-features = false, features = ["async-await"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
chrono = { version = "0.4", default-features = false, optional = true } chrono = { version = "0.4", default-features = false, optional = true }
embedded-io = { version = "0.6.0" } embedded-io = { version = "0.5.0" }
embedded-io-async = { version = "0.6.0", optional = true } embedded-io-async = { version = "0.5.0", optional = true }
embedded-storage = { version = "0.3" } embedded-storage = { version = "0.3" }
embedded-storage-async = { version = "0.4.0", optional = true } embedded-storage-async = { version = "0.4.0", optional = true }
rand_core = "0.6.4" rand_core = "0.6.4"

View File

@ -1,83 +0,0 @@
//! Boot Select button
//!
//! The RP2040 rom supports a BOOTSEL button that is used to enter the USB bootloader
//! if held during reset. To avoid wasting GPIO pins, the button is multiplexed onto
//! the CS pin of the QSPI flash, but that makes it somewhat expensive and complicated
//! to utilize outside of the rom's bootloader.
//!
//! This module provides functionality to poll BOOTSEL from an embassy application.
use crate::flash::in_ram;
impl crate::peripherals::BOOTSEL {
/// Polls the BOOTSEL button. Returns true if the button is pressed.
///
/// Polling isn't cheap, as this function waits for core 1 to finish it's current
/// task and for any DMAs from flash to complete
pub fn is_pressed(&mut self) -> bool {
let mut cs_status = Default::default();
unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0");
// bootsel is active low, so invert
!cs_status.infrompad()
}
}
mod ram_helpers {
use rp_pac::io::regs::GpioStatus;
/// Temporally reconfigures the CS gpio and returns the GpioStatus.
/// This function runs from RAM so it can disable flash XIP.
///
/// # Safety
///
/// The caller must ensure flash is idle and will remain idle.
/// This function must live in ram. It uses inline asm to avoid any
/// potential calls to ABI functions that might be in flash.
#[inline(never)]
#[link_section = ".data.ram_func"]
#[cfg(target_arch = "arm")]
pub unsafe fn read_cs_status() -> GpioStatus {
let result: u32;
// Magic value, used as both OEOVER::DISABLE and delay loop counter
let magic = 0x2000;
core::arch::asm!(
".equiv GPIO_STATUS, 0x0",
".equiv GPIO_CTRL, 0x4",
"ldr {orig_ctrl}, [{cs_gpio}, $GPIO_CTRL]",
// The BOOTSEL pulls the flash's CS line low though a 1K resistor.
// this is weak enough to avoid disrupting normal operation.
// But, if we disable CS's output drive and allow it to float...
"str {val}, [{cs_gpio}, $GPIO_CTRL]",
// ...then wait for the state to settle...
"1:", // ~4000 cycle delay loop
"subs {val}, #8",
"bne 1b",
// ...we can read the current state of bootsel
"ldr {val}, [{cs_gpio}, $GPIO_STATUS]",
// Finally, restore CS to normal operation so XIP can continue
"str {orig_ctrl}, [{cs_gpio}, $GPIO_CTRL]",
cs_gpio = in(reg) rp_pac::IO_QSPI.gpio(1).as_ptr(),
orig_ctrl = out(reg) _,
val = inout(reg) magic => result,
options(nostack),
);
core::mem::transmute(result)
}
#[cfg(not(target_arch = "arm"))]
pub unsafe fn read_cs_status() -> GpioStatus {
unimplemented!()
}
}

View File

@ -131,7 +131,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
let len = to - from; let len = to - from;
unsafe { in_ram(|| ram_helpers::flash_range_erase(from, len))? }; unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len))? };
Ok(()) Ok(())
} }
@ -156,7 +156,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
let unaligned_offset = offset as usize - start; let unaligned_offset = offset as usize - start;
unsafe { in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
} }
let remaining_len = bytes.len() - start_padding; let remaining_len = bytes.len() - start_padding;
@ -174,12 +174,12 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
if bytes.as_ptr() as usize >= 0x2000_0000 { if bytes.as_ptr() as usize >= 0x2000_0000 {
let aligned_data = &bytes[start_padding..end_padding]; let aligned_data = &bytes[start_padding..end_padding];
unsafe { in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? } unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? }
} else { } else {
for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) { for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) {
let mut ram_buf = [0xFF_u8; PAGE_SIZE]; let mut ram_buf = [0xFF_u8; PAGE_SIZE];
ram_buf.copy_from_slice(chunk); ram_buf.copy_from_slice(chunk);
unsafe { in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? } unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? }
aligned_offset += PAGE_SIZE; aligned_offset += PAGE_SIZE;
} }
} }
@ -194,15 +194,47 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset); let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset);
unsafe { in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
} }
Ok(()) Ok(())
} }
/// Make sure to uphold the contract points with rp2040-flash.
/// - interrupts must be disabled
/// - DMA must not access flash memory
unsafe fn in_ram(&mut self, operation: impl FnOnce()) -> Result<(), Error> {
// Make sure we're running on CORE0
let core_id: u32 = pac::SIO.cpuid().read();
if core_id != 0 {
return Err(Error::InvalidCore);
}
// Make sure CORE1 is paused during the entire duration of the RAM function
crate::multicore::pause_core1();
critical_section::with(|_| {
// Wait for all DMA channels in flash to finish before ram operation
const SRAM_LOWER: u32 = 0x2000_0000;
for n in 0..crate::dma::CHANNEL_COUNT {
let ch = crate::pac::DMA.ch(n);
while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {}
}
// Wait for completion of any background reads
while pac::XIP_CTRL.stream_ctr().read().0 > 0 {}
// Run our flash operation in RAM
operation();
});
// Resume CORE1 execution
crate::multicore::resume_core1();
Ok(())
}
/// Read SPI flash unique ID /// Read SPI flash unique ID
pub fn blocking_unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> { pub fn blocking_unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> {
unsafe { in_ram(|| ram_helpers::flash_unique_id(uid))? }; unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid))? };
Ok(()) Ok(())
} }
@ -210,7 +242,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
pub fn blocking_jedec_id(&mut self) -> Result<u32, Error> { pub fn blocking_jedec_id(&mut self) -> Result<u32, Error> {
let mut jedec = None; let mut jedec = None;
unsafe { unsafe {
in_ram(|| { self.in_ram(|| {
jedec.replace(ram_helpers::flash_jedec_id()); jedec.replace(ram_helpers::flash_jedec_id());
})?; })?;
}; };
@ -839,38 +871,6 @@ mod ram_helpers {
} }
} }
/// Make sure to uphold the contract points with rp2040-flash.
/// - interrupts must be disabled
/// - DMA must not access flash memory
pub(crate) unsafe fn in_ram(operation: impl FnOnce()) -> Result<(), Error> {
// Make sure we're running on CORE0
let core_id: u32 = pac::SIO.cpuid().read();
if core_id != 0 {
return Err(Error::InvalidCore);
}
// Make sure CORE1 is paused during the entire duration of the RAM function
crate::multicore::pause_core1();
critical_section::with(|_| {
// Wait for all DMA channels in flash to finish before ram operation
const SRAM_LOWER: u32 = 0x2000_0000;
for n in 0..crate::dma::CHANNEL_COUNT {
let ch = crate::pac::DMA.ch(n);
while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {}
}
// Wait for completion of any background reads
while pac::XIP_CTRL.stream_ctr().read().0 > 0 {}
// Run our flash operation in RAM
operation();
});
// Resume CORE1 execution
crate::multicore::resume_core1();
Ok(())
}
mod sealed { mod sealed {
pub trait Instance {} pub trait Instance {}
pub trait Mode {} pub trait Mode {}

View File

@ -6,12 +6,13 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use pac::i2c; use pac::i2c;
use crate::gpio::sealed::Pin;
use crate::gpio::AnyPin; use crate::gpio::AnyPin;
use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{interrupt, pac, peripherals, Peripheral}; use crate::{interrupt, pac, peripherals, Peripheral};
/// I2C error abort reason /// I2C error abort reason
#[derive(Debug, PartialEq, Eq)] #[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum AbortReason { pub enum AbortReason {
/// A bus operation was not acknowledged, e.g. due to the addressed device /// A bus operation was not acknowledged, e.g. due to the addressed device
@ -26,7 +27,7 @@ pub enum AbortReason {
} }
/// I2C error /// I2C error
#[derive(Debug, PartialEq, Eq)] #[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error { pub enum Error {
/// I2C abort with error /// I2C abort with error
@ -294,24 +295,13 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> { pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> {
Self::setup(addr)?; Self::setup(addr)?;
self.read_async_internal(buffer, true, true).await self.read_async_internal(buffer, false, true).await
} }
pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator<Item = u8>) -> Result<(), Error> { pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator<Item = u8>) -> Result<(), Error> {
Self::setup(addr)?; Self::setup(addr)?;
self.write_async_internal(bytes, true).await self.write_async_internal(bytes, true).await
} }
pub async fn write_read_async(
&mut self,
addr: u16,
bytes: impl IntoIterator<Item = u8>,
buffer: &mut [u8],
) -> Result<(), Error> {
Self::setup(addr)?;
self.write_async_internal(bytes, false).await?;
self.read_async_internal(buffer, true, true).await
}
} }
pub struct InterruptHandler<T: Instance> { pub struct InterruptHandler<T: Instance> {
@ -328,22 +318,6 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
} }
} }
pub(crate) fn set_up_i2c_pin<'d, P, T>(pin: &P)
where
P: core::ops::Deref<Target = T>,
T: crate::gpio::Pin,
{
pin.gpio().ctrl().write(|w| w.set_funcsel(3));
pin.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_slewfast(false);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
}
impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
fn new_inner( fn new_inner(
_peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
@ -381,8 +355,23 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
p.ic_rx_tl().write(|w| w.set_rx_tl(0)); p.ic_rx_tl().write(|w| w.set_rx_tl(0));
// Configure SCL & SDA pins // Configure SCL & SDA pins
set_up_i2c_pin(&scl); scl.gpio().ctrl().write(|w| w.set_funcsel(3));
set_up_i2c_pin(&sda); sda.gpio().ctrl().write(|w| w.set_funcsel(3));
scl.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
sda.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
// Configure baudrate // Configure baudrate
@ -724,7 +713,7 @@ mod nightly {
Self::setup(addr)?; Self::setup(addr)?;
self.write_async_internal(write.iter().cloned(), false).await?; self.write_async_internal(write.iter().cloned(), false).await?;
self.read_async_internal(read, true, true).await self.read_async_internal(read, false, true).await
} }
async fn transaction(&mut self, address: A, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { async fn transaction(&mut self, address: A, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {

View File

@ -5,14 +5,12 @@ use core::task::Poll;
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use pac::i2c; use pac::i2c;
use crate::i2c::{ use crate::i2c::{i2c_reserved_addr, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE};
i2c_reserved_addr, set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE,
};
use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{pac, Peripheral}; use crate::{pac, Peripheral};
/// I2C error /// I2C error
#[derive(Debug, PartialEq, Eq)] #[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive] #[non_exhaustive]
pub enum Error { pub enum Error {
@ -102,8 +100,23 @@ impl<'d, T: Instance> I2cSlave<'d, T> {
p.ic_rx_tl().write(|w| w.set_rx_tl(0)); p.ic_rx_tl().write(|w| w.set_rx_tl(0));
// Configure SCL & SDA pins // Configure SCL & SDA pins
set_up_i2c_pin(&scl); scl.gpio().ctrl().write(|w| w.set_funcsel(3));
set_up_i2c_pin(&sda); sda.gpio().ctrl().write(|w| w.set_funcsel(3));
scl.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
sda.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
// Clear interrupts // Clear interrupts
p.ic_clr_intr().read(); p.ic_clr_intr().read();

View File

@ -10,7 +10,6 @@ mod critical_section_impl;
mod intrinsics; mod intrinsics;
pub mod adc; pub mod adc;
pub mod bootsel;
pub mod clocks; pub mod clocks;
pub mod dma; pub mod dma;
pub mod flash; pub mod flash;
@ -194,7 +193,6 @@ embassy_hal_internal::peripherals! {
PIO1, PIO1,
WATCHDOG, WATCHDOG,
BOOTSEL,
} }
macro_rules! select_bootloader { macro_rules! select_bootloader {

View File

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

View File

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

View File

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

View File

@ -33,11 +33,11 @@ flavors = [
[dependencies] [dependencies]
embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.3", path = "../embassy-time", optional = true }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
embassy-executor = { version = "0.3.0", path = "../embassy-executor", optional = true } embassy-executor = { version = "0.3.0", path = "../embassy-executor", optional = true }
@ -58,14 +58,16 @@ 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" } atomic-polyfill = "1.0.1"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-06d13dfd245cc9bf86fd88c35b401bdb84c079c4" }
vcell = "0.1.3" vcell = "0.1.3"
bxcan = "0.7.0" bxcan = "0.7.0"
nb = "1.0.0" nb = "1.0.0"
stm32-fmc = "0.3.0" stm32-fmc = "0.3.0"
seq-macro = "0.3.0"
cfg-if = "1.0.0" cfg-if = "1.0.0"
embedded-io = { version = "0.6.0" } embedded-io = { version = "0.5.0" }
embedded-io-async = { version = "0.6.0", optional = true } embedded-io-async = { version = "0.5.0", optional = true }
chrono = { version = "^0.4", default-features = false, optional = true} chrono = { version = "^0.4", default-features = false, optional = true}
bit_field = "0.10.2" bit_field = "0.10.2"
document-features = "0.2.7" document-features = "0.2.7"
@ -76,7 +78,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-06d13dfd245cc9bf86fd88c35b401bdb84c079c4", default-features = false, features = ["metadata"]}
[features] [features]

View File

@ -5,36 +5,9 @@ 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::{MemoryRegionKind, METADATA};
use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA};
fn main() { fn main() {
let target = env::var("TARGET").unwrap();
if target.starts_with("thumbv6m-") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv6m");
} else if target.starts_with("thumbv7m-") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv7m");
} else if target.starts_with("thumbv7em-") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv7m");
println!("cargo:rustc-cfg=armv7em"); // (not currently used)
} else if target.starts_with("thumbv8m.base") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv8m");
println!("cargo:rustc-cfg=armv8m_base");
} else if target.starts_with("thumbv8m.main") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv8m");
println!("cargo:rustc-cfg=armv8m_main");
}
if target.ends_with("-eabihf") {
println!("cargo:rustc-cfg=has_fpu");
}
let chip_name = match env::vars() let chip_name = match env::vars()
.map(|(a, _)| a) .map(|(a, _)| a)
.filter(|x| x.starts_with("CARGO_FEATURE_STM32")) .filter(|x| x.starts_with("CARGO_FEATURE_STM32"))
@ -77,14 +50,12 @@ fn main() {
// We *shouldn't* have singletons for these, but the HAL currently requires // We *shouldn't* have singletons for these, but the HAL currently requires
// singletons, for using with RccPeripheral to enable/disable clocks to them. // singletons, for using with RccPeripheral to enable/disable clocks to them.
"rcc" => { "rcc" => {
for pin in p.pins { if r.version.starts_with("h5") || r.version.starts_with("h7") || r.version.starts_with("f4") {
if pin.signal.starts_with("MCO") { singletons.push("MCO1".to_string());
let name = pin.signal.replace('_', "").to_string(); singletons.push("MCO2".to_string());
if !singletons.contains(&name) { }
println!("cargo:rustc-cfg={}", name.to_ascii_lowercase()); if r.version.starts_with("l4") {
singletons.push(name); singletons.push("MCO".to_string());
}
}
} }
singletons.push(p.name.to_string()); singletons.push(p.name.to_string());
} }
@ -388,47 +359,6 @@ 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
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_fieldsets: HashMap<&str, &FieldSet> = rcc_registers.ir.fieldsets.iter().map(|f| (f.name, f)).collect();
let rcc_enums: HashMap<&str, &Enum> = rcc_registers.ir.enums.iter().map(|e| (e.name, e)).collect();
rcc_blocks
.iter()
.filter_map(|b| match &b.inner {
BlockItemInner::Register(register) => register.fieldset.map(|f| (b.name, f)),
_ => None,
})
.filter_map(|(b, f)| {
rcc_fieldsets.get(f).map(|f| {
(
b,
f.fields
.iter()
.filter_map(|f| {
let enumm = f.enumm?;
let enumm = rcc_enums.get(enumm)?;
Some((f.name, *enumm))
})
.collect(),
)
})
})
.collect()
};
// ======== // ========
// Generate RccPeripheral impls // Generate RccPeripheral impls
@ -448,8 +378,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 +398,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,82 +426,31 @@ 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>| {
// restrict mux implementation to supported versions
if !mux_supported {
return None;
}
let mux = mux?;
let fieldset = rcc_enum_map.get(mux.register)?;
let enumm = fieldset.get(mux.field)?;
Some((mux, *enumm))
};
let clock_frequency = match mux_for(rcc.mux.as_ref()) {
Some((mux, rcc_enumm)) => {
let fieldset_name = format_ident!("{}", mux.register);
let field_name = format_ident!("{}", mux.field);
let enum_name = format_ident!("{}", rcc_enumm.name);
let match_arms: TokenStream = rcc_enumm
.variants
.iter()
.filter(|v| v.name != "DISABLE")
.map(|v| {
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" {
quote! {
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name },
}
} else {
quote! {
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
}
}
})
.collect();
quote! {
use crate::pac::rcc::vals::#enum_name;
#[allow(unreachable_patterns)]
match crate::pac::RCC.#fieldset_name().read().#field_name() {
#match_arms
_ => unreachable!(),
}
}
}
None => quote! {
unsafe { crate::rcc::get_freqs().#clk }
},
};
g.extend(quote! { g.extend(quote! {
impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { impl crate::rcc::sealed::RccPeripheral for peripherals::#pname {
fn frequency() -> crate::time::Hertz { fn frequency() -> crate::time::Hertz {
#clock_frequency unsafe { crate::rcc::get_freqs().#clk }
} }
fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { fn enable() {
#before_enable critical_section::with(|_| {
#[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();
#after_enable crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true));
#after_enable
})
}
fn disable() {
critical_section::with(|_| {
#before_disable
crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false));
#[cfg(feature = "low-power")]
crate::rcc::clock_refcount_sub();
})
}
fn reset() {
#rst #rst
} }
fn disable_with_cs(_cs: critical_section::CriticalSection) {
#before_disable
crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false));
#[cfg(feature = "low-power")]
crate::rcc::clock_refcount_sub(_cs);
}
} }
impl crate::rcc::RccPeripheral for peripherals::#pname {} impl crate::rcc::RccPeripheral for peripherals::#pname {}
@ -577,14 +458,12 @@ fn main() {
} }
} }
let refcount_mod: TokenStream = refcount_statics let mut refcount_mod = TokenStream::new();
.iter() for refcount_static in refcount_statics {
.map(|refcount_static| { refcount_mod.extend(quote! {
quote! { pub(crate) static mut #refcount_static: u8 = 0;
pub(crate) static mut #refcount_static: u8 = 0; });
} }
})
.collect();
g.extend(quote! { g.extend(quote! {
mod refcount_statics { mod refcount_statics {
@ -872,8 +751,25 @@ fn main() {
let af = pin.af.unwrap_or(0); let af = pin.af.unwrap_or(0);
// MCO is special // MCO is special
if pin.signal.starts_with("MCO") { if pin.signal.starts_with("MCO_") {
peri = format_ident!("{}", pin.signal.replace('_', "")); // Supported in H7 only for now
if regs.version.starts_with("h5")
|| regs.version.starts_with("h7")
|| regs.version.starts_with("f4")
{
peri = format_ident!("{}", pin.signal.replace('_', ""));
} else {
continue;
}
}
if pin.signal == "MCO" {
// Supported in H7 only for now
if regs.version.starts_with("l4") {
peri = format_ident!("MCO");
} else {
continue;
}
} }
g.extend(quote! { g.extend(quote! {
@ -1012,97 +908,6 @@ fn main() {
} }
} }
// ========
// Generate Div/Mul impls for RCC prescalers/dividers/multipliers.
for e in rcc_registers.ir.enums {
fn is_rcc_name(e: &str) -> bool {
match e {
"Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true,
"Timpre" | "Pllrclkpre" => false,
e if e.ends_with("pre") || e.ends_with("pres") || e.ends_with("div") || e.ends_with("mul") => true,
_ => false,
}
}
#[derive(Copy, Clone, Debug)]
struct Frac {
num: u32,
denom: u32,
}
impl Frac {
fn simplify(self) -> Self {
let d = gcd(self.num, self.denom);
Self {
num: self.num / d,
denom: self.denom / d,
}
}
}
fn gcd(a: u32, b: u32) -> u32 {
if b == 0 {
return a;
}
gcd(b, a % b)
}
fn parse_num(n: &str) -> Result<Frac, ()> {
for prefix in ["DIV", "MUL"] {
if let Some(n) = n.strip_prefix(prefix) {
let exponent = n.find('_').map(|e| n.len() - 1 - e).unwrap_or(0) as u32;
let mantissa = n.replace('_', "").parse().map_err(|_| ())?;
let f = Frac {
num: mantissa,
denom: 10u32.pow(exponent),
};
return Ok(f.simplify());
}
}
Err(())
}
if is_rcc_name(e.name) {
let enum_name = format_ident!("{}", e.name);
let mut muls = Vec::new();
let mut divs = Vec::new();
for v in e.variants {
let Ok(val) = parse_num(v.name) else {
panic!("could not parse mul/div. enum={} variant={}", e.name, v.name)
};
let variant_name = format_ident!("{}", v.name);
let variant = quote!(crate::pac::rcc::vals::#enum_name::#variant_name);
let num = val.num;
let denom = val.denom;
muls.push(quote!(#variant => self * #num / #denom,));
divs.push(quote!(#variant => self * #denom / #num,));
}
g.extend(quote! {
impl core::ops::Div<crate::pac::rcc::vals::#enum_name> for crate::time::Hertz {
type Output = crate::time::Hertz;
fn div(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output {
match rhs {
#(#divs)*
#[allow(unreachable_patterns)]
_ => unreachable!(),
}
}
}
impl core::ops::Mul<crate::pac::rcc::vals::#enum_name> for crate::time::Hertz {
type Output = crate::time::Hertz;
fn mul(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output {
match rhs {
#(#muls)*
#[allow(unreachable_patterns)]
_ => unreachable!(),
}
}
}
});
}
}
// ======== // ========
// Write foreach_foo! macrotables // Write foreach_foo! macrotables

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,7 @@ use crate::{peripherals, Peripheral};
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// Custom Errors /// Curstom Errors
pub enum Error { pub enum Error {
UnconfiguredChannel, UnconfiguredChannel,
InvalidValue, InvalidValue,
@ -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(rcc_h7)]
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(rcc_h7)]
impl crate::rcc::RccPeripheral for peripherals::$inst {}
impl crate::dac::sealed::Instance for peripherals::$inst { impl crate::dac::sealed::Instance for peripherals::$inst {
fn regs() -> &'static crate::pac::dac::Dac { fn regs() -> &'static crate::pac::dac::Dac {

View File

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

View File

@ -2,9 +2,10 @@
use core::future::Future; use core::future::Future;
use core::pin::Pin; use core::pin::Pin;
use core::sync::atomic::{fence, AtomicUsize, Ordering}; use core::sync::atomic::{fence, Ordering};
use core::task::{Context, Poll, Waker}; use core::task::{Context, Poll, Waker};
use atomic_polyfill::AtomicUsize;
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -77,10 +78,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();
}; };
} }
@ -126,13 +127,7 @@ pub(crate) unsafe fn on_irq_inner(dma: pac::bdma::Dma, channel_num: usize, index
} else if isr.tcif(channel_num) && cr.read().tcie() { } else if isr.tcif(channel_num) && cr.read().tcie() {
// Acknowledge transfer complete interrupt // Acknowledge transfer complete interrupt
dma.ifcr().write(|w| w.set_tcif(channel_num, true)); dma.ifcr().write(|w| w.set_tcif(channel_num, true));
#[cfg(not(armv6m))]
STATE.complete_count[index].fetch_add(1, Ordering::Release); STATE.complete_count[index].fetch_add(1, Ordering::Release);
#[cfg(armv6m)]
critical_section::with(|_| {
let x = STATE.complete_count[index].load(Ordering::Relaxed);
STATE.complete_count[index].store(x + 1, Ordering::Release);
})
} else { } else {
return; return;
} }
@ -396,14 +391,7 @@ impl<'a, C: Channel> DmaCtrl for DmaCtrlImpl<'a, C> {
} }
fn reset_complete_count(&mut self) -> usize { fn reset_complete_count(&mut self) -> usize {
#[cfg(not(armv6m))] STATE.complete_count[self.0.index()].swap(0, Ordering::AcqRel)
return STATE.complete_count[self.0.index()].swap(0, Ordering::AcqRel);
#[cfg(armv6m)]
return critical_section::with(|_| {
let x = STATE.complete_count[self.0.index()].load(Ordering::Acquire);
STATE.complete_count[self.0.index()].store(0, Ordering::Release);
x
});
} }
fn set_waker(&mut self, waker: &Waker) { fn set_waker(&mut self, waker: &Waker) {

View File

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

View File

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

View File

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

View File

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

View File

@ -41,40 +41,39 @@ mod phy_consts {
} }
use self::phy_consts::*; use self::phy_consts::*;
/// Generic SMI Ethernet PHY implementation /// Generic SMI Ethernet PHY
pub struct GenericSMI { pub struct GenericSMI {
phy_addr: u8,
#[cfg(feature = "time")] #[cfg(feature = "time")]
poll_interval: Duration, poll_interval: Duration,
#[cfg(not(feature = "time"))]
_private: (),
} }
impl GenericSMI { impl GenericSMI {
/// Construct the PHY. It assumes the address `phy_addr` in the SMI communication pub fn new() -> Self {
pub fn new(phy_addr: u8) -> Self {
Self { Self {
phy_addr,
#[cfg(feature = "time")] #[cfg(feature = "time")]
poll_interval: Duration::from_millis(500), poll_interval: Duration::from_millis(500),
#[cfg(not(feature = "time"))]
_private: (),
} }
} }
} }
unsafe impl PHY for GenericSMI { unsafe impl PHY for GenericSMI {
/// Reset PHY and wait for it to come out of reset.
fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) { fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) {
sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET);
while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} while sm.smi_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {}
} }
/// PHY initialisation.
fn phy_init<S: StationManagement>(&mut self, sm: &mut S) { fn phy_init<S: StationManagement>(&mut self, sm: &mut S) {
// Clear WU CSR // Clear WU CSR
self.smi_write_ext(sm, PHY_REG_WUCSR, 0); self.smi_write_ext(sm, PHY_REG_WUCSR, 0);
// Enable auto-negotiation // Enable auto-negotiation
sm.smi_write( sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M);
self.phy_addr,
PHY_REG_BCR,
PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M,
);
} }
fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool { fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool {
@ -84,7 +83,7 @@ unsafe impl PHY for GenericSMI {
#[cfg(feature = "time")] #[cfg(feature = "time")]
let _ = Timer::after(self.poll_interval).poll_unpin(cx); let _ = Timer::after(self.poll_interval).poll_unpin(cx);
let bsr = sm.smi_read(self.phy_addr, PHY_REG_BSR); let bsr = sm.smi_read(PHY_REG_BSR);
// No link without autonegotiate // No link without autonegotiate
if bsr & PHY_REG_BSR_ANDONE == 0 { if bsr & PHY_REG_BSR_ANDONE == 0 {
@ -109,9 +108,9 @@ impl GenericSMI {
// Writes a value to an extended PHY register in MMD address space // Writes a value to an extended PHY register in MMD address space
fn smi_write_ext<S: StationManagement>(&mut self, sm: &mut S, reg_addr: u16, reg_data: u16) { fn smi_write_ext<S: StationManagement>(&mut self, sm: &mut S, reg_addr: u16, reg_data: u16) {
sm.smi_write(self.phy_addr, PHY_REG_CTL, 0x0003); // set address sm.smi_write(PHY_REG_CTL, 0x0003); // set address
sm.smi_write(self.phy_addr, PHY_REG_ADDAR, reg_addr); sm.smi_write(PHY_REG_ADDAR, reg_addr);
sm.smi_write(self.phy_addr, PHY_REG_CTL, 0x4003); // set data sm.smi_write(PHY_REG_CTL, 0x4003); // set data
sm.smi_write(self.phy_addr, PHY_REG_ADDAR, reg_data); sm.smi_write(PHY_REG_ADDAR, reg_data);
} }
} }

View File

@ -134,9 +134,9 @@ impl<'a, 'd> embassy_net_driver::TxToken for TxToken<'a, 'd> {
/// The methods cannot move out of self /// The methods cannot move out of self
pub unsafe trait StationManagement { pub unsafe trait StationManagement {
/// Read a register over SMI. /// Read a register over SMI.
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16; fn smi_read(&mut self, reg: u8) -> u16;
/// Write a register over SMI. /// Write a register over SMI.
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16); fn smi_write(&mut self, reg: u8, val: u16);
} }
/// Traits for an Ethernet PHY /// Traits for an Ethernet PHY

View File

@ -107,6 +107,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd, tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd,
phy: P, phy: P,
mac_addr: [u8; 6], mac_addr: [u8; 6],
phy_addr: u8,
) -> Self { ) -> Self {
into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
@ -191,7 +192,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
@ -226,6 +227,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
station_management: EthernetStationManagement { station_management: EthernetStationManagement {
peri: PhantomData, peri: PhantomData,
clock_range: clock_range, clock_range: clock_range,
phy_addr: phy_addr,
}, },
mac_addr, mac_addr,
tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
@ -269,14 +271,15 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
pub struct EthernetStationManagement<T: Instance> { pub struct EthernetStationManagement<T: Instance> {
peri: PhantomData<T>, peri: PhantomData<T>,
clock_range: Cr, clock_range: Cr,
phy_addr: u8,
} }
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { fn smi_read(&mut self, reg: u8) -> u16 {
let mac = ETH.ethernet_mac(); let mac = ETH.ethernet_mac();
mac.macmiiar().modify(|w| { mac.macmiiar().modify(|w| {
w.set_pa(phy_addr); w.set_pa(self.phy_addr);
w.set_mr(reg); w.set_mr(reg);
w.set_mw(Mw::READ); // read operation w.set_mw(Mw::READ); // read operation
w.set_cr(self.clock_range); w.set_cr(self.clock_range);
@ -286,12 +289,12 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
mac.macmiidr().read().md() mac.macmiidr().read().md()
} }
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { fn smi_write(&mut self, reg: u8, val: u16) {
let mac = ETH.ethernet_mac(); let mac = ETH.ethernet_mac();
mac.macmiidr().write(|w| w.set_md(val)); mac.macmiidr().write(|w| w.set_md(val));
mac.macmiiar().modify(|w| { mac.macmiiar().modify(|w| {
w.set_pa(phy_addr); w.set_pa(self.phy_addr);
w.set_mr(reg); w.set_mr(reg);
w.set_mw(Mw::WRITE); // write w.set_mw(Mw::WRITE); // write
w.set_cr(self.clock_range); w.set_cr(self.clock_range);

View File

@ -71,6 +71,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd, tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd,
phy: P, phy: P,
mac_addr: [u8; 6], mac_addr: [u8; 6],
phy_addr: u8,
) -> Self { ) -> Self {
into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
@ -164,7 +165,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
@ -201,6 +202,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
station_management: EthernetStationManagement { station_management: EthernetStationManagement {
peri: PhantomData, peri: PhantomData,
clock_range: clock_range, clock_range: clock_range,
phy_addr: phy_addr,
}, },
mac_addr, mac_addr,
}; };
@ -240,14 +242,15 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
pub struct EthernetStationManagement<T: Instance> { pub struct EthernetStationManagement<T: Instance> {
peri: PhantomData<T>, peri: PhantomData<T>,
clock_range: u8, clock_range: u8,
phy_addr: u8,
} }
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { fn smi_read(&mut self, reg: u8) -> u16 {
let mac = ETH.ethernet_mac(); let mac = ETH.ethernet_mac();
mac.macmdioar().modify(|w| { mac.macmdioar().modify(|w| {
w.set_pa(phy_addr); w.set_pa(self.phy_addr);
w.set_rda(reg); w.set_rda(reg);
w.set_goc(0b11); // read w.set_goc(0b11); // read
w.set_cr(self.clock_range); w.set_cr(self.clock_range);
@ -257,12 +260,12 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
mac.macmdiodr().read().md() mac.macmdiodr().read().md()
} }
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { fn smi_write(&mut self, reg: u8, val: u16) {
let mac = ETH.ethernet_mac(); let mac = ETH.ethernet_mac();
mac.macmdiodr().write(|w| w.set_md(val)); mac.macmdiodr().write(|w| w.set_md(val));
mac.macmdioar().modify(|w| { mac.macmdioar().modify(|w| {
w.set_pa(phy_addr); w.set_pa(self.phy_addr);
w.set_rda(reg); w.set_rda(reg);
w.set_goc(0b01); // write w.set_goc(0b01); // write
w.set_cr(self.clock_range); w.set_cr(self.clock_range);

View File

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

View File

@ -19,10 +19,8 @@ pub(crate) unsafe fn lock() {
} }
pub(crate) unsafe fn unlock() { pub(crate) unsafe fn unlock() {
if pac::FLASH.cr().read().lock() { pac::FLASH.keyr().write(|w| w.set_fkeyr(0x4567_0123));
pac::FLASH.keyr().write(|w| w.set_fkeyr(0x4567_0123)); pac::FLASH.keyr().write(|w| w.set_fkeyr(0xCDEF_89AB));
pac::FLASH.keyr().write(|w| w.set_fkeyr(0xCDEF_89AB));
}
} }
pub(crate) unsafe fn enable_blocking_write() { pub(crate) unsafe fn enable_blocking_write() {

View File

@ -19,10 +19,8 @@ pub(crate) unsafe fn lock() {
} }
pub(crate) unsafe fn unlock() { pub(crate) unsafe fn unlock() {
if pac::FLASH.cr().read().lock() { pac::FLASH.keyr().write(|w| w.set_fkeyr(0x4567_0123));
pac::FLASH.keyr().write(|w| w.set_fkeyr(0x4567_0123)); pac::FLASH.keyr().write(|w| w.set_fkeyr(0xCDEF_89AB));
pac::FLASH.keyr().write(|w| w.set_fkeyr(0xCDEF_89AB));
}
} }
pub(crate) unsafe fn enable_blocking_write() { pub(crate) unsafe fn enable_blocking_write() {

View File

@ -228,10 +228,8 @@ pub(crate) unsafe fn lock() {
} }
pub(crate) unsafe fn unlock() { pub(crate) unsafe fn unlock() {
if pac::FLASH.cr().read().lock() { pac::FLASH.keyr().write(|w| w.set_key(0x45670123));
pac::FLASH.keyr().write(|w| w.set_key(0x45670123)); pac::FLASH.keyr().write(|w| w.set_key(0xCDEF89AB));
pac::FLASH.keyr().write(|w| w.set_key(0xCDEF89AB));
}
} }
pub(crate) unsafe fn enable_write() { pub(crate) unsafe fn enable_write() {

View File

@ -19,10 +19,8 @@ pub(crate) unsafe fn lock() {
} }
pub(crate) unsafe fn unlock() { pub(crate) unsafe fn unlock() {
if pac::FLASH.cr().read().lock() { pac::FLASH.keyr().write(|w| w.set_key(0x4567_0123));
pac::FLASH.keyr().write(|w| w.set_key(0x4567_0123)); pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB));
pac::FLASH.keyr().write(|w| w.set_key(0xCDEF_89AB));
}
} }
pub(crate) unsafe fn enable_blocking_write() { pub(crate) unsafe fn enable_blocking_write() {

View File

@ -24,10 +24,8 @@ pub(crate) unsafe fn unlock() {
while pac::FLASH.sr().read().bsy() {} while pac::FLASH.sr().read().bsy() {}
// Unlock flash // Unlock flash
if pac::FLASH.cr().read().lock() { pac::FLASH.keyr().write(|w| w.set_keyr(0x4567_0123));
pac::FLASH.keyr().write(|w| w.set_keyr(0x4567_0123)); pac::FLASH.keyr().write(|w| w.set_keyr(0xCDEF_89AB));
pac::FLASH.keyr().write(|w| w.set_keyr(0xCDEF_89AB));
}
} }
pub(crate) unsafe fn enable_blocking_write() { pub(crate) unsafe fn enable_blocking_write() {

View File

@ -26,15 +26,11 @@ pub(crate) unsafe fn lock() {
} }
pub(crate) unsafe fn unlock() { pub(crate) unsafe fn unlock() {
if pac::FLASH.bank(0).cr().read().lock() { pac::FLASH.bank(0).keyr().write(|w| w.set_keyr(0x4567_0123));
pac::FLASH.bank(0).keyr().write(|w| w.set_keyr(0x4567_0123)); pac::FLASH.bank(0).keyr().write(|w| w.set_keyr(0xCDEF_89AB));
pac::FLASH.bank(0).keyr().write(|w| w.set_keyr(0xCDEF_89AB));
}
if is_dual_bank() { if is_dual_bank() {
if pac::FLASH.bank(1).cr().read().lock() { pac::FLASH.bank(1).keyr().write(|w| w.set_keyr(0x4567_0123));
pac::FLASH.bank(1).keyr().write(|w| w.set_keyr(0x4567_0123)); pac::FLASH.bank(1).keyr().write(|w| w.set_keyr(0xCDEF_89AB));
pac::FLASH.bank(1).keyr().write(|w| w.set_keyr(0xCDEF_89AB));
}
} }
} }

View File

@ -28,23 +28,17 @@ pub(crate) unsafe fn lock() {
pub(crate) unsafe fn unlock() { pub(crate) unsafe fn unlock() {
#[cfg(any(flash_wl, flash_wb, flash_l4))] #[cfg(any(flash_wl, flash_wb, flash_l4))]
{ {
if pac::FLASH.cr().read().lock() { pac::FLASH.keyr().write(|w| w.set_keyr(0x4567_0123));
pac::FLASH.keyr().write(|w| w.set_keyr(0x4567_0123)); pac::FLASH.keyr().write(|w| w.set_keyr(0xCDEF_89AB));
pac::FLASH.keyr().write(|w| w.set_keyr(0xCDEF_89AB));
}
} }
#[cfg(any(flash_l0, flash_l1))] #[cfg(any(flash_l0, flash_l1))]
{ {
if pac::FLASH.pecr().read().pelock() { pac::FLASH.pekeyr().write(|w| w.set_pekeyr(0x89ABCDEF));
pac::FLASH.pekeyr().write(|w| w.set_pekeyr(0x89ABCDEF)); pac::FLASH.pekeyr().write(|w| w.set_pekeyr(0x02030405));
pac::FLASH.pekeyr().write(|w| w.set_pekeyr(0x02030405));
}
if pac::FLASH.pecr().read().prglock() { pac::FLASH.prgkeyr().write(|w| w.set_prgkeyr(0x8C9DAEBF));
pac::FLASH.prgkeyr().write(|w| w.set_prgkeyr(0x8C9DAEBF)); pac::FLASH.prgkeyr().write(|w| w.set_prgkeyr(0x13141516));
pac::FLASH.prgkeyr().write(|w| w.set_prgkeyr(0x13141516));
}
} }
} }

View File

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

View File

@ -1,7 +1,6 @@
#![macro_use] #![macro_use]
use core::convert::Infallible; use core::convert::Infallible;
use critical_section::CriticalSection;
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
use crate::pac::gpio::{self, vals}; use crate::pac::gpio::{self, vals};
@ -758,9 +757,9 @@ foreach_pin!(
}; };
); );
pub(crate) unsafe fn init(_cs: CriticalSection) { pub(crate) unsafe fn init() {
#[cfg(afio)] #[cfg(afio)]
<crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(_cs); <crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable();
crate::_generated::init_gpio(); crate::_generated::init_gpio();
} }
@ -975,18 +974,6 @@ mod eh1 {
type Error = Infallible; type Error = Infallible;
} }
impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> {
#[inline]
fn is_high(&self) -> Result<bool, Self::Error> {
Ok(self.is_high())
}
#[inline]
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(self.is_low())
}
}
impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> { impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> {
#[inline] #[inline]
fn set_high(&mut self) -> Result<(), Self::Error> { fn set_high(&mut self) -> Result<(), Self::Error> {

View File

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

View File

@ -7,9 +7,14 @@ 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)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error { pub enum Error {
Bus, Bus,

View File

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

View File

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

View File

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

View File

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

View File

@ -93,14 +93,30 @@ pub struct Ipcc;
impl Ipcc { impl Ipcc {
pub fn enable(_config: Config) { pub fn enable(_config: Config) {
IPCC::enable_and_reset(); // TODO: move these lines to the rcc mod
// set LPTIM1 & LPTIM2 clock source
crate::pac::RCC.ccipr().modify(|w| {
w.set_lptim1sel(0b00); // PCLK
w.set_lptim2sel(0b00); // PCLK
});
// set RF wake-up clock = LSE
crate::pac::RCC.csr().modify(|w| w.set_rfwkpsel(0b01));
IPCC::enable();
IPCC::reset();
// insert bus access and fence for delay
IPCC::enable();
compiler_fence(Ordering::SeqCst);
IPCC::set_cpu2(true); IPCC::set_cpu2(true);
_configure_pwr(); // insert bus access and fence for delay
IPCC::set_cpu2(true);
compiler_fence(Ordering::SeqCst);
let regs = IPCC::regs(); IPCC::regs().cpu(0).cr().modify(|w| {
regs.cpu(0).cr().modify(|w| {
w.set_rxoie(true); w.set_rxoie(true);
w.set_txfie(true); w.set_txfie(true);
}); });
@ -262,18 +278,3 @@ pub(crate) mod sealed {
fn state() -> &'static State; fn state() -> &'static State;
} }
} }
fn _configure_pwr() {
// TODO: move the rest of this to rcc
let rcc = crate::pac::RCC;
// TODO: required
// set RF wake-up clock = LSE
rcc.csr().modify(|w| w.set_rfwkpsel(0b01));
// set LPTIM1 & LPTIM2 clock source
rcc.ccipr().modify(|w| {
w.set_lptim1sel(0b00); // PCLK
w.set_lptim2sel(0b00); // PCLK
});
}

View File

@ -155,82 +155,79 @@ 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() {
crate::rcc::clock_refcount_sub();
}
}
p
} }

View File

@ -1,7 +1,7 @@
use core::arch::asm; use core::arch::asm;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use atomic_polyfill::{compiler_fence, Ordering};
use cortex_m::peripheral::SCB; use cortex_m::peripheral::SCB;
use embassy_executor::*; use embassy_executor::*;

View File

@ -4,15 +4,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use crate::Peripheral; use crate::Peripheral;
#[derive(Clone, Copy)] #[cfg(opamp_f3)]
pub enum OpAmpGain {
Mul1,
Mul2,
Mul4,
Mul8,
Mul16,
}
pub struct OpAmpOutput<'d, 'p, T: Instance, P: NonInvertingPin<T>> { pub struct OpAmpOutput<'d, 'p, T: Instance, P: NonInvertingPin<T>> {
_inner: &'d OpAmp<'d, T>, _inner: &'d OpAmp<'d, T>,
_input: &'p mut P, _input: &'p mut P,
@ -43,32 +35,14 @@ impl<'d, T: Instance> OpAmp<'d, T> {
Self { _inner: opamp } Self { _inner: opamp }
} }
pub fn buffer_for<'a, 'b, P>(&'a mut self, pin: &'b mut P, gain: OpAmpGain) -> OpAmpOutput<'a, 'b, T, P> #[cfg(opamp_f3)]
pub fn buffer_for<'a, 'b, P>(&'a mut self, pin: &'b mut P) -> OpAmpOutput<'a, 'b, T, P>
where where
P: NonInvertingPin<T>, P: NonInvertingPin<T>,
{ {
let (vm_sel, pga_gain) = match gain {
OpAmpGain::Mul1 => (0b11, 0b00),
OpAmpGain::Mul2 => (0b10, 0b00),
OpAmpGain::Mul4 => (0b10, 0b01),
OpAmpGain::Mul8 => (0b10, 0b10),
OpAmpGain::Mul16 => (0b10, 0b11),
};
#[cfg(opamp_f3)] #[cfg(opamp_f3)]
T::regs().opampcsr().modify(|w| { T::regs().opampcsr().modify(|w| {
w.set_vp_sel(pin.channel()); w.set_vp_sel(pin.channel());
w.set_vm_sel(vm_sel);
w.set_pga_gain(pga_gain);
});
#[cfg(opamp_g4)]
T::regs().opamp_csr().modify(|w| {
use crate::pac::opamp::vals::*;
w.set_vp_sel(OpampCsrVpSel::from_bits(pin.channel()));
w.set_vm_sel(OpampCsrVmSel::from_bits(vm_sel));
w.set_pga_gain(OpampCsrPgaGain::from_bits(pga_gain));
}); });
OpAmpOutput { OpAmpOutput {

View File

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

View File

@ -1,161 +1,110 @@
use core::sync::atomic::{compiler_fence, Ordering};
use crate::pac::common::{Reg, RW};
pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource;
use crate::time::Hertz;
#[cfg(any(stm32f0, stm32f1, stm32f3))]
pub const LSI_FREQ: Hertz = Hertz(40_000);
#[cfg(not(any(stm32f0, stm32f1, stm32f3)))]
pub const LSI_FREQ: Hertz = Hertz(32_000);
#[allow(dead_code)]
#[derive(Clone, Copy)]
pub enum LseMode {
Oscillator(LseDrive),
Bypass,
}
pub struct LseConfig {
pub frequency: Hertz,
pub mode: LseMode,
}
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Default, Clone, Copy)] #[derive(Default, Clone, Copy)]
pub enum LseDrive { pub enum LseDrive {
#[cfg(any(rtc_v2f7, rtc_v2l4))]
Low = 0, Low = 0,
MediumLow = 0x01, MediumLow = 0x01,
#[default] #[default]
MediumHigh = 0x02, MediumHigh = 0x02,
#[cfg(any(rtc_v2f7, rtc_v2l4))]
High = 0x03, High = 0x03,
} }
// All families but these have the LSEDRV register #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))]
#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))]
impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv { impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv {
fn from(value: LseDrive) -> Self { fn from(value: LseDrive) -> Self {
use crate::pac::rcc::vals::Lsedrv; use crate::pac::rcc::vals::Lsedrv;
match value { match value {
#[cfg(any(rtc_v2f7, rtc_v2l4))]
LseDrive::Low => Lsedrv::LOW, LseDrive::Low => Lsedrv::LOW,
LseDrive::MediumLow => Lsedrv::MEDIUMLOW, LseDrive::MediumLow => Lsedrv::MEDIUMLOW,
LseDrive::MediumHigh => Lsedrv::MEDIUMHIGH, LseDrive::MediumHigh => Lsedrv::MEDIUMHIGH,
#[cfg(any(rtc_v2f7, rtc_v2l4))]
LseDrive::High => Lsedrv::HIGH, LseDrive::High => Lsedrv::HIGH,
} }
} }
} }
pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource;
#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
#[allow(dead_code)]
type Bdcr = crate::pac::rcc::regs::Bdcr; type Bdcr = crate::pac::rcc::regs::Bdcr;
#[cfg(any(rtc_v2l0, rtc_v2l1))] #[cfg(any(rtc_v2l0, rtc_v2l1))]
#[allow(dead_code)]
type Bdcr = crate::pac::rcc::regs::Csr; type Bdcr = crate::pac::rcc::regs::Csr;
#[cfg(any(stm32c0))]
type Bdcr = crate::pac::rcc::regs::Csr1;
#[cfg(any(stm32c0))] #[allow(dead_code)]
fn unlock() {} pub struct BackupDomain {}
#[cfg(not(any(stm32c0)))] impl BackupDomain {
fn unlock() { #[cfg(any(
#[cfg(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1))] rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
let cr = crate::pac::PWR.cr(); rtc_v3u5
#[cfg(not(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1, stm32u5, stm32h5, stm32wba)))] ))]
let cr = crate::pac::PWR.cr1(); #[allow(dead_code, unused_variables)]
#[cfg(any(stm32u5, stm32h5, stm32wba))] fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R {
let cr = crate::pac::PWR.dbpcr(); #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1, rtc_v2l0))]
let cr = crate::pac::PWR.cr();
#[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
let cr = crate::pac::PWR.cr1();
cr.modify(|w| w.set_dbp(true)); // TODO: Missing from PAC for l0 and f0?
while !cr.read().dbp() {} #[cfg(not(any(rtc_v2f0, rtc_v3u5)))]
} {
cr.modify(|w| w.set_dbp(true));
fn bdcr() -> Reg<Bdcr, RW> { while !cr.read().dbp() {}
#[cfg(any(rtc_v2l0, rtc_v2l1))]
return crate::pac::RCC.csr();
#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
return crate::pac::RCC.bdcr();
#[cfg(any(stm32c0))]
return crate::pac::RCC.csr1();
}
pub struct LsConfig {
pub rtc: RtcClockSource,
pub lsi: bool,
pub lse: Option<LseConfig>,
}
impl LsConfig {
pub const fn default_lse() -> Self {
Self {
rtc: RtcClockSource::LSE,
lse: Some(LseConfig {
frequency: Hertz(32_768),
mode: LseMode::Oscillator(LseDrive::MediumHigh),
}),
lsi: false,
} }
#[cfg(any(rtc_v2l0, rtc_v2l1))]
let cr = crate::pac::RCC.csr();
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
let cr = crate::pac::RCC.bdcr();
cr.modify(|w| f(w))
} }
pub const fn default_lsi() -> Self { #[cfg(any(
Self { rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
rtc: RtcClockSource::LSI, rtc_v3u5
lsi: true, ))]
lse: None, #[allow(dead_code)]
} fn read() -> Bdcr {
#[cfg(any(rtc_v2l0, rtc_v2l1))]
let r = crate::pac::RCC.csr().read();
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
let r = crate::pac::RCC.bdcr().read();
r
} }
pub const fn off() -> Self { #[cfg(any(
Self { rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
rtc: RtcClockSource::DISABLE, rtc_v3u5
lsi: false, ))]
lse: None, #[allow(dead_code, unused_variables)]
} pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option<LseDrive>) {
} use atomic_polyfill::{compiler_fence, Ordering};
}
impl Default for LsConfig { match clock_source {
fn default() -> Self { RtcClockSource::LSI => assert!(lsi),
// on L5, just the fact that LSI is enabled makes things crash. RtcClockSource::LSE => assert!(&lse.is_some()),
// TODO: investigate. _ => {}
#[cfg(not(stm32l5))]
return Self::default_lsi();
#[cfg(stm32l5)]
return Self::off();
}
}
impl LsConfig {
pub(crate) fn init(&self) -> Option<Hertz> {
let rtc_clk = match self.rtc {
RtcClockSource::LSI => {
assert!(self.lsi);
Some(LSI_FREQ)
}
RtcClockSource::LSE => Some(self.lse.as_ref().unwrap().frequency),
RtcClockSource::DISABLE => None,
_ => todo!(),
}; };
let (lse_en, lse_byp, lse_drv) = match &self.lse { if lsi {
Some(c) => match c.mode { #[cfg(rtc_v3u5)]
LseMode::Oscillator(lse_drv) => (true, false, Some(lse_drv)),
LseMode::Bypass => (true, true, None),
},
None => (false, false, None),
};
_ = lse_drv; // not all chips have it.
// Disable backup domain write protection
unlock();
if self.lsi {
#[cfg(any(stm32u5, stm32h5, stm32wba))]
let csr = crate::pac::RCC.bdcr(); let csr = crate::pac::RCC.bdcr();
#[cfg(not(any(stm32u5, stm32h5, stm32wba, stm32c0)))]
#[cfg(not(rtc_v3u5))]
let csr = crate::pac::RCC.csr(); let csr = crate::pac::RCC.csr();
#[cfg(any(stm32c0))]
let csr = crate::pac::RCC.csr2(); // Disable backup domain write protection
Self::modify(|_| {});
#[cfg(not(any(rcc_wb, rcc_wba)))] #[cfg(not(any(rcc_wb, rcc_wba)))]
csr.modify(|w| w.set_lsion(true)); csr.modify(|w| w.set_lsion(true));
@ -175,71 +124,60 @@ impl LsConfig {
// first check if the configuration matches what we want. // first check if the configuration matches what we want.
// check if it's already enabled and in the source we want. // check if it's already enabled and in the source we want.
let reg = bdcr().read(); let reg = Self::read();
let mut ok = true; let mut ok = true;
ok &= reg.rtcsel() == self.rtc; ok &= reg.rtcsel() == clock_source;
#[cfg(not(rcc_wba))] #[cfg(not(rcc_wba))]
{ {
ok &= reg.rtcen() == (self.rtc != RtcClockSource::DISABLE); ok &= reg.rtcen() == (clock_source != RtcClockSource::NOCLOCK);
} }
ok &= reg.lseon() == lse_en; ok &= reg.lseon() == lse.is_some();
ok &= reg.lsebyp() == lse_byp; #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))]
#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] if let Some(lse_drive) = lse {
if let Some(lse_drv) = lse_drv { ok &= reg.lsedrv() == lse_drive.into();
ok &= reg.lsedrv() == lse_drv.into();
} }
// if configuration is OK, we're done. // if configuration is OK, we're done.
if ok { if ok {
trace!("BDCR ok: {:08x}", bdcr().read().0); // RTC code assumes backup domain is unlocked
return rtc_clk; Self::modify(|w| {});
trace!("BDCR ok: {:08x}", Self::read().0);
compiler_fence(Ordering::SeqCst);
return;
} }
// If not OK, reset backup domain and configure it. // If not OK, reset backup domain and configure it.
#[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1, stm32h5, stm32c0)))] #[cfg(not(any(rcc_l0, rcc_l1)))]
{ {
bdcr().modify(|w| w.set_bdrst(true)); Self::modify(|w| w.set_bdrst(true));
bdcr().modify(|w| w.set_bdrst(false)); Self::modify(|w| w.set_bdrst(false));
}
#[cfg(any(stm32h5))]
{
bdcr().modify(|w| w.set_vswrst(true));
bdcr().modify(|w| w.set_vswrst(false));
}
#[cfg(any(stm32c0))]
{
bdcr().modify(|w| w.set_rtcrst(true));
bdcr().modify(|w| w.set_rtcrst(false));
} }
if lse_en { if let Some(lse_drive) = lse {
bdcr().modify(|w| { Self::modify(|w| {
#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))]
if let Some(lse_drv) = lse_drv { w.set_lsedrv(lse_drive.into());
w.set_lsedrv(lse_drv.into());
}
w.set_lsebyp(lse_byp);
w.set_lseon(true); w.set_lseon(true);
}); });
while !bdcr().read().lserdy() {} while !Self::read().lserdy() {}
} }
if self.rtc != RtcClockSource::DISABLE { if clock_source != RtcClockSource::NOCLOCK {
bdcr().modify(|w| { Self::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.");
#[cfg(not(rcc_wba))] #[cfg(not(rcc_wba))]
w.set_rtcen(true); w.set_rtcen(true);
w.set_rtcsel(self.rtc); w.set_rtcsel(clock_source);
}); });
} }
trace!("BDCR configured: {:08x}", bdcr().read().0); trace!("BDCR configured: {:08x}", Self::read().0);
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
rtc_clk
} }
} }

View File

@ -0,0 +1,56 @@
use core::ops::Div;
#[allow(unused_imports)]
use crate::pac::rcc;
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
use crate::time::Hertz;
impl Div<AHBPrescaler> for Hertz {
type Output = Hertz;
fn div(self, rhs: AHBPrescaler) -> Self::Output {
let divisor = match rhs {
AHBPrescaler::DIV1 => 1,
AHBPrescaler::DIV2 => 2,
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
AHBPrescaler::DIV3 => 3,
AHBPrescaler::DIV4 => 4,
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
AHBPrescaler::DIV5 => 5,
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
AHBPrescaler::DIV6 => 6,
AHBPrescaler::DIV8 => 8,
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
AHBPrescaler::DIV10 => 10,
AHBPrescaler::DIV16 => 16,
#[cfg(any(rcc_wb, rcc_wl5, rcc_wle))]
AHBPrescaler::DIV32 => 32,
#[cfg(not(rcc_wba))]
AHBPrescaler::DIV64 => 64,
#[cfg(not(rcc_wba))]
AHBPrescaler::DIV128 => 128,
#[cfg(not(rcc_wba))]
AHBPrescaler::DIV256 => 256,
#[cfg(not(rcc_wba))]
AHBPrescaler::DIV512 => 512,
_ => unreachable!(),
};
Hertz(self.0 / divisor)
}
}
impl Div<APBPrescaler> for Hertz {
type Output = Hertz;
fn div(self, rhs: APBPrescaler) -> Self::Output {
let divisor = match rhs {
APBPrescaler::DIV1 => 1,
APBPrescaler::DIV2 => 2,
APBPrescaler::DIV4 => 4,
APBPrescaler::DIV8 => 8,
APBPrescaler::DIV16 => 16,
_ => unreachable!(),
};
Hertz(self.0 / divisor)
}
}

View File

@ -1,6 +1,6 @@
pub use super::bus::{AHBPrescaler, APBPrescaler};
use crate::pac::flash::vals::Latency; use crate::pac::flash::vals::Latency;
use crate::pac::rcc::vals::Sw; use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw};
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Ppre as APBPrescaler};
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
@ -8,6 +8,9 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(48_000_000); pub const HSI_FREQ: Hertz = Hertz(48_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source /// System clock mux source
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum ClockSrc { pub enum ClockSrc {
@ -16,22 +19,47 @@ pub enum ClockSrc {
LSI, LSI,
} }
#[derive(Clone, Copy)]
pub enum HSIPrescaler {
NotDivided,
Div2,
Div4,
Div8,
Div16,
Div32,
Div64,
Div128,
}
impl Into<Hsidiv> for HSIPrescaler {
fn into(self) -> Hsidiv {
match self {
HSIPrescaler::NotDivided => Hsidiv::DIV1,
HSIPrescaler::Div2 => Hsidiv::DIV2,
HSIPrescaler::Div4 => Hsidiv::DIV4,
HSIPrescaler::Div8 => Hsidiv::DIV8,
HSIPrescaler::Div16 => Hsidiv::DIV16,
HSIPrescaler::Div32 => Hsidiv::DIV32,
HSIPrescaler::Div64 => Hsidiv::DIV64,
HSIPrescaler::Div128 => Hsidiv::DIV128,
}
}
}
/// Clocks configutation /// Clocks configutation
pub struct Config { pub struct Config {
pub mux: ClockSrc, pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler, pub ahb_pre: AHBPrescaler,
pub apb_pre: APBPrescaler, pub apb_pre: APBPrescaler,
pub ls: super::LsConfig,
} }
impl Default for Config { impl Default for Config {
#[inline] #[inline]
fn default() -> Config { fn default() -> Config {
Config { Config {
mux: ClockSrc::HSI(HSIPrescaler::DIV1), mux: ClockSrc::HSI(HSIPrescaler::NotDivided),
ahb_pre: AHBPrescaler::DIV1, ahb_pre: AHBPrescaler::DIV1,
apb_pre: APBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1,
ls: Default::default(),
} }
} }
} }
@ -40,34 +68,33 @@ pub(crate) unsafe fn init(config: Config) {
let (sys_clk, sw) = match config.mux { let (sys_clk, sw) = match config.mux {
ClockSrc::HSI(div) => { ClockSrc::HSI(div) => {
// Enable HSI // Enable HSI
let div: Hsidiv = div.into();
RCC.cr().write(|w| { RCC.cr().write(|w| {
w.set_hsidiv(div); w.set_hsidiv(div);
w.set_hsion(true) w.set_hsion(true)
}); });
while !RCC.cr().read().hsirdy() {} while !RCC.cr().read().hsirdy() {}
(HSI_FREQ / div, Sw::HSI) (HSI_FREQ.0 >> div.to_bits(), Sw::HSI)
} }
ClockSrc::HSE(freq) => { ClockSrc::HSE(freq) => {
// Enable HSE // Enable HSE
RCC.cr().write(|w| w.set_hseon(true)); RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {} while !RCC.cr().read().hserdy() {}
(freq, Sw::HSE) (freq.0, Sw::HSE)
} }
ClockSrc::LSI => { ClockSrc::LSI => {
// Enable LSI // Enable LSI
RCC.csr2().write(|w| w.set_lsion(true)); RCC.csr2().write(|w| w.set_lsion(true));
while !RCC.csr2().read().lsirdy() {} while !RCC.csr2().read().lsirdy() {}
(super::LSI_FREQ, Sw::LSI) (LSI_FREQ.0, Sw::LSI)
} }
}; };
let rtc = config.ls.init();
// Determine the flash latency implied by the target clock speed // Determine the flash latency implied by the target clock speed
// RM0454 § 3.3.4: // RM0454 § 3.3.4:
let target_flash_latency = if sys_clk <= Hertz(24_000_000) { let target_flash_latency = if sys_clk <= 24_000_000 {
Latency::WS0 Latency::WS0
} else { } else {
Latency::WS1 Latency::WS1
@ -102,7 +129,7 @@ pub(crate) unsafe fn init(config: Config) {
} }
// Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once // Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once
let (sw, hpre, ppre) = (sw.into(), config.ahb_pre, config.apb_pre); let (sw, hpre, ppre) = (sw.into(), config.ahb_pre.into(), config.apb_pre.into());
RCC.cfgr().modify(|w| { RCC.cfgr().modify(|w| {
w.set_sw(sw); w.set_sw(sw);
w.set_hpre(hpre); w.set_hpre(hpre);
@ -123,23 +150,34 @@ pub(crate) unsafe fn init(config: Config) {
FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); FLASH.acr().modify(|w| w.set_latency(target_flash_latency));
} }
let ahb_freq = sys_clk / config.ahb_pre; let ahb_div = match config.ahb_pre {
AHBPrescaler::DIV1 => 1,
AHBPrescaler::DIV2 => 2,
AHBPrescaler::DIV4 => 4,
AHBPrescaler::DIV8 => 8,
AHBPrescaler::DIV16 => 16,
AHBPrescaler::DIV64 => 64,
AHBPrescaler::DIV128 => 128,
AHBPrescaler::DIV256 => 256,
AHBPrescaler::DIV512 => 512,
_ => unreachable!(),
};
let ahb_freq = sys_clk / ahb_div;
let (apb_freq, apb_tim_freq) = match config.apb_pre { let (apb_freq, apb_tim_freq) = match config.apb_pre {
APBPrescaler::DIV1 => (ahb_freq, ahb_freq), APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
pre => { pre => {
let freq = ahb_freq / pre; let pre: Ppre = pre.into();
(freq, freq * 2u32) let pre: u8 = 1 << (pre.to_bits() - 3);
let freq = ahb_freq / pre as u32;
(freq, freq * 2)
} }
}; };
set_freqs(Clocks { set_freqs(Clocks {
hsi: None, sys: Hertz(sys_clk),
lse: None, ahb1: Hertz(ahb_freq),
sys: sys_clk, apb1: Hertz(apb_freq),
hclk1: ahb_freq, apb1_tim: Hertz(apb_tim_freq),
pclk1: apb_freq,
pclk1_tim: apb_tim_freq,
rtc,
}); });
} }

View File

@ -8,6 +8,9 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(8_000_000); pub const HSI_FREQ: Hertz = Hertz(8_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(40_000);
/// Configuration of the clocks /// Configuration of the clocks
/// ///
/// hse takes precedence over hsi48 if both are enabled /// hse takes precedence over hsi48 if both are enabled
@ -24,8 +27,6 @@ pub struct Config {
pub sys_ck: Option<Hertz>, pub sys_ck: Option<Hertz>,
pub hclk: Option<Hertz>, pub hclk: Option<Hertz>,
pub pclk: Option<Hertz>, pub pclk: Option<Hertz>,
pub ls: super::LsConfig,
} }
pub(crate) unsafe fn init(config: Config) { pub(crate) unsafe fn init(config: Config) {
@ -158,15 +159,12 @@ pub(crate) unsafe fn init(config: Config) {
}) })
} }
let rtc = config.ls.init();
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,
}); });
} }

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