Compare commits
2 Commits
embassy-ti
...
asynci2cv1
Author | SHA1 | Date | |
---|---|---|---|
54123de7bd | |||
838a97c186 |
12
.github/ci/build-stable.sh
vendored
12
.github/ci/build-stable.sh
vendored
@ -12,19 +12,9 @@ export CARGO_TARGET_DIR=/ci/cache/target
|
|||||||
# used when pointing stm32-metapac to a CI-built one.
|
# used when pointing stm32-metapac to a CI-built one.
|
||||||
export CARGO_NET_GIT_FETCH_WITH_CLI=true
|
export CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||||
|
|
||||||
# Restore lockfiles
|
|
||||||
if [ -f /ci/cache/lockfiles.tar ]; then
|
|
||||||
echo Restoring lockfiles...
|
|
||||||
tar xf /ci/cache/lockfiles.tar
|
|
||||||
fi
|
|
||||||
|
|
||||||
hashtime restore /ci/cache/filetime.json || true
|
hashtime restore /ci/cache/filetime.json || true
|
||||||
hashtime save /ci/cache/filetime.json
|
hashtime save /ci/cache/filetime.json
|
||||||
|
|
||||||
sed -i 's/channel.*/channel = "beta"/g' rust-toolchain.toml
|
sed -i 's/channel.*/channel = "stable"/g' rust-toolchain.toml
|
||||||
|
|
||||||
./ci_stable.sh
|
./ci_stable.sh
|
||||||
|
|
||||||
# Save lockfiles
|
|
||||||
echo Saving lockfiles...
|
|
||||||
find . -type f -name Cargo.lock -exec tar -cf /ci/cache/lockfiles.tar '{}' \+
|
|
10
.github/ci/build.sh
vendored
10
.github/ci/build.sh
vendored
@ -18,17 +18,7 @@ fi
|
|||||||
# used when pointing stm32-metapac to a CI-built one.
|
# used when pointing stm32-metapac to a CI-built one.
|
||||||
export CARGO_NET_GIT_FETCH_WITH_CLI=true
|
export CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||||
|
|
||||||
# Restore lockfiles
|
|
||||||
if [ -f /ci/cache/lockfiles.tar ]; then
|
|
||||||
echo Restoring lockfiles...
|
|
||||||
tar xf /ci/cache/lockfiles.tar
|
|
||||||
fi
|
|
||||||
|
|
||||||
hashtime restore /ci/cache/filetime.json || true
|
hashtime restore /ci/cache/filetime.json || true
|
||||||
hashtime save /ci/cache/filetime.json
|
hashtime save /ci/cache/filetime.json
|
||||||
|
|
||||||
./ci.sh
|
./ci.sh
|
||||||
|
|
||||||
# Save lockfiles
|
|
||||||
echo Saving lockfiles...
|
|
||||||
find . -type f -name Cargo.lock -exec tar -cf /ci/cache/lockfiles.tar '{}' \+
|
|
1
.github/ci/doc.sh
vendored
1
.github/ci/doc.sh
vendored
@ -22,6 +22,7 @@ docserver-builder -i ./embassy-boot/stm32 -o webroot/crates/embassy-boot-stm32/g
|
|||||||
docserver-builder -i ./embassy-embedded-hal -o webroot/crates/embassy-embedded-hal/git.zup
|
docserver-builder -i ./embassy-embedded-hal -o webroot/crates/embassy-embedded-hal/git.zup
|
||||||
docserver-builder -i ./embassy-executor -o webroot/crates/embassy-executor/git.zup
|
docserver-builder -i ./embassy-executor -o webroot/crates/embassy-executor/git.zup
|
||||||
docserver-builder -i ./embassy-futures -o webroot/crates/embassy-futures/git.zup
|
docserver-builder -i ./embassy-futures -o webroot/crates/embassy-futures/git.zup
|
||||||
|
docserver-builder -i ./embassy-lora -o webroot/crates/embassy-lora/git.zup
|
||||||
docserver-builder -i ./embassy-net -o webroot/crates/embassy-net/git.zup
|
docserver-builder -i ./embassy-net -o webroot/crates/embassy-net/git.zup
|
||||||
docserver-builder -i ./embassy-net-driver -o webroot/crates/embassy-net-driver/git.zup
|
docserver-builder -i ./embassy-net-driver -o webroot/crates/embassy-net-driver/git.zup
|
||||||
docserver-builder -i ./embassy-net-driver-channel -o webroot/crates/embassy-net-driver-channel/git.zup
|
docserver-builder -i ./embassy-net-driver-channel -o webroot/crates/embassy-net-driver-channel/git.zup
|
||||||
|
27
.github/ci/test.sh
vendored
27
.github/ci/test.sh
vendored
@ -4,8 +4,16 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml
|
export RUSTUP_HOME=/ci/cache/rustup
|
||||||
MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml --features nightly
|
export CARGO_HOME=/ci/cache/cargo
|
||||||
|
export CARGO_TARGET_DIR=/ci/cache/target
|
||||||
|
|
||||||
|
# needed for "dumb HTTP" transport support
|
||||||
|
# used when pointing stm32-metapac to a CI-built one.
|
||||||
|
export CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||||
|
|
||||||
|
hashtime restore /ci/cache/filetime.json || true
|
||||||
|
hashtime save /ci/cache/filetime.json
|
||||||
|
|
||||||
cargo test --manifest-path ./embassy-sync/Cargo.toml
|
cargo test --manifest-path ./embassy-sync/Cargo.toml
|
||||||
cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml
|
cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml
|
||||||
@ -13,15 +21,16 @@ cargo test --manifest-path ./embassy-hal-internal/Cargo.toml
|
|||||||
cargo test --manifest-path ./embassy-time/Cargo.toml --features generic-queue
|
cargo test --manifest-path ./embassy-time/Cargo.toml --features generic-queue
|
||||||
|
|
||||||
cargo test --manifest-path ./embassy-boot/boot/Cargo.toml
|
cargo test --manifest-path ./embassy-boot/boot/Cargo.toml
|
||||||
cargo test --manifest-path ./embassy-boot/boot/Cargo.toml --features ed25519-dalek
|
cargo test --manifest-path ./embassy-boot/boot/Cargo.toml --features nightly
|
||||||
cargo test --manifest-path ./embassy-boot/boot/Cargo.toml --features ed25519-salty
|
cargo test --manifest-path ./embassy-boot/boot/Cargo.toml --features nightly,ed25519-dalek
|
||||||
|
cargo test --manifest-path ./embassy-boot/boot/Cargo.toml --features nightly,ed25519-salty
|
||||||
|
|
||||||
cargo test --manifest-path ./embassy-nrf/Cargo.toml --no-default-features --features nrf52840,time-driver-rtc1,gpiote
|
cargo test --manifest-path ./embassy-nrf/Cargo.toml --no-default-features --features nightly,nrf52840,time-driver-rtc1,gpiote
|
||||||
|
|
||||||
cargo test --manifest-path ./embassy-rp/Cargo.toml --no-default-features --features time-driver
|
cargo test --manifest-path ./embassy-rp/Cargo.toml --no-default-features --features nightly,time-driver
|
||||||
|
|
||||||
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f429vg,exti,time-driver-any,exti
|
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features nightly,stm32f429vg,exti,time-driver-any,exti
|
||||||
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f732ze,exti,time-driver-any,exti
|
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features nightly,stm32f732ze,exti,time-driver-any,exti
|
||||||
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f769ni,exti,time-driver-any,exti
|
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features nightly,stm32f769ni,exti,time-driver-any,exti
|
||||||
|
|
||||||
cargo test --manifest-path ./embassy-net-adin1110/Cargo.toml
|
cargo test --manifest-path ./embassy-net-adin1110/Cargo.toml
|
||||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -3,9 +3,6 @@
|
|||||||
"[toml]": {
|
"[toml]": {
|
||||||
"editor.formatOnSave": false
|
"editor.formatOnSave": false
|
||||||
},
|
},
|
||||||
"[markdown]": {
|
|
||||||
"editor.formatOnSave": false
|
|
||||||
},
|
|
||||||
"rust-analyzer.check.allTargets": false,
|
"rust-analyzer.check.allTargets": false,
|
||||||
"rust-analyzer.check.noDefaultFeatures": true,
|
"rust-analyzer.check.noDefaultFeatures": true,
|
||||||
"rust-analyzer.cargo.noDefaultFeatures": true,
|
"rust-analyzer.cargo.noDefaultFeatures": true,
|
||||||
|
@ -36,7 +36,7 @@ The <a href="https://github.com/embassy-rs/nrf-softdevice">nrf-softdevice</a> cr
|
|||||||
The <a href="https://github.com/embassy-rs/embassy/tree/main/embassy-stm32-wpan">embassy-stm32-wpan</a> crate provides Bluetooth Low Energy 5.x support for stm32wb microcontrollers.
|
The <a href="https://github.com/embassy-rs/embassy/tree/main/embassy-stm32-wpan">embassy-stm32-wpan</a> crate provides Bluetooth Low Energy 5.x support for stm32wb microcontrollers.
|
||||||
|
|
||||||
- **LoRa** -
|
- **LoRa** -
|
||||||
<a href="hthttps://github.com/lora-rs/lora-rs">The lora-rs project</a> provides an async LoRa and LoRaWAN stack that works well on Embassy.
|
<a href="https://docs.embassy.dev/embassy-lora/">embassy-lora</a> supports LoRa networking.
|
||||||
|
|
||||||
- **USB** -
|
- **USB** -
|
||||||
<a href="https://docs.embassy.dev/embassy-usb/">embassy-usb</a> implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own.
|
<a href="https://docs.embassy.dev/embassy-usb/">embassy-usb</a> implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own.
|
||||||
|
175
ci.sh
175
ci.sh
@ -35,94 +35,102 @@ cargo batch \
|
|||||||
--- 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,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 \
|
||||||
--- 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-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 defmt \
|
--- 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 defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \
|
--- 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,proto-ipv4,medium-ethernet \
|
||||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,igmp,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 \
|
||||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,dhcpv4-hostname \
|
--- 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-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-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,medium-ieee802154 \
|
||||||
--- 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-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 \
|
||||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip \
|
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-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 \
|
--- 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,medium-ieee802154 \
|
--- 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-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52805,gpiote,time-driver-rtc1 \
|
--- 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 nrf52810,gpiote,time-driver-rtc1 \
|
--- 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 nrf52811,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 nrf52820,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 nrf52832,gpiote,time-driver-rtc1,reset-pin-as-gpio \
|
--- 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 nrf52833,gpiote,time-driver-rtc1,nfc-pins-as-gpio \
|
--- 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 thumbv8m.main-none-eabihf --features nrf9160-s,gpiote,time-driver-rtc1 \
|
--- 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 nrf9160-ns,gpiote,time-driver-rtc1 \
|
--- 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 nrf5340-app-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 nrf5340-app-ns,gpiote,time-driver-rtc1 \
|
--- 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 nrf5340-net,gpiote,time-driver-rtc1 \
|
--- 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 thumbv7em-none-eabi --features nrf52840,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 nrf52840,log,gpiote,time-driver-rtc1 \
|
--- 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 nrf52840,defmt,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-rp/Cargo.toml --target thumbv6m-none-eabi --features defmt \
|
--- 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 log \
|
--- 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 intrinsics \
|
--- 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 qspi-as-gpio \
|
--- 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,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,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,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,defmt,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,nightly,defmt,exti,time-driver-any,unstable-traits,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,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,defmt,exti,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,defmt,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,defmt,exti \
|
--- 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,defmt \
|
--- 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 thumbv7em-none-eabi --features stm32f401ve,defmt,exti,time-driver-any \
|
--- 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 thumbv7em-none-eabi --features stm32f405zg,defmt,exti,time-driver-any \
|
--- 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 thumbv7em-none-eabi --features stm32f407zg,defmt,exti,time-driver-any \
|
--- 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 thumbv7em-none-eabi --features stm32f401ve,defmt,exti,time-driver-any,time \
|
--- 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 stm32f405zg,defmt,exti,time-driver-any,time \
|
--- 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 stm32f407zg,defmt,exti,time-driver-any,time \
|
--- 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 stm32f410tb,defmt,exti,time-driver-any,time \
|
--- 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 stm32f411ce,defmt,exti,time-driver-any,time \
|
--- 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 stm32f412zg,defmt,exti,time-driver-any,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 stm32f413vh,defmt,exti,time-driver-any,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 stm32f415zg,defmt,exti,time-driver-any,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 stm32f417zg,defmt,exti,time-driver-any,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 stm32f423zh,defmt,exti,time-driver-any,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 stm32f427zi,defmt,exti,time-driver-any,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 stm32f429zi,log,exti,time-driver-any,embedded-sdmmc,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 stm32f437zi,log,exti,time-driver-any,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 stm32f439zi,defmt,exti,time-driver-any,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 stm32f446ze,defmt,exti,time-driver-any,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 stm32f469zi,defmt,exti,time-driver-any,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 stm32f479zi,defmt,exti,time-driver-any,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 stm32f730i8,defmt,exti,time-driver-any,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 stm32h753zi,defmt,exti,time-driver-any,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 stm32h735zg,defmt,exti,time-driver-any,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 stm32h755zi-cm7,defmt,exti,time-driver-any,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 stm32h725re,defmt,exti,time-driver-any,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 stm32h7b3ai,defmt,exti,time-driver-any,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 stm32l476vg,defmt,exti,time-driver-any,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 stm32l422cb,defmt,exti,time-driver-any,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 stm32wb15cc,defmt,exti,time-driver-any,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 thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,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 thumbv6m-none-eabi --features stm32l041f6,defmt,exti,time-driver-any,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 thumbv6m-none-eabi --features stm32l073cz,defmt,exti,time-driver-any,low-power,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 thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,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 thumbv7m-none-eabi --features stm32f398ve,defmt,exti,time-driver-any,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 thumbv7m-none-eabi --features stm32f378cc,defmt,exti,time-driver-any,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 thumbv6m-none-eabi --features stm32g0c1ve,defmt,exti,time-driver-any,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 stm32f217zg,defmt,exti,time-driver-any,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 thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,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 stm32wl54jc-cm0p,defmt,exti,time-driver-any,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 thumbv7em-none-eabi --features stm32wle5jb,defmt,exti,time-driver-any,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 thumbv7em-none-eabi --features stm32g474pe,defmt,exti,time-driver-any,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 thumbv7m-none-eabi --features stm32f107vc,defmt,exti,time-driver-any,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 thumbv7m-none-eabi --features stm32f103re,defmt,exti,time-driver-any,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 thumbv7m-none-eabi --features stm32f100c4,defmt,exti,time-driver-any,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 stm32h503rb,defmt,exti,time-driver-any,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 stm32h562ag,defmt,exti,time-driver-any,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 ''\
|
||||||
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \
|
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \
|
||||||
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \
|
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \
|
||||||
@ -130,10 +138,10 @@ cargo batch \
|
|||||||
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt,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 '' \
|
||||||
--- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'overclock' \
|
--- 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 \
|
--- 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 \
|
--- 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 \
|
--- 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 \
|
--- 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/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-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-hal/Cargo.toml --target thumbv7em-none-eabi \
|
||||||
@ -180,7 +188,6 @@ cargo batch \
|
|||||||
--- build --release --manifest-path examples/wasm/Cargo.toml --target wasm32-unknown-unknown --out-dir out/examples/wasm \
|
--- 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 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 stm32f429zi --out-dir out/tests/stm32f429zi \
|
||||||
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f446re --out-dir out/tests/stm32f446re \
|
|
||||||
--- 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 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 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 thumbv6m-none-eabi --features stm32c031c6 --out-dir out/tests/stm32c031c6 \
|
||||||
@ -211,8 +218,6 @@ cargo batch \
|
|||||||
rm out/tests/stm32wb55rg/wpan_mac
|
rm out/tests/stm32wb55rg/wpan_mac
|
||||||
rm out/tests/stm32wb55rg/wpan_ble
|
rm out/tests/stm32wb55rg/wpan_ble
|
||||||
|
|
||||||
# not in CI yet.
|
|
||||||
rm -rf out/tests/stm32f446re
|
|
||||||
|
|
||||||
# unstable, I think it's running out of RAM?
|
# unstable, I think it's running out of RAM?
|
||||||
rm out/tests/stm32f207zg/eth
|
rm out/tests/stm32f207zg/eth
|
||||||
|
64
ci_stable.sh
64
ci_stable.sh
@ -22,56 +22,56 @@ cargo batch \
|
|||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52811,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52811,gpiote,time-driver-rtc1 \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52820,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52820,gpiote,time-driver-rtc1 \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52832,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52832,gpiote,time-driver-rtc1 \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52833,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52833,gpiote,time-driver-rtc1,unstable-traits \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf9160-s,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf9160-s,gpiote,time-driver-rtc1 \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf9160-ns,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf9160-ns,gpiote,time-driver-rtc1,unstable-traits \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-s,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-s,gpiote,time-driver-rtc1,unstable-traits \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-ns,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-app-ns,gpiote,time-driver-rtc1 \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-net,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features nrf5340-net,gpiote,time-driver-rtc1,unstable-traits \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,gpiote,time-driver-rtc1 \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,log,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,log,gpiote,time-driver-rtc1 \
|
||||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,defmt,gpiote,time-driver-rtc1 \
|
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,defmt,gpiote,time-driver-rtc1,unstable-traits \
|
||||||
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features defmt \
|
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features unstable-traits,defmt \
|
||||||
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features log \
|
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features unstable-traits,log \
|
||||||
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi \
|
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi \
|
||||||
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features qspi-as-gpio \
|
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features qspi-as-gpio \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,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 \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,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 \
|
--- 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 \
|
--- 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 \
|
--- 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,time \
|
--- 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 stm32g491re,defmt,exti,time-driver-any,time \
|
--- 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 stm32u585zi,defmt,exti,time-driver-any,time \
|
--- 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 stm32wb55vy,defmt,exti,time-driver-any,time \
|
--- 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 stm32wl55cc-cm4,defmt,exti,time-driver-any,time \
|
--- 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 stm32l4r9zi,defmt,exti,time-driver-any,time \
|
--- 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 stm32f303vc,defmt,exti,time-driver-any,time \
|
--- 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 stm32f411ce,defmt,time-driver-any,time \
|
|
||||||
--- 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 stm32f411ce,defmt,time-driver-any,time \
|
||||||
|
--- 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 stm32f429zi,log,time-driver-any,time \
|
--- 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 stm32f429zi,log,time-driver-any,time \
|
--- 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 thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,time \
|
|
||||||
--- 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 thumbv7em-none-eabi --features stm32h755zi-cm7,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,time \
|
||||||
--- 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 thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,time \
|
||||||
--- 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 thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits,time \
|
||||||
--- 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 thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,time \
|
--- 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 thumbv6m-none-eabi --features stm32l072cz,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,time \
|
--- 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 thumbv7m-none-eabi --features stm32l151cb-a,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,time \
|
||||||
--- 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 stm32f410tb,defmt,exti,time-driver-any,time \
|
--- 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 stm32f410tb,defmt,exti,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,time \
|
--- 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 stm32f429zi,log,exti,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,time \
|
||||||
--- 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 thumbv7em-none-eabi --features stm32h755zi-cm7,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,time \
|
||||||
|
--- 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 thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \
|
--- 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 thumbv7em-none-eabi --features stm32l476vg,defmt,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,time \
|
||||||
--- 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 thumbv6m-none-eabi --features stm32l072cz,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,time \
|
||||||
|
--- 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,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,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 \
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(async_fn_in_trait)]
|
#![feature(async_fn_in_trait)]
|
||||||
|
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
|
||||||
|
|
||||||
use core::slice;
|
use core::slice;
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ log = ["dep:log"]
|
|||||||
firmware-logs = []
|
firmware-logs = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time"}
|
embassy-time = { version = "0.1.5", path = "../embassy-time"}
|
||||||
embassy-sync = { version = "0.5.0", path = "../embassy-sync"}
|
embassy-sync = { version = "0.4.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.2.0", path = "../embassy-net-driver-channel"}
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ cortex-m = "0.7.6"
|
|||||||
cortex-m-rt = "0.7.0"
|
cortex-m-rt = "0.7.0"
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] }
|
||||||
|
|
||||||
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-rc.2" }
|
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-rc.1" }
|
||||||
num_enum = { version = "0.5.7", default-features = false }
|
num_enum = { version = "0.5.7", default-features = false }
|
||||||
|
|
||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![allow(async_fn_in_trait)]
|
#![feature(async_fn_in_trait, type_alias_impl_trait, concat_bytes)]
|
||||||
|
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
|
||||||
#![deny(unused_must_use)]
|
#![deny(unused_must_use)]
|
||||||
|
|
||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
|
@ -1,48 +1,54 @@
|
|||||||
pub static NVRAM: &'static [u8] = b"
|
macro_rules! nvram {
|
||||||
NVRAMRev=$Rev$\x00\
|
($($s:literal,)*) => {
|
||||||
manfid=0x2d0\x00\
|
concat_bytes!($($s, b"\x00",)* b"\x00\x00")
|
||||||
prodid=0x0727\x00\
|
};
|
||||||
vendid=0x14e4\x00\
|
}
|
||||||
devid=0x43e2\x00\
|
|
||||||
boardtype=0x0887\x00\
|
pub static NVRAM: &'static [u8] = &*nvram!(
|
||||||
boardrev=0x1100\x00\
|
b"NVRAMRev=$Rev$",
|
||||||
boardnum=22\x00\
|
b"manfid=0x2d0",
|
||||||
macaddr=00:A0:50:b5:59:5e\x00\
|
b"prodid=0x0727",
|
||||||
sromrev=11\x00\
|
b"vendid=0x14e4",
|
||||||
boardflags=0x00404001\x00\
|
b"devid=0x43e2",
|
||||||
boardflags3=0x04000000\x00\
|
b"boardtype=0x0887",
|
||||||
xtalfreq=37400\x00\
|
b"boardrev=0x1100",
|
||||||
nocrc=1\x00\
|
b"boardnum=22",
|
||||||
ag0=255\x00\
|
b"macaddr=00:A0:50:b5:59:5e",
|
||||||
aa2g=1\x00\
|
b"sromrev=11",
|
||||||
ccode=ALL\x00\
|
b"boardflags=0x00404001",
|
||||||
pa0itssit=0x20\x00\
|
b"boardflags3=0x04000000",
|
||||||
extpagain2g=0\x00\
|
b"xtalfreq=37400",
|
||||||
pa2ga0=-168,6649,-778\x00\
|
b"nocrc=1",
|
||||||
AvVmid_c0=0x0,0xc8\x00\
|
b"ag0=255",
|
||||||
cckpwroffset0=5\x00\
|
b"aa2g=1",
|
||||||
maxp2ga0=84\x00\
|
b"ccode=ALL",
|
||||||
txpwrbckof=6\x00\
|
b"pa0itssit=0x20",
|
||||||
cckbw202gpo=0\x00\
|
b"extpagain2g=0",
|
||||||
legofdmbw202gpo=0x66111111\x00\
|
b"pa2ga0=-168,6649,-778",
|
||||||
mcsbw202gpo=0x77711111\x00\
|
b"AvVmid_c0=0x0,0xc8",
|
||||||
propbw202gpo=0xdd\x00\
|
b"cckpwroffset0=5",
|
||||||
ofdmdigfilttype=18\x00\
|
b"maxp2ga0=84",
|
||||||
ofdmdigfilttypebe=18\x00\
|
b"txpwrbckof=6",
|
||||||
papdmode=1\x00\
|
b"cckbw202gpo=0",
|
||||||
papdvalidtest=1\x00\
|
b"legofdmbw202gpo=0x66111111",
|
||||||
pacalidx2g=45\x00\
|
b"mcsbw202gpo=0x77711111",
|
||||||
papdepsoffset=-30\x00\
|
b"propbw202gpo=0xdd",
|
||||||
papdendidx=58\x00\
|
b"ofdmdigfilttype=18",
|
||||||
ltecxmux=0\x00\
|
b"ofdmdigfilttypebe=18",
|
||||||
ltecxpadnum=0x0102\x00\
|
b"papdmode=1",
|
||||||
ltecxfnsel=0x44\x00\
|
b"papdvalidtest=1",
|
||||||
ltecxgcigpio=0x01\x00\
|
b"pacalidx2g=45",
|
||||||
il0macaddr=00:90:4c:c5:12:38\x00\
|
b"papdepsoffset=-30",
|
||||||
wl0id=0x431b\x00\
|
b"papdendidx=58",
|
||||||
deadman_to=0xffffffff\x00\
|
b"ltecxmux=0",
|
||||||
muxenab=0x100\x00\
|
b"ltecxpadnum=0x0102",
|
||||||
spurconfig=0x3\x00\
|
b"ltecxfnsel=0x44",
|
||||||
glitch_based_crsmin=1\x00\
|
b"ltecxgcigpio=0x01",
|
||||||
btc_mode=1\x00\
|
b"il0macaddr=00:90:4c:c5:12:38",
|
||||||
\x00";
|
b"wl0id=0x431b",
|
||||||
|
b"deadman_to=0xffffffff",
|
||||||
|
b"muxenab=0x100",
|
||||||
|
b"spurconfig=0x3",
|
||||||
|
b"glitch_based_crsmin=1",
|
||||||
|
b"btc_mode=1",
|
||||||
|
);
|
||||||
|
@ -6,9 +6,9 @@ version = "0.1.0"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-executor = { version = "0.3.0", path = "../../../../../embassy-executor", features = ["defmt", "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.2.0", path = "../../../../../embassy-time", features = ["defmt"] }
|
embassy-time = { version = "0.1.4", path = "../../../../../embassy-time", features = ["defmt", "nightly"] }
|
||||||
embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] }
|
embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "nightly"] }
|
||||||
|
|
||||||
defmt = "0.3"
|
defmt = "0.3"
|
||||||
defmt-rtt = "0.3"
|
defmt-rtt = "0.3"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
* xref:getting_started.adoc[Getting started]
|
* xref:getting_started.adoc[Getting started]
|
||||||
** xref:basic_application.adoc[Basic application]
|
** xref:basic_application.adoc[Basic application]
|
||||||
** xref:project_structure.adoc[Project Structure]
|
|
||||||
* xref:layer_by_layer.adoc[Bare metal to async]
|
* xref:layer_by_layer.adoc[Bare metal to async]
|
||||||
* xref:runtime.adoc[Executor]
|
* xref:runtime.adoc[Executor]
|
||||||
* xref:hal.adoc[HAL]
|
* xref:hal.adoc[HAL]
|
||||||
@ -11,4 +10,3 @@
|
|||||||
* xref:examples.adoc[Examples]
|
* xref:examples.adoc[Examples]
|
||||||
* xref:developer.adoc[Developer]
|
* xref:developer.adoc[Developer]
|
||||||
** xref:developer_stm32.adoc[Developer: STM32]
|
** xref:developer_stm32.adoc[Developer: STM32]
|
||||||
* xref:faq.adoc[Frequently Asked Questions]
|
|
||||||
|
@ -6,22 +6,13 @@ So you've got one of the xref:examples.adoc[examples] running, but what now? Let
|
|||||||
|
|
||||||
The full example can be found link:https://github.com/embassy-rs/embassy/tree/master/docs/modules/ROOT/examples/basic[here].
|
The full example can be found link:https://github.com/embassy-rs/embassy/tree/master/docs/modules/ROOT/examples/basic[here].
|
||||||
|
|
||||||
=== Bare metal
|
|
||||||
|
|
||||||
The first thing you'll notice is a few declarations, two of which indicate that Embassy is suitable for bare metal development:
|
|
||||||
|
|
||||||
[source,rust]
|
|
||||||
----
|
|
||||||
include::example$basic/src/main.rs[lines="1..2"]
|
|
||||||
----
|
|
||||||
|
|
||||||
=== Rust Nightly
|
=== Rust Nightly
|
||||||
|
|
||||||
The next declaration is a Rust Unstable feature, which means that Embassy requires Rust Nightly:
|
The first thing you'll notice is a few declarations stating that Embassy requires some nightly features:
|
||||||
|
|
||||||
[source,rust]
|
[source,rust]
|
||||||
----
|
----
|
||||||
include::example$basic/src/main.rs[lines="3"]
|
include::example$basic/src/main.rs[lines="1..3"]
|
||||||
----
|
----
|
||||||
|
|
||||||
=== Dealing with errors
|
=== Dealing with errors
|
||||||
|
@ -1,137 +0,0 @@
|
|||||||
= Frequently Asked Questions
|
|
||||||
|
|
||||||
These are a list of unsorted, commonly asked questions and answers.
|
|
||||||
|
|
||||||
Please feel free to add items to link:https://github.com/embassy-rs/embassy/edit/main/docs/modules/ROOT/pages/faq.adoc[this page], especially if someone in the chat answered a question for you!
|
|
||||||
|
|
||||||
== How to deploy to RP2040 without a debugging probe.
|
|
||||||
|
|
||||||
Install link:https://github.com/JoNil/elf2uf2-rs[elf2uf2-rs] for converting the generated elf binary into a uf2 file.
|
|
||||||
|
|
||||||
Configure the runner to use this tool, add this to `.cargo/config.toml`:
|
|
||||||
[source,toml]
|
|
||||||
----
|
|
||||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
|
||||||
runner = "elf2uf2-rs --deploy --serial --verbose"
|
|
||||||
----
|
|
||||||
|
|
||||||
The command-line parameters `--deploy` will detect your device and upload the binary, `--serial` starts a serial connection. See the documentation for more info.
|
|
||||||
|
|
||||||
== Missing main macro
|
|
||||||
|
|
||||||
If you see an error like this:
|
|
||||||
|
|
||||||
[source,rust]
|
|
||||||
----
|
|
||||||
#[embassy_executor::main]
|
|
||||||
| ^^^^ could not find `main` in `embassy_executor`
|
|
||||||
----
|
|
||||||
|
|
||||||
You are likely missing some features of the `embassy-executor` crate.
|
|
||||||
|
|
||||||
For Cortex-M targets, consider making sure that ALL of the following features are active in your `Cargo.toml` for the `embassy-executor` crate:
|
|
||||||
|
|
||||||
* `arch-cortex-m`
|
|
||||||
* `executor-thread`
|
|
||||||
* `nightly`
|
|
||||||
|
|
||||||
For Xtensa ESP32, consider using the executors and `#[main]` macro provided by your appropriate link:https://crates.io/crates/esp-hal-common[HAL crate].
|
|
||||||
|
|
||||||
== Why is my binary so big?
|
|
||||||
|
|
||||||
The first step to managing your binary size is to set up your link:https://doc.rust-lang.org/cargo/reference/profiles.html[profiles].
|
|
||||||
|
|
||||||
[source,toml]
|
|
||||||
----
|
|
||||||
[profile.release]
|
|
||||||
debug = false
|
|
||||||
lto = true
|
|
||||||
opt-level = "s"
|
|
||||||
incremental = true
|
|
||||||
----
|
|
||||||
|
|
||||||
All of these flags are elaborated on in the Rust Book page linked above.
|
|
||||||
|
|
||||||
=== My binary is still big... filled with `std::fmt` stuff!
|
|
||||||
|
|
||||||
This means your code is sufficiently complex that `panic!` invocation's formatting requirements could not be optimized out, despite your usage of `panic-halt` or `panic-reset`.
|
|
||||||
|
|
||||||
You can remedy this by adding the following to your `.cargo/config.toml`:
|
|
||||||
|
|
||||||
[source,toml]
|
|
||||||
----
|
|
||||||
[unstable]
|
|
||||||
build-std = ["core"]
|
|
||||||
build-std-features = ["panic_immediate_abort"]
|
|
||||||
----
|
|
||||||
|
|
||||||
This replaces all panics with a `UDF` (undefined) instruction.
|
|
||||||
|
|
||||||
Depending on your chipset, this will exhibit different behavior.
|
|
||||||
|
|
||||||
Refer to the spec for your chipset, but for `thumbv6m`, it results in a hardfault. Which can be configured like so:
|
|
||||||
|
|
||||||
[source,rust]
|
|
||||||
----
|
|
||||||
#[exception]
|
|
||||||
unsafe fn HardFault(_frame: &ExceptionFrame) -> ! {
|
|
||||||
SCB::sys_reset() // <- you could do something other than reset
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
Refer to cortex-m's link:https://docs.rs/cortex-m-rt/latest/cortex_m_rt/attr.exception.html[exception handling] for more info.
|
|
||||||
|
|
||||||
== `embassy-time` throws linker errors
|
|
||||||
|
|
||||||
If you see linker error like this:
|
|
||||||
|
|
||||||
[source,text]
|
|
||||||
----
|
|
||||||
= note: rust-lld: error: undefined symbol: _embassy_time_now
|
|
||||||
>>> referenced by driver.rs:127 (src/driver.rs:127)
|
|
||||||
>>> embassy_time-846f66f1620ad42c.embassy_time.4f6a638abb75dd4c-cgu.0.rcgu.o:(embassy_time::driver::now::hefb1f99d6e069842) in archive Devel/Embedded/pogodyna/target/thumbv7em-none-eabihf/debug/deps/libembassy_time-846f66f1620ad42c.rlib
|
|
||||||
|
|
||||||
rust-lld: error: undefined symbol: _embassy_time_allocate_alarm
|
|
||||||
>>> referenced by driver.rs:134 (src/driver.rs:134)
|
|
||||||
>>> embassy_time-846f66f1620ad42c.embassy_time.4f6a638abb75dd4c-cgu.0.rcgu.o:(embassy_time::driver::allocate_alarm::hf5145b6bd46706b2) in archive Devel/Embedded/pogodyna/target/thumbv7em-none-eabihf/debug/deps/libembassy_time-846f66f1620ad42c.rlib
|
|
||||||
|
|
||||||
rust-lld: error: undefined symbol: _embassy_time_set_alarm_callback
|
|
||||||
>>> referenced by driver.rs:139 (src/driver.rs:139)
|
|
||||||
>>> embassy_time-846f66f1620ad42c.embassy_time.4f6a638abb75dd4c-cgu.0.rcgu.o:(embassy_time::driver::set_alarm_callback::h24f92388d96eafd2) in archive Devel/Embedded/pogodyna/target/thumbv7em-none-eabihf/debug/deps/libembassy_time-846f66f1620ad42c.rlib
|
|
||||||
|
|
||||||
rust-lld: error: undefined symbol: _embassy_time_set_alarm
|
|
||||||
>>> referenced by driver.rs:144 (src/driver.rs:144)
|
|
||||||
>>> embassy_time-846f66f1620ad42c.embassy_time.4f6a638abb75dd4c-cgu.0.rcgu.o:(embassy_time::driver::set_alarm::h530a5b1f444a6d5b) in archive Devel/Embedded/pogodyna/target/thumbv7em-none-eabihf/debug/deps/libembassy_time-846f66f1620ad42c.rlib
|
|
||||||
----
|
|
||||||
|
|
||||||
You probably need to enable a time driver for your HAL (not in `embassy-time`!). For example with `embassy-stm32`, you might need to enable `time-driver-any`:
|
|
||||||
|
|
||||||
[source,toml]
|
|
||||||
----
|
|
||||||
[dependencies.embassy-stm32]
|
|
||||||
version = "0.1.0"
|
|
||||||
features = [
|
|
||||||
# ...
|
|
||||||
"time-driver-any", # Add this line!
|
|
||||||
# ...
|
|
||||||
]
|
|
||||||
----
|
|
||||||
|
|
||||||
== Error: `Only one package in the dependency graph may specify the same links value.`
|
|
||||||
|
|
||||||
You have multiple versions of the same crate in your dependency tree. This means that some of your
|
|
||||||
embassy crates are coming from crates.io, and some from git, each of them pulling in a different set
|
|
||||||
of dependencies.
|
|
||||||
|
|
||||||
To resolve this issue, make sure to only use a single source for all your embassy crates! To do this,
|
|
||||||
you should patch your dependencies to use git sources using `[patch.crates.io]` and maybe `[patch.'https://github.com/embassy-rs/embassy.git']`.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
[source,toml]
|
|
||||||
----
|
|
||||||
[patch.crates-io]
|
|
||||||
embassy-time = { git = "https://github.com/embassy-rs/embassy.git", rev = "e5fdd35" }
|
|
||||||
----
|
|
||||||
|
|
||||||
Note that the git revision should match any other embassy patches or git dependencies that you are using!
|
|
@ -1,80 +0,0 @@
|
|||||||
= Project Structure
|
|
||||||
|
|
||||||
There are many ways to configure embassy and its components for your exact application. The link:https://github.com/embassy-rs/embassy/tree/main/examples[examples] directory for each chipset demonstrates how your project structure should look. Let's break it down:
|
|
||||||
|
|
||||||
The toplevel file structure of your project should look like this:
|
|
||||||
[source,plain]
|
|
||||||
----
|
|
||||||
{} = Maybe
|
|
||||||
|
|
||||||
my-project
|
|
||||||
|- .cargo
|
|
||||||
| |- config.toml
|
|
||||||
|- src
|
|
||||||
| |- main.rs
|
|
||||||
|- build.rs
|
|
||||||
|- Cargo.toml
|
|
||||||
|- {memory.x}
|
|
||||||
|- rust-toolchain.toml
|
|
||||||
----
|
|
||||||
|
|
||||||
=== .cargo/config.toml
|
|
||||||
|
|
||||||
This directory/file describes what platform you're on, and configures link:https://github.com/probe-rs/probe-rs[probe-rs] to deploy to your device.
|
|
||||||
|
|
||||||
Here is a minimal example:
|
|
||||||
|
|
||||||
[source,toml]
|
|
||||||
----
|
|
||||||
[target.thumbv6m-none-eabi] # <-change for your platform
|
|
||||||
runner = 'probe-rs run --chip STM32F031K6Tx' # <- change for your chip
|
|
||||||
|
|
||||||
[build]
|
|
||||||
target = "thumbv6m-none-eabi" # <-change for your platform
|
|
||||||
|
|
||||||
[env]
|
|
||||||
DEFMT_LOG = "trace" # <- can change to info, warn, or error
|
|
||||||
----
|
|
||||||
|
|
||||||
=== build.rs
|
|
||||||
|
|
||||||
This is the build script for your project. It links defmt (what is defmt?) and the `memory.x` file if needed. This file is pretty specific for each chipset, just copy and paste from the corresponding link:https://github.com/embassy-rs/embassy/tree/main/examples[example].
|
|
||||||
|
|
||||||
=== Cargo.toml
|
|
||||||
|
|
||||||
This is your manifest file, where you can configure all of the embassy components to use the features you need.
|
|
||||||
|
|
||||||
TODO: someone should exhaustively describe every feature for every component!
|
|
||||||
|
|
||||||
=== memory.x
|
|
||||||
|
|
||||||
This file outlines the flash/ram usage of your program. It is especially useful when using link:https://github.com/embassy-rs/nrf-softdevice[nrf-softdevice] on an nRF5x.
|
|
||||||
|
|
||||||
Here is an example for using S140 with an nRF52840:
|
|
||||||
|
|
||||||
[source,x]
|
|
||||||
----
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
/* NOTE 1 K = 1 KiBi = 1024 bytes */
|
|
||||||
/* These values correspond to the NRF52840 with Softdevices S140 7.0.1 */
|
|
||||||
FLASH : ORIGIN = 0x00027000, LENGTH = 868K
|
|
||||||
RAM : ORIGIN = 0x20020000, LENGTH = 128K
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
=== rust-toolchain.toml
|
|
||||||
|
|
||||||
This file configures the rust version and configuration to use.
|
|
||||||
|
|
||||||
A minimal example:
|
|
||||||
|
|
||||||
[source,toml]
|
|
||||||
----
|
|
||||||
[toolchain]
|
|
||||||
channel = "nightly-2023-08-19" # <- as of writing, this is the exact rust version embassy uses
|
|
||||||
components = [ "rust-src", "rustfmt" ] # <- optionally add "llvm-tools-preview" for some extra features like "cargo size"
|
|
||||||
targets = [
|
|
||||||
"thumbv6m-none-eabi" # <-change for your platform
|
|
||||||
]
|
|
||||||
----
|
|
@ -27,7 +27,7 @@ If you use the `#[embassy_executor::main]` macro in your application, it creates
|
|||||||
|
|
||||||
Interrupts are a common way for peripherals to signal completion of some operation and fits well with the async execution model. The following diagram describes a typical application flow where (1) a task is polled and is attempting to make progress. The task then (2) instructs the peripheral to perform some operation, and awaits. After some time has passed, (3) an interrupt is raised, marking the completion of the operation.
|
Interrupts are a common way for peripherals to signal completion of some operation and fits well with the async execution model. The following diagram describes a typical application flow where (1) a task is polled and is attempting to make progress. The task then (2) instructs the peripheral to perform some operation, and awaits. After some time has passed, (3) an interrupt is raised, marking the completion of the operation.
|
||||||
|
|
||||||
The peripheral HAL then (4) ensures that interrupt signals are routed to the peripheral and updating the peripheral state with the results of the operation. The executor is then (5) notified that the task should be polled, which it will do.
|
The peripheral HAL then (4) ensures that interrupt signals are routed to to the peripheral and updating the peripheral state with the results of the operation. The executor is then (5) notified that the task should be polled, which it will do.
|
||||||
|
|
||||||
image::embassy_irq.png[Interrupt handling]
|
image::embassy_irq.png[Interrupt handling]
|
||||||
|
|
||||||
|
@ -25,12 +25,12 @@ features = ["defmt"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
digest = "0.10"
|
digest = "0.10"
|
||||||
log = { version = "0.4", optional = true }
|
log = { version = "0.4", optional = true }
|
||||||
ed25519-dalek = { version = "1.0.1", default_features = false, features = ["u32_backend"], optional = true }
|
ed25519-dalek = { version = "1.0.1", default_features = false, features = ["u32_backend"], optional = true }
|
||||||
embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
|
embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
|
||||||
embassy-sync = { version = "0.5.0", path = "../../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
|
||||||
embedded-storage = "0.3.1"
|
embedded-storage = "0.3.0"
|
||||||
embedded-storage-async = { version = "0.4.1" }
|
embedded-storage-async = { version = "0.4.0", optional = true }
|
||||||
salty = { git = "https://github.com/ycrypto/salty.git", rev = "a9f17911a5024698406b75c0fac56ab5ccf6a8c7", optional = true }
|
salty = { git = "https://github.com/ycrypto/salty.git", rev = "a9f17911a5024698406b75c0fac56ab5ccf6a8c7", optional = true }
|
||||||
signature = { version = "1.6.4", default-features = false }
|
signature = { version = "1.6.4", default-features = false }
|
||||||
|
|
||||||
@ -50,5 +50,7 @@ features = ["rand", "std", "u32_backend"]
|
|||||||
ed25519-dalek = ["dep:ed25519-dalek", "_verify"]
|
ed25519-dalek = ["dep:ed25519-dalek", "_verify"]
|
||||||
ed25519-salty = ["dep:salty", "_verify"]
|
ed25519-salty = ["dep:salty", "_verify"]
|
||||||
|
|
||||||
|
nightly = ["dep:embedded-storage-async", "embassy-embedded-hal/nightly"]
|
||||||
|
|
||||||
#Internal features
|
#Internal features
|
||||||
_verify = []
|
_verify = []
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
#[cfg(feature = "nightly")]
|
||||||
mod asynch;
|
mod asynch;
|
||||||
mod blocking;
|
mod blocking;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub use asynch::{FirmwareState, FirmwareUpdater};
|
pub use asynch::{FirmwareState, FirmwareUpdater};
|
||||||
pub use blocking::{BlockingFirmwareState, BlockingFirmwareUpdater};
|
pub use blocking::{BlockingFirmwareState, BlockingFirmwareUpdater};
|
||||||
use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind};
|
use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
|
||||||
|
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(async_fn_in_trait)]
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
mod fmt;
|
mod fmt;
|
||||||
@ -17,9 +18,10 @@ mod test_flash;
|
|||||||
pub(crate) const STATE_ERASE_VALUE: u8 = 0xFF;
|
pub(crate) const STATE_ERASE_VALUE: u8 = 0xFF;
|
||||||
pub use boot_loader::{BootError, BootLoader, BootLoaderConfig};
|
pub use boot_loader::{BootError, BootLoader, BootLoaderConfig};
|
||||||
pub use firmware_updater::{
|
pub use firmware_updater::{
|
||||||
BlockingFirmwareState, BlockingFirmwareUpdater, FirmwareState, FirmwareUpdater, FirmwareUpdaterConfig,
|
BlockingFirmwareState, BlockingFirmwareUpdater, FirmwareUpdaterConfig, FirmwareUpdaterError,
|
||||||
FirmwareUpdaterError,
|
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
pub use firmware_updater::{FirmwareState, FirmwareUpdater};
|
||||||
|
|
||||||
pub(crate) const BOOT_MAGIC: u8 = 0xD0;
|
pub(crate) const BOOT_MAGIC: u8 = 0xD0;
|
||||||
pub(crate) const SWAP_MAGIC: u8 = 0xF0;
|
pub(crate) const SWAP_MAGIC: u8 = 0xF0;
|
||||||
@ -55,6 +57,7 @@ mod tests {
|
|||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
|
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash;
|
use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash;
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
|
|
||||||
@ -62,7 +65,9 @@ mod tests {
|
|||||||
use crate::boot_loader::BootLoaderConfig;
|
use crate::boot_loader::BootLoaderConfig;
|
||||||
use crate::firmware_updater::FirmwareUpdaterConfig;
|
use crate::firmware_updater::FirmwareUpdaterConfig;
|
||||||
use crate::mem_flash::MemFlash;
|
use crate::mem_flash::MemFlash;
|
||||||
use crate::test_flash::{AsyncTestFlash, BlockingTestFlash};
|
#[cfg(feature = "nightly")]
|
||||||
|
use crate::test_flash::AsyncTestFlash;
|
||||||
|
use crate::test_flash::BlockingTestFlash;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
@ -100,7 +105,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "_verify"))]
|
#[cfg(all(feature = "nightly", not(feature = "_verify")))]
|
||||||
fn test_swap_state() {
|
fn test_swap_state() {
|
||||||
const FIRMWARE_SIZE: usize = 57344;
|
const FIRMWARE_SIZE: usize = 57344;
|
||||||
let flash = AsyncTestFlash::new(BootLoaderConfig {
|
let flash = AsyncTestFlash::new(BootLoaderConfig {
|
||||||
@ -178,7 +183,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "_verify"))]
|
#[cfg(all(feature = "nightly", not(feature = "_verify")))]
|
||||||
fn test_swap_state_active_page_biggest() {
|
fn test_swap_state_active_page_biggest() {
|
||||||
const FIRMWARE_SIZE: usize = 12288;
|
const FIRMWARE_SIZE: usize = 12288;
|
||||||
let flash = AsyncTestFlash::new(BootLoaderConfig {
|
let flash = AsyncTestFlash::new(BootLoaderConfig {
|
||||||
@ -223,7 +228,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "_verify"))]
|
#[cfg(all(feature = "nightly", not(feature = "_verify")))]
|
||||||
fn test_swap_state_dfu_page_biggest() {
|
fn test_swap_state_dfu_page_biggest() {
|
||||||
const FIRMWARE_SIZE: usize = 12288;
|
const FIRMWARE_SIZE: usize = 12288;
|
||||||
let flash = AsyncTestFlash::new(BootLoaderConfig {
|
let flash = AsyncTestFlash::new(BootLoaderConfig {
|
||||||
@ -267,7 +272,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "_verify")]
|
#[cfg(all(feature = "nightly", feature = "_verify"))]
|
||||||
fn test_verify() {
|
fn test_verify() {
|
||||||
// The following key setup is based on:
|
// The following key setup is based on:
|
||||||
// https://docs.rs/ed25519-dalek/latest/ed25519_dalek/#example
|
// https://docs.rs/ed25519-dalek/latest/ed25519_dalek/#example
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
use core::ops::{Bound, Range, RangeBounds};
|
use core::ops::{Bound, Range, RangeBounds};
|
||||||
|
|
||||||
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
|
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
|
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
|
||||||
|
|
||||||
pub struct MemFlash<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> {
|
pub struct MemFlash<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> {
|
||||||
@ -140,6 +141,7 @@ impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> NorFla
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncReadNorFlash
|
impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncReadNorFlash
|
||||||
for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
|
for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
|
||||||
{
|
{
|
||||||
@ -154,6 +156,7 @@ impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncNorFlash
|
impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncNorFlash
|
||||||
for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
|
for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<ACTIVE, DFU, STATE> BlockingTestFlash<ACTIVE, DFU, STATE>
|
impl<ACTIVE, DFU, STATE> BlockingTestFlash<ACTIVE, DFU, STATE>
|
||||||
where
|
where
|
||||||
ACTIVE: NorFlash + embedded_storage_async::nor_flash::NorFlash,
|
ACTIVE: NorFlash + embedded_storage_async::nor_flash::NorFlash,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
#[cfg(feature = "nightly")]
|
||||||
mod asynch;
|
mod asynch;
|
||||||
mod blocking;
|
mod blocking;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub(crate) use asynch::AsyncTestFlash;
|
pub(crate) use asynch::AsyncTestFlash;
|
||||||
pub(crate) use blocking::BlockingTestFlash;
|
pub(crate) use blocking::BlockingTestFlash;
|
||||||
|
@ -16,13 +16,13 @@ target = "thumbv7em-none-eabi"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
|
|
||||||
embassy-sync = { version = "0.5.0", path = "../../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
|
||||||
embassy-nrf = { path = "../../embassy-nrf" }
|
embassy-nrf = { path = "../../embassy-nrf" }
|
||||||
embassy-boot = { path = "../boot", default-features = false }
|
embassy-boot = { path = "../boot", default-features = false }
|
||||||
cortex-m = { version = "0.7.6" }
|
cortex-m = { version = "0.7.6" }
|
||||||
cortex-m-rt = { version = "0.7" }
|
cortex-m-rt = { version = "0.7" }
|
||||||
embedded-storage = "0.3.1"
|
embedded-storage = "0.3.0"
|
||||||
embedded-storage-async = { version = "0.4.1" }
|
embedded-storage-async = { version = "0.4.0", optional = true }
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
|
||||||
nrf-softdevice-mbr = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-softdevice.git", branch = "master", optional = true }
|
nrf-softdevice-mbr = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-softdevice.git", branch = "master", optional = true }
|
||||||
@ -36,3 +36,8 @@ defmt = [
|
|||||||
softdevice = [
|
softdevice = [
|
||||||
"nrf-softdevice-mbr",
|
"nrf-softdevice-mbr",
|
||||||
]
|
]
|
||||||
|
nightly = [
|
||||||
|
"dep:embedded-storage-async",
|
||||||
|
"embassy-boot/nightly",
|
||||||
|
"embassy-nrf/nightly"
|
||||||
|
]
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
mod fmt;
|
mod fmt;
|
||||||
|
|
||||||
pub use embassy_boot::{
|
pub use embassy_boot::{
|
||||||
AlignedBuffer, BlockingFirmwareState, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareState, FirmwareUpdater,
|
AlignedBuffer, BlockingFirmwareState, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig,
|
||||||
FirmwareUpdaterConfig,
|
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
pub use embassy_boot::{FirmwareState, FirmwareUpdater};
|
||||||
use embassy_nrf::nvmc::PAGE_SIZE;
|
use embassy_nrf::nvmc::PAGE_SIZE;
|
||||||
use embassy_nrf::peripherals::WDT;
|
use embassy_nrf::peripherals::WDT;
|
||||||
use embassy_nrf::wdt;
|
use embassy_nrf::wdt;
|
||||||
|
@ -17,15 +17,15 @@ defmt = { version = "0.3", optional = true }
|
|||||||
defmt-rtt = { version = "0.4", optional = true }
|
defmt-rtt = { version = "0.4", optional = true }
|
||||||
log = { version = "0.4", optional = true }
|
log = { version = "0.4", optional = true }
|
||||||
|
|
||||||
embassy-sync = { version = "0.5.0", path = "../../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
|
||||||
embassy-rp = { path = "../../embassy-rp", default-features = false }
|
embassy-rp = { path = "../../embassy-rp", default-features = false }
|
||||||
embassy-boot = { path = "../boot", default-features = false }
|
embassy-boot = { path = "../boot", default-features = false }
|
||||||
embassy-time = { path = "../../embassy-time" }
|
embassy-time = { path = "../../embassy-time" }
|
||||||
|
|
||||||
cortex-m = { version = "0.7.6" }
|
cortex-m = { version = "0.7.6" }
|
||||||
cortex-m-rt = { version = "0.7" }
|
cortex-m-rt = { version = "0.7" }
|
||||||
embedded-storage = "0.3.1"
|
embedded-storage = "0.3.0"
|
||||||
embedded-storage-async = { version = "0.4.1" }
|
embedded-storage-async = { version = "0.4.0", optional = true }
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@ -40,6 +40,12 @@ log = [
|
|||||||
"embassy-rp/log",
|
"embassy-rp/log",
|
||||||
]
|
]
|
||||||
debug = ["defmt-rtt"]
|
debug = ["defmt-rtt"]
|
||||||
|
nightly = [
|
||||||
|
"dep:embedded-storage-async",
|
||||||
|
"embassy-boot/nightly",
|
||||||
|
"embassy-rp/nightly",
|
||||||
|
"embassy-time/nightly"
|
||||||
|
]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
debug = 2
|
debug = 2
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
mod fmt;
|
mod fmt;
|
||||||
|
|
||||||
pub use embassy_boot::{
|
pub use embassy_boot::{
|
||||||
AlignedBuffer, BlockingFirmwareState, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareState, FirmwareUpdater,
|
AlignedBuffer, BlockingFirmwareState, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig, State,
|
||||||
FirmwareUpdaterConfig, State,
|
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
pub use embassy_boot::{FirmwareState, FirmwareUpdater};
|
||||||
use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE};
|
use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE};
|
||||||
use embassy_rp::peripherals::{FLASH, WATCHDOG};
|
use embassy_rp::peripherals::{FLASH, WATCHDOG};
|
||||||
use embassy_rp::watchdog::Watchdog;
|
use embassy_rp::watchdog::Watchdog;
|
||||||
|
@ -18,19 +18,32 @@ defmt = { version = "0.3", optional = true }
|
|||||||
defmt-rtt = { version = "0.4", optional = true }
|
defmt-rtt = { version = "0.4", optional = true }
|
||||||
log = { version = "0.4", optional = true }
|
log = { version = "0.4", optional = true }
|
||||||
|
|
||||||
embassy-sync = { version = "0.5.0", path = "../../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
|
||||||
embassy-stm32 = { path = "../../embassy-stm32", default-features = false }
|
embassy-stm32 = { path = "../../embassy-stm32", default-features = false }
|
||||||
embassy-boot = { path = "../boot", default-features = false }
|
embassy-boot = { path = "../boot", default-features = false }
|
||||||
cortex-m = { version = "0.7.6" }
|
cortex-m = { version = "0.7.6" }
|
||||||
cortex-m-rt = { version = "0.7" }
|
cortex-m-rt = { version = "0.7" }
|
||||||
embedded-storage = "0.3.1"
|
embedded-storage = "0.3.0"
|
||||||
embedded-storage-async = { version = "0.4.1" }
|
embedded-storage-async = { version = "0.4.0", optional = true }
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
defmt = ["dep:defmt", "embassy-boot/defmt", "embassy-stm32/defmt"]
|
defmt = [
|
||||||
log = ["dep:log", "embassy-boot/log", "embassy-stm32/log"]
|
"dep:defmt",
|
||||||
|
"embassy-boot/defmt",
|
||||||
|
"embassy-stm32/defmt",
|
||||||
|
]
|
||||||
|
log = [
|
||||||
|
"dep:log",
|
||||||
|
"embassy-boot/log",
|
||||||
|
"embassy-stm32/log",
|
||||||
|
]
|
||||||
debug = ["defmt-rtt"]
|
debug = ["defmt-rtt"]
|
||||||
|
nightly = [
|
||||||
|
"dep:embedded-storage-async",
|
||||||
|
"embassy-boot/nightly",
|
||||||
|
"embassy-stm32/nightly"
|
||||||
|
]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
debug = 2
|
debug = 2
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
mod fmt;
|
mod fmt;
|
||||||
|
|
||||||
pub use embassy_boot::{
|
pub use embassy_boot::{
|
||||||
AlignedBuffer, BlockingFirmwareState, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareState, FirmwareUpdater,
|
AlignedBuffer, BlockingFirmwareState, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig, State,
|
||||||
FirmwareUpdaterConfig, State,
|
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
pub use embassy_boot::{FirmwareState, FirmwareUpdater};
|
||||||
use embedded_storage::nor_flash::NorFlash;
|
use embedded_storage::nor_flash::NorFlash;
|
||||||
|
|
||||||
/// A bootloader for STM32 devices.
|
/// A bootloader for STM32 devices.
|
||||||
|
@ -8,25 +8,27 @@ license = "MIT OR Apache-2.0"
|
|||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-embedded-hal-v$VERSION/embassy-embedded-hal/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-embedded-hal-v$VERSION/embassy-embedded-hal/src/"
|
||||||
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-embedded-hal/src/"
|
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-embedded-hal/src/"
|
||||||
features = ["std"]
|
features = ["nightly", "std"]
|
||||||
target = "x86_64-unknown-linux-gnu"
|
target = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
std = []
|
std = []
|
||||||
|
# Enable nightly-only features
|
||||||
|
nightly = ["embassy-futures", "embedded-hal-async", "embedded-storage-async"]
|
||||||
time = ["dep:embassy-time"]
|
time = ["dep:embassy-time"]
|
||||||
default = ["time"]
|
default = ["time"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
|
embassy-futures = { version = "0.1.0", path = "../embassy-futures", optional = true }
|
||||||
embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time", optional = true }
|
embassy-time = { version = "0.1.5", 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",
|
||||||
] }
|
] }
|
||||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" }
|
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" }
|
||||||
embedded-hal-async = { version = "=1.0.0-rc.2" }
|
embedded-hal-async = { version = "=1.0.0-rc.1", optional = true }
|
||||||
embedded-storage = "0.3.1"
|
embedded-storage = "0.3.0"
|
||||||
embedded-storage-async = { version = "0.4.1" }
|
embedded-storage-async = { version = "0.4.0", optional = true }
|
||||||
nb = "1.0.0"
|
nb = "1.0.0"
|
||||||
|
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
use std::env;
|
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
|
||||||
|
|
||||||
let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
|
|
||||||
|
|
||||||
let output = Command::new(rustc)
|
|
||||||
.arg("--version")
|
|
||||||
.output()
|
|
||||||
.expect("failed to run `rustc --version`");
|
|
||||||
|
|
||||||
if String::from_utf8_lossy(&output.stdout).contains("nightly") {
|
|
||||||
println!("cargo:rustc-cfg=nightly");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, ReadNorFlash};
|
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, ReadNorFlash};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
|
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
|
||||||
|
|
||||||
/// Convenience helper for concatenating two consecutive flashes into one.
|
/// Convenience helper for concatenating two consecutive flashes into one.
|
||||||
@ -116,6 +117,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<First, Second, E> AsyncReadNorFlash for ConcatFlash<First, Second>
|
impl<First, Second, E> AsyncReadNorFlash for ConcatFlash<First, Second>
|
||||||
where
|
where
|
||||||
First: AsyncReadNorFlash<Error = E>,
|
First: AsyncReadNorFlash<Error = E>,
|
||||||
@ -144,6 +146,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<First, Second, E> AsyncNorFlash for ConcatFlash<First, Second>
|
impl<First, Second, E> AsyncNorFlash for ConcatFlash<First, Second>
|
||||||
where
|
where
|
||||||
First: AsyncNorFlash<Error = E>,
|
First: AsyncNorFlash<Error = E>,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
|
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
|
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
@ -92,6 +93,7 @@ impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> NorFla
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncReadNorFlash
|
impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncReadNorFlash
|
||||||
for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
|
for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
|
||||||
{
|
{
|
||||||
@ -107,6 +109,7 @@ impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncNorFlash
|
impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncNorFlash
|
||||||
for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
|
for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
|
||||||
{
|
{
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind};
|
use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind};
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
mod asynch;
|
mod asynch;
|
||||||
mod blocking;
|
mod blocking;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub use asynch::Partition;
|
pub use asynch::Partition;
|
||||||
pub use blocking::BlockingPartition;
|
pub use blocking::BlockingPartition;
|
||||||
|
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
#![cfg_attr(nightly, feature(async_fn_in_trait, impl_trait_projections))]
|
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections, try_blocks))]
|
||||||
#![cfg_attr(nightly, allow(stable_features, unknown_lints))]
|
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
|
||||||
#![allow(async_fn_in_trait)]
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
//! Utilities to use `embedded-hal` traits with Embassy.
|
//! Utilities to use `embedded-hal` traits with Embassy.
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub mod adapter;
|
pub mod adapter;
|
||||||
|
|
||||||
pub mod flash;
|
pub mod flash;
|
||||||
|
|
||||||
pub mod shared_bus;
|
pub mod shared_bus;
|
||||||
|
|
||||||
/// Set the configuration of a peripheral driver.
|
/// Set the configuration of a peripheral driver.
|
||||||
|
@ -2,15 +2,16 @@
|
|||||||
//!
|
//!
|
||||||
//! # Example (nrf52)
|
//! # Example (nrf52)
|
||||||
//!
|
//!
|
||||||
//! ```rust,ignore
|
//! ```rust
|
||||||
//! use embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice;
|
//! use embassy_embedded_hal::shared_bus::i2c::I2cDevice;
|
||||||
//! use embassy_sync::mutex::Mutex;
|
//! use embassy_sync::mutex::Mutex;
|
||||||
//! use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
//! use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||||
//!
|
//!
|
||||||
//! static I2C_BUS: StaticCell<Mutex<NoopRawMutex, Twim<TWISPI0>>> = StaticCell::new();
|
//! static I2C_BUS: StaticCell<Mutex::<ThreadModeRawMutex, Twim<TWISPI0>>> = StaticCell::new();
|
||||||
//! let config = twim::Config::default();
|
//! let config = twim::Config::default();
|
||||||
//! let i2c = Twim::new(p.TWISPI0, Irqs, p.P0_03, p.P0_04, config);
|
//! let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
|
||||||
//! let i2c_bus = Mutex::new(i2c);
|
//! let i2c = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
|
||||||
|
//! let i2c_bus = Mutex::<ThreadModeRawMutex, _>::new(i2c);
|
||||||
//! let i2c_bus = I2C_BUS.init(i2c_bus);
|
//! let i2c_bus = I2C_BUS.init(i2c_bus);
|
||||||
//!
|
//!
|
||||||
//! // Device 1, using embedded-hal-async compatible driver for QMC5883L compass
|
//! // Device 1, using embedded-hal-async compatible driver for QMC5883L compass
|
||||||
|
@ -2,16 +2,17 @@
|
|||||||
//!
|
//!
|
||||||
//! # Example (nrf52)
|
//! # Example (nrf52)
|
||||||
//!
|
//!
|
||||||
//! ```rust,ignore
|
//! ```rust
|
||||||
//! use embassy_embedded_hal::shared_bus::spi::SpiDevice;
|
//! use embassy_embedded_hal::shared_bus::spi::SpiDevice;
|
||||||
//! use embassy_sync::mutex::Mutex;
|
//! use embassy_sync::mutex::Mutex;
|
||||||
//! use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
//! use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||||
//!
|
//!
|
||||||
//! static SPI_BUS: StaticCell<Mutex<NoopRawMutex, spim::Spim<SPI3>>> = StaticCell::new();
|
//! static SPI_BUS: StaticCell<Mutex<ThreadModeRawMutex, spim::Spim<SPI3>>> = StaticCell::new();
|
||||||
//! let mut config = spim::Config::default();
|
//! let mut config = spim::Config::default();
|
||||||
//! config.frequency = spim::Frequency::M32;
|
//! config.frequency = spim::Frequency::M32;
|
||||||
//! let spi = spim::Spim::new_txonly(p.SPI3, Irqs, p.P0_15, p.P0_18, config);
|
//! let irq = interrupt::take!(SPIM3);
|
||||||
//! let spi_bus = Mutex::new(spi);
|
//! let spi = spim::Spim::new_txonly(p.SPI3, irq, p.P0_15, p.P0_18, config);
|
||||||
|
//! let spi_bus = Mutex::<ThreadModeRawMutex, _>::new(spi);
|
||||||
//! let spi_bus = SPI_BUS.init(spi_bus);
|
//! let spi_bus = SPI_BUS.init(spi_bus);
|
||||||
//!
|
//!
|
||||||
//! // Device 1, using embedded-hal-async compatible driver for ST7735 LCD display
|
//! // Device 1, using embedded-hal-async compatible driver for ST7735 LCD display
|
||||||
@ -62,36 +63,22 @@ where
|
|||||||
CS: OutputPin,
|
CS: OutputPin,
|
||||||
{
|
{
|
||||||
async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> {
|
async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> {
|
||||||
if cfg!(not(feature = "time")) && operations.iter().any(|op| matches!(op, Operation::DelayNs(_))) {
|
|
||||||
return Err(SpiDeviceError::DelayNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut bus = self.bus.lock().await;
|
let mut bus = self.bus.lock().await;
|
||||||
self.cs.set_low().map_err(SpiDeviceError::Cs)?;
|
self.cs.set_low().map_err(SpiDeviceError::Cs)?;
|
||||||
|
|
||||||
let op_res = 'ops: {
|
let op_res: Result<(), BUS::Error> = try {
|
||||||
for op in operations {
|
for op in operations {
|
||||||
let res = match op {
|
match op {
|
||||||
Operation::Read(buf) => bus.read(buf).await,
|
Operation::Read(buf) => bus.read(buf).await?,
|
||||||
Operation::Write(buf) => bus.write(buf).await,
|
Operation::Write(buf) => bus.write(buf).await?,
|
||||||
Operation::Transfer(read, write) => bus.transfer(read, write).await,
|
Operation::Transfer(read, write) => bus.transfer(read, write).await?,
|
||||||
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await,
|
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?,
|
||||||
#[cfg(not(feature = "time"))]
|
#[cfg(not(feature = "time"))]
|
||||||
Operation::DelayNs(_) => unreachable!(),
|
Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported),
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
Operation::DelayNs(ns) => match bus.flush().await {
|
Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await,
|
||||||
Err(e) => Err(e),
|
|
||||||
Ok(()) => {
|
|
||||||
embassy_time::Timer::after_nanos(*ns as _).await;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if let Err(e) = res {
|
|
||||||
break 'ops Err(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// On failure, it's important to still flush and deassert CS.
|
// On failure, it's important to still flush and deassert CS.
|
||||||
@ -140,37 +127,23 @@ where
|
|||||||
CS: OutputPin,
|
CS: OutputPin,
|
||||||
{
|
{
|
||||||
async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> {
|
async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> {
|
||||||
if cfg!(not(feature = "time")) && operations.iter().any(|op| matches!(op, Operation::DelayNs(_))) {
|
|
||||||
return Err(SpiDeviceError::DelayNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut bus = self.bus.lock().await;
|
let mut bus = self.bus.lock().await;
|
||||||
bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?;
|
bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?;
|
||||||
self.cs.set_low().map_err(SpiDeviceError::Cs)?;
|
self.cs.set_low().map_err(SpiDeviceError::Cs)?;
|
||||||
|
|
||||||
let op_res = 'ops: {
|
let op_res: Result<(), BUS::Error> = try {
|
||||||
for op in operations {
|
for op in operations {
|
||||||
let res = match op {
|
match op {
|
||||||
Operation::Read(buf) => bus.read(buf).await,
|
Operation::Read(buf) => bus.read(buf).await?,
|
||||||
Operation::Write(buf) => bus.write(buf).await,
|
Operation::Write(buf) => bus.write(buf).await?,
|
||||||
Operation::Transfer(read, write) => bus.transfer(read, write).await,
|
Operation::Transfer(read, write) => bus.transfer(read, write).await?,
|
||||||
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await,
|
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?,
|
||||||
#[cfg(not(feature = "time"))]
|
#[cfg(not(feature = "time"))]
|
||||||
Operation::DelayNs(_) => unreachable!(),
|
Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported),
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
Operation::DelayNs(ns) => match bus.flush().await {
|
Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await,
|
||||||
Err(e) => Err(e),
|
|
||||||
Ok(()) => {
|
|
||||||
embassy_time::Timer::after_nanos(*ns as _).await;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if let Err(e) = res {
|
|
||||||
break 'ops Err(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// On failure, it's important to still flush and deassert CS.
|
// On failure, it's important to still flush and deassert CS.
|
||||||
|
@ -55,10 +55,6 @@ where
|
|||||||
CS: OutputPin,
|
CS: OutputPin,
|
||||||
{
|
{
|
||||||
fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
|
fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
|
||||||
if cfg!(not(feature = "time")) && operations.iter().any(|op| matches!(op, Operation::DelayNs(_))) {
|
|
||||||
return Err(SpiDeviceError::DelayNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.bus.lock(|bus| {
|
self.bus.lock(|bus| {
|
||||||
let mut bus = bus.borrow_mut();
|
let mut bus = bus.borrow_mut();
|
||||||
self.cs.set_low().map_err(SpiDeviceError::Cs)?;
|
self.cs.set_low().map_err(SpiDeviceError::Cs)?;
|
||||||
@ -69,10 +65,10 @@ where
|
|||||||
Operation::Transfer(read, write) => bus.transfer(read, write),
|
Operation::Transfer(read, write) => bus.transfer(read, write),
|
||||||
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
|
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
|
||||||
#[cfg(not(feature = "time"))]
|
#[cfg(not(feature = "time"))]
|
||||||
Operation::DelayNs(_) => unreachable!(),
|
Operation::DelayUs(_) => Err(SpiDeviceError::DelayUsNotSupported),
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
Operation::DelayNs(ns) => {
|
Operation::DelayUs(us) => {
|
||||||
embassy_time::block_for(embassy_time::Duration::from_nanos(*ns as _));
|
embassy_time::block_for(embassy_time::Duration::from_micros(*us as _));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -165,10 +161,6 @@ where
|
|||||||
CS: OutputPin,
|
CS: OutputPin,
|
||||||
{
|
{
|
||||||
fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
|
fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
|
||||||
if cfg!(not(feature = "time")) && operations.iter().any(|op| matches!(op, Operation::DelayNs(_))) {
|
|
||||||
return Err(SpiDeviceError::DelayNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.bus.lock(|bus| {
|
self.bus.lock(|bus| {
|
||||||
let mut bus = bus.borrow_mut();
|
let mut bus = bus.borrow_mut();
|
||||||
bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?;
|
bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?;
|
||||||
@ -180,10 +172,10 @@ where
|
|||||||
Operation::Transfer(read, write) => bus.transfer(read, write),
|
Operation::Transfer(read, write) => bus.transfer(read, write),
|
||||||
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
|
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
|
||||||
#[cfg(not(feature = "time"))]
|
#[cfg(not(feature = "time"))]
|
||||||
Operation::DelayNs(_) => unreachable!(),
|
Operation::DelayUs(_) => Err(SpiDeviceError::DelayUsNotSupported),
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
Operation::DelayNs(ns) => {
|
Operation::DelayUs(us) => {
|
||||||
embassy_time::block_for(embassy_time::Duration::from_nanos(*ns as _));
|
embassy_time::block_for(embassy_time::Duration::from_micros(*us as _));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,9 @@ use core::fmt::Debug;
|
|||||||
|
|
||||||
use embedded_hal_1::{i2c, spi};
|
use embedded_hal_1::{i2c, spi};
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub mod asynch;
|
pub mod asynch;
|
||||||
|
|
||||||
pub mod blocking;
|
pub mod blocking;
|
||||||
|
|
||||||
/// Error returned by I2C device implementations in this crate.
|
/// Error returned by I2C device implementations in this crate.
|
||||||
@ -37,8 +39,8 @@ pub enum SpiDeviceError<BUS, CS> {
|
|||||||
Spi(BUS),
|
Spi(BUS),
|
||||||
/// Setting the value of the Chip Select (CS) pin failed.
|
/// Setting the value of the Chip Select (CS) pin failed.
|
||||||
Cs(CS),
|
Cs(CS),
|
||||||
/// Delay operations are not supported when the `time` Cargo feature is not enabled.
|
/// DelayUs operations are not supported when the `time` Cargo feature is not enabled.
|
||||||
DelayNotSupported,
|
DelayUsNotSupported,
|
||||||
/// The SPI bus could not be configured.
|
/// The SPI bus could not be configured.
|
||||||
Config,
|
Config,
|
||||||
}
|
}
|
||||||
@ -52,7 +54,7 @@ where
|
|||||||
match self {
|
match self {
|
||||||
Self::Spi(e) => e.kind(),
|
Self::Spi(e) => e.kind(),
|
||||||
Self::Cs(_) => spi::ErrorKind::Other,
|
Self::Cs(_) => spi::ErrorKind::Other,
|
||||||
Self::DelayNotSupported => spi::ErrorKind::Other,
|
Self::DelayUsNotSupported => spi::ErrorKind::Other,
|
||||||
Self::Config => spi::ErrorKind::Other,
|
Self::Config => spi::ErrorKind::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,6 @@ 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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## Unreleased
|
|
||||||
|
|
||||||
- Removed `arch-xtensa`. Use the executor provided by the HAL crate (`esp-hal`, `esp32s3-hal`, etc...) instead.
|
|
||||||
|
|
||||||
## 0.3.3 - 2023-11-15
|
## 0.3.3 - 2023-11-15
|
||||||
|
|
||||||
- Add `main` macro reexport for Xtensa arch.
|
- Add `main` macro reexport for Xtensa arch.
|
||||||
|
@ -27,13 +27,38 @@ default-target = "thumbv7em-none-eabi"
|
|||||||
targets = ["thumbv7em-none-eabi"]
|
targets = ["thumbv7em-none-eabi"]
|
||||||
features = ["nightly", "defmt", "arch-cortex-m", "executor-thread", "executor-interrupt"]
|
features = ["nightly", "defmt", "arch-cortex-m", "executor-thread", "executor-interrupt"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
|
||||||
|
# Architecture
|
||||||
|
_arch = [] # some arch was picked
|
||||||
|
arch-std = ["_arch", "critical-section/std"]
|
||||||
|
arch-cortex-m = ["_arch", "dep:cortex-m"]
|
||||||
|
arch-xtensa = ["_arch"]
|
||||||
|
arch-riscv32 = ["_arch", "dep:portable-atomic"]
|
||||||
|
arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"]
|
||||||
|
|
||||||
|
# Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded archs)
|
||||||
|
executor-thread = []
|
||||||
|
# Enable the interrupt-mode executor (available in Cortex-M only)
|
||||||
|
executor-interrupt = []
|
||||||
|
|
||||||
|
# Enable nightly-only features
|
||||||
|
nightly = []
|
||||||
|
|
||||||
|
turbowakers = []
|
||||||
|
|
||||||
|
integrated-timers = ["dep:embassy-time"]
|
||||||
|
|
||||||
|
# Trace interrupt invocations with rtos-trace.
|
||||||
|
rtos-trace-interrupt = ["rtos-trace", "embassy-macros/rtos-trace-interrupt"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
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 }
|
||||||
rtos-trace = { version = "0.1.2", optional = true }
|
rtos-trace = { version = "0.1.2", optional = true }
|
||||||
|
|
||||||
embassy-macros = { version = "0.2.1", path = "../embassy-macros" }
|
embassy-macros = { version = "0.2.1", path = "../embassy-macros" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time", optional = true}
|
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true}
|
||||||
critical-section = "1.1"
|
critical-section = "1.1"
|
||||||
|
|
||||||
# needed for riscv
|
# needed for riscv
|
||||||
@ -46,73 +71,3 @@ cortex-m = { version = "0.7.6", optional = true }
|
|||||||
# arch-wasm dependencies
|
# arch-wasm dependencies
|
||||||
wasm-bindgen = { version = "0.2.82", optional = true }
|
wasm-bindgen = { version = "0.2.82", optional = true }
|
||||||
js-sys = { version = "0.3", optional = true }
|
js-sys = { version = "0.3", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
critical-section = { version = "1.1", features = ["std"] }
|
|
||||||
|
|
||||||
|
|
||||||
[features]
|
|
||||||
|
|
||||||
# Architecture
|
|
||||||
_arch = [] # some arch was picked
|
|
||||||
arch-std = ["_arch", "critical-section/std"]
|
|
||||||
arch-cortex-m = ["_arch", "dep:cortex-m"]
|
|
||||||
arch-riscv32 = ["_arch", "dep:portable-atomic"]
|
|
||||||
arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"]
|
|
||||||
|
|
||||||
# Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded archs)
|
|
||||||
executor-thread = []
|
|
||||||
# Enable the interrupt-mode executor (available in Cortex-M only)
|
|
||||||
executor-interrupt = []
|
|
||||||
|
|
||||||
# Enable nightly-only features
|
|
||||||
nightly = ["embassy-macros/nightly"]
|
|
||||||
|
|
||||||
turbowakers = []
|
|
||||||
|
|
||||||
integrated-timers = ["dep:embassy-time"]
|
|
||||||
|
|
||||||
# BEGIN AUTOGENERATED CONFIG FEATURES
|
|
||||||
# Generated by gen_config.py. DO NOT EDIT.
|
|
||||||
task-arena-size-64 = []
|
|
||||||
task-arena-size-128 = []
|
|
||||||
task-arena-size-192 = []
|
|
||||||
task-arena-size-256 = []
|
|
||||||
task-arena-size-320 = []
|
|
||||||
task-arena-size-384 = []
|
|
||||||
task-arena-size-512 = []
|
|
||||||
task-arena-size-640 = []
|
|
||||||
task-arena-size-768 = []
|
|
||||||
task-arena-size-1024 = []
|
|
||||||
task-arena-size-1280 = []
|
|
||||||
task-arena-size-1536 = []
|
|
||||||
task-arena-size-2048 = []
|
|
||||||
task-arena-size-2560 = []
|
|
||||||
task-arena-size-3072 = []
|
|
||||||
task-arena-size-4096 = [] # Default
|
|
||||||
task-arena-size-5120 = []
|
|
||||||
task-arena-size-6144 = []
|
|
||||||
task-arena-size-8192 = []
|
|
||||||
task-arena-size-10240 = []
|
|
||||||
task-arena-size-12288 = []
|
|
||||||
task-arena-size-16384 = []
|
|
||||||
task-arena-size-20480 = []
|
|
||||||
task-arena-size-24576 = []
|
|
||||||
task-arena-size-32768 = []
|
|
||||||
task-arena-size-40960 = []
|
|
||||||
task-arena-size-49152 = []
|
|
||||||
task-arena-size-65536 = []
|
|
||||||
task-arena-size-81920 = []
|
|
||||||
task-arena-size-98304 = []
|
|
||||||
task-arena-size-131072 = []
|
|
||||||
task-arena-size-163840 = []
|
|
||||||
task-arena-size-196608 = []
|
|
||||||
task-arena-size-262144 = []
|
|
||||||
task-arena-size-327680 = []
|
|
||||||
task-arena-size-393216 = []
|
|
||||||
task-arena-size-524288 = []
|
|
||||||
task-arena-size-655360 = []
|
|
||||||
task-arena-size-786432 = []
|
|
||||||
task-arena-size-1048576 = []
|
|
||||||
|
|
||||||
# END AUTOGENERATED CONFIG FEATURES
|
|
||||||
|
@ -2,36 +2,10 @@
|
|||||||
|
|
||||||
An async/await executor designed for embedded usage.
|
An async/await executor designed for embedded usage.
|
||||||
|
|
||||||
- No `alloc`, no heap needed.
|
- No `alloc`, no heap needed. Task futures are statically allocated.
|
||||||
- With nightly Rust, task futures can be fully 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_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.
|
||||||
- Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks.
|
- Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks.
|
||||||
|
|
||||||
## Task arena
|
|
||||||
|
|
||||||
When the `nightly` Cargo feature is not enabled, `embassy-executor` allocates tasks out of an arena (a very simple bump allocator).
|
|
||||||
|
|
||||||
If the task arena gets full, the program will panic at runtime. To guarantee this doesn't happen, you must set the size to the sum of sizes of all tasks.
|
|
||||||
|
|
||||||
Tasks are allocated from the arena when spawned for the first time. If the task exists, the allocation is not released to the arena, but can be reused to spawn the task again. For multiple-instance tasks (like `#[embassy_executor::task(pool_size = 4)]`), the first spawn will allocate memory for all instances. This is done for performance and to increase predictability (for example, spawning at least 1 instance of every task at boot guarantees an immediate panic if the arena is too small, while allocating instances on-demand could delay the panic to only when the program is under load).
|
|
||||||
|
|
||||||
The arena size can be configured in two ways:
|
|
||||||
|
|
||||||
- Via Cargo features: enable a Cargo feature like `task-arena-size-8192`. Only a selection of values
|
|
||||||
is available, check `Cargo.toml` for the list.
|
|
||||||
- Via environment variables at build time: set the variable named `EMBASSY_EXECUTOR_TASK_ARENA_SIZE`. For example
|
|
||||||
`EMBASSY_EXECUTOR_TASK_ARENA_SIZE=4321 cargo build`. You can also set them in the `[env]` section of `.cargo/config.toml`.
|
|
||||||
Any value can be set, unlike with Cargo features.
|
|
||||||
|
|
||||||
Environment variables take precedence over Cargo features. If two Cargo features are enabled for the same setting
|
|
||||||
with different values, compilation fails.
|
|
||||||
|
|
||||||
## Statically allocating tasks
|
|
||||||
|
|
||||||
When using nightly Rust, enable the `nightly` Cargo feature. This will make `embassy-executor` use the `type_alias_impl_trait` feature to allocate all tasks in `static`s. Each task gets its own `static`, with the exact size to hold the task (or multiple instances of it, if using `pool_size`) calculated automatically at compile time. If tasks don't fit in RAM, this is detected at compile time by the linker. Runtime panics due to running out of memory are not possible.
|
|
||||||
|
|
||||||
The configured arena size is ignored, no arena is used at all.
|
|
||||||
|
@ -1,97 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
use std::env;
|
||||||
use std::fmt::Write;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::{env, fs};
|
|
||||||
|
|
||||||
static CONFIGS: &[(&str, usize)] = &[
|
|
||||||
// BEGIN AUTOGENERATED CONFIG FEATURES
|
|
||||||
// Generated by gen_config.py. DO NOT EDIT.
|
|
||||||
("TASK_ARENA_SIZE", 4096),
|
|
||||||
// END AUTOGENERATED CONFIG FEATURES
|
|
||||||
];
|
|
||||||
|
|
||||||
struct ConfigState {
|
|
||||||
value: usize,
|
|
||||||
seen_feature: bool,
|
|
||||||
seen_env: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let crate_name = env::var("CARGO_PKG_NAME")
|
|
||||||
.unwrap()
|
|
||||||
.to_ascii_uppercase()
|
|
||||||
.replace('-', "_");
|
|
||||||
|
|
||||||
// only rebuild if build.rs changed. Otherwise Cargo will rebuild if any
|
|
||||||
// other file changed.
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
|
||||||
|
|
||||||
// Rebuild if config envvar changed.
|
|
||||||
for (name, _) in CONFIGS {
|
|
||||||
println!("cargo:rerun-if-env-changed={crate_name}_{name}");
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut configs = HashMap::new();
|
|
||||||
for (name, default) in CONFIGS {
|
|
||||||
configs.insert(
|
|
||||||
*name,
|
|
||||||
ConfigState {
|
|
||||||
value: *default,
|
|
||||||
seen_env: false,
|
|
||||||
seen_feature: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let prefix = format!("{crate_name}_");
|
|
||||||
for (var, value) in env::vars() {
|
|
||||||
if let Some(name) = var.strip_prefix(&prefix) {
|
|
||||||
let Some(cfg) = configs.get_mut(name) else {
|
|
||||||
panic!("Unknown env var {name}")
|
|
||||||
};
|
|
||||||
|
|
||||||
let Ok(value) = value.parse::<usize>() else {
|
|
||||||
panic!("Invalid value for env var {name}: {value}")
|
|
||||||
};
|
|
||||||
|
|
||||||
cfg.value = value;
|
|
||||||
cfg.seen_env = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(feature) = var.strip_prefix("CARGO_FEATURE_") {
|
|
||||||
if let Some(i) = feature.rfind('_') {
|
|
||||||
let name = &feature[..i];
|
|
||||||
let value = &feature[i + 1..];
|
|
||||||
if let Some(cfg) = configs.get_mut(name) {
|
|
||||||
let Ok(value) = value.parse::<usize>() else {
|
|
||||||
panic!("Invalid value for feature {name}: {value}")
|
|
||||||
};
|
|
||||||
|
|
||||||
// envvars take priority.
|
|
||||||
if !cfg.seen_env {
|
|
||||||
if cfg.seen_feature {
|
|
||||||
panic!("multiple values set for feature {}: {} and {}", name, cfg.value, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.value = value;
|
|
||||||
cfg.seen_feature = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut data = String::new();
|
|
||||||
|
|
||||||
for (name, cfg) in &configs {
|
|
||||||
writeln!(&mut data, "pub const {}: usize = {};", name, cfg.value).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
|
||||||
let out_file = out_dir.join("config.rs").to_string_lossy().to_string();
|
|
||||||
fs::write(out_file, data).unwrap();
|
|
||||||
|
|
||||||
// cortex-m targets
|
|
||||||
let target = env::var("TARGET").unwrap();
|
let target = env::var("TARGET").unwrap();
|
||||||
|
|
||||||
if target.starts_with("thumbv6m-") {
|
if target.starts_with("thumbv6m-") {
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
abspath = os.path.abspath(__file__)
|
|
||||||
dname = os.path.dirname(abspath)
|
|
||||||
os.chdir(dname)
|
|
||||||
|
|
||||||
features = []
|
|
||||||
|
|
||||||
|
|
||||||
def feature(name, default, min=None, max=None, pow2=None, vals=None, factors=[]):
|
|
||||||
if vals is None:
|
|
||||||
assert min is not None
|
|
||||||
assert max is not None
|
|
||||||
|
|
||||||
vals = set()
|
|
||||||
val = min
|
|
||||||
while val <= max:
|
|
||||||
vals.add(val)
|
|
||||||
for f in factors:
|
|
||||||
if val * f <= max:
|
|
||||||
vals.add(val * f)
|
|
||||||
if (pow2 == True or (isinstance(pow2, int) and val >= pow2)) and val > 0:
|
|
||||||
val *= 2
|
|
||||||
else:
|
|
||||||
val += 1
|
|
||||||
vals.add(default)
|
|
||||||
vals = sorted(list(vals))
|
|
||||||
|
|
||||||
features.append(
|
|
||||||
{
|
|
||||||
"name": name,
|
|
||||||
"default": default,
|
|
||||||
"vals": vals,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
feature(
|
|
||||||
"task_arena_size", default=4096, min=64, max=1024 * 1024, pow2=True, factors=[3, 5]
|
|
||||||
)
|
|
||||||
|
|
||||||
# ========= Update Cargo.toml
|
|
||||||
|
|
||||||
things = ""
|
|
||||||
for f in features:
|
|
||||||
name = f["name"].replace("_", "-")
|
|
||||||
for val in f["vals"]:
|
|
||||||
things += f"{name}-{val} = []"
|
|
||||||
if val == f["default"]:
|
|
||||||
things += " # Default"
|
|
||||||
things += "\n"
|
|
||||||
things += "\n"
|
|
||||||
|
|
||||||
SEPARATOR_START = "# BEGIN AUTOGENERATED CONFIG FEATURES\n"
|
|
||||||
SEPARATOR_END = "# END AUTOGENERATED CONFIG FEATURES\n"
|
|
||||||
HELP = "# Generated by gen_config.py. DO NOT EDIT.\n"
|
|
||||||
with open("Cargo.toml", "r") as f:
|
|
||||||
data = f.read()
|
|
||||||
before, data = data.split(SEPARATOR_START, maxsplit=1)
|
|
||||||
_, after = data.split(SEPARATOR_END, maxsplit=1)
|
|
||||||
data = before + SEPARATOR_START + HELP + things + SEPARATOR_END + after
|
|
||||||
with open("Cargo.toml", "w") as f:
|
|
||||||
f.write(data)
|
|
||||||
|
|
||||||
|
|
||||||
# ========= Update build.rs
|
|
||||||
|
|
||||||
things = ""
|
|
||||||
for f in features:
|
|
||||||
name = f["name"].upper()
|
|
||||||
things += f' ("{name}", {f["default"]}),\n'
|
|
||||||
|
|
||||||
SEPARATOR_START = "// BEGIN AUTOGENERATED CONFIG FEATURES\n"
|
|
||||||
SEPARATOR_END = "// END AUTOGENERATED CONFIG FEATURES\n"
|
|
||||||
HELP = " // Generated by gen_config.py. DO NOT EDIT.\n"
|
|
||||||
with open("build.rs", "r") as f:
|
|
||||||
data = f.read()
|
|
||||||
before, data = data.split(SEPARATOR_START, maxsplit=1)
|
|
||||||
_, after = data.split(SEPARATOR_END, maxsplit=1)
|
|
||||||
data = before + SEPARATOR_START + HELP + things + " " + SEPARATOR_END + after
|
|
||||||
with open("build.rs", "w") as f:
|
|
||||||
f.write(data)
|
|
@ -51,6 +51,7 @@ mod thread {
|
|||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub use embassy_macros::main_cortex_m as main;
|
pub use embassy_macros::main_cortex_m as main;
|
||||||
|
|
||||||
use crate::{raw, Spawner};
|
use crate::{raw, Spawner};
|
||||||
|
@ -7,6 +7,7 @@ pub use thread::*;
|
|||||||
mod thread {
|
mod thread {
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub use embassy_macros::main_riscv as main;
|
pub use embassy_macros::main_riscv as main;
|
||||||
use portable_atomic::{AtomicBool, Ordering};
|
use portable_atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ mod thread {
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::{Condvar, Mutex};
|
use std::sync::{Condvar, Mutex};
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub use embassy_macros::main_std as main;
|
pub use embassy_macros::main_std as main;
|
||||||
|
|
||||||
use crate::{raw, Spawner};
|
use crate::{raw, Spawner};
|
||||||
|
@ -8,6 +8,7 @@ mod thread {
|
|||||||
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub use embassy_macros::main_wasm as main;
|
pub use embassy_macros::main_wasm as main;
|
||||||
use js_sys::Promise;
|
use js_sys::Promise;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
90
embassy-executor/src/arch/xtensa.rs
Normal file
90
embassy-executor/src/arch/xtensa.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#[cfg(feature = "executor-interrupt")]
|
||||||
|
compile_error!("`executor-interrupt` is not supported with `arch-xtensa`.");
|
||||||
|
|
||||||
|
#[cfg(feature = "executor-thread")]
|
||||||
|
pub use thread::*;
|
||||||
|
#[cfg(feature = "executor-thread")]
|
||||||
|
mod thread {
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
pub use embassy_macros::main_riscv as main;
|
||||||
|
|
||||||
|
use crate::{raw, Spawner};
|
||||||
|
|
||||||
|
/// global atomic used to keep track of whether there is work to do since sev() is not available on Xtensa
|
||||||
|
static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
#[export_name = "__pender"]
|
||||||
|
fn __pender(_context: *mut ()) {
|
||||||
|
SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Xtensa Executor
|
||||||
|
pub struct Executor {
|
||||||
|
inner: raw::Executor,
|
||||||
|
not_send: PhantomData<*mut ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Executor {
|
||||||
|
/// Create a new Executor.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: raw::Executor::new(core::ptr::null_mut()),
|
||||||
|
not_send: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run the executor.
|
||||||
|
///
|
||||||
|
/// The `init` closure is called with a [`Spawner`] that spawns tasks on
|
||||||
|
/// this executor. Use it to spawn the initial task(s). After `init` returns,
|
||||||
|
/// the executor starts running the tasks.
|
||||||
|
///
|
||||||
|
/// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`),
|
||||||
|
/// for example by passing it as an argument to the initial tasks.
|
||||||
|
///
|
||||||
|
/// This function requires `&'static mut self`. This means you have to store the
|
||||||
|
/// Executor instance in a place where it'll live forever and grants you mutable
|
||||||
|
/// access. There's a few ways to do this:
|
||||||
|
///
|
||||||
|
/// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
|
||||||
|
/// - a `static mut` (unsafe)
|
||||||
|
/// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
|
||||||
|
///
|
||||||
|
/// This function never returns.
|
||||||
|
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
|
||||||
|
init(self.inner.spawner());
|
||||||
|
|
||||||
|
loop {
|
||||||
|
unsafe {
|
||||||
|
self.inner.poll();
|
||||||
|
|
||||||
|
// Manual critical section implementation that only masks interrupts handlers.
|
||||||
|
// We must not acquire the cross-core on dual-core systems because that would
|
||||||
|
// prevent the other core from doing useful work while this core is sleeping.
|
||||||
|
let token: critical_section::RawRestoreState;
|
||||||
|
core::arch::asm!("rsil {0}, 5", out(reg) token);
|
||||||
|
|
||||||
|
// we do not care about race conditions between the load and store operations, interrupts
|
||||||
|
// will only set this value to true.
|
||||||
|
// if there is work to do, loop back to polling
|
||||||
|
if SIGNAL_WORK_THREAD_MODE.load(Ordering::SeqCst) {
|
||||||
|
SIGNAL_WORK_THREAD_MODE.store(false, Ordering::SeqCst);
|
||||||
|
|
||||||
|
core::arch::asm!(
|
||||||
|
"wsr.ps {0}",
|
||||||
|
"rsync", in(reg) token)
|
||||||
|
} else {
|
||||||
|
// waiti sets the PS.INTLEVEL when slipping into sleep
|
||||||
|
// because critical sections in Xtensa are implemented via increasing
|
||||||
|
// PS.INTLEVEL the critical section ends here
|
||||||
|
// take care not add code after `waiti` if it needs to be inside the CS
|
||||||
|
core::arch::asm!("waiti 0"); // critical section ends here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)]
|
#![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)]
|
||||||
|
#![cfg_attr(all(feature = "nightly", feature = "arch-xtensa"), feature(asm_experimental_arch))]
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
@ -6,6 +7,7 @@
|
|||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub use embassy_macros::task;
|
pub use embassy_macros::task;
|
||||||
|
|
||||||
macro_rules! check_at_most_one {
|
macro_rules! check_at_most_one {
|
||||||
@ -20,11 +22,12 @@ macro_rules! check_at_most_one {
|
|||||||
check_at_most_one!(@amo [$($f)*] [$($f)*] []);
|
check_at_most_one!(@amo [$($f)*] [$($f)*] []);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
check_at_most_one!("arch-cortex-m", "arch-riscv32", "arch-std", "arch-wasm",);
|
check_at_most_one!("arch-cortex-m", "arch-riscv32", "arch-xtensa", "arch-std", "arch-wasm",);
|
||||||
|
|
||||||
#[cfg(feature = "_arch")]
|
#[cfg(feature = "_arch")]
|
||||||
#[cfg_attr(feature = "arch-cortex-m", path = "arch/cortex_m.rs")]
|
#[cfg_attr(feature = "arch-cortex-m", path = "arch/cortex_m.rs")]
|
||||||
#[cfg_attr(feature = "arch-riscv32", path = "arch/riscv32.rs")]
|
#[cfg_attr(feature = "arch-riscv32", path = "arch/riscv32.rs")]
|
||||||
|
#[cfg_attr(feature = "arch-xtensa", path = "arch/xtensa.rs")]
|
||||||
#[cfg_attr(feature = "arch-std", path = "arch/std.rs")]
|
#[cfg_attr(feature = "arch-std", path = "arch/std.rs")]
|
||||||
#[cfg_attr(feature = "arch-wasm", path = "arch/wasm.rs")]
|
#[cfg_attr(feature = "arch-wasm", path = "arch/wasm.rs")]
|
||||||
mod arch;
|
mod arch;
|
||||||
@ -38,101 +41,28 @@ pub mod raw;
|
|||||||
mod spawner;
|
mod spawner;
|
||||||
pub use spawner::*;
|
pub use spawner::*;
|
||||||
|
|
||||||
mod config {
|
|
||||||
#![allow(unused)]
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/config.rs"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation details for embassy macros.
|
/// Implementation details for embassy macros.
|
||||||
/// Do not use. Used for macros and HALs only. Not covered by semver guarantees.
|
/// Do not use. Used for macros and HALs only. Not covered by semver guarantees.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg(not(feature = "nightly"))]
|
|
||||||
pub mod _export {
|
pub mod _export {
|
||||||
use core::alloc::Layout;
|
#[cfg(feature = "rtos-trace")]
|
||||||
use core::cell::{Cell, UnsafeCell};
|
pub use rtos_trace::trace;
|
||||||
use core::future::Future;
|
|
||||||
use core::mem::MaybeUninit;
|
|
||||||
use core::ptr::null_mut;
|
|
||||||
|
|
||||||
use critical_section::{CriticalSection, Mutex};
|
/// Expands the given block of code when `embassy-executor` is compiled with
|
||||||
|
/// the `rtos-trace-interrupt` feature.
|
||||||
use crate::raw::TaskPool;
|
#[doc(hidden)]
|
||||||
|
#[macro_export]
|
||||||
struct Arena<const N: usize> {
|
#[cfg(feature = "rtos-trace-interrupt")]
|
||||||
buf: UnsafeCell<MaybeUninit<[u8; N]>>,
|
macro_rules! rtos_trace_interrupt {
|
||||||
ptr: Mutex<Cell<*mut u8>>,
|
($($tt:tt)*) => { $($tt)* };
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<const N: usize> Sync for Arena<N> {}
|
/// Does not expand the given block of code when `embassy-executor` is
|
||||||
unsafe impl<const N: usize> Send for Arena<N> {}
|
/// compiled without the `rtos-trace-interrupt` feature.
|
||||||
|
#[doc(hidden)]
|
||||||
impl<const N: usize> Arena<N> {
|
#[macro_export]
|
||||||
const fn new() -> Self {
|
#[cfg(not(feature = "rtos-trace-interrupt"))]
|
||||||
Self {
|
macro_rules! rtos_trace_interrupt {
|
||||||
buf: UnsafeCell::new(MaybeUninit::uninit()),
|
($($tt:tt)*) => {};
|
||||||
ptr: Mutex::new(Cell::new(null_mut())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alloc<T>(&'static self, cs: CriticalSection) -> &'static mut MaybeUninit<T> {
|
|
||||||
let layout = Layout::new::<T>();
|
|
||||||
|
|
||||||
let start = self.buf.get().cast::<u8>();
|
|
||||||
let end = unsafe { start.add(N) };
|
|
||||||
|
|
||||||
let mut ptr = self.ptr.borrow(cs).get();
|
|
||||||
if ptr.is_null() {
|
|
||||||
ptr = self.buf.get().cast::<u8>();
|
|
||||||
}
|
|
||||||
|
|
||||||
let bytes_left = (end as usize) - (ptr as usize);
|
|
||||||
let align_offset = (ptr as usize).next_multiple_of(layout.align()) - (ptr as usize);
|
|
||||||
|
|
||||||
if align_offset + layout.size() > bytes_left {
|
|
||||||
panic!("embassy-executor: task arena is full. You must increase the arena size, see the documentation for details: https://docs.embassy.dev/embassy-executor/");
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = unsafe { ptr.add(align_offset) };
|
|
||||||
let ptr = unsafe { ptr.add(align_offset + layout.size()) };
|
|
||||||
|
|
||||||
self.ptr.borrow(cs).set(ptr);
|
|
||||||
|
|
||||||
unsafe { &mut *(res as *mut MaybeUninit<T>) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ARENA: Arena<{ crate::config::TASK_ARENA_SIZE }> = Arena::new();
|
|
||||||
|
|
||||||
pub struct TaskPoolRef {
|
|
||||||
// type-erased `&'static mut TaskPool<F, N>`
|
|
||||||
// Needed because statics can't have generics.
|
|
||||||
ptr: Mutex<Cell<*mut ()>>,
|
|
||||||
}
|
|
||||||
unsafe impl Sync for TaskPoolRef {}
|
|
||||||
unsafe impl Send for TaskPoolRef {}
|
|
||||||
|
|
||||||
impl TaskPoolRef {
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
ptr: Mutex::new(Cell::new(null_mut())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the pool for this ref, allocating it from the arena the first time.
|
|
||||||
///
|
|
||||||
/// safety: for a given TaskPoolRef instance, must always call with the exact
|
|
||||||
/// same generic params.
|
|
||||||
pub unsafe fn get<F: Future, const N: usize>(&'static self) -> &'static TaskPool<F, N> {
|
|
||||||
critical_section::with(|cs| {
|
|
||||||
let ptr = self.ptr.borrow(cs);
|
|
||||||
if ptr.get().is_null() {
|
|
||||||
let pool = ARENA.alloc::<TaskPool<F, N>>(cs);
|
|
||||||
pool.write(TaskPool::new());
|
|
||||||
ptr.set(pool as *mut _ as _);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe { &*(ptr.get() as *const _) }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,137 +0,0 @@
|
|||||||
#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
|
|
||||||
|
|
||||||
use std::boxed::Box;
|
|
||||||
use std::future::poll_fn;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use std::task::Poll;
|
|
||||||
|
|
||||||
use embassy_executor::raw::Executor;
|
|
||||||
use embassy_executor::task;
|
|
||||||
|
|
||||||
#[export_name = "__pender"]
|
|
||||||
fn __pender(context: *mut ()) {
|
|
||||||
unsafe {
|
|
||||||
let trace = &*(context as *const Trace);
|
|
||||||
trace.push("pend");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Trace {
|
|
||||||
trace: Arc<Mutex<Vec<&'static str>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Trace {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
trace: Arc::new(Mutex::new(Vec::new())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn push(&self, value: &'static str) {
|
|
||||||
self.trace.lock().unwrap().push(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get(&self) -> Vec<&'static str> {
|
|
||||||
self.trace.lock().unwrap().clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup() -> (&'static Executor, Trace) {
|
|
||||||
let trace = Trace::new();
|
|
||||||
let context = Box::leak(Box::new(trace.clone())) as *mut _ as *mut ();
|
|
||||||
let executor = &*Box::leak(Box::new(Executor::new(context)));
|
|
||||||
(executor, trace)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn executor_noop() {
|
|
||||||
let (executor, trace) = setup();
|
|
||||||
unsafe { executor.poll() };
|
|
||||||
assert!(trace.get().is_empty())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn executor_task() {
|
|
||||||
#[task]
|
|
||||||
async fn task1(trace: Trace) {
|
|
||||||
trace.push("poll task1")
|
|
||||||
}
|
|
||||||
|
|
||||||
let (executor, trace) = setup();
|
|
||||||
executor.spawner().spawn(task1(trace.clone())).unwrap();
|
|
||||||
|
|
||||||
unsafe { executor.poll() };
|
|
||||||
unsafe { executor.poll() };
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
trace.get(),
|
|
||||||
&[
|
|
||||||
"pend", // spawning a task pends the executor
|
|
||||||
"poll task1", // poll only once.
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn executor_task_self_wake() {
|
|
||||||
#[task]
|
|
||||||
async fn task1(trace: Trace) {
|
|
||||||
poll_fn(|cx| {
|
|
||||||
trace.push("poll task1");
|
|
||||||
cx.waker().wake_by_ref();
|
|
||||||
Poll::Pending
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
let (executor, trace) = setup();
|
|
||||||
executor.spawner().spawn(task1(trace.clone())).unwrap();
|
|
||||||
|
|
||||||
unsafe { executor.poll() };
|
|
||||||
unsafe { executor.poll() };
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
trace.get(),
|
|
||||||
&[
|
|
||||||
"pend", // spawning a task pends the executor
|
|
||||||
"poll task1", //
|
|
||||||
"pend", // task self-wakes
|
|
||||||
"poll task1", //
|
|
||||||
"pend", // task self-wakes
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn executor_task_self_wake_twice() {
|
|
||||||
#[task]
|
|
||||||
async fn task1(trace: Trace) {
|
|
||||||
poll_fn(|cx| {
|
|
||||||
trace.push("poll task1");
|
|
||||||
cx.waker().wake_by_ref();
|
|
||||||
trace.push("poll task1 wake 2");
|
|
||||||
cx.waker().wake_by_ref();
|
|
||||||
Poll::Pending
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
let (executor, trace) = setup();
|
|
||||||
executor.spawner().spawn(task1(trace.clone())).unwrap();
|
|
||||||
|
|
||||||
unsafe { executor.poll() };
|
|
||||||
unsafe { executor.poll() };
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
trace.get(),
|
|
||||||
&[
|
|
||||||
"pend", // spawning a task pends the executor
|
|
||||||
"poll task1", //
|
|
||||||
"pend", // task self-wakes
|
|
||||||
"poll task1 wake 2", // task self-wakes again, shouldn't pend
|
|
||||||
"poll task1", //
|
|
||||||
"pend", // task self-wakes
|
|
||||||
"poll task1 wake 2", // task self-wakes again, shouldn't pend
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
31
embassy-lora/Cargo.toml
Normal file
31
embassy-lora/Cargo.toml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
[package]
|
||||||
|
name = "embassy-lora"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[package.metadata.embassy_docs]
|
||||||
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-lora-v$VERSION/embassy-lora/src/"
|
||||||
|
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-lora/src/"
|
||||||
|
features = ["stm32wl", "embassy-stm32?/stm32wl55jc-cm4", "embassy-stm32?/unstable-pac", "time", "defmt"]
|
||||||
|
target = "thumbv7em-none-eabi"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
stm32wl = ["dep:embassy-stm32"]
|
||||||
|
time = ["embassy-time", "lorawan-device"]
|
||||||
|
defmt = ["dep:defmt", "lorawan-device/defmt"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
defmt = { version = "0.3", optional = true }
|
||||||
|
log = { version = "0.4.14", optional = true }
|
||||||
|
|
||||||
|
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
|
||||||
|
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
|
||||||
|
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 = { version = "0.2", features = ["unproven"] }
|
||||||
|
|
||||||
|
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
|
||||||
|
lora-phy = { version = "2" }
|
||||||
|
lorawan-device = { version = "0.11.0", default-features = false, features = ["async"], optional = true }
|
258
embassy-lora/src/fmt.rs
Normal file
258
embassy-lora/src/fmt.rs
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
#![macro_use]
|
||||||
|
#![allow(unused_macros)]
|
||||||
|
|
||||||
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
|
#[cfg(all(feature = "defmt", feature = "log"))]
|
||||||
|
compile_error!("You may not enable both `defmt` and `log` features.");
|
||||||
|
|
||||||
|
macro_rules! assert {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
{
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
::core::assert!($($x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::assert!($($x)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_eq {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
{
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
::core::assert_eq!($($x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::assert_eq!($($x)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_ne {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
{
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
::core::assert_ne!($($x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::assert_ne!($($x)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! debug_assert {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
{
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
::core::debug_assert!($($x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::debug_assert!($($x)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! debug_assert_eq {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
{
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
::core::debug_assert_eq!($($x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::debug_assert_eq!($($x)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! debug_assert_ne {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
{
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
::core::debug_assert_ne!($($x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::debug_assert_ne!($($x)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! todo {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
{
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
::core::todo!($($x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::todo!($($x)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
macro_rules! unreachable {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
::core::unreachable!($($x)*)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
macro_rules! unreachable {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
::defmt::unreachable!($($x)*)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! panic {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
{
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
::core::panic!($($x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::panic!($($x)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! trace {
|
||||||
|
($s:literal $(, $x:expr)* $(,)?) => {
|
||||||
|
{
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
::log::trace!($s $(, $x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::trace!($s $(, $x)*);
|
||||||
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
|
let _ = ($( & $x ),*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! debug {
|
||||||
|
($s:literal $(, $x:expr)* $(,)?) => {
|
||||||
|
{
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
::log::debug!($s $(, $x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::debug!($s $(, $x)*);
|
||||||
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
|
let _ = ($( & $x ),*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! info {
|
||||||
|
($s:literal $(, $x:expr)* $(,)?) => {
|
||||||
|
{
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
::log::info!($s $(, $x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::info!($s $(, $x)*);
|
||||||
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
|
let _ = ($( & $x ),*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! warn {
|
||||||
|
($s:literal $(, $x:expr)* $(,)?) => {
|
||||||
|
{
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
::log::warn!($s $(, $x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::warn!($s $(, $x)*);
|
||||||
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
|
let _ = ($( & $x ),*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! error {
|
||||||
|
($s:literal $(, $x:expr)* $(,)?) => {
|
||||||
|
{
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
::log::error!($s $(, $x)*);
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
::defmt::error!($s $(, $x)*);
|
||||||
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
|
let _ = ($( & $x ),*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
macro_rules! unwrap {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
::defmt::unwrap!($($x)*)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
|
macro_rules! unwrap {
|
||||||
|
($arg:expr) => {
|
||||||
|
match $crate::fmt::Try::into_result($arg) {
|
||||||
|
::core::result::Result::Ok(t) => t,
|
||||||
|
::core::result::Result::Err(e) => {
|
||||||
|
::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($arg:expr, $($msg:expr),+ $(,)? ) => {
|
||||||
|
match $crate::fmt::Try::into_result($arg) {
|
||||||
|
::core::result::Result::Ok(t) => t,
|
||||||
|
::core::result::Result::Err(e) => {
|
||||||
|
::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
pub struct NoneError;
|
||||||
|
|
||||||
|
pub trait Try {
|
||||||
|
type Ok;
|
||||||
|
type Error;
|
||||||
|
fn into_result(self) -> Result<Self::Ok, Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Try for Option<T> {
|
||||||
|
type Ok = T;
|
||||||
|
type Error = NoneError;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn into_result(self) -> Result<T, NoneError> {
|
||||||
|
self.ok_or(NoneError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E> Try for Result<T, E> {
|
||||||
|
type Ok = T;
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn into_result(self) -> Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
write!(f, "{:#02x?}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Display for Bytes<'a> {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
write!(f, "{:#02x?}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LowerHex for Bytes<'a> {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
write!(f, "{:#02x?}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "defmt")]
|
||||||
|
impl<'a> defmt::Format for Bytes<'a> {
|
||||||
|
fn format(&self, fmt: defmt::Formatter) {
|
||||||
|
defmt::write!(fmt, "{:02x}", self.0)
|
||||||
|
}
|
||||||
|
}
|
317
embassy-lora/src/iv.rs
Normal file
317
embassy-lora/src/iv.rs
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
use embassy_stm32::interrupt;
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
use embassy_stm32::interrupt::InterruptExt;
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
use embassy_stm32::pac;
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
use embassy_sync::signal::Signal;
|
||||||
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
|
use embedded_hal_async::delay::DelayUs;
|
||||||
|
use embedded_hal_async::digital::Wait;
|
||||||
|
use lora_phy::mod_params::RadioError::*;
|
||||||
|
use lora_phy::mod_params::{BoardType, RadioError};
|
||||||
|
use lora_phy::mod_traits::InterfaceVariant;
|
||||||
|
|
||||||
|
/// Interrupt handler.
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
pub struct InterruptHandler {}
|
||||||
|
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
impl interrupt::typelevel::Handler<interrupt::typelevel::SUBGHZ_RADIO> for InterruptHandler {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
|
interrupt::SUBGHZ_RADIO.disable();
|
||||||
|
IRQ_SIGNAL.signal(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
static IRQ_SIGNAL: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
||||||
|
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
/// Base for the InterfaceVariant implementation for an stm32wl/sx1262 combination
|
||||||
|
pub struct Stm32wlInterfaceVariant<CTRL> {
|
||||||
|
board_type: BoardType,
|
||||||
|
rf_switch_rx: Option<CTRL>,
|
||||||
|
rf_switch_tx: Option<CTRL>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
impl<'a, CTRL> Stm32wlInterfaceVariant<CTRL>
|
||||||
|
where
|
||||||
|
CTRL: OutputPin,
|
||||||
|
{
|
||||||
|
/// Create an InterfaceVariant instance for an stm32wl/sx1262 combination
|
||||||
|
pub fn new(
|
||||||
|
_irq: impl interrupt::typelevel::Binding<interrupt::typelevel::SUBGHZ_RADIO, InterruptHandler>,
|
||||||
|
rf_switch_rx: Option<CTRL>,
|
||||||
|
rf_switch_tx: Option<CTRL>,
|
||||||
|
) -> Result<Self, RadioError> {
|
||||||
|
interrupt::SUBGHZ_RADIO.disable();
|
||||||
|
Ok(Self {
|
||||||
|
board_type: BoardType::Stm32wlSx1262, // updated when associated with a specific LoRa board
|
||||||
|
rf_switch_rx,
|
||||||
|
rf_switch_tx,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stm32wl")]
|
||||||
|
impl<CTRL> InterfaceVariant for Stm32wlInterfaceVariant<CTRL>
|
||||||
|
where
|
||||||
|
CTRL: OutputPin,
|
||||||
|
{
|
||||||
|
fn set_board_type(&mut self, board_type: BoardType) {
|
||||||
|
self.board_type = board_type;
|
||||||
|
}
|
||||||
|
async fn set_nss_low(&mut self) -> Result<(), RadioError> {
|
||||||
|
pac::PWR.subghzspicr().modify(|w| w.set_nss(false));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn set_nss_high(&mut self) -> Result<(), RadioError> {
|
||||||
|
pac::PWR.subghzspicr().modify(|w| w.set_nss(true));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn reset(&mut self, _delay: &mut impl DelayUs) -> Result<(), RadioError> {
|
||||||
|
pac::RCC.csr().modify(|w| w.set_rfrst(true));
|
||||||
|
pac::RCC.csr().modify(|w| w.set_rfrst(false));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn wait_on_busy(&mut self) -> Result<(), RadioError> {
|
||||||
|
while pac::PWR.sr2().read().rfbusys() {}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn await_irq(&mut self) -> Result<(), RadioError> {
|
||||||
|
unsafe { interrupt::SUBGHZ_RADIO.enable() };
|
||||||
|
IRQ_SIGNAL.wait().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn enable_rf_switch_rx(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchTx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_high().map_err(|_| RfSwitchRx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn enable_rf_switch_tx(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchRx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_high().map_err(|_| RfSwitchTx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn disable_rf_switch(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchRx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchTx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Base for the InterfaceVariant implementation for an stm32l0/sx1276 combination
|
||||||
|
pub struct Stm32l0InterfaceVariant<CTRL, WAIT> {
|
||||||
|
board_type: BoardType,
|
||||||
|
nss: CTRL,
|
||||||
|
reset: CTRL,
|
||||||
|
irq: WAIT,
|
||||||
|
rf_switch_rx: Option<CTRL>,
|
||||||
|
rf_switch_tx: Option<CTRL>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<CTRL, WAIT> Stm32l0InterfaceVariant<CTRL, WAIT>
|
||||||
|
where
|
||||||
|
CTRL: OutputPin,
|
||||||
|
WAIT: Wait,
|
||||||
|
{
|
||||||
|
/// Create an InterfaceVariant instance for an stm32l0/sx1276 combination
|
||||||
|
pub fn new(
|
||||||
|
nss: CTRL,
|
||||||
|
reset: CTRL,
|
||||||
|
irq: WAIT,
|
||||||
|
rf_switch_rx: Option<CTRL>,
|
||||||
|
rf_switch_tx: Option<CTRL>,
|
||||||
|
) -> Result<Self, RadioError> {
|
||||||
|
Ok(Self {
|
||||||
|
board_type: BoardType::Stm32l0Sx1276, // updated when associated with a specific LoRa board
|
||||||
|
nss,
|
||||||
|
reset,
|
||||||
|
irq,
|
||||||
|
rf_switch_rx,
|
||||||
|
rf_switch_tx,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<CTRL, WAIT> InterfaceVariant for Stm32l0InterfaceVariant<CTRL, WAIT>
|
||||||
|
where
|
||||||
|
CTRL: OutputPin,
|
||||||
|
WAIT: Wait,
|
||||||
|
{
|
||||||
|
fn set_board_type(&mut self, board_type: BoardType) {
|
||||||
|
self.board_type = board_type;
|
||||||
|
}
|
||||||
|
async fn set_nss_low(&mut self) -> Result<(), RadioError> {
|
||||||
|
self.nss.set_low().map_err(|_| NSS)
|
||||||
|
}
|
||||||
|
async fn set_nss_high(&mut self) -> Result<(), RadioError> {
|
||||||
|
self.nss.set_high().map_err(|_| NSS)
|
||||||
|
}
|
||||||
|
async fn reset(&mut self, delay: &mut impl DelayUs) -> Result<(), RadioError> {
|
||||||
|
delay.delay_ms(10).await;
|
||||||
|
self.reset.set_low().map_err(|_| Reset)?;
|
||||||
|
delay.delay_ms(10).await;
|
||||||
|
self.reset.set_high().map_err(|_| Reset)?;
|
||||||
|
delay.delay_ms(10).await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn wait_on_busy(&mut self) -> Result<(), RadioError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn await_irq(&mut self) -> Result<(), RadioError> {
|
||||||
|
self.irq.wait_for_high().await.map_err(|_| Irq)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn enable_rf_switch_rx(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchTx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_high().map_err(|_| RfSwitchRx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn enable_rf_switch_tx(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchRx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_high().map_err(|_| RfSwitchTx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn disable_rf_switch(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchRx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchTx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Base for the InterfaceVariant implementation for a generic Sx126x LoRa board
|
||||||
|
pub struct GenericSx126xInterfaceVariant<CTRL, WAIT> {
|
||||||
|
board_type: BoardType,
|
||||||
|
nss: CTRL,
|
||||||
|
reset: CTRL,
|
||||||
|
dio1: WAIT,
|
||||||
|
busy: WAIT,
|
||||||
|
rf_switch_rx: Option<CTRL>,
|
||||||
|
rf_switch_tx: Option<CTRL>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<CTRL, WAIT> GenericSx126xInterfaceVariant<CTRL, WAIT>
|
||||||
|
where
|
||||||
|
CTRL: OutputPin,
|
||||||
|
WAIT: Wait,
|
||||||
|
{
|
||||||
|
/// Create an InterfaceVariant instance for an nrf52840/sx1262 combination
|
||||||
|
pub fn new(
|
||||||
|
nss: CTRL,
|
||||||
|
reset: CTRL,
|
||||||
|
dio1: WAIT,
|
||||||
|
busy: WAIT,
|
||||||
|
rf_switch_rx: Option<CTRL>,
|
||||||
|
rf_switch_tx: Option<CTRL>,
|
||||||
|
) -> Result<Self, RadioError> {
|
||||||
|
Ok(Self {
|
||||||
|
board_type: BoardType::Rak4631Sx1262, // updated when associated with a specific LoRa board
|
||||||
|
nss,
|
||||||
|
reset,
|
||||||
|
dio1,
|
||||||
|
busy,
|
||||||
|
rf_switch_rx,
|
||||||
|
rf_switch_tx,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<CTRL, WAIT> InterfaceVariant for GenericSx126xInterfaceVariant<CTRL, WAIT>
|
||||||
|
where
|
||||||
|
CTRL: OutputPin,
|
||||||
|
WAIT: Wait,
|
||||||
|
{
|
||||||
|
fn set_board_type(&mut self, board_type: BoardType) {
|
||||||
|
self.board_type = board_type;
|
||||||
|
}
|
||||||
|
async fn set_nss_low(&mut self) -> Result<(), RadioError> {
|
||||||
|
self.nss.set_low().map_err(|_| NSS)
|
||||||
|
}
|
||||||
|
async fn set_nss_high(&mut self) -> Result<(), RadioError> {
|
||||||
|
self.nss.set_high().map_err(|_| NSS)
|
||||||
|
}
|
||||||
|
async fn reset(&mut self, delay: &mut impl DelayUs) -> Result<(), RadioError> {
|
||||||
|
delay.delay_ms(10).await;
|
||||||
|
self.reset.set_low().map_err(|_| Reset)?;
|
||||||
|
delay.delay_ms(20).await;
|
||||||
|
self.reset.set_high().map_err(|_| Reset)?;
|
||||||
|
delay.delay_ms(10).await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn wait_on_busy(&mut self) -> Result<(), RadioError> {
|
||||||
|
self.busy.wait_for_low().await.map_err(|_| Busy)
|
||||||
|
}
|
||||||
|
async fn await_irq(&mut self) -> Result<(), RadioError> {
|
||||||
|
self.dio1.wait_for_high().await.map_err(|_| DIO1)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn enable_rf_switch_rx(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchTx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_high().map_err(|_| RfSwitchRx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn enable_rf_switch_tx(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchRx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_high().map_err(|_| RfSwitchTx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn disable_rf_switch(&mut self) -> Result<(), RadioError> {
|
||||||
|
match &mut self.rf_switch_rx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchRx)?,
|
||||||
|
None => (),
|
||||||
|
};
|
||||||
|
match &mut self.rf_switch_tx {
|
||||||
|
Some(pin) => pin.set_low().map_err(|_| RfSwitchTx),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
embassy-lora/src/lib.rs
Normal file
40
embassy-lora/src/lib.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![feature(async_fn_in_trait, impl_trait_projections)]
|
||||||
|
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
|
||||||
|
//! embassy-lora holds LoRa-specific functionality.
|
||||||
|
|
||||||
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
|
/// interface variants required by the external lora physical layer crate (lora-phy)
|
||||||
|
pub mod iv;
|
||||||
|
|
||||||
|
#[cfg(feature = "time")]
|
||||||
|
use embassy_time::{Duration, Instant, Timer};
|
||||||
|
|
||||||
|
/// A convenience timer to use with the LoRaWAN crate
|
||||||
|
#[cfg(feature = "time")]
|
||||||
|
pub struct LoraTimer {
|
||||||
|
start: Instant,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "time")]
|
||||||
|
impl LoraTimer {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self { start: Instant::now() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "time")]
|
||||||
|
impl lorawan_device::async_device::radio::Timer for LoraTimer {
|
||||||
|
fn reset(&mut self) {
|
||||||
|
self.start = Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn at(&mut self, millis: u64) {
|
||||||
|
Timer::at(self.start + Duration::from_millis(millis)).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn delay_ms(&mut self, millis: u64) {
|
||||||
|
Timer::after_millis(millis).await
|
||||||
|
}
|
||||||
|
}
|
@ -21,4 +21,5 @@ proc-macro2 = "1.0.29"
|
|||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
nightly = []
|
# Enabling this cause interrupt::take! to require embassy-executor
|
||||||
|
rtos-trace-interrupt = []
|
||||||
|
@ -79,7 +79,6 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre
|
|||||||
task_inner.vis = syn::Visibility::Inherited;
|
task_inner.vis = syn::Visibility::Inherited;
|
||||||
task_inner.sig.ident = task_inner_ident.clone();
|
task_inner.sig.ident = task_inner_ident.clone();
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
|
||||||
let mut task_outer: ItemFn = parse_quote! {
|
let mut task_outer: ItemFn = parse_quote! {
|
||||||
#visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
|
#visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
|
||||||
type Fut = impl ::core::future::Future + 'static;
|
type Fut = impl ::core::future::Future + 'static;
|
||||||
@ -88,14 +87,6 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre
|
|||||||
unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#arg_names,)*)) }
|
unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#arg_names,)*)) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "nightly"))]
|
|
||||||
let mut task_outer: ItemFn = parse_quote! {
|
|
||||||
#visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
|
|
||||||
const POOL_SIZE: usize = #pool_size;
|
|
||||||
static POOL: ::embassy_executor::_export::TaskPoolRef = ::embassy_executor::_export::TaskPoolRef::new();
|
|
||||||
unsafe { POOL.get::<_, POOL_SIZE>()._spawn_async_fn(move || #task_inner_ident(#(#arg_names,)*)) }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
task_outer.attrs.append(&mut task_inner.attrs.clone());
|
task_outer.attrs.append(&mut task_inner.attrs.clone());
|
||||||
|
|
||||||
|
@ -13,16 +13,16 @@ edition = "2021"
|
|||||||
heapless = "0.8"
|
heapless = "0.8"
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
log = { version = "0.4", default-features = false, optional = true }
|
log = { version = "0.4", default-features = false, optional = true }
|
||||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" }
|
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" }
|
||||||
embedded-hal-async = { version = "=1.0.0-rc.2" }
|
embedded-hal-async = { version = "=1.0.0-rc.1" }
|
||||||
embedded-hal-bus = { version = "=0.1.0-rc.2", 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.2.0", path = "../embassy-net-driver-channel" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time" }
|
embassy-time = { version = "0.1.5", path = "../embassy-time" }
|
||||||
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"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
embedded-hal-mock = { git = "https://github.com/Dirbaio/embedded-hal-mock", rev = "c5c4dca18e043e6386aee02173f61a65fea3981e", features = ["embedded-hal-async", "eh1"] }
|
embedded-hal-mock = { version = "=0.10.0-rc.1", features = ["embedded-hal-async", "eh1"] }
|
||||||
crc = "3.0.1"
|
crc = "3.0.1"
|
||||||
env_logger = "0.10"
|
env_logger = "0.10"
|
||||||
critical-section = { version = "1.1.2", features = ["std"] }
|
critical-section = { version = "1.1.2", features = ["std"] }
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![deny(clippy::pedantic)]
|
#![deny(clippy::pedantic)]
|
||||||
#![allow(async_fn_in_trait)]
|
#![feature(async_fn_in_trait)]
|
||||||
|
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
|
||||||
#![cfg_attr(not(any(test, feature = "std")), no_std)]
|
#![cfg_attr(not(any(test, feature = "std")), no_std)]
|
||||||
#![allow(clippy::module_name_repetitions)]
|
#![allow(clippy::module_name_repetitions)]
|
||||||
#![allow(clippy::missing_errors_doc)]
|
#![allow(clippy::missing_errors_doc)]
|
||||||
@ -728,7 +729,7 @@ mod tests {
|
|||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use embedded_hal_1::digital::{ErrorType, OutputPin};
|
use embedded_hal_1::digital::{ErrorType, OutputPin};
|
||||||
use embedded_hal_async::delay::DelayNs;
|
use embedded_hal_async::delay::DelayUs;
|
||||||
use embedded_hal_bus::spi::ExclusiveDevice;
|
use embedded_hal_bus::spi::ExclusiveDevice;
|
||||||
use embedded_hal_mock::common::Generic;
|
use embedded_hal_mock::common::Generic;
|
||||||
use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
|
use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
|
||||||
@ -759,11 +760,7 @@ mod tests {
|
|||||||
// see https://github.com/rust-embedded/embedded-hal/pull/462#issuecomment-1560014426
|
// see https://github.com/rust-embedded/embedded-hal/pull/462#issuecomment-1560014426
|
||||||
struct MockDelay {}
|
struct MockDelay {}
|
||||||
|
|
||||||
impl DelayNs for MockDelay {
|
impl DelayUs for MockDelay {
|
||||||
async fn delay_ns(&mut self, _ns: u32) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn delay_us(&mut self, _us: u32) {
|
async fn delay_us(&mut self, _us: u32) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,6 @@ features = ["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-sync = { version = "0.5.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.4.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.2.0", path = "../embassy-net-driver" }
|
||||||
|
@ -8,10 +8,10 @@ license = "MIT OR Apache-2.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embedded-hal = { version = "1.0.0-rc.2" }
|
embedded-hal = { version = "1.0.0-rc.1" }
|
||||||
embedded-hal-async = { version = "=1.0.0-rc.2" }
|
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.2.0", path = "../embassy-net-driver" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time" }
|
embassy-time = { version = "0.1.5", path = "../embassy-time" }
|
||||||
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
|
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
|
||||||
|
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
|
@ -7,13 +7,13 @@ 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.2", path = "../embassy-time" }
|
embassy-time = { version = "0.1.5", path = "../embassy-time" }
|
||||||
embassy-sync = { version = "0.5.0", path = "../embassy-sync"}
|
embassy-sync = { version = "0.4.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.2.0", path = "../embassy-net-driver-channel"}
|
||||||
|
|
||||||
embedded-hal = { version = "1.0.0-rc.2" }
|
embedded-hal = { version = "1.0.0-rc.1" }
|
||||||
embedded-hal-async = { version = "=1.0.0-rc.2" }
|
embedded-hal-async = { version = "=1.0.0-rc.1" }
|
||||||
|
|
||||||
noproto = { git="https://github.com/embassy-rs/noproto", rev = "f5e6d1f325b6ad4e344f60452b09576e24671f62", default-features = false, features = ["derive"] }
|
noproto = { git="https://github.com/embassy-rs/noproto", rev = "f5e6d1f325b6ad4e344f60452b09576e24671f62", default-features = false, features = ["derive"] }
|
||||||
#noproto = { version = "0.1", path = "/home/dirbaio/noproto", default-features = false, features = ["derive"] }
|
#noproto = { version = "0.1", path = "/home/dirbaio/noproto", default-features = false, features = ["derive"] }
|
||||||
|
@ -15,11 +15,11 @@ 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.1" }
|
embedded-io-async = { version = "0.6.0" }
|
||||||
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" }
|
embassy-net-driver-channel = { version = "0.2.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.5.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
|
||||||
|
|
||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-ppp-v$VERSION/embassy-net-ppp/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-ppp-v$VERSION/embassy-net-ppp/src/"
|
||||||
|
@ -8,10 +8,10 @@ license = "MIT OR Apache-2.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embedded-hal = { version = "1.0.0-rc.2" }
|
embedded-hal = { version = "1.0.0-rc.1" }
|
||||||
embedded-hal-async = { version = "=1.0.0-rc.2" }
|
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.2.0", path = "../embassy-net-driver-channel" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time" }
|
embassy-time = { version = "0.1.5", 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 }
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(async_fn_in_trait)]
|
#![feature(async_fn_in_trait)]
|
||||||
|
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
pub mod chip;
|
pub mod chip;
|
||||||
|
@ -15,11 +15,11 @@ categories = [
|
|||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-v$VERSION/embassy-net/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-v$VERSION/embassy-net/src/"
|
||||||
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net/src/"
|
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net/src/"
|
||||||
features = ["defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp"]
|
features = ["nightly", "defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp"]
|
||||||
target = "thumbv7em-none-eabi"
|
target = "thumbv7em-none-eabi"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp"]
|
features = ["nightly", "defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
@ -27,6 +27,8 @@ std = []
|
|||||||
|
|
||||||
defmt = ["dep:defmt", "smoltcp/defmt", "embassy-net-driver/defmt", "heapless/defmt-03"]
|
defmt = ["dep:defmt", "smoltcp/defmt", "embassy-net-driver/defmt", "heapless/defmt-03"]
|
||||||
|
|
||||||
|
nightly = ["dep:embedded-io-async", "dep:embedded-nal-async"]
|
||||||
|
|
||||||
udp = ["smoltcp/socket-udp"]
|
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"]
|
||||||
@ -50,9 +52,9 @@ smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp.git", rev = "b57e2f9e70
|
|||||||
] }
|
] }
|
||||||
|
|
||||||
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
|
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time" }
|
embassy-time = { version = "0.1.5", path = "../embassy-time" }
|
||||||
embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
|
||||||
embedded-io-async = { version = "0.6.1" }
|
embedded-io-async = { version = "0.6.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.8", default-features = false }
|
heapless = { version = "0.8", default-features = false }
|
||||||
@ -61,4 +63,4 @@ 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.7.1" }
|
embedded-nal-async = { version = "0.7", optional = true }
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
use std::env;
|
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
|
||||||
|
|
||||||
let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
|
|
||||||
|
|
||||||
let output = Command::new(rustc)
|
|
||||||
.arg("--version")
|
|
||||||
.output()
|
|
||||||
.expect("failed to run `rustc --version`");
|
|
||||||
|
|
||||||
if String::from_utf8_lossy(&output.stdout).contains("nightly") {
|
|
||||||
println!("cargo:rustc-cfg=nightly");
|
|
||||||
}
|
|
||||||
}
|
|
@ -72,6 +72,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<'a, D> embedded_nal_async::Dns for DnsSocket<'a, D>
|
impl<'a, D> embedded_nal_async::Dns for DnsSocket<'a, D>
|
||||||
where
|
where
|
||||||
D: Driver + 'static,
|
D: Driver + 'static,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
#![cfg_attr(nightly, feature(async_fn_in_trait, impl_trait_projections))]
|
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
|
||||||
#![cfg_attr(nightly, allow(stable_features, unknown_lints))]
|
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
|
||||||
#![allow(async_fn_in_trait)]
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
@ -617,11 +616,9 @@ impl<D: Driver> Stack<D> {
|
|||||||
let addr = addr.into();
|
let addr = addr.into();
|
||||||
|
|
||||||
self.with_mut(|s, i| {
|
self.with_mut(|s, i| {
|
||||||
let (_hardware_addr, medium) = to_smoltcp_hardware_address(i.device.hardware_address());
|
|
||||||
let mut smoldev = DriverAdapter {
|
let mut smoldev = DriverAdapter {
|
||||||
cx: Some(cx),
|
cx: Some(cx),
|
||||||
inner: &mut i.device,
|
inner: &mut i.device,
|
||||||
medium,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match s
|
match s
|
||||||
@ -656,11 +653,9 @@ impl<D: Driver> Stack<D> {
|
|||||||
let addr = addr.into();
|
let addr = addr.into();
|
||||||
|
|
||||||
self.with_mut(|s, i| {
|
self.with_mut(|s, i| {
|
||||||
let (_hardware_addr, medium) = to_smoltcp_hardware_address(i.device.hardware_address());
|
|
||||||
let mut smoldev = DriverAdapter {
|
let mut smoldev = DriverAdapter {
|
||||||
cx: Some(cx),
|
cx: Some(cx),
|
||||||
inner: &mut i.device,
|
inner: &mut i.device,
|
||||||
medium,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match s
|
match s
|
||||||
|
@ -515,6 +515,7 @@ impl<'d> TcpIo<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
mod embedded_io_impls {
|
mod embedded_io_impls {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -583,6 +584,7 @@ mod embedded_io_impls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TCP client compatible with `embedded-nal-async` traits.
|
/// TCP client compatible with `embedded-nal-async` traits.
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub mod client {
|
pub mod client {
|
||||||
use core::cell::{Cell, UnsafeCell};
|
use core::cell::{Cell, UnsafeCell};
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
|
@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
|
|||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-nrf-v$VERSION/embassy-nrf/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-nrf-v$VERSION/embassy-nrf/src/"
|
||||||
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-nrf/src/"
|
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-nrf/src/"
|
||||||
|
|
||||||
features = ["time", "defmt", "unstable-pac", "gpiote", "time-driver-rtc1"]
|
features = ["nightly", "time", "defmt", "unstable-pac", "unstable-traits", "gpiote", "time-driver-rtc1"]
|
||||||
flavors = [
|
flavors = [
|
||||||
{ regex_feature = "nrf52.*", target = "thumbv7em-none-eabihf" },
|
{ regex_feature = "nrf52.*", target = "thumbv7em-none-eabihf" },
|
||||||
{ regex_feature = "nrf53.*", target = "thumbv8m.main-none-eabihf" },
|
{ regex_feature = "nrf53.*", target = "thumbv8m.main-none-eabihf" },
|
||||||
@ -32,7 +32,10 @@ rt = [
|
|||||||
|
|
||||||
time = ["dep:embassy-time"]
|
time = ["dep:embassy-time"]
|
||||||
|
|
||||||
defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt", "embassy-usb-driver/defmt", "embassy-embedded-hal/defmt"]
|
defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt", "embassy-usb-driver?/defmt", "embassy-embedded-hal/defmt"]
|
||||||
|
|
||||||
|
# Enable nightly-only features
|
||||||
|
nightly = ["embedded-hal-1", "embedded-hal-async", "dep:embassy-usb-driver", "embedded-storage-async", "dep:embedded-io-async", "embassy-embedded-hal/nightly"]
|
||||||
|
|
||||||
# Reexport the PAC for the currently enabled chip at `embassy_nrf::pac`.
|
# Reexport the PAC for the currently enabled chip at `embassy_nrf::pac`.
|
||||||
# This is unstable because semver-minor (non-breaking) releases of embassy-nrf may major-bump (breaking) the PAC version.
|
# This is unstable because semver-minor (non-breaking) releases of embassy-nrf may major-bump (breaking) the PAC version.
|
||||||
@ -40,6 +43,10 @@ defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt", "embas
|
|||||||
# There are no plans to make this stable.
|
# There are no plans to make this stable.
|
||||||
unstable-pac = []
|
unstable-pac = []
|
||||||
|
|
||||||
|
# Implement embedded-hal 1.0 alpha traits.
|
||||||
|
# Implement embedded-hal-async traits if `nightly` is set as well.
|
||||||
|
unstable-traits = ["embedded-hal-1"]
|
||||||
|
|
||||||
nrf52805 = ["nrf52805-pac", "_nrf52"]
|
nrf52805 = ["nrf52805-pac", "_nrf52"]
|
||||||
nrf52810 = ["nrf52810-pac", "_nrf52"]
|
nrf52810 = ["nrf52810-pac", "_nrf52"]
|
||||||
nrf52811 = ["nrf52811-pac", "_nrf52"]
|
nrf52811 = ["nrf52811-pac", "_nrf52"]
|
||||||
@ -87,17 +94,17 @@ _gpio-p1 = []
|
|||||||
_nrf52832_anomaly_109 = []
|
_nrf52832_anomaly_109 = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time", optional = true }
|
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
|
||||||
embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.4.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" }
|
||||||
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver" }
|
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true }
|
||||||
|
|
||||||
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.2" }
|
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = true}
|
||||||
embedded-hal-async = { version = "=1.0.0-rc.2" }
|
embedded-hal-async = { version = "=1.0.0-rc.1", optional = true}
|
||||||
embedded-io = { version = "0.6.0" }
|
embedded-io = { version = "0.6.0" }
|
||||||
embedded-io-async = { version = "0.6.1" }
|
embedded-io-async = { version = "0.6.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 }
|
||||||
@ -106,8 +113,8 @@ cortex-m = "0.7.6"
|
|||||||
critical-section = "1.1"
|
critical-section = "1.1"
|
||||||
rand_core = "0.6.3"
|
rand_core = "0.6.3"
|
||||||
fixed = "1.10.0"
|
fixed = "1.10.0"
|
||||||
embedded-storage = "0.3.1"
|
embedded-storage = "0.3.0"
|
||||||
embedded-storage-async = "0.4.0"
|
embedded-storage-async = { version = "0.4.0", optional = true }
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
|
||||||
nrf52805-pac = { version = "0.12.0", optional = true }
|
nrf52805-pac = { version = "0.12.0", optional = true }
|
||||||
|
@ -607,6 +607,7 @@ impl<'u, 'd, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'u, 'd, U, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
mod _embedded_io {
|
mod _embedded_io {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 256;
|
|||||||
pub const FLASH_SIZE: usize = 192 * 1024;
|
pub const FLASH_SIZE: usize = 192 * 1024;
|
||||||
|
|
||||||
pub const RESET_PIN: u32 = 21;
|
pub const RESET_PIN: u32 = 21;
|
||||||
pub const APPROTECT_MIN_BUILD_CODE: u8 = b'B';
|
|
||||||
|
|
||||||
embassy_hal_internal::peripherals! {
|
embassy_hal_internal::peripherals! {
|
||||||
// RTC
|
// RTC
|
||||||
|
@ -7,7 +7,6 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 256;
|
|||||||
pub const FLASH_SIZE: usize = 192 * 1024;
|
pub const FLASH_SIZE: usize = 192 * 1024;
|
||||||
|
|
||||||
pub const RESET_PIN: u32 = 21;
|
pub const RESET_PIN: u32 = 21;
|
||||||
pub const APPROTECT_MIN_BUILD_CODE: u8 = b'E';
|
|
||||||
|
|
||||||
embassy_hal_internal::peripherals! {
|
embassy_hal_internal::peripherals! {
|
||||||
// RTC
|
// RTC
|
||||||
|
@ -7,7 +7,6 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 256;
|
|||||||
pub const FLASH_SIZE: usize = 192 * 1024;
|
pub const FLASH_SIZE: usize = 192 * 1024;
|
||||||
|
|
||||||
pub const RESET_PIN: u32 = 21;
|
pub const RESET_PIN: u32 = 21;
|
||||||
pub const APPROTECT_MIN_BUILD_CODE: u8 = b'B';
|
|
||||||
|
|
||||||
embassy_hal_internal::peripherals! {
|
embassy_hal_internal::peripherals! {
|
||||||
// RTC
|
// RTC
|
||||||
|
@ -7,7 +7,6 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512;
|
|||||||
pub const FLASH_SIZE: usize = 256 * 1024;
|
pub const FLASH_SIZE: usize = 256 * 1024;
|
||||||
|
|
||||||
pub const RESET_PIN: u32 = 18;
|
pub const RESET_PIN: u32 = 18;
|
||||||
pub const APPROTECT_MIN_BUILD_CODE: u8 = b'D';
|
|
||||||
|
|
||||||
embassy_hal_internal::peripherals! {
|
embassy_hal_internal::peripherals! {
|
||||||
// USB
|
// USB
|
||||||
@ -132,6 +131,7 @@ embassy_hal_internal::peripherals! {
|
|||||||
QDEC,
|
QDEC,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl_usb!(USBD, USBD, USBD);
|
impl_usb!(USBD, USBD, USBD);
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -11,7 +11,6 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 255;
|
|||||||
pub const FLASH_SIZE: usize = 512 * 1024;
|
pub const FLASH_SIZE: usize = 512 * 1024;
|
||||||
|
|
||||||
pub const RESET_PIN: u32 = 21;
|
pub const RESET_PIN: u32 = 21;
|
||||||
pub const APPROTECT_MIN_BUILD_CODE: u8 = b'G';
|
|
||||||
|
|
||||||
embassy_hal_internal::peripherals! {
|
embassy_hal_internal::peripherals! {
|
||||||
// RTC
|
// RTC
|
||||||
|
@ -7,7 +7,6 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512;
|
|||||||
pub const FLASH_SIZE: usize = 512 * 1024;
|
pub const FLASH_SIZE: usize = 512 * 1024;
|
||||||
|
|
||||||
pub const RESET_PIN: u32 = 18;
|
pub const RESET_PIN: u32 = 18;
|
||||||
pub const APPROTECT_MIN_BUILD_CODE: u8 = b'B';
|
|
||||||
|
|
||||||
embassy_hal_internal::peripherals! {
|
embassy_hal_internal::peripherals! {
|
||||||
// USB
|
// USB
|
||||||
@ -172,6 +171,7 @@ embassy_hal_internal::peripherals! {
|
|||||||
I2S,
|
I2S,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl_usb!(USBD, USBD, USBD);
|
impl_usb!(USBD, USBD, USBD);
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -7,7 +7,6 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512;
|
|||||||
pub const FLASH_SIZE: usize = 1024 * 1024;
|
pub const FLASH_SIZE: usize = 1024 * 1024;
|
||||||
|
|
||||||
pub const RESET_PIN: u32 = 18;
|
pub const RESET_PIN: u32 = 18;
|
||||||
pub const APPROTECT_MIN_BUILD_CODE: u8 = b'F';
|
|
||||||
|
|
||||||
embassy_hal_internal::peripherals! {
|
embassy_hal_internal::peripherals! {
|
||||||
// USB
|
// USB
|
||||||
@ -175,6 +174,7 @@ embassy_hal_internal::peripherals! {
|
|||||||
I2S,
|
I2S,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl_usb!(USBD, USBD, USBD);
|
impl_usb!(USBD, USBD, USBD);
|
||||||
|
|
||||||
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
|
||||||
|
@ -382,6 +382,7 @@ embassy_hal_internal::peripherals! {
|
|||||||
P1_15,
|
P1_15,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl_usb!(USBD, USBD, USBD);
|
impl_usb!(USBD, USBD, USBD);
|
||||||
|
|
||||||
impl_uarte!(SERIAL0, UARTE0, SERIAL0);
|
impl_uarte!(SERIAL0, UARTE0, SERIAL0);
|
||||||
|
@ -566,77 +566,82 @@ mod eh02 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Input<'d, T> {
|
#[cfg(feature = "unstable-traits")]
|
||||||
type Error = Infallible;
|
mod eh1 {
|
||||||
}
|
use super::*;
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Input<'d, T> {
|
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Input<'d, T> {
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
type Error = Infallible;
|
||||||
Ok(self.is_high())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Input<'d, T> {
|
||||||
Ok(self.is_low())
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Output<'d, T> {
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
type Error = Infallible;
|
Ok(self.is_low())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Output<'d, T> {
|
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Output<'d, T> {
|
||||||
Ok(self.set_high())
|
type Error = Infallible;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Output<'d, T> {
|
||||||
Ok(self.set_low())
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
Ok(self.set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Output<'d, T> {
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
Ok(self.set_low())
|
||||||
Ok(self.is_set_high())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Output<'d, T> {
|
||||||
Ok(self.is_set_low())
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Flex<'d, T> {
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||||
type Error = Infallible;
|
Ok(self.is_set_low())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// Implement [`InputPin`] for [`Flex`];
|
|
||||||
///
|
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Flex<'d, T> {
|
||||||
/// If the pin is not in input mode the result is unspecified.
|
type Error = Infallible;
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Flex<'d, T> {
|
}
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(self.is_high())
|
/// Implement [`InputPin`] for [`Flex`];
|
||||||
}
|
///
|
||||||
|
/// If the pin is not in input mode the result is unspecified.
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Flex<'d, T> {
|
||||||
Ok(self.is_low())
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Flex<'d, T> {
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
Ok(self.is_low())
|
||||||
Ok(self.set_high())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Flex<'d, T> {
|
||||||
Ok(self.set_low())
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
Ok(self.set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Flex<'d, T> {
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
Ok(self.set_low())
|
||||||
Ok(self.is_set_high())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Flex<'d, T> {
|
||||||
Ok(self.is_set_low())
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_set_high())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_set_low())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,60 +490,70 @@ mod eh02 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::ErrorType for InputChannel<'d, C, T> {
|
#[cfg(feature = "unstable-traits")]
|
||||||
type Error = Infallible;
|
mod eh1 {
|
||||||
}
|
use super::*;
|
||||||
|
|
||||||
impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::InputPin for InputChannel<'d, C, T> {
|
impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::ErrorType for InputChannel<'d, C, T> {
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
type Error = Infallible;
|
||||||
Ok(self.pin.is_high())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::InputPin for InputChannel<'d, C, T> {
|
||||||
Ok(self.pin.is_low())
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.pin.is_high())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.pin.is_low())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> {
|
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
|
||||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
mod eha {
|
||||||
Ok(self.wait_for_high().await)
|
use super::*;
|
||||||
|
|
||||||
|
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> {
|
||||||
|
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(self.wait_for_high().await)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(self.wait_for_low().await)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(self.wait_for_rising_edge().await)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(self.wait_for_falling_edge().await)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(self.wait_for_any_edge().await)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> {
|
||||||
Ok(self.wait_for_low().await)
|
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
Ok(self.wait_for_high().await)
|
||||||
|
}
|
||||||
|
|
||||||
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
||||||
Ok(self.wait_for_rising_edge().await)
|
Ok(self.wait_for_low().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
Ok(self.wait_for_falling_edge().await)
|
Ok(self.wait_for_rising_edge().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
Ok(self.wait_for_any_edge().await)
|
Ok(self.wait_for_falling_edge().await)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> {
|
Ok(self.wait_for_any_edge().await)
|
||||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
}
|
||||||
Ok(self.wait_for_high().await)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
|
||||||
Ok(self.wait_for_low().await)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
|
||||||
Ok(self.wait_for_rising_edge().await)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
|
||||||
Ok(self.wait_for_falling_edge().await)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
|
||||||
Ok(self.wait_for_any_edge().await)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(async_fn_in_trait)]
|
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
|
||||||
|
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ pub mod uarte;
|
|||||||
feature = "nrf52833",
|
feature = "nrf52833",
|
||||||
feature = "nrf52840"
|
feature = "nrf52840"
|
||||||
))]
|
))]
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub mod usb;
|
pub mod usb;
|
||||||
#[cfg(not(feature = "_nrf5340"))]
|
#[cfg(not(feature = "_nrf5340"))]
|
||||||
pub mod wdt;
|
pub mod wdt;
|
||||||
@ -349,11 +351,10 @@ pub fn init(config: config::Config) -> Peripherals {
|
|||||||
// Get the letter for the build code (b'A' .. b'F')
|
// Get the letter for the build code (b'A' .. b'F')
|
||||||
let build_code = (variant >> 8) as u8;
|
let build_code = (variant >> 8) as u8;
|
||||||
|
|
||||||
if build_code >= chip::APPROTECT_MIN_BUILD_CODE {
|
if build_code >= b'F' {
|
||||||
// Chips with a certain chip type-specific build code or higher have an
|
// Chips with build code F and higher (revision 3 and higher) have an
|
||||||
// improved APPROTECT ("hardware and software controlled access port protection")
|
// improved APPROTECT ("hardware and software controlled access port protection")
|
||||||
// which needs explicit action by the firmware to keep it unlocked
|
// which needs explicit action by the firmware to keep it unlocked
|
||||||
// See https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/working-with-the-nrf52-series-improved-approtect
|
|
||||||
|
|
||||||
// UICR.APPROTECT = SwDisabled
|
// UICR.APPROTECT = SwDisabled
|
||||||
let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED);
|
let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED);
|
||||||
|
23
embassy-nrf/src/qspi.rs
Executable file → Normal file
23
embassy-nrf/src/qspi.rs
Executable file → Normal file
@ -391,13 +391,8 @@ impl<'d, T: Instance> Qspi<'d, T> {
|
|||||||
///
|
///
|
||||||
/// The difference with `read` is that this does not do bounds checks
|
/// The difference with `read` is that this does not do bounds checks
|
||||||
/// against the flash capacity. It is intended for use when QSPI is used as
|
/// against the flash capacity. It is intended for use when QSPI is used as
|
||||||
/// a raw bus, not with flash memory.
|
/// a raw bus, not with flash memory.
|
||||||
pub async fn read_raw(&mut self, address: u32, data: &mut [u8]) -> Result<(), Error> {
|
pub async fn read_raw(&mut self, address: u32, data: &mut [u8]) -> Result<(), Error> {
|
||||||
// Avoid blocking_wait_ready() blocking forever on zero-length buffers.
|
|
||||||
if data.len() == 0 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let ondrop = OnDrop::new(Self::blocking_wait_ready);
|
let ondrop = OnDrop::new(Self::blocking_wait_ready);
|
||||||
|
|
||||||
self.start_read(address, data)?;
|
self.start_read(address, data)?;
|
||||||
@ -414,11 +409,6 @@ impl<'d, T: Instance> Qspi<'d, T> {
|
|||||||
/// against the flash capacity. It is intended for use when QSPI is used as
|
/// against the flash capacity. It is intended for use when QSPI is used as
|
||||||
/// a raw bus, not with flash memory.
|
/// a raw bus, not with flash memory.
|
||||||
pub async fn write_raw(&mut self, address: u32, data: &[u8]) -> Result<(), Error> {
|
pub async fn write_raw(&mut self, address: u32, data: &[u8]) -> Result<(), Error> {
|
||||||
// Avoid blocking_wait_ready() blocking forever on zero-length buffers.
|
|
||||||
if data.len() == 0 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let ondrop = OnDrop::new(Self::blocking_wait_ready);
|
let ondrop = OnDrop::new(Self::blocking_wait_ready);
|
||||||
|
|
||||||
self.start_write(address, data)?;
|
self.start_write(address, data)?;
|
||||||
@ -435,11 +425,6 @@ impl<'d, T: Instance> Qspi<'d, T> {
|
|||||||
/// against the flash capacity. It is intended for use when QSPI is used as
|
/// against the flash capacity. It is intended for use when QSPI is used as
|
||||||
/// a raw bus, not with flash memory.
|
/// a raw bus, not with flash memory.
|
||||||
pub fn blocking_read_raw(&mut self, address: u32, data: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_read_raw(&mut self, address: u32, data: &mut [u8]) -> Result<(), Error> {
|
||||||
// Avoid blocking_wait_ready() blocking forever on zero-length buffers.
|
|
||||||
if data.len() == 0 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.start_read(address, data)?;
|
self.start_read(address, data)?;
|
||||||
Self::blocking_wait_ready();
|
Self::blocking_wait_ready();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -451,11 +436,6 @@ impl<'d, T: Instance> Qspi<'d, T> {
|
|||||||
/// against the flash capacity. It is intended for use when QSPI is used as
|
/// against the flash capacity. It is intended for use when QSPI is used as
|
||||||
/// a raw bus, not with flash memory.
|
/// a raw bus, not with flash memory.
|
||||||
pub fn blocking_write_raw(&mut self, address: u32, data: &[u8]) -> Result<(), Error> {
|
pub fn blocking_write_raw(&mut self, address: u32, data: &[u8]) -> Result<(), Error> {
|
||||||
// Avoid blocking_wait_ready() blocking forever on zero-length buffers.
|
|
||||||
if data.len() == 0 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.start_write(address, data)?;
|
self.start_write(address, data)?;
|
||||||
Self::blocking_wait_ready();
|
Self::blocking_wait_ready();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -605,6 +585,7 @@ impl<'d, T: Instance> NorFlash for Qspi<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
mod _eh1 {
|
mod _eh1 {
|
||||||
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
|
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
|
||||||
|
|
||||||
|
@ -495,61 +495,72 @@ mod eh02 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl embedded_hal_1::spi::Error for Error {
|
#[cfg(feature = "unstable-traits")]
|
||||||
fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
|
mod eh1 {
|
||||||
match *self {
|
use super::*;
|
||||||
Self::TxBufferTooLong => embedded_hal_1::spi::ErrorKind::Other,
|
|
||||||
Self::RxBufferTooLong => embedded_hal_1::spi::ErrorKind::Other,
|
impl embedded_hal_1::spi::Error for Error {
|
||||||
Self::BufferNotInRAM => embedded_hal_1::spi::ErrorKind::Other,
|
fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
|
||||||
|
match *self {
|
||||||
|
Self::TxBufferTooLong => embedded_hal_1::spi::ErrorKind::Other,
|
||||||
|
Self::RxBufferTooLong => embedded_hal_1::spi::ErrorKind::Other,
|
||||||
|
Self::BufferNotInRAM => embedded_hal_1::spi::ErrorKind::Other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_1::spi::ErrorType for Spim<'d, T> {
|
||||||
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_1::spi::SpiBus<u8> for Spim<'d, T> {
|
||||||
|
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_transfer(words, &[])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_write(words)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_transfer(read, write)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_transfer_in_place(words)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_1::spi::ErrorType for Spim<'d, T> {
|
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
|
||||||
type Error = Error;
|
mod eha {
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_1::spi::SpiBus<u8> for Spim<'d, T> {
|
use super::*;
|
||||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
|
||||||
self.blocking_transfer(words, &[])
|
async fn flush(&mut self) -> Result<(), Error> {
|
||||||
}
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
async fn read(&mut self, words: &mut [u8]) -> Result<(), Error> {
|
||||||
self.blocking_write(words)
|
self.read(words).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
|
async fn write(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||||
self.blocking_transfer(read, write)
|
self.write(data).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
async fn transfer(&mut self, rx: &mut [u8], tx: &[u8]) -> Result<(), Error> {
|
||||||
self.blocking_transfer_in_place(words)
|
self.transfer(rx, tx).await
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
|
async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> {
|
||||||
async fn flush(&mut self) -> Result<(), Error> {
|
self.transfer_in_place(words).await
|
||||||
Ok(())
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async fn read(&mut self, words: &mut [u8]) -> Result<(), Error> {
|
|
||||||
self.read(words).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn write(&mut self, data: &[u8]) -> Result<(), Error> {
|
|
||||||
self.write(data).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn transfer(&mut self, rx: &mut [u8], tx: &[u8]) -> Result<(), Error> {
|
|
||||||
self.transfer(rx, tx).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> {
|
|
||||||
self.transfer_in_place(words).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,72 +810,81 @@ mod eh02 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl embedded_hal_1::i2c::Error for Error {
|
#[cfg(feature = "unstable-traits")]
|
||||||
fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
|
mod eh1 {
|
||||||
match *self {
|
use super::*;
|
||||||
Self::TxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
|
|
||||||
Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
|
impl embedded_hal_1::i2c::Error for Error {
|
||||||
Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other,
|
fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
|
||||||
Self::Receive => embedded_hal_1::i2c::ErrorKind::Other,
|
match *self {
|
||||||
Self::BufferNotInRAM => embedded_hal_1::i2c::ErrorKind::Other,
|
Self::TxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
Self::AddressNack => {
|
Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
|
Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
|
Self::Receive => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
|
Self::BufferNotInRAM => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
|
Self::AddressNack => {
|
||||||
|
embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
|
||||||
|
}
|
||||||
|
Self::DataNack => {
|
||||||
|
embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Data)
|
||||||
|
}
|
||||||
|
Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
|
||||||
|
Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
}
|
}
|
||||||
Self::DataNack => {
|
}
|
||||||
embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Data)
|
}
|
||||||
}
|
|
||||||
Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
|
impl<'d, T: Instance> embedded_hal_1::i2c::ErrorType for Twim<'d, T> {
|
||||||
Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_1::i2c::I2c for Twim<'d, T> {
|
||||||
|
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_read(address, buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_write(address, buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_write_read(address, wr_buffer, rd_buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transaction<'a>(
|
||||||
|
&mut self,
|
||||||
|
_address: u8,
|
||||||
|
_operations: &mut [embedded_hal_1::i2c::Operation<'a>],
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_1::i2c::ErrorType for Twim<'d, T> {
|
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
|
||||||
type Error = Error;
|
mod eha {
|
||||||
}
|
use super::*;
|
||||||
|
impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> {
|
||||||
|
async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.read(address, read).await
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_1::i2c::I2c for Twim<'d, T> {
|
async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
|
||||||
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
self.write(address, write).await
|
||||||
self.blocking_read(address, buffer)
|
}
|
||||||
}
|
async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.write_read(address, write, read).await
|
||||||
|
}
|
||||||
|
|
||||||
fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Self::Error> {
|
async fn transaction(
|
||||||
self.blocking_write(address, buffer)
|
&mut self,
|
||||||
}
|
address: u8,
|
||||||
|
operations: &mut [embedded_hal_1::i2c::Operation<'_>],
|
||||||
fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
self.blocking_write_read(address, wr_buffer, rd_buffer)
|
let _ = address;
|
||||||
}
|
let _ = operations;
|
||||||
|
todo!()
|
||||||
fn transaction<'a>(
|
}
|
||||||
&mut self,
|
|
||||||
_address: u8,
|
|
||||||
_operations: &mut [embedded_hal_1::i2c::Operation<'a>],
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> {
|
|
||||||
async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
|
|
||||||
self.read(address, read).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
|
|
||||||
self.write(address, write).await
|
|
||||||
}
|
|
||||||
async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
|
|
||||||
self.write_read(address, write, read).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn transaction(
|
|
||||||
&mut self,
|
|
||||||
address: u8,
|
|
||||||
operations: &mut [embedded_hal_1::i2c::Operation<'_>],
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
let _ = address;
|
|
||||||
let _ = operations;
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
|
|||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-rp-v$VERSION/embassy-rp/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-rp-v$VERSION/embassy-rp/src/"
|
||||||
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-rp/src/"
|
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-rp/src/"
|
||||||
features = ["defmt", "unstable-pac", "time-driver"]
|
features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver"]
|
||||||
flavors = [
|
flavors = [
|
||||||
{ name = "rp2040", target = "thumbv6m-none-eabi" },
|
{ name = "rp2040", target = "thumbv6m-none-eabi" },
|
||||||
]
|
]
|
||||||
@ -16,7 +16,7 @@ flavors = [
|
|||||||
default = [ "rt" ]
|
default = [ "rt" ]
|
||||||
rt = [ "rp-pac/rt" ]
|
rt = [ "rp-pac/rt" ]
|
||||||
|
|
||||||
defmt = ["dep:defmt", "embassy-usb-driver/defmt", "embassy-hal-internal/defmt"]
|
defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-internal/defmt"]
|
||||||
|
|
||||||
# critical section that is safe for multicore use
|
# critical section that is safe for multicore use
|
||||||
critical-section-impl = ["critical-section/restore-state-u8"]
|
critical-section-impl = ["critical-section/restore-state-u8"]
|
||||||
@ -51,13 +51,20 @@ qspi-as-gpio = []
|
|||||||
# This allows the flash driver to not force pausing execution on both cores when doing flash operations.
|
# This allows the flash driver to not force pausing execution on both cores when doing flash operations.
|
||||||
run-from-ram = []
|
run-from-ram = []
|
||||||
|
|
||||||
|
# Enable nightly-only features
|
||||||
|
nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io-async"]
|
||||||
|
|
||||||
|
# Implement embedded-hal 1.0 alpha traits.
|
||||||
|
# Implement embedded-hal-async traits if `nightly` is set as well.
|
||||||
|
unstable-traits = ["embedded-hal-1", "embedded-hal-nb"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] }
|
embassy-time = { version = "0.1.5", 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" }
|
||||||
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver" }
|
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
|
||||||
atomic-polyfill = "1.0.1"
|
atomic-polyfill = "1.0.1"
|
||||||
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 }
|
||||||
@ -69,18 +76,18 @@ 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.6.0" }
|
||||||
embedded-io-async = { version = "0.6.1" }
|
embedded-io-async = { version = "0.6.0", optional = true }
|
||||||
embedded-storage = { version = "0.3" }
|
embedded-storage = { version = "0.3" }
|
||||||
embedded-storage-async = { version = "0.4.1" }
|
embedded-storage-async = { version = "0.4.0", optional = true }
|
||||||
rand_core = "0.6.4"
|
rand_core = "0.6.4"
|
||||||
fixed = "1.23.1"
|
fixed = "1.23.1"
|
||||||
|
|
||||||
rp-pac = { version = "6" }
|
rp-pac = { version = "6" }
|
||||||
|
|
||||||
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.2" }
|
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = true}
|
||||||
embedded-hal-async = { version = "=1.0.0-rc.2" }
|
embedded-hal-async = { version = "=1.0.0-rc.1", optional = true}
|
||||||
embedded-hal-nb = { version = "=1.0.0-rc.2" }
|
embedded-hal-nb = { version = "=1.0.0-rc.1", optional = true}
|
||||||
|
|
||||||
pio-proc = {version= "0.2" }
|
pio-proc = {version= "0.2" }
|
||||||
pio = {version= "0.2.1" }
|
pio = {version= "0.2.1" }
|
||||||
|
@ -352,6 +352,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> NorFlash for Flash<'d, T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::ReadNorFlash
|
impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::ReadNorFlash
|
||||||
for Flash<'d, T, Async, FLASH_SIZE>
|
for Flash<'d, T, Async, FLASH_SIZE>
|
||||||
{
|
{
|
||||||
@ -366,6 +367,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::NorFlash
|
impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::NorFlash
|
||||||
for Flash<'d, T, Async, FLASH_SIZE>
|
for Flash<'d, T, Async, FLASH_SIZE>
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
use core::convert::Infallible;
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::pin::Pin as FuturePin;
|
use core::pin::Pin as FuturePin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
@ -1037,207 +1036,217 @@ mod eh02 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Input<'d, T> {
|
#[cfg(feature = "unstable-traits")]
|
||||||
type Error = Infallible;
|
mod eh1 {
|
||||||
}
|
use core::convert::Infallible;
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Input<'d, T> {
|
use super::*;
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
|
||||||
Ok(self.is_high())
|
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Input<'d, T> {
|
||||||
|
type Error = Infallible;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Input<'d, T> {
|
||||||
Ok(self.is_low())
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Output<'d, T> {
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
type Error = Infallible;
|
Ok(self.is_low())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Output<'d, T> {
|
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Output<'d, T> {
|
||||||
Ok(self.set_high())
|
type Error = Infallible;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Output<'d, T> {
|
||||||
Ok(self.set_low())
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
Ok(self.set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Output<'d, T> {
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
Ok(self.set_low())
|
||||||
Ok(self.is_set_high())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Output<'d, T> {
|
||||||
Ok(self.is_set_low())
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for Output<'d, T> {
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
Ok(self.is_set_low())
|
||||||
Ok(self.toggle())
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for Output<'d, T> {
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for OutputOpenDrain<'d, T> {
|
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||||
type Error = Infallible;
|
Ok(self.toggle())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for OutputOpenDrain<'d, T> {
|
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for OutputOpenDrain<'d, T> {
|
||||||
Ok(self.set_high())
|
type Error = Infallible;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for OutputOpenDrain<'d, T> {
|
||||||
Ok(self.set_low())
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
Ok(self.set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for OutputOpenDrain<'d, T> {
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
Ok(self.set_low())
|
||||||
Ok(self.is_set_high())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for OutputOpenDrain<'d, T> {
|
||||||
Ok(self.is_set_low())
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for OutputOpenDrain<'d, T> {
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
Ok(self.is_set_low())
|
||||||
Ok(self.toggle())
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for OutputOpenDrain<'d, T> {
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for OutputOpenDrain<'d, T> {
|
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
Ok(self.toggle())
|
||||||
Ok(self.is_high())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for OutputOpenDrain<'d, T> {
|
||||||
Ok(self.is_low())
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Flex<'d, T> {
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
type Error = Infallible;
|
Ok(self.is_low())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Flex<'d, T> {
|
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Flex<'d, T> {
|
||||||
Ok(self.is_high())
|
type Error = Infallible;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Flex<'d, T> {
|
||||||
Ok(self.is_low())
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Flex<'d, T> {
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
Ok(self.is_low())
|
||||||
Ok(self.set_high())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Flex<'d, T> {
|
||||||
Ok(self.set_low())
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
Ok(self.set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Flex<'d, T> {
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
Ok(self.set_low())
|
||||||
Ok(self.is_set_high())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Flex<'d, T> {
|
||||||
Ok(self.is_set_low())
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||||
}
|
Ok(self.is_set_high())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for Flex<'d, T> {
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
Ok(self.is_set_low())
|
||||||
Ok(self.toggle())
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for Flex<'d, T> {
|
||||||
impl<'d, T: Pin> embedded_hal_async::digital::Wait for Flex<'d, T> {
|
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
Ok(self.toggle())
|
||||||
self.wait_for_high().await;
|
}
|
||||||
Ok(())
|
}
|
||||||
}
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Pin> embedded_hal_async::digital::Wait for Flex<'d, T> {
|
||||||
self.wait_for_low().await;
|
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||||
Ok(())
|
self.wait_for_high().await;
|
||||||
}
|
Ok(())
|
||||||
|
}
|
||||||
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
|
||||||
self.wait_for_rising_edge().await;
|
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
||||||
Ok(())
|
self.wait_for_low().await;
|
||||||
}
|
Ok(())
|
||||||
|
}
|
||||||
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
|
||||||
self.wait_for_falling_edge().await;
|
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
Ok(())
|
self.wait_for_rising_edge().await;
|
||||||
}
|
Ok(())
|
||||||
|
}
|
||||||
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
|
||||||
self.wait_for_any_edge().await;
|
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
Ok(())
|
self.wait_for_falling_edge().await;
|
||||||
}
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Pin> embedded_hal_async::digital::Wait for Input<'d, T> {
|
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
self.wait_for_any_edge().await;
|
||||||
self.wait_for_high().await;
|
Ok(())
|
||||||
Ok(())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
#[cfg(feature = "nightly")]
|
||||||
self.wait_for_low().await;
|
impl<'d, T: Pin> embedded_hal_async::digital::Wait for Input<'d, T> {
|
||||||
Ok(())
|
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
self.wait_for_high().await;
|
||||||
|
Ok(())
|
||||||
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
}
|
||||||
self.wait_for_rising_edge().await;
|
|
||||||
Ok(())
|
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
self.wait_for_low().await;
|
||||||
|
Ok(())
|
||||||
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
}
|
||||||
self.wait_for_falling_edge().await;
|
|
||||||
Ok(())
|
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
self.wait_for_rising_edge().await;
|
||||||
|
Ok(())
|
||||||
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
}
|
||||||
self.wait_for_any_edge().await;
|
|
||||||
Ok(())
|
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
self.wait_for_falling_edge().await;
|
||||||
}
|
Ok(())
|
||||||
|
}
|
||||||
impl<'d, T: Pin> embedded_hal_async::digital::Wait for OutputOpenDrain<'d, T> {
|
|
||||||
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
self.wait_for_high().await;
|
self.wait_for_any_edge().await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
|
||||||
self.wait_for_low().await;
|
#[cfg(feature = "nightly")]
|
||||||
Ok(())
|
impl<'d, T: Pin> embedded_hal_async::digital::Wait for OutputOpenDrain<'d, T> {
|
||||||
}
|
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_high().await;
|
||||||
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
Ok(())
|
||||||
self.wait_for_rising_edge().await;
|
}
|
||||||
Ok(())
|
|
||||||
}
|
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_low().await;
|
||||||
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
Ok(())
|
||||||
self.wait_for_falling_edge().await;
|
}
|
||||||
Ok(())
|
|
||||||
}
|
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_rising_edge().await;
|
||||||
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
Ok(())
|
||||||
self.wait_for_any_edge().await;
|
}
|
||||||
Ok(())
|
|
||||||
|
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_falling_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.wait_for_any_edge().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,157 +588,167 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, T, M> {
|
mod eh02 {
|
||||||
type Error = Error;
|
use super::*;
|
||||||
|
|
||||||
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, T, M> {
|
||||||
self.blocking_read(address, buffer)
|
type Error = Error;
|
||||||
|
|
||||||
|
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_read(address, buffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, T, M> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
|
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||||
self.blocking_write(address, bytes)
|
self.blocking_write(address, bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T, M> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
|
fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
self.blocking_write_read(address, bytes, buffer)
|
self.blocking_write_read(address, bytes, buffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Transactional for I2c<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Transactional for I2c<'d, T, M> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn exec(
|
fn exec(
|
||||||
&mut self,
|
&mut self,
|
||||||
address: u8,
|
address: u8,
|
||||||
operations: &mut [embedded_hal_02::blocking::i2c::Operation<'_>],
|
operations: &mut [embedded_hal_02::blocking::i2c::Operation<'_>],
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
Self::setup(address.into())?;
|
Self::setup(address.into())?;
|
||||||
for i in 0..operations.len() {
|
for i in 0..operations.len() {
|
||||||
let last = i == operations.len() - 1;
|
let last = i == operations.len() - 1;
|
||||||
match &mut operations[i] {
|
match &mut operations[i] {
|
||||||
embedded_hal_02::blocking::i2c::Operation::Read(buf) => {
|
embedded_hal_02::blocking::i2c::Operation::Read(buf) => {
|
||||||
self.read_blocking_internal(buf, false, last)?
|
self.read_blocking_internal(buf, false, last)?
|
||||||
|
}
|
||||||
|
embedded_hal_02::blocking::i2c::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
|
||||||
}
|
}
|
||||||
embedded_hal_02::blocking::i2c::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
|
|
||||||
}
|
}
|
||||||
}
|
Ok(())
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl embedded_hal_1::i2c::Error for Error {
|
|
||||||
fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
|
|
||||||
match *self {
|
|
||||||
Self::Abort(AbortReason::ArbitrationLoss) => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss,
|
|
||||||
Self::Abort(AbortReason::NoAcknowledge) => {
|
|
||||||
embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
|
|
||||||
}
|
|
||||||
Self::Abort(AbortReason::TxNotEmpty(_)) => embedded_hal_1::i2c::ErrorKind::Other,
|
|
||||||
Self::Abort(AbortReason::Other(_)) => embedded_hal_1::i2c::ErrorKind::Other,
|
|
||||||
Self::InvalidReadBufferLength => embedded_hal_1::i2c::ErrorKind::Other,
|
|
||||||
Self::InvalidWriteBufferLength => embedded_hal_1::i2c::ErrorKind::Other,
|
|
||||||
Self::AddressOutOfRange(_) => embedded_hal_1::i2c::ErrorKind::Other,
|
|
||||||
Self::AddressReserved(_) => embedded_hal_1::i2c::ErrorKind::Other,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, T, M> {
|
#[cfg(feature = "unstable-traits")]
|
||||||
type Error = Error;
|
mod eh1 {
|
||||||
}
|
use super::*;
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> {
|
impl embedded_hal_1::i2c::Error for Error {
|
||||||
fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
|
fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
|
||||||
self.blocking_read(address, read)
|
match *self {
|
||||||
}
|
Self::Abort(AbortReason::ArbitrationLoss) => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss,
|
||||||
|
Self::Abort(AbortReason::NoAcknowledge) => {
|
||||||
fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
|
embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
|
||||||
self.blocking_write(address, write)
|
}
|
||||||
}
|
Self::Abort(AbortReason::TxNotEmpty(_)) => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
|
Self::Abort(AbortReason::Other(_)) => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
|
Self::InvalidReadBufferLength => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
self.blocking_write_read(address, write, read)
|
Self::InvalidWriteBufferLength => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
}
|
Self::AddressOutOfRange(_) => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
|
Self::AddressReserved(_) => embedded_hal_1::i2c::ErrorKind::Other,
|
||||||
fn transaction(
|
|
||||||
&mut self,
|
|
||||||
address: u8,
|
|
||||||
operations: &mut [embedded_hal_1::i2c::Operation<'_>],
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
Self::setup(address.into())?;
|
|
||||||
for i in 0..operations.len() {
|
|
||||||
let last = i == operations.len() - 1;
|
|
||||||
match &mut operations[i] {
|
|
||||||
embedded_hal_1::i2c::Operation::Read(buf) => self.read_blocking_internal(buf, false, last)?,
|
|
||||||
embedded_hal_1::i2c::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, T, M> {
|
||||||
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> {
|
||||||
|
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> {
|
||||||
|
Self::setup(address.into())?;
|
||||||
|
for i in 0..operations.len() {
|
||||||
|
let last = i == operations.len() - 1;
|
||||||
|
match &mut operations[i] {
|
||||||
|
embedded_hal_1::i2c::Operation::Read(buf) => self.read_blocking_internal(buf, false, last)?,
|
||||||
|
embedded_hal_1::i2c::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
|
||||||
|
mod nightly {
|
||||||
|
use embedded_hal_1::i2c::Operation;
|
||||||
|
use embedded_hal_async::i2c::AddressMode;
|
||||||
|
|
||||||
impl<'d, A, T> embedded_hal_async::i2c::I2c<A> for I2c<'d, T, Async>
|
use super::*;
|
||||||
where
|
|
||||||
A: embedded_hal_async::i2c::AddressMode + Into<u16> + 'static,
|
|
||||||
T: Instance + 'd,
|
|
||||||
{
|
|
||||||
async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
|
|
||||||
let addr: u16 = address.into();
|
|
||||||
|
|
||||||
Self::setup(addr)?;
|
impl<'d, A, T> embedded_hal_async::i2c::I2c<A> for I2c<'d, T, Async>
|
||||||
self.read_async_internal(read, false, true).await
|
where
|
||||||
}
|
A: AddressMode + Into<u16> + 'static,
|
||||||
|
T: Instance + 'd,
|
||||||
|
{
|
||||||
|
async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
let addr: u16 = address.into();
|
||||||
|
|
||||||
async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
|
|
||||||
let addr: u16 = address.into();
|
|
||||||
|
|
||||||
Self::setup(addr)?;
|
|
||||||
self.write_async_internal(write.iter().copied(), true).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
|
|
||||||
let addr: u16 = address.into();
|
|
||||||
|
|
||||||
Self::setup(addr)?;
|
|
||||||
self.write_async_internal(write.iter().cloned(), false).await?;
|
|
||||||
self.read_async_internal(read, true, true).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn transaction(
|
|
||||||
&mut self,
|
|
||||||
address: A,
|
|
||||||
operations: &mut [embedded_hal_1::i2c::Operation<'_>],
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
use embedded_hal_1::i2c::Operation;
|
|
||||||
|
|
||||||
let addr: u16 = address.into();
|
|
||||||
|
|
||||||
if operations.len() > 0 {
|
|
||||||
Self::setup(addr)?;
|
Self::setup(addr)?;
|
||||||
|
self.read_async_internal(read, false, true).await
|
||||||
}
|
}
|
||||||
let mut iterator = operations.iter_mut();
|
|
||||||
|
|
||||||
while let Some(op) = iterator.next() {
|
async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
|
||||||
let last = iterator.len() == 0;
|
let addr: u16 = address.into();
|
||||||
|
|
||||||
match op {
|
Self::setup(addr)?;
|
||||||
Operation::Read(buffer) => {
|
self.write_async_internal(write.iter().copied(), true).await
|
||||||
self.read_async_internal(buffer, false, last).await?;
|
}
|
||||||
}
|
|
||||||
Operation::Write(buffer) => {
|
async fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
self.write_async_internal(buffer.into_iter().cloned(), last).await?;
|
let addr: u16 = address.into();
|
||||||
|
|
||||||
|
Self::setup(addr)?;
|
||||||
|
self.write_async_internal(write.iter().cloned(), false).await?;
|
||||||
|
self.read_async_internal(read, true, true).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn transaction(&mut self, address: A, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
|
||||||
|
let addr: u16 = address.into();
|
||||||
|
|
||||||
|
if operations.len() > 0 {
|
||||||
|
Self::setup(addr)?;
|
||||||
|
}
|
||||||
|
let mut iterator = operations.iter_mut();
|
||||||
|
|
||||||
|
while let Some(op) = iterator.next() {
|
||||||
|
let last = iterator.len() == 0;
|
||||||
|
|
||||||
|
match op {
|
||||||
|
Operation::Read(buffer) => {
|
||||||
|
self.read_async_internal(buffer, false, last).await?;
|
||||||
|
}
|
||||||
|
Operation::Write(buffer) => {
|
||||||
|
self.write_async_internal(buffer.into_iter().cloned(), last).await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(async_fn_in_trait)]
|
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
|
||||||
|
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
|
||||||
|
|
||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
@ -27,6 +28,7 @@ pub mod spi;
|
|||||||
#[cfg(feature = "time-driver")]
|
#[cfg(feature = "time-driver")]
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
pub mod uart;
|
pub mod uart;
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub mod usb;
|
pub mod usb;
|
||||||
pub mod watchdog;
|
pub mod watchdog;
|
||||||
|
|
||||||
|
@ -511,73 +511,87 @@ impl_mode!(Async);
|
|||||||
|
|
||||||
// ====================
|
// ====================
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::spi::Transfer<u8> for Spi<'d, T, M> {
|
mod eh02 {
|
||||||
type Error = Error;
|
use super::*;
|
||||||
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
|
|
||||||
self.blocking_transfer_in_place(words)?;
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::spi::Transfer<u8> for Spi<'d, T, M> {
|
||||||
Ok(words)
|
type Error = Error;
|
||||||
|
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
|
||||||
|
self.blocking_transfer_in_place(words)?;
|
||||||
|
Ok(words)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::spi::Write<u8> for Spi<'d, T, M> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_write(words)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::spi::Write<u8> for Spi<'d, T, M> {
|
#[cfg(feature = "unstable-traits")]
|
||||||
type Error = Error;
|
mod eh1 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
impl embedded_hal_1::spi::Error for Error {
|
||||||
self.blocking_write(words)
|
fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
|
||||||
|
match *self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::ErrorType for Spi<'d, T, M> {
|
||||||
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::SpiBus<u8> for Spi<'d, T, M> {
|
||||||
|
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_transfer(words, &[])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_write(words)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_transfer(read, write)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_transfer_in_place(words)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl embedded_hal_1::spi::Error for Error {
|
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
|
||||||
fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
|
mod eha {
|
||||||
match *self {}
|
use super::*;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::ErrorType for Spi<'d, T, M> {
|
impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spi<'d, T, Async> {
|
||||||
type Error = Error;
|
async fn flush(&mut self) -> Result<(), Self::Error> {
|
||||||
}
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::SpiBus<u8> for Spi<'d, T, M> {
|
async fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
||||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
self.write(words).await
|
||||||
Ok(())
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
async fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
self.blocking_transfer(words, &[])
|
self.read(words).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
|
||||||
self.blocking_write(words)
|
self.transfer(read, write).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
|
async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
self.blocking_transfer(read, write)
|
self.transfer_in_place(words).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
|
||||||
self.blocking_transfer_in_place(words)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spi<'d, T, Async> {
|
|
||||||
async fn flush(&mut self) -> Result<(), Self::Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
|
||||||
self.write(words).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
|
||||||
self.read(words).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
|
|
||||||
self.transfer(read, write).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
|
|
||||||
self.transfer_in_place(words).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,117 +668,126 @@ impl<'d, T: Instance + 'd> embedded_io::Write for BufferedUartTx<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d, T> {
|
mod eh02 {
|
||||||
type Error = Error;
|
use super::*;
|
||||||
|
|
||||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d, T> {
|
||||||
let r = T::regs();
|
type Error = Error;
|
||||||
if r.uartfr().read().rxfe() {
|
|
||||||
return Err(nb::Error::WouldBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
let dr = r.uartdr().read();
|
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||||
|
let r = T::regs();
|
||||||
|
if r.uartfr().read().rxfe() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
if dr.oe() {
|
let dr = r.uartdr().read();
|
||||||
Err(nb::Error::Other(Error::Overrun))
|
|
||||||
} else if dr.be() {
|
|
||||||
Err(nb::Error::Other(Error::Break))
|
|
||||||
} else if dr.pe() {
|
|
||||||
Err(nb::Error::Other(Error::Parity))
|
|
||||||
} else if dr.fe() {
|
|
||||||
Err(nb::Error::Other(Error::Framing))
|
|
||||||
} else {
|
|
||||||
Ok(dr.data())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> {
|
if dr.oe() {
|
||||||
type Error = Error;
|
Err(nb::Error::Other(Error::Overrun))
|
||||||
|
} else if dr.be() {
|
||||||
fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
|
Err(nb::Error::Other(Error::Break))
|
||||||
while !buffer.is_empty() {
|
} else if dr.pe() {
|
||||||
match self.blocking_write(buffer) {
|
Err(nb::Error::Other(Error::Parity))
|
||||||
Ok(0) => panic!("zero-length write."),
|
} else if dr.fe() {
|
||||||
Ok(n) => buffer = &buffer[n..],
|
Err(nb::Error::Other(Error::Framing))
|
||||||
Err(e) => return Err(e),
|
} else {
|
||||||
|
Ok(dr.data())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bflush(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> {
|
||||||
self.blocking_flush()
|
type Error = Error;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d, T> {
|
fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
|
||||||
type Error = Error;
|
while !buffer.is_empty() {
|
||||||
|
match self.blocking_write(buffer) {
|
||||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
Ok(0) => panic!("zero-length write."),
|
||||||
embedded_hal_02::serial::Read::read(&mut self.rx)
|
Ok(n) => buffer = &buffer[n..],
|
||||||
}
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d, T> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
|
|
||||||
while !buffer.is_empty() {
|
|
||||||
match self.blocking_write(buffer) {
|
|
||||||
Ok(0) => panic!("zero-length write."),
|
|
||||||
Ok(n) => buffer = &buffer[n..],
|
|
||||||
Err(e) => return Err(e),
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bflush(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_flush()
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bflush(&mut self) -> Result<(), Self::Error> {
|
impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d, T> {
|
||||||
self.blocking_flush()
|
type Error = Error;
|
||||||
|
|
||||||
|
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||||
|
embedded_hal_02::serial::Read::read(&mut self.rx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d, T> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
while !buffer.is_empty() {
|
||||||
|
match self.blocking_write(buffer) {
|
||||||
|
Ok(0) => panic!("zero-length write."),
|
||||||
|
Ok(n) => buffer = &buffer[n..],
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bflush(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_flush()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUartRx<'d, T> {
|
#[cfg(feature = "unstable-traits")]
|
||||||
type Error = Error;
|
mod eh1 {
|
||||||
}
|
use super::*;
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUartTx<'d, T> {
|
impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUartRx<'d, T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUart<'d, T> {
|
|
||||||
type Error = Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_nb::serial::Read for BufferedUartRx<'d, T> {
|
|
||||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
|
||||||
embedded_hal_02::serial::Read::read(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, T> {
|
|
||||||
fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
|
|
||||||
self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUartTx<'d, T> {
|
||||||
self.blocking_flush().map_err(nb::Error::Other)
|
type Error = Error;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_nb::serial::Read for BufferedUart<'d, T> {
|
|
||||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
|
||||||
embedded_hal_02::serial::Read::read(&mut self.rx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUart<'d, T> {
|
|
||||||
fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
|
|
||||||
self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUart<'d, T> {
|
||||||
self.blocking_flush().map_err(nb::Error::Other)
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_nb::serial::Read for BufferedUartRx<'d, T> {
|
||||||
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
|
embedded_hal_02::serial::Read::read(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, T> {
|
||||||
|
fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
|
||||||
|
self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
|
self.blocking_flush().map_err(nb::Error::Other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_nb::serial::Read for BufferedUart<'d, T> {
|
||||||
|
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||||
|
embedded_hal_02::serial::Read::read(&mut self.rx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUart<'d, T> {
|
||||||
|
fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
|
||||||
|
self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
|
self.blocking_flush().map_err(nb::Error::Other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@ use crate::interrupt::typelevel::{Binding, Interrupt};
|
|||||||
use crate::pac::io::vals::{Inover, Outover};
|
use crate::pac::io::vals::{Inover, Outover};
|
||||||
use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
|
use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
mod buffered;
|
mod buffered;
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
|
pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
@ -191,6 +193,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> UartTx<'d, T, Blocking> {
|
impl<'d, T: Instance> UartTx<'d, T, Blocking> {
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub fn into_buffered(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
@ -304,6 +307,7 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> {
|
|||||||
Self::new_inner(false, None)
|
Self::new_inner(false, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub fn into_buffered(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
@ -458,6 +462,7 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
pub fn into_buffered(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
@ -704,163 +709,172 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, M> {
|
mod eh02 {
|
||||||
type Error = Error;
|
use super::*;
|
||||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
|
||||||
let r = T::regs();
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, M> {
|
||||||
if r.uartfr().read().rxfe() {
|
type Error = Error;
|
||||||
return Err(nb::Error::WouldBlock);
|
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||||
|
let r = T::regs();
|
||||||
|
if r.uartfr().read().rxfe() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
let dr = r.uartdr().read();
|
||||||
|
|
||||||
|
if dr.oe() {
|
||||||
|
Err(nb::Error::Other(Error::Overrun))
|
||||||
|
} else if dr.be() {
|
||||||
|
Err(nb::Error::Other(Error::Break))
|
||||||
|
} else if dr.pe() {
|
||||||
|
Err(nb::Error::Other(Error::Parity))
|
||||||
|
} else if dr.fe() {
|
||||||
|
Err(nb::Error::Other(Error::Framing))
|
||||||
|
} else {
|
||||||
|
Ok(dr.data())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for UartTx<'d, T, M> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> {
|
||||||
|
let r = T::regs();
|
||||||
|
if r.uartfr().read().txff() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
r.uartdr().write(|w| w.set_data(word));
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
let dr = r.uartdr().read();
|
fn flush(&mut self) -> Result<(), nb::Error<Self::Error>> {
|
||||||
|
let r = T::regs();
|
||||||
|
if !r.uartfr().read().txfe() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if dr.oe() {
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, M> {
|
||||||
Err(nb::Error::Other(Error::Overrun))
|
type Error = Error;
|
||||||
} else if dr.be() {
|
|
||||||
Err(nb::Error::Other(Error::Break))
|
fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
|
||||||
} else if dr.pe() {
|
self.blocking_write(buffer)
|
||||||
Err(nb::Error::Other(Error::Parity))
|
}
|
||||||
} else if dr.fe() {
|
|
||||||
Err(nb::Error::Other(Error::Framing))
|
fn bflush(&mut self) -> Result<(), Self::Error> {
|
||||||
} else {
|
self.blocking_flush()
|
||||||
Ok(dr.data())
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, T, M> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||||
|
embedded_hal_02::serial::Read::read(&mut self.rx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for Uart<'d, T, M> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> {
|
||||||
|
embedded_hal_02::serial::Write::write(&mut self.tx, word)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> Result<(), nb::Error<Self::Error>> {
|
||||||
|
embedded_hal_02::serial::Write::flush(&mut self.tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, M> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_write(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bflush(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.blocking_flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for UartTx<'d, T, M> {
|
#[cfg(feature = "unstable-traits")]
|
||||||
type Error = Error;
|
mod eh1 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> {
|
impl embedded_hal_nb::serial::Error for Error {
|
||||||
let r = T::regs();
|
fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
|
||||||
if r.uartfr().read().txff() {
|
match *self {
|
||||||
return Err(nb::Error::WouldBlock);
|
Self::Framing => embedded_hal_nb::serial::ErrorKind::FrameFormat,
|
||||||
}
|
Self::Break => embedded_hal_nb::serial::ErrorKind::Other,
|
||||||
|
Self::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun,
|
||||||
r.uartdr().write(|w| w.set_data(word));
|
Self::Parity => embedded_hal_nb::serial::ErrorKind::Parity,
|
||||||
Ok(())
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> Result<(), nb::Error<Self::Error>> {
|
|
||||||
let r = T::regs();
|
|
||||||
if !r.uartfr().read().txfe() {
|
|
||||||
return Err(nb::Error::WouldBlock);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, M> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
|
|
||||||
self.blocking_write(buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bflush(&mut self) -> Result<(), Self::Error> {
|
|
||||||
self.blocking_flush()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, T, M> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
|
||||||
embedded_hal_02::serial::Read::read(&mut self.rx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for Uart<'d, T, M> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> {
|
|
||||||
embedded_hal_02::serial::Write::write(&mut self.tx, word)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> Result<(), nb::Error<Self::Error>> {
|
|
||||||
embedded_hal_02::serial::Write::flush(&mut self.tx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, M> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
|
|
||||||
self.blocking_write(buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bflush(&mut self) -> Result<(), Self::Error> {
|
|
||||||
self.blocking_flush()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl embedded_hal_nb::serial::Error for Error {
|
|
||||||
fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
|
|
||||||
match *self {
|
|
||||||
Self::Framing => embedded_hal_nb::serial::ErrorKind::FrameFormat,
|
|
||||||
Self::Break => embedded_hal_nb::serial::ErrorKind::Other,
|
|
||||||
Self::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun,
|
|
||||||
Self::Parity => embedded_hal_nb::serial::ErrorKind::Parity,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for UartRx<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for UartRx<'d, T, M> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for UartTx<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for UartTx<'d, T, M> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for Uart<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for Uart<'d, T, M> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M> {
|
||||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
let dr = r.uartdr().read();
|
let dr = r.uartdr().read();
|
||||||
|
|
||||||
if dr.oe() {
|
if dr.oe() {
|
||||||
Err(nb::Error::Other(Error::Overrun))
|
Err(nb::Error::Other(Error::Overrun))
|
||||||
} else if dr.be() {
|
} else if dr.be() {
|
||||||
Err(nb::Error::Other(Error::Break))
|
Err(nb::Error::Other(Error::Break))
|
||||||
} else if dr.pe() {
|
} else if dr.pe() {
|
||||||
Err(nb::Error::Other(Error::Parity))
|
Err(nb::Error::Other(Error::Parity))
|
||||||
} else if dr.fe() {
|
} else if dr.fe() {
|
||||||
Err(nb::Error::Other(Error::Framing))
|
Err(nb::Error::Other(Error::Framing))
|
||||||
} else if dr.fe() {
|
} else if dr.fe() {
|
||||||
Ok(dr.data())
|
Ok(dr.data())
|
||||||
} else {
|
} else {
|
||||||
Err(nb::Error::WouldBlock)
|
Err(nb::Error::WouldBlock)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, T, M> {
|
||||||
fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
|
fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
|
||||||
self.blocking_write(&[char]).map_err(nb::Error::Other)
|
self.blocking_write(&[char]).map_err(nb::Error::Other)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
|
self.blocking_flush().map_err(nb::Error::Other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, T, M> {
|
||||||
self.blocking_flush().map_err(nb::Error::Other)
|
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||||
}
|
embedded_hal_02::serial::Read::read(&mut self.rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, T, M> {
|
|
||||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
|
||||||
embedded_hal_02::serial::Read::read(&mut self.rx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, T, M> {
|
|
||||||
fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
|
|
||||||
self.blocking_write(&[char]).map_err(nb::Error::Other)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, T, M> {
|
||||||
self.blocking_flush().map_err(nb::Error::Other)
|
fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
|
||||||
|
self.blocking_write(&[char]).map_err(nb::Error::Other)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
|
self.blocking_flush().map_err(nb::Error::Other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,6 +891,7 @@ mod sealed {
|
|||||||
|
|
||||||
fn regs() -> pac::uart::Uart;
|
fn regs() -> pac::uart::Uart;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
fn buffered_state() -> &'static buffered::State;
|
fn buffered_state() -> &'static buffered::State;
|
||||||
|
|
||||||
fn dma_state() -> &'static DmaState;
|
fn dma_state() -> &'static DmaState;
|
||||||
@ -916,6 +931,7 @@ macro_rules! impl_instance {
|
|||||||
pac::$inst
|
pac::$inst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
fn buffered_state() -> &'static buffered::State {
|
fn buffered_state() -> &'static buffered::State {
|
||||||
static STATE: buffered::State = buffered::State::new();
|
static STATE: buffered::State = buffered::State::new();
|
||||||
&STATE
|
&STATE
|
||||||
|
@ -12,8 +12,8 @@ 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.5.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time", optional = true }
|
embassy-time = { version = "0.1.5", 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" }
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(async_fn_in_trait)]
|
#![cfg_attr(any(feature = "ble", feature = "mac"), feature(async_fn_in_trait))]
|
||||||
|
#![cfg_attr(
|
||||||
|
any(feature = "ble", feature = "mac"),
|
||||||
|
allow(stable_features, unknown_lints, async_fn_in_trait)
|
||||||
|
)]
|
||||||
|
#![cfg_attr(feature = "mac", feature(type_alias_impl_trait, concat_bytes))]
|
||||||
|
|
||||||
// This must go FIRST so that all the other modules see its macros.
|
// This must go FIRST so that all the other modules see its macros.
|
||||||
mod fmt;
|
mod fmt;
|
||||||
|
@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
|
|||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-stm32-v$VERSION/embassy-stm32/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-stm32-v$VERSION/embassy-stm32/src/"
|
||||||
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-stm32/src/"
|
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-stm32/src/"
|
||||||
|
|
||||||
features = ["defmt", "unstable-pac", "exti", "time-driver-any", "time"]
|
features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "exti", "time-driver-any", "time"]
|
||||||
flavors = [
|
flavors = [
|
||||||
{ regex_feature = "stm32f0.*", target = "thumbv6m-none-eabi" },
|
{ regex_feature = "stm32f0.*", target = "thumbv6m-none-eabi" },
|
||||||
{ regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" },
|
{ regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" },
|
||||||
@ -32,22 +32,22 @@ flavors = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
|
||||||
embassy-time = { version = "0.2", path = "../embassy-time", optional = true }
|
embassy-time = { version = "0.1.5", 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.2.0", path = "../embassy-net-driver" }
|
||||||
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver" }
|
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
|
||||||
embassy-executor = { version = "0.3.3", path = "../embassy-executor", optional = true }
|
embassy-executor = { version = "0.3.3", path = "../embassy-executor", optional = true }
|
||||||
|
|
||||||
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.2" }
|
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = true}
|
||||||
embedded-hal-async = { version = "=1.0.0-rc.2" }
|
embedded-hal-async = { version = "=1.0.0-rc.1", optional = true}
|
||||||
embedded-hal-nb = { version = "=1.0.0-rc.2" }
|
embedded-hal-nb = { version = "=1.0.0-rc.1", optional = true}
|
||||||
|
|
||||||
embedded-storage = "0.3.1"
|
embedded-storage = "0.3.0"
|
||||||
embedded-storage-async = { version = "0.4.1" }
|
embedded-storage-async = { version = "0.4.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 }
|
||||||
@ -58,14 +58,14 @@ 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-7117ad49c06fa00c388130a34977e029910083bd" }
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f6d1ffc1a25f208b5cd6b1024bff246592da1949" }
|
||||||
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"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
embedded-io = { version = "0.6.0" }
|
embedded-io = { version = "0.6.0" }
|
||||||
embedded-io-async = { version = "0.6.1" }
|
embedded-io-async = { version = "0.6.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 +76,7 @@ critical-section = { version = "1.1", features = ["std"] }
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
proc-macro2 = "1.0.36"
|
proc-macro2 = "1.0.36"
|
||||||
quote = "1.0.15"
|
quote = "1.0.15"
|
||||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7117ad49c06fa00c388130a34977e029910083bd", default-features = false, features = ["metadata"]}
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f6d1ffc1a25f208b5cd6b1024bff246592da1949", default-features = false, features = ["metadata"]}
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@ -86,21 +86,29 @@ default = ["rt"]
|
|||||||
rt = ["stm32-metapac/rt"]
|
rt = ["stm32-metapac/rt"]
|
||||||
|
|
||||||
## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging
|
## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging
|
||||||
defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async/defmt-03", "embassy-usb-driver/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"]
|
defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io-async?/defmt-03", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"]
|
||||||
|
|
||||||
exti = []
|
exti = []
|
||||||
low-power = [ "dep:embassy-executor", "embassy-executor?/arch-cortex-m" ]
|
low-power = [ "dep:embassy-executor", "embassy-executor/arch-cortex-m" ]
|
||||||
low-power-debug-with-sleep = []
|
low-power-debug-with-sleep = []
|
||||||
|
embassy-executor = []
|
||||||
|
|
||||||
## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/)
|
## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/)
|
||||||
memory-x = ["stm32-metapac/memory-x"]
|
memory-x = ["stm32-metapac/memory-x"]
|
||||||
|
|
||||||
|
## Enable nightly-only features
|
||||||
|
nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io-async", "dep:embassy-usb-driver", "embassy-embedded-hal/nightly"]
|
||||||
|
|
||||||
## Re-export stm32-metapac at `embassy_stm32::pac`.
|
## Re-export stm32-metapac at `embassy_stm32::pac`.
|
||||||
## This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
|
## This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
|
||||||
## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC.
|
## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC.
|
||||||
## There are no plans to make this stable.
|
## There are no plans to make this stable.
|
||||||
unstable-pac = []
|
unstable-pac = []
|
||||||
|
|
||||||
|
## Implement embedded-hal 1.0 alpha traits.
|
||||||
|
## Implement embedded-hal-async traits if `nightly` is set as well.
|
||||||
|
unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"]
|
||||||
|
|
||||||
#! ## Time
|
#! ## Time
|
||||||
|
|
||||||
## Enables additional driver features that depend on embassy-time
|
## Enables additional driver features that depend on embassy-time
|
||||||
|
@ -61,10 +61,10 @@ fn main() {
|
|||||||
let mut singletons: Vec<String> = Vec::new();
|
let mut singletons: Vec<String> = Vec::new();
|
||||||
for p in METADATA.peripherals {
|
for p in METADATA.peripherals {
|
||||||
if let Some(r) = &p.registers {
|
if let Some(r) = &p.registers {
|
||||||
println!("cargo:rustc-cfg=peri_{}", p.name.to_ascii_lowercase());
|
|
||||||
match r.kind {
|
match r.kind {
|
||||||
// Generate singletons per pin, not per port
|
// Generate singletons per pin, not per port
|
||||||
"gpio" => {
|
"gpio" => {
|
||||||
|
println!("{}", p.name);
|
||||||
let port_letter = p.name.strip_prefix("GPIO").unwrap();
|
let port_letter = p.name.strip_prefix("GPIO").unwrap();
|
||||||
for pin_num in 0..16 {
|
for pin_num in 0..16 {
|
||||||
singletons.push(format!("P{}{}", port_letter, pin_num));
|
singletons.push(format!("P{}{}", port_letter, pin_num));
|
||||||
@ -996,8 +996,8 @@ fn main() {
|
|||||||
// SDMMCv1 uses the same channel for both directions, so just implement for RX
|
// SDMMCv1 uses the same channel for both directions, so just implement for RX
|
||||||
(("sdmmc", "RX"), quote!(crate::sdmmc::SdmmcDma)),
|
(("sdmmc", "RX"), quote!(crate::sdmmc::SdmmcDma)),
|
||||||
(("quadspi", "QUADSPI"), quote!(crate::qspi::QuadDma)),
|
(("quadspi", "QUADSPI"), quote!(crate::qspi::QuadDma)),
|
||||||
(("dac", "CH1"), quote!(crate::dac::DacDma1)),
|
(("dac", "CH1"), quote!(crate::dac::DmaCh1)),
|
||||||
(("dac", "CH2"), quote!(crate::dac::DacDma2)),
|
(("dac", "CH2"), quote!(crate::dac::DmaCh2)),
|
||||||
]
|
]
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
@ -1351,6 +1351,15 @@ fn main() {
|
|||||||
|
|
||||||
if let Some(core) = core_name {
|
if let Some(core) = core_name {
|
||||||
println!("cargo:rustc-cfg={}_{}", &chip_name[..chip_name.len() - 2], core);
|
println!("cargo:rustc-cfg={}_{}", &chip_name[..chip_name.len() - 2], core);
|
||||||
|
} else {
|
||||||
|
println!("cargo:rustc-cfg={}", &chip_name[..chip_name.len() - 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========
|
||||||
|
// stm32f3 wildcard features used in RCC
|
||||||
|
|
||||||
|
if chip_name.starts_with("stm32f3") {
|
||||||
|
println!("cargo:rustc-cfg={}x{}", &chip_name[..9], &chip_name[10..11]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======
|
// =======
|
||||||
@ -1365,25 +1374,16 @@ fn main() {
|
|||||||
if &chip_name[..8] == "stm32wba" {
|
if &chip_name[..8] == "stm32wba" {
|
||||||
println!("cargo:rustc-cfg={}", &chip_name[..8]); // stm32wba
|
println!("cargo:rustc-cfg={}", &chip_name[..8]); // stm32wba
|
||||||
println!("cargo:rustc-cfg={}", &chip_name[..10]); // stm32wba52
|
println!("cargo:rustc-cfg={}", &chip_name[..10]); // stm32wba52
|
||||||
println!("cargo:rustc-cfg=package_{}", &chip_name[10..11]);
|
|
||||||
println!("cargo:rustc-cfg=flashsize_{}", &chip_name[11..12]);
|
|
||||||
} else {
|
} else {
|
||||||
println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4
|
println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4
|
||||||
println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429
|
println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429
|
||||||
println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x
|
println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x
|
||||||
println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9
|
println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9
|
||||||
println!("cargo:rustc-cfg=package_{}", &chip_name[9..10]);
|
|
||||||
println!("cargo:rustc-cfg=flashsize_{}", &chip_name[10..11]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the L4+ chips as they have many differences to regular L4.
|
// Handle time-driver-XXXX features.
|
||||||
if &chip_name[..7] == "stm32l4" {
|
if env::var("CARGO_FEATURE_TIME_DRIVER_ANY").is_ok() {}
|
||||||
if "pqrs".contains(&chip_name[7..8]) {
|
println!("cargo:rustc-cfg={}", &chip_name[..chip_name.len() - 2]);
|
||||||
println!("cargo:rustc-cfg=stm32l4_plus");
|
|
||||||
} else {
|
|
||||||
println!("cargo:rustc-cfg=stm32l4_nonplus");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use core::cell::{RefCell, RefMut};
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
@ -83,7 +84,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Can<'d, T: Instance> {
|
pub struct Can<'d, T: Instance> {
|
||||||
pub can: bxcan::Can<BxcanInstance<'d, T>>,
|
pub can: RefCell<bxcan::Can<BxcanInstance<'d, T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -174,12 +175,17 @@ impl<'d, T: Instance> Can<'d, T> {
|
|||||||
tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
|
tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
|
||||||
|
|
||||||
let can = bxcan::Can::builder(BxcanInstance(peri)).leave_disabled();
|
let can = bxcan::Can::builder(BxcanInstance(peri)).leave_disabled();
|
||||||
Self { can }
|
let can_ref_cell = RefCell::new(can);
|
||||||
|
Self { can: can_ref_cell }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bitrate(&mut self, bitrate: u32) {
|
pub fn set_bitrate(&mut self, bitrate: u32) {
|
||||||
let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap();
|
let bit_timing = Self::calc_bxcan_timings(T::frequency(), bitrate).unwrap();
|
||||||
self.can.modify_config().set_bit_timing(bit_timing).leave_disabled();
|
self.can
|
||||||
|
.borrow_mut()
|
||||||
|
.modify_config()
|
||||||
|
.set_bit_timing(bit_timing)
|
||||||
|
.leave_disabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables the peripheral and synchronizes with the bus.
|
/// Enables the peripheral and synchronizes with the bus.
|
||||||
@ -187,7 +193,7 @@ impl<'d, T: Instance> Can<'d, T> {
|
|||||||
/// This will wait for 11 consecutive recessive bits (bus idle state).
|
/// This will wait for 11 consecutive recessive bits (bus idle state).
|
||||||
/// Contrary to enable method from bxcan library, this will not freeze the executor while waiting.
|
/// Contrary to enable method from bxcan library, this will not freeze the executor while waiting.
|
||||||
pub async fn enable(&mut self) {
|
pub async fn enable(&mut self) {
|
||||||
while self.enable_non_blocking().is_err() {
|
while self.borrow_mut().enable_non_blocking().is_err() {
|
||||||
// SCE interrupt is only generated for entering sleep mode, but not leaving.
|
// SCE interrupt is only generated for entering sleep mode, but not leaving.
|
||||||
// Yield to allow other tasks to execute while can bus is initializing.
|
// Yield to allow other tasks to execute while can bus is initializing.
|
||||||
embassy_futures::yield_now().await;
|
embassy_futures::yield_now().await;
|
||||||
@ -196,46 +202,46 @@ impl<'d, T: Instance> Can<'d, T> {
|
|||||||
|
|
||||||
/// Queues the message to be sent but exerts backpressure
|
/// Queues the message to be sent but exerts backpressure
|
||||||
pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
|
pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
|
||||||
self.split().0.write(frame).await
|
CanTx { can: &self.can }.write(frame).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to transmit a frame without blocking.
|
/// Attempts to transmit a frame without blocking.
|
||||||
///
|
///
|
||||||
/// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full.
|
/// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full.
|
||||||
pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> {
|
pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> {
|
||||||
self.split().0.try_write(frame)
|
CanTx { can: &self.can }.try_write(frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits for a specific transmit mailbox to become empty
|
/// Waits for a specific transmit mailbox to become empty
|
||||||
pub async fn flush(&self, mb: bxcan::Mailbox) {
|
pub async fn flush(&self, mb: bxcan::Mailbox) {
|
||||||
CanTx::<T>::flush_inner(mb).await
|
CanTx { can: &self.can }.flush(mb).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits until any of the transmit mailboxes become empty
|
/// Waits until any of the transmit mailboxes become empty
|
||||||
pub async fn flush_any(&self) {
|
pub async fn flush_any(&self) {
|
||||||
CanTx::<T>::flush_any_inner().await
|
CanTx { can: &self.can }.flush_any().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits until all of the transmit mailboxes become empty
|
/// Waits until all of the transmit mailboxes become empty
|
||||||
pub async fn flush_all(&self) {
|
pub async fn flush_all(&self) {
|
||||||
CanTx::<T>::flush_all_inner().await
|
CanTx { can: &self.can }.flush_all().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a tuple of the time the message was received and the message frame
|
/// Returns a tuple of the time the message was received and the message frame
|
||||||
pub async fn read(&mut self) -> Result<Envelope, BusError> {
|
pub async fn read(&mut self) -> Result<Envelope, BusError> {
|
||||||
self.split().1.read().await
|
CanRx { can: &self.can }.read().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to read a can frame without blocking.
|
/// Attempts to read a can frame without blocking.
|
||||||
///
|
///
|
||||||
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
||||||
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
||||||
self.split().1.try_read()
|
CanRx { can: &self.can }.try_read()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits while receive queue is empty.
|
/// Waits while receive queue is empty.
|
||||||
pub async fn wait_not_empty(&mut self) {
|
pub async fn wait_not_empty(&mut self) {
|
||||||
self.split().1.wait_not_empty().await
|
CanRx { can: &self.can }.wait_not_empty().await
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn receive_fifo(fifo: RxFifo) {
|
unsafe fn receive_fifo(fifo: RxFifo) {
|
||||||
@ -379,25 +385,24 @@ impl<'d, T: Instance> Can<'d, T> {
|
|||||||
Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler - 1))
|
Some((sjw - 1) << 24 | (bs1 as u32 - 1) << 16 | (bs2 as u32 - 1) << 20 | (prescaler - 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split<'c>(&'c mut self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) {
|
pub fn split<'c>(&'c self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) {
|
||||||
let (tx, rx0, rx1) = self.can.split_by_ref();
|
(CanTx { can: &self.can }, CanRx { can: &self.can })
|
||||||
(CanTx { tx }, CanRx { rx0, rx1 })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_mut(&mut self) -> &mut bxcan::Can<BxcanInstance<'d, T>> {
|
pub fn as_mut(&self) -> RefMut<'_, bxcan::Can<BxcanInstance<'d, T>>> {
|
||||||
&mut self.can
|
self.can.borrow_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CanTx<'c, 'd, T: Instance> {
|
pub struct CanTx<'c, 'd, T: Instance> {
|
||||||
tx: &'c mut bxcan::Tx<BxcanInstance<'d, T>>,
|
can: &'c RefCell<bxcan::Can<BxcanInstance<'d, T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
|
impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
|
||||||
pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
|
pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
T::state().tx_waker.register(cx.waker());
|
T::state().tx_waker.register(cx.waker());
|
||||||
if let Ok(status) = self.tx.transmit(frame) {
|
if let Ok(status) = self.can.borrow_mut().transmit(frame) {
|
||||||
return Poll::Ready(status);
|
return Poll::Ready(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,10 +415,11 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
|
|||||||
///
|
///
|
||||||
/// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full.
|
/// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full.
|
||||||
pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> {
|
pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> {
|
||||||
self.tx.transmit(frame).map_err(|_| TryWriteError::Full)
|
self.can.borrow_mut().transmit(frame).map_err(|_| TryWriteError::Full)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn flush_inner(mb: bxcan::Mailbox) {
|
/// Waits for a specific transmit mailbox to become empty
|
||||||
|
pub async fn flush(&self, mb: bxcan::Mailbox) {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
T::state().tx_waker.register(cx.waker());
|
T::state().tx_waker.register(cx.waker());
|
||||||
if T::regs().tsr().read().tme(mb.index()) {
|
if T::regs().tsr().read().tme(mb.index()) {
|
||||||
@ -425,12 +431,8 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits for a specific transmit mailbox to become empty
|
/// Waits until any of the transmit mailboxes become empty
|
||||||
pub async fn flush(&self, mb: bxcan::Mailbox) {
|
pub async fn flush_any(&self) {
|
||||||
Self::flush_inner(mb).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn flush_any_inner() {
|
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
T::state().tx_waker.register(cx.waker());
|
T::state().tx_waker.register(cx.waker());
|
||||||
|
|
||||||
@ -447,12 +449,8 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits until any of the transmit mailboxes become empty
|
/// Waits until all of the transmit mailboxes become empty
|
||||||
pub async fn flush_any(&self) {
|
pub async fn flush_all(&self) {
|
||||||
Self::flush_any_inner().await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn flush_all_inner() {
|
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
T::state().tx_waker.register(cx.waker());
|
T::state().tx_waker.register(cx.waker());
|
||||||
|
|
||||||
@ -468,17 +466,11 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
|
|||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits until all of the transmit mailboxes become empty
|
|
||||||
pub async fn flush_all(&self) {
|
|
||||||
Self::flush_all_inner().await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct CanRx<'c, 'd, T: Instance> {
|
pub struct CanRx<'c, 'd, T: Instance> {
|
||||||
rx0: &'c mut bxcan::Rx0<BxcanInstance<'d, T>>,
|
can: &'c RefCell<bxcan::Can<BxcanInstance<'d, T>>>,
|
||||||
rx1: &'c mut bxcan::Rx1<BxcanInstance<'d, T>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> {
|
impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> {
|
||||||
@ -546,7 +538,7 @@ impl<'d, T: Instance> Drop for Can<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Deref for Can<'d, T> {
|
impl<'d, T: Instance> Deref for Can<'d, T> {
|
||||||
type Target = bxcan::Can<BxcanInstance<'d, T>>;
|
type Target = RefCell<bxcan::Can<BxcanInstance<'d, T>>>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.can
|
&self.can
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user