aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rwxr-xr-xci.sh19
-rw-r--r--cyw43-pio/Cargo.toml2
-rw-r--r--cyw43/Cargo.toml2
-rw-r--r--docs/examples/basic/Cargo.toml6
-rw-r--r--docs/examples/layer-by-layer/blinky-async/Cargo.toml6
-rw-r--r--docs/examples/layer-by-layer/blinky-hal/Cargo.toml6
-rw-r--r--docs/examples/layer-by-layer/blinky-irq/Cargo.toml6
-rw-r--r--docs/examples/layer-by-layer/blinky-pac/Cargo.toml6
-rw-r--r--docs/pages/imxrt.adoc5
-rw-r--r--embassy-boot-nrf/Cargo.toml2
-rw-r--r--embassy-boot-rp/Cargo.toml2
-rw-r--r--embassy-boot-stm32/Cargo.toml2
-rw-r--r--embassy-boot/Cargo.toml2
-rw-r--r--embassy-embedded-hal/Cargo.toml2
-rw-r--r--embassy-executor/Cargo.toml2
-rw-r--r--embassy-executor/src/raw/mod.rs20
-rw-r--r--embassy-executor/src/raw/trace.rs183
-rw-r--r--embassy-executor/src/spawner.rs53
-rw-r--r--embassy-futures/Cargo.toml2
-rw-r--r--embassy-hal-internal/Cargo.toml2
-rw-r--r--embassy-hal-internal/src/macros.rs2
-rw-r--r--embassy-hal-internal/src/peripheral.rs2
-rw-r--r--embassy-imxrt/Cargo.toml6
-rw-r--r--embassy-imxrt/src/crc.rs190
-rw-r--r--embassy-imxrt/src/dma.rs418
-rw-r--r--embassy-imxrt/src/flexcomm/mod.rs252
-rw-r--r--embassy-imxrt/src/flexcomm/uart.rs1230
-rw-r--r--embassy-imxrt/src/gpio.rs20
-rw-r--r--embassy-imxrt/src/lib.rs40
-rw-r--r--embassy-imxrt/src/rng.rs287
-rw-r--r--embassy-mspm0/Cargo.toml142
-rw-r--r--embassy-mspm0/README.md28
-rw-r--r--embassy-mspm0/build.rs91
-rw-r--r--embassy-mspm0/src/gpio.rs4
-rw-r--r--embassy-mspm0/src/int_group/g110x.rs47
-rw-r--r--embassy-mspm0/src/int_group/g150x.rs51
-rw-r--r--embassy-mspm0/src/int_group/g151x.rs52
-rw-r--r--embassy-mspm0/src/int_group/g310x.rs48
-rw-r--r--embassy-mspm0/src/int_group/l11xx.rs25
-rw-r--r--embassy-mspm0/src/int_group/l12xx.rs49
-rw-r--r--embassy-mspm0/src/int_group/l13xx.rs (renamed from embassy-mspm0/src/int_group/l130x.rs)0
-rw-r--r--embassy-mspm0/src/lib.rs23
-rw-r--r--embassy-net-adin1110/Cargo.toml4
-rw-r--r--embassy-net-driver-channel/Cargo.toml2
-rw-r--r--embassy-net-driver/Cargo.toml2
-rw-r--r--embassy-net-enc28j60/Cargo.toml2
-rw-r--r--embassy-net-esp-hosted/Cargo.toml6
-rw-r--r--embassy-net-nrf91/Cargo.toml12
-rw-r--r--embassy-net-ppp/Cargo.toml2
-rw-r--r--embassy-net-wiznet/Cargo.toml2
-rw-r--r--embassy-net/Cargo.toml2
-rw-r--r--embassy-nrf/Cargo.toml6
-rw-r--r--embassy-nrf/src/chips/nrf5340_app.rs5
-rw-r--r--embassy-nrf/src/chips/nrf5340_net.rs5
-rw-r--r--embassy-nrf/src/ipc.rs363
-rw-r--r--embassy-nrf/src/lib.rs18
-rw-r--r--embassy-nrf/src/rng.rs47
-rw-r--r--embassy-nxp/Cargo.toml7
-rw-r--r--embassy-rp/Cargo.toml11
-rw-r--r--embassy-rp/src/adc.rs2
-rw-r--r--embassy-rp/src/clocks.rs293
-rw-r--r--embassy-rp/src/gpio.rs2
-rw-r--r--embassy-rp/src/lib.rs12
-rw-r--r--embassy-rp/src/pio_programs/i2s.rs18
-rw-r--r--embassy-rp/src/pwm.rs8
-rw-r--r--embassy-rp/src/trng.rs25
-rw-r--r--embassy-stm32-wpan/Cargo.toml2
-rw-r--r--embassy-stm32/Cargo.toml16
-rw-r--r--embassy-stm32/src/adc/g4.rs4
-rw-r--r--embassy-stm32/src/adc/v3.rs4
-rw-r--r--embassy-stm32/src/adc/v4.rs4
-rw-r--r--embassy-stm32/src/lib.rs30
-rw-r--r--embassy-stm32/src/rcc/mod.rs29
-rw-r--r--embassy-stm32/src/rng.rs55
-rw-r--r--embassy-sync/Cargo.toml2
-rw-r--r--embassy-time/Cargo.toml2
-rw-r--r--embassy-usb-dfu/Cargo.toml2
-rw-r--r--embassy-usb-dfu/src/application.rs8
-rw-r--r--embassy-usb-dfu/src/dfu.rs8
-rw-r--r--embassy-usb-driver/Cargo.toml2
-rw-r--r--embassy-usb-synopsys-otg/Cargo.toml2
-rw-r--r--embassy-usb/Cargo.toml4
-rw-r--r--examples/boot/application/nrf/Cargo.toml4
-rw-r--r--examples/boot/application/rp/Cargo.toml6
-rw-r--r--examples/boot/application/stm32f3/Cargo.toml4
-rw-r--r--examples/boot/application/stm32f7/Cargo.toml4
-rw-r--r--examples/boot/application/stm32h7/Cargo.toml4
-rw-r--r--examples/boot/application/stm32l0/Cargo.toml4
-rw-r--r--examples/boot/application/stm32l1/Cargo.toml4
-rw-r--r--examples/boot/application/stm32l4/Cargo.toml4
-rw-r--r--examples/boot/application/stm32wb-dfu/Cargo.toml4
-rw-r--r--examples/boot/application/stm32wb-dfu/src/main.rs30
-rw-r--r--examples/boot/application/stm32wl/Cargo.toml4
-rw-r--r--examples/boot/bootloader/nrf/Cargo.toml4
-rw-r--r--examples/boot/bootloader/rp/Cargo.toml4
-rw-r--r--examples/boot/bootloader/stm32-dual-bank/Cargo.toml4
-rw-r--r--examples/boot/bootloader/stm32/Cargo.toml4
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/Cargo.toml4
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/src/main.rs17
-rw-r--r--examples/lpc55s69/Cargo.toml8
-rw-r--r--examples/mimxrt6/Cargo.toml7
-rw-r--r--examples/mimxrt6/src/bin/crc.rs175
-rw-r--r--examples/mimxrt6/src/bin/rng.rs39
-rw-r--r--examples/mimxrt6/src/bin/uart-async.rs87
-rw-r--r--examples/mimxrt6/src/bin/uart.rs55
-rw-r--r--examples/mspm0c1104/Cargo.toml10
-rw-r--r--examples/mspm0c1104/README.md4
-rw-r--r--examples/mspm0g3507/Cargo.toml10
-rw-r--r--examples/mspm0g3507/README.md4
-rw-r--r--examples/mspm0g3519/Cargo.toml10
-rw-r--r--examples/mspm0g3519/README.md4
-rw-r--r--examples/mspm0l1306/Cargo.toml10
-rw-r--r--examples/mspm0l1306/README.md4
-rw-r--r--examples/mspm0l2228/Cargo.toml10
-rw-r--r--examples/mspm0l2228/README.md4
-rw-r--r--examples/nrf-rtos-trace/Cargo.toml3
-rw-r--r--examples/nrf51/Cargo.toml6
-rw-r--r--examples/nrf52810/Cargo.toml6
-rw-r--r--examples/nrf52840-rtic/Cargo.toml6
-rw-r--r--examples/nrf52840/Cargo.toml8
-rwxr-xr-x[-rw-r--r--]examples/nrf52840/src/bin/rng.rs2
-rw-r--r--examples/nrf5340/Cargo.toml7
-rw-r--r--examples/nrf54l15/Cargo.toml6
-rw-r--r--examples/nrf9151/ns/Cargo.toml6
-rw-r--r--examples/nrf9151/s/Cargo.toml6
-rw-r--r--examples/nrf9160/Cargo.toml6
-rw-r--r--examples/rp/Cargo.toml9
-rw-r--r--examples/rp/src/bin/adc.rs9
-rw-r--r--examples/rp/src/bin/ethernet_w5500_icmp.rs1
-rw-r--r--examples/rp/src/bin/ethernet_w5500_icmp_ping.rs1
-rw-r--r--examples/rp/src/bin/ethernet_w5500_multisocket.rs1
-rw-r--r--examples/rp/src/bin/ethernet_w5500_tcp_client.rs1
-rw-r--r--examples/rp/src/bin/ethernet_w5500_tcp_server.rs1
-rw-r--r--examples/rp/src/bin/ethernet_w5500_udp.rs1
-rw-r--r--examples/rp/src/bin/orchestrate_tasks.rs1
-rw-r--r--examples/rp/src/bin/overclock.rs10
-rw-r--r--examples/rp/src/bin/overclock_manual.rs10
-rw-r--r--examples/rp/src/bin/pio_i2s.rs2
-rw-r--r--examples/rp/src/bin/sharing.rs1
-rw-r--r--examples/rp/src/bin/spi_gc9a01.rs1
-rw-r--r--examples/rp/src/bin/usb_ethernet.rs1
-rwxr-xr-x[-rw-r--r--]examples/rp/src/bin/usb_hid_mouse.rs4
-rw-r--r--examples/rp/src/bin/wifi_ap_tcp_server.rs1
-rw-r--r--examples/rp/src/bin/wifi_tcp_server.rs1
-rw-r--r--examples/rp/src/bin/wifi_webrequest.rs1
-rw-r--r--examples/rp235x/Cargo.toml7
-rw-r--r--examples/rp235x/src/bin/overclock.rs74
-rw-r--r--examples/rp235x/src/bin/pio_i2s.rs2
-rw-r--r--examples/rp235x/src/bin/sharing.rs1
-rw-r--r--examples/rp235x/src/bin/trng.rs5
-rw-r--r--examples/std/Cargo.toml2
-rw-r--r--examples/std/src/bin/net.rs4
-rw-r--r--examples/std/src/bin/net_dns.rs4
-rw-r--r--examples/std/src/bin/net_ppp.rs4
-rw-r--r--examples/std/src/bin/net_udp.rs4
-rw-r--r--examples/std/src/bin/tcp_accept.rs4
-rw-r--r--examples/stm32c0/Cargo.toml6
-rw-r--r--examples/stm32f0/Cargo.toml6
-rw-r--r--examples/stm32f1/Cargo.toml6
-rw-r--r--examples/stm32f2/Cargo.toml6
-rw-r--r--examples/stm32f3/Cargo.toml6
-rw-r--r--examples/stm32f334/Cargo.toml6
-rw-r--r--examples/stm32f4/Cargo.toml6
-rw-r--r--examples/stm32f469/Cargo.toml6
-rw-r--r--examples/stm32f7/Cargo.toml7
-rw-r--r--examples/stm32f7/src/bin/eth.rs1
-rw-r--r--examples/stm32g0/Cargo.toml6
-rw-r--r--examples/stm32g4/Cargo.toml6
-rw-r--r--examples/stm32h5/Cargo.toml7
-rw-r--r--examples/stm32h5/src/bin/eth.rs1
-rw-r--r--examples/stm32h7/Cargo.toml7
-rw-r--r--examples/stm32h7/src/bin/eth.rs1
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs1
-rw-r--r--examples/stm32h7/src/bin/eth_client_mii.rs1
-rw-r--r--examples/stm32h723/Cargo.toml7
-rw-r--r--examples/stm32h735/Cargo.toml6
-rw-r--r--examples/stm32h742/Cargo.toml7
-rw-r--r--examples/stm32h755cm4/Cargo.toml1
-rw-r--r--examples/stm32h755cm7/Cargo.toml1
-rw-r--r--examples/stm32h7b0/Cargo.toml7
-rw-r--r--examples/stm32h7rs/Cargo.toml7
-rw-r--r--examples/stm32h7rs/src/bin/eth.rs1
-rw-r--r--examples/stm32l0/Cargo.toml6
-rw-r--r--examples/stm32l1/Cargo.toml6
-rw-r--r--examples/stm32l4/Cargo.toml7
-rw-r--r--examples/stm32l4/src/bin/spe_adin1110_http_server.rs1
-rw-r--r--examples/stm32l432/Cargo.toml6
-rw-r--r--examples/stm32l5/Cargo.toml7
-rw-r--r--examples/stm32l5/src/bin/usb_ethernet.rs1
-rw-r--r--examples/stm32u0/Cargo.toml6
-rw-r--r--examples/stm32u5/Cargo.toml6
-rw-r--r--examples/stm32wb/Cargo.toml10
-rw-r--r--examples/stm32wba/Cargo.toml10
-rw-r--r--examples/stm32wl/Cargo.toml6
-rw-r--r--rustfmt.toml2
-rw-r--r--tests/mspm0/Cargo.toml4
-rw-r--r--tests/nrf/Cargo.toml6
-rw-r--r--tests/perf-client/Cargo.toml2
-rw-r--r--tests/rp/Cargo.toml7
-rw-r--r--tests/rp/src/bin/ethernet_w5100s_perf.rs1
-rw-r--r--tests/rp/src/bin/overclock.rs49
-rw-r--r--tests/stm32/Cargo.toml10
-rw-r--r--tests/stm32/src/bin/eth.rs1
-rw-r--r--tests/utils/Cargo.toml2
205 files changed, 4872 insertions, 558 deletions
diff --git a/README.md b/README.md
index 669fa469b..68d8460d3 100644
--- a/README.md
+++ b/README.md
@@ -12,8 +12,8 @@ Rust's [async/await](https://rust-lang.github.io/async-book/) allows for unprece
12 12
13## Batteries included 13## Batteries included
14 14
15- **Hardware Abstraction Layers 15- **Hardware Abstraction Layers**
16 ** - HALs implement safe, idiomatic Rust APIs to use the hardware capabilities, so raw register manipulation is not needed. The Embassy project maintains HALs for select hardware, but you can still use HALs from other projects with Embassy. 16 - HALs implement safe, idiomatic Rust APIs to use the hardware capabilities, so raw register manipulation is not needed. The Embassy project maintains HALs for select hardware, but you can still use HALs from other projects with Embassy.
17 - [embassy-stm32](https://docs.embassy.dev/embassy-stm32/), for all STM32 microcontroller families. 17 - [embassy-stm32](https://docs.embassy.dev/embassy-stm32/), for all STM32 microcontroller families.
18 - [embassy-nrf](https://docs.embassy.dev/embassy-nrf/), for the Nordic Semiconductor nRF52, nRF53, nRF54 and nRF91 series. 18 - [embassy-nrf](https://docs.embassy.dev/embassy-nrf/), for the Nordic Semiconductor nRF52, nRF53, nRF54 and nRF91 series.
19 - [embassy-rp](https://docs.embassy.dev/embassy-rp/), for the Raspberry Pi RP2040 and RP23xx microcontrollers. 19 - [embassy-rp](https://docs.embassy.dev/embassy-rp/), for the Raspberry Pi RP2040 and RP23xx microcontrollers.
diff --git a/ci.sh b/ci.sh
index 6e320e4d1..2be84ef6b 100755
--- a/ci.sh
+++ b/ci.sh
@@ -19,7 +19,7 @@ fi
19TARGET=$(rustc -vV | sed -n 's|host: ||p') 19TARGET=$(rustc -vV | sed -n 's|host: ||p')
20 20
21BUILD_EXTRA="" 21BUILD_EXTRA=""
22if [ $TARGET = "x86_64-unknown-linux-gnu" ]; then 22if [ $TARGET = "x86_64-unknown-linux-gnu" ] || [ $TARGET = "aarch64-unknown-linux-gnu" ]; then
23 BUILD_EXTRA="--- build --release --manifest-path examples/std/Cargo.toml --target $TARGET --artifact-dir out/examples/std" 23 BUILD_EXTRA="--- build --release --manifest-path examples/std/Cargo.toml --target $TARGET --artifact-dir out/examples/std"
24fi 24fi
25 25
@@ -174,11 +174,18 @@ cargo batch \
174 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \ 174 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \
175 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \ 175 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \
176 --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv8m.main-none-eabihf \ 176 --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv8m.main-none-eabihf \
177 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0c110x,defmt,time-driver-any \ 177 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0c1104dgs20,defmt,time-driver-any \
178 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g350x,defmt,time-driver-any \ 178 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3507pm,defmt,time-driver-any \
179 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g351x,defmt,time-driver-any \ 179 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3519pz,defmt,time-driver-any \
180 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l130x,defmt,time-driver-any \ 180 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1306rhb,defmt,time-driver-any \
181 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l222x,defmt,time-driver-any \ 181 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l2228pn,defmt,time-driver-any \
182 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1345dgs28,defmt,time-driver-any \
183 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1106dgs28,defmt,time-driver-any \
184 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1228pm,defmt,time-driver-any \
185 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g1107ycj,defmt,time-driver-any \
186 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3105rhb,defmt,time-driver-any \
187 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g1505pt,defmt,time-driver-any \
188 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g1519rhb,defmt,time-driver-any \
182 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ 189 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\
183 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ 190 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \
184 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ 191 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \
diff --git a/cyw43-pio/Cargo.toml b/cyw43-pio/Cargo.toml
index 600caf5ed..93a2e7089 100644
--- a/cyw43-pio/Cargo.toml
+++ b/cyw43-pio/Cargo.toml
@@ -13,7 +13,7 @@ documentation = "https://docs.embassy.dev/cyw43-pio"
13cyw43 = { version = "0.3.0", path = "../cyw43" } 13cyw43 = { version = "0.3.0", path = "../cyw43" }
14embassy-rp = { version = "0.4.0", path = "../embassy-rp" } 14embassy-rp = { version = "0.4.0", path = "../embassy-rp" }
15fixed = "1.23.1" 15fixed = "1.23.1"
16defmt = { version = "0.3", optional = true } 16defmt = { version = "1.0.1", optional = true }
17 17
18[package.metadata.embassy_docs] 18[package.metadata.embassy_docs]
19src_base = "https://github.com/embassy-rs/embassy/blob/cyw43-pio-v$VERSION/cyw43-pio/src/" 19src_base = "https://github.com/embassy-rs/embassy/blob/cyw43-pio-v$VERSION/cyw43-pio/src/"
diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml
index 88d1fe506..4b58ee9c9 100644
--- a/cyw43/Cargo.toml
+++ b/cyw43/Cargo.toml
@@ -23,7 +23,7 @@ embassy-sync = { version = "0.6.2", path = "../embassy-sync"}
23embassy-futures = { version = "0.1.0", path = "../embassy-futures"} 23embassy-futures = { version = "0.1.0", path = "../embassy-futures"}
24embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel"} 24embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel"}
25 25
26defmt = { version = "0.3", optional = true } 26defmt = { version = "1.0.1", optional = true }
27log = { version = "0.4.17", optional = true } 27log = { version = "0.4.17", optional = true }
28 28
29cortex-m = "0.7.6" 29cortex-m = "0.7.6"
diff --git a/docs/examples/basic/Cargo.toml b/docs/examples/basic/Cargo.toml
index 705c334a7..f5cf2b231 100644
--- a/docs/examples/basic/Cargo.toml
+++ b/docs/examples/basic/Cargo.toml
@@ -10,9 +10,9 @@ embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", feat
10embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt"] } 10embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt"] }
11embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } 11embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] }
12 12
13defmt = "0.3" 13defmt = "1.0.1"
14defmt-rtt = "0.3" 14defmt-rtt = "1.0.0"
15 15
16cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 16cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
17cortex-m-rt = "0.7.0" 17cortex-m-rt = "0.7.0"
18panic-probe = { version = "0.3", features = ["print-defmt"] } 18panic-probe = { version = "1.0.0", features = ["print-defmt"] }
diff --git a/docs/examples/layer-by-layer/blinky-async/Cargo.toml b/docs/examples/layer-by-layer/blinky-async/Cargo.toml
index 541eb6edf..2a6741b33 100644
--- a/docs/examples/layer-by-layer/blinky-async/Cargo.toml
+++ b/docs/examples/layer-by-layer/blinky-async/Cargo.toml
@@ -10,6 +10,6 @@ cortex-m-rt = "0.7"
10embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x", "exti"] } 10embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x", "exti"] }
11embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } 11embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
12 12
13defmt = "0.3" 13defmt = "1.0.1"
14defmt-rtt = "0.4" 14defmt-rtt = "1.0.0"
15panic-probe = { version = "0.3.0", features = ["print-defmt"] } 15panic-probe = { version = "1.0.0", features = ["print-defmt"] }
diff --git a/docs/examples/layer-by-layer/blinky-hal/Cargo.toml b/docs/examples/layer-by-layer/blinky-hal/Cargo.toml
index dd574c3e7..9a261f804 100644
--- a/docs/examples/layer-by-layer/blinky-hal/Cargo.toml
+++ b/docs/examples/layer-by-layer/blinky-hal/Cargo.toml
@@ -9,6 +9,6 @@ cortex-m-rt = "0.7"
9cortex-m = { version = "0.7", features = ["critical-section-single-core"] } 9cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
10embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x"] } 10embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x"] }
11 11
12defmt = "0.3" 12defmt = "1.0.1"
13defmt-rtt = "0.4" 13defmt-rtt = "1.0.0"
14panic-probe = { version = "0.3.0", features = ["print-defmt"] } 14panic-probe = { version = "1.0.0", features = ["print-defmt"] }
diff --git a/docs/examples/layer-by-layer/blinky-irq/Cargo.toml b/docs/examples/layer-by-layer/blinky-irq/Cargo.toml
index 8733ee894..c3ec9ad1a 100644
--- a/docs/examples/layer-by-layer/blinky-irq/Cargo.toml
+++ b/docs/examples/layer-by-layer/blinky-irq/Cargo.toml
@@ -11,6 +11,6 @@ cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
11cortex-m-rt = { version = "0.7" } 11cortex-m-rt = { version = "0.7" }
12embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x", "unstable-pac"] } 12embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x", "unstable-pac"] }
13 13
14defmt = "0.3" 14defmt = "1.0.1"
15defmt-rtt = "0.4" 15defmt-rtt = "1.0.0"
16panic-probe = { version = "0.3.0", features = ["print-defmt"] } 16panic-probe = { version = "1.0.0", features = ["print-defmt"] }
diff --git a/docs/examples/layer-by-layer/blinky-pac/Cargo.toml b/docs/examples/layer-by-layer/blinky-pac/Cargo.toml
index 155c41ec6..4e7e2f2ff 100644
--- a/docs/examples/layer-by-layer/blinky-pac/Cargo.toml
+++ b/docs/examples/layer-by-layer/blinky-pac/Cargo.toml
@@ -9,6 +9,6 @@ cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
9cortex-m-rt = "0.7" 9cortex-m-rt = "0.7"
10stm32-metapac = { version = "16", features = ["stm32l475vg"] } 10stm32-metapac = { version = "16", features = ["stm32l475vg"] }
11 11
12defmt = "0.3" 12defmt = "1.0.1"
13defmt-rtt = "0.4" 13defmt-rtt = "1.0.0"
14panic-probe = { version = "0.3.0", features = ["print-defmt"] } 14panic-probe = { version = "1.0.0", features = ["print-defmt"] }
diff --git a/docs/pages/imxrt.adoc b/docs/pages/imxrt.adoc
index adf5218e8..87867e1e0 100644
--- a/docs/pages/imxrt.adoc
+++ b/docs/pages/imxrt.adoc
@@ -9,5 +9,8 @@ The link: link:https://github.com/embassy-rs/embassy/tree/main/embassy-imxrt[Emb
9 9
10The following peripherals have a HAL implementation at present 10The following peripherals have a HAL implementation at present
11 11
12* CRC
13* DMA
12* GPIO 14* GPIO
13 15* RNG
16* UART
diff --git a/embassy-boot-nrf/Cargo.toml b/embassy-boot-nrf/Cargo.toml
index c3e0cb5ec..7d3e04419 100644
--- a/embassy-boot-nrf/Cargo.toml
+++ b/embassy-boot-nrf/Cargo.toml
@@ -21,7 +21,7 @@ target = "thumbv7em-none-eabi"
21[lib] 21[lib]
22 22
23[dependencies] 23[dependencies]
24defmt = { version = "0.3", optional = true } 24defmt = { version = "1.0.1", optional = true }
25log = { version = "0.4.17", optional = true } 25log = { version = "0.4.17", optional = true }
26 26
27embassy-sync = { version = "0.6.2", path = "../embassy-sync" } 27embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
diff --git a/embassy-boot-rp/Cargo.toml b/embassy-boot-rp/Cargo.toml
index 284ac654c..10eec774f 100644
--- a/embassy-boot-rp/Cargo.toml
+++ b/embassy-boot-rp/Cargo.toml
@@ -21,7 +21,7 @@ features = ["embassy-rp/rp2040"]
21[lib] 21[lib]
22 22
23[dependencies] 23[dependencies]
24defmt = { version = "0.3", optional = true } 24defmt = { version = "1.0.1", optional = true }
25log = { version = "0.4", optional = true } 25log = { version = "0.4", optional = true }
26 26
27embassy-sync = { version = "0.6.2", path = "../embassy-sync" } 27embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
diff --git a/embassy-boot-stm32/Cargo.toml b/embassy-boot-stm32/Cargo.toml
index 7dbe7e22b..2b741cc95 100644
--- a/embassy-boot-stm32/Cargo.toml
+++ b/embassy-boot-stm32/Cargo.toml
@@ -21,7 +21,7 @@ target = "thumbv7em-none-eabi"
21[lib] 21[lib]
22 22
23[dependencies] 23[dependencies]
24defmt = { version = "0.3", optional = true } 24defmt = { version = "1.0.1", optional = true }
25log = { version = "0.4", optional = true } 25log = { version = "0.4", optional = true }
26 26
27embassy-sync = { version = "0.6.2", path = "../embassy-sync" } 27embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
diff --git a/embassy-boot/Cargo.toml b/embassy-boot/Cargo.toml
index 4906da0ea..8889f1a20 100644
--- a/embassy-boot/Cargo.toml
+++ b/embassy-boot/Cargo.toml
@@ -24,7 +24,7 @@ features = ["defmt"]
24[lib] 24[lib]
25 25
26[dependencies] 26[dependencies]
27defmt = { version = "0.3", optional = true } 27defmt = { version = "1.0.1", optional = true }
28digest = "0.10" 28digest = "0.10"
29log = { version = "0.4", optional = true } 29log = { version = "0.4", optional = true }
30ed25519-dalek = { version = "2", default-features = false, features = ["digest"], optional = true } 30ed25519-dalek = { version = "2", default-features = false, features = ["digest"], optional = true }
diff --git a/embassy-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml
index f385963f1..f7a973a8d 100644
--- a/embassy-embedded-hal/Cargo.toml
+++ b/embassy-embedded-hal/Cargo.toml
@@ -35,7 +35,7 @@ embedded-storage = "0.3.1"
35embedded-storage-async = { version = "0.4.1" } 35embedded-storage-async = { version = "0.4.1" }
36nb = "1.0.0" 36nb = "1.0.0"
37 37
38defmt = { version = "0.3", optional = true } 38defmt = { version = "1.0.1", optional = true }
39 39
40[dev-dependencies] 40[dev-dependencies]
41critical-section = { version = "1.1.1", features = ["std"] } 41critical-section = { version = "1.1.1", features = ["std"] }
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml
index 0f69d3c8a..9f9eaa600 100644
--- a/embassy-executor/Cargo.toml
+++ b/embassy-executor/Cargo.toml
@@ -29,7 +29,7 @@ targets = ["thumbv7em-none-eabi"]
29features = ["defmt", "arch-cortex-m", "executor-thread", "executor-interrupt"] 29features = ["defmt", "arch-cortex-m", "executor-thread", "executor-interrupt"]
30 30
31[dependencies] 31[dependencies]
32defmt = { version = "0.3", optional = true } 32defmt = { version = "1.0.1", optional = true }
33log = { version = "0.4.14", optional = true } 33log = { version = "0.4.14", optional = true }
34rtos-trace = { version = "0.1.3", optional = true } 34rtos-trace = { version = "0.1.3", optional = true }
35 35
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs
index 88d839e07..e7a27035a 100644
--- a/embassy-executor/src/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -18,7 +18,7 @@ mod state;
18 18
19pub mod timer_queue; 19pub mod timer_queue;
20#[cfg(feature = "trace")] 20#[cfg(feature = "trace")]
21mod trace; 21pub mod trace;
22pub(crate) mod util; 22pub(crate) mod util;
23#[cfg_attr(feature = "turbowakers", path = "waker_turbo.rs")] 23#[cfg_attr(feature = "turbowakers", path = "waker_turbo.rs")]
24mod waker; 24mod waker;
@@ -89,6 +89,12 @@ pub(crate) struct TaskHeader {
89 89
90 /// Integrated timer queue storage. This field should not be accessed outside of the timer queue. 90 /// Integrated timer queue storage. This field should not be accessed outside of the timer queue.
91 pub(crate) timer_queue_item: timer_queue::TimerQueueItem, 91 pub(crate) timer_queue_item: timer_queue::TimerQueueItem,
92 #[cfg(feature = "trace")]
93 pub(crate) name: Option<&'static str>,
94 #[cfg(feature = "trace")]
95 pub(crate) id: u32,
96 #[cfg(feature = "trace")]
97 all_tasks_next: AtomicPtr<TaskHeader>,
92} 98}
93 99
94/// This is essentially a `&'static TaskStorage<F>` where the type of the future has been erased. 100/// This is essentially a `&'static TaskStorage<F>` where the type of the future has been erased.
@@ -143,12 +149,6 @@ impl TaskRef {
143 pub(crate) fn as_ptr(self) -> *const TaskHeader { 149 pub(crate) fn as_ptr(self) -> *const TaskHeader {
144 self.ptr.as_ptr() 150 self.ptr.as_ptr()
145 } 151 }
146
147 /// Get the ID for a task
148 #[cfg(feature = "trace")]
149 pub fn as_id(self) -> u32 {
150 self.ptr.as_ptr() as u32
151 }
152} 152}
153 153
154/// Raw storage in which a task can be spawned. 154/// Raw storage in which a task can be spawned.
@@ -190,6 +190,12 @@ impl<F: Future + 'static> TaskStorage<F> {
190 poll_fn: SyncUnsafeCell::new(None), 190 poll_fn: SyncUnsafeCell::new(None),
191 191
192 timer_queue_item: timer_queue::TimerQueueItem::new(), 192 timer_queue_item: timer_queue::TimerQueueItem::new(),
193 #[cfg(feature = "trace")]
194 name: None,
195 #[cfg(feature = "trace")]
196 id: 0,
197 #[cfg(feature = "trace")]
198 all_tasks_next: AtomicPtr::new(core::ptr::null_mut()),
193 }, 199 },
194 future: UninitCell::uninit(), 200 future: UninitCell::uninit(),
195 } 201 }
diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs
index aba519c8f..6c9cfda25 100644
--- a/embassy-executor/src/raw/trace.rs
+++ b/embassy-executor/src/raw/trace.rs
@@ -81,7 +81,131 @@
81 81
82#![allow(unused)] 82#![allow(unused)]
83 83
84use crate::raw::{SyncExecutor, TaskRef}; 84use core::cell::UnsafeCell;
85use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
86
87use rtos_trace::TaskInfo;
88
89use crate::raw::{SyncExecutor, TaskHeader, TaskRef};
90use crate::spawner::{SpawnError, SpawnToken, Spawner};
91
92/// Global task tracker instance
93///
94/// This static provides access to the global task tracker which maintains
95/// a list of all tasks in the system. It's automatically updated by the
96/// task lifecycle hooks in the trace module.
97pub static TASK_TRACKER: TaskTracker = TaskTracker::new();
98
99/// A thread-safe tracker for all tasks in the system
100///
101/// This struct uses an intrusive linked list approach to track all tasks
102/// without additional memory allocations. It maintains a global list of
103/// tasks that can be traversed to find all currently existing tasks.
104pub struct TaskTracker {
105 head: AtomicPtr<TaskHeader>,
106}
107
108impl TaskTracker {
109 /// Creates a new empty task tracker
110 ///
111 /// Initializes a tracker with no tasks in its list.
112 pub const fn new() -> Self {
113 Self {
114 head: AtomicPtr::new(core::ptr::null_mut()),
115 }
116 }
117
118 /// Adds a task to the tracker
119 ///
120 /// This method inserts a task at the head of the intrusive linked list.
121 /// The operation is thread-safe and lock-free, using atomic operations
122 /// to ensure consistency even when called from different contexts.
123 ///
124 /// # Arguments
125 /// * `task` - The task reference to add to the tracker
126 pub fn add(&self, task: TaskRef) {
127 let task_ptr = task.as_ptr() as *mut TaskHeader;
128
129 loop {
130 let current_head = self.head.load(Ordering::Acquire);
131 unsafe {
132 (*task_ptr).all_tasks_next.store(current_head, Ordering::Relaxed);
133 }
134
135 if self
136 .head
137 .compare_exchange(current_head, task_ptr, Ordering::Release, Ordering::Relaxed)
138 .is_ok()
139 {
140 break;
141 }
142 }
143 }
144
145 /// Performs an operation on each task in the tracker
146 ///
147 /// This method traverses the entire list of tasks and calls the provided
148 /// function for each task. This allows inspecting or processing all tasks
149 /// in the system without modifying the tracker's structure.
150 ///
151 /// # Arguments
152 /// * `f` - A function to call for each task in the tracker
153 pub fn for_each<F>(&self, mut f: F)
154 where
155 F: FnMut(TaskRef),
156 {
157 let mut current = self.head.load(Ordering::Acquire);
158 while !current.is_null() {
159 let task = unsafe { TaskRef::from_ptr(current) };
160 f(task);
161
162 current = unsafe { (*current).all_tasks_next.load(Ordering::Acquire) };
163 }
164 }
165}
166
167/// Extension trait for `TaskRef` that provides tracing functionality.
168///
169/// This trait is only available when the `trace` feature is enabled.
170/// It extends `TaskRef` with methods for accessing and modifying task identifiers
171/// and names, which are useful for debugging, logging, and performance analysis.
172pub trait TaskRefTrace {
173 /// Get the name for a task
174 fn name(&self) -> Option<&'static str>;
175
176 /// Set the name for a task
177 fn set_name(&self, name: Option<&'static str>);
178
179 /// Get the ID for a task
180 fn id(&self) -> u32;
181
182 /// Set the ID for a task
183 fn set_id(&self, id: u32);
184}
185
186impl TaskRefTrace for TaskRef {
187 fn name(&self) -> Option<&'static str> {
188 self.header().name
189 }
190
191 fn set_name(&self, name: Option<&'static str>) {
192 unsafe {
193 let header_ptr = self.ptr.as_ptr() as *mut TaskHeader;
194 (*header_ptr).name = name;
195 }
196 }
197
198 fn id(&self) -> u32 {
199 self.header().id
200 }
201
202 fn set_id(&self, id: u32) {
203 unsafe {
204 let header_ptr = self.ptr.as_ptr() as *mut TaskHeader;
205 (*header_ptr).id = id;
206 }
207 }
208}
85 209
86#[cfg(not(feature = "rtos-trace"))] 210#[cfg(not(feature = "rtos-trace"))]
87extern "Rust" { 211extern "Rust" {
@@ -160,6 +284,9 @@ pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) {
160 284
161 #[cfg(feature = "rtos-trace")] 285 #[cfg(feature = "rtos-trace")]
162 rtos_trace::trace::task_new(task.as_ptr() as u32); 286 rtos_trace::trace::task_new(task.as_ptr() as u32);
287
288 #[cfg(feature = "rtos-trace")]
289 TASK_TRACKER.add(*task);
163} 290}
164 291
165#[inline] 292#[inline]
@@ -210,10 +337,62 @@ pub(crate) fn executor_idle(executor: &SyncExecutor) {
210 rtos_trace::trace::system_idle(); 337 rtos_trace::trace::system_idle();
211} 338}
212 339
340/// Returns an iterator over all active tasks in the system
341///
342/// This function provides a convenient way to iterate over all tasks
343/// that are currently tracked in the system. The returned iterator
344/// yields each task in the global task tracker.
345///
346/// # Returns
347/// An iterator that yields `TaskRef` items for each task
348fn get_all_active_tasks() -> impl Iterator<Item = TaskRef> + 'static {
349 struct TaskIterator<'a> {
350 tracker: &'a TaskTracker,
351 current: *mut TaskHeader,
352 }
353
354 impl<'a> Iterator for TaskIterator<'a> {
355 type Item = TaskRef;
356
357 fn next(&mut self) -> Option<Self::Item> {
358 if self.current.is_null() {
359 return None;
360 }
361
362 let task = unsafe { TaskRef::from_ptr(self.current) };
363 self.current = unsafe { (*self.current).all_tasks_next.load(Ordering::Acquire) };
364
365 Some(task)
366 }
367 }
368
369 TaskIterator {
370 tracker: &TASK_TRACKER,
371 current: TASK_TRACKER.head.load(Ordering::Acquire),
372 }
373}
374
375/// Perform an action on each active task
376fn with_all_active_tasks<F>(f: F)
377where
378 F: FnMut(TaskRef),
379{
380 TASK_TRACKER.for_each(f);
381}
382
213#[cfg(feature = "rtos-trace")] 383#[cfg(feature = "rtos-trace")]
214impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor { 384impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor {
215 fn task_list() { 385 fn task_list() {
216 // We don't know what tasks exist, so we can't send them. 386 with_all_active_tasks(|task| {
387 let name = task.name().unwrap_or("unnamed task\0");
388 let info = rtos_trace::TaskInfo {
389 name,
390 priority: 0,
391 stack_base: 0,
392 stack_size: 0,
393 };
394 rtos_trace::trace::task_send_info(task.id(), info);
395 });
217 } 396 }
218 fn time() -> u64 { 397 fn time() -> u64 {
219 const fn gcd(a: u64, b: u64) -> u64 { 398 const fn gcd(a: u64, b: u64) -> u64 {
diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs
index ff243081c..522d97db3 100644
--- a/embassy-executor/src/spawner.rs
+++ b/embassy-executor/src/spawner.rs
@@ -5,6 +5,8 @@ use core::sync::atomic::Ordering;
5use core::task::Poll; 5use core::task::Poll;
6 6
7use super::raw; 7use super::raw;
8#[cfg(feature = "trace")]
9use crate::raw::trace::TaskRefTrace;
8 10
9/// Token to spawn a newly-created task in an executor. 11/// Token to spawn a newly-created task in an executor.
10/// 12///
@@ -22,7 +24,7 @@ use super::raw;
22/// Once you've invoked a task function and obtained a SpawnToken, you *must* spawn it. 24/// Once you've invoked a task function and obtained a SpawnToken, you *must* spawn it.
23#[must_use = "Calling a task function does nothing on its own. You must spawn the returned SpawnToken, typically with Spawner::spawn()"] 25#[must_use = "Calling a task function does nothing on its own. You must spawn the returned SpawnToken, typically with Spawner::spawn()"]
24pub struct SpawnToken<S> { 26pub struct SpawnToken<S> {
25 raw_task: Option<raw::TaskRef>, 27 pub(crate) raw_task: Option<raw::TaskRef>,
26 phantom: PhantomData<*mut S>, 28 phantom: PhantomData<*mut S>,
27} 29}
28 30
@@ -103,7 +105,7 @@ impl core::error::Error for SpawnError {}
103/// If you want to spawn tasks from another thread, use [SendSpawner]. 105/// If you want to spawn tasks from another thread, use [SendSpawner].
104#[derive(Copy, Clone)] 106#[derive(Copy, Clone)]
105pub struct Spawner { 107pub struct Spawner {
106 executor: &'static raw::Executor, 108 pub(crate) executor: &'static raw::Executor,
107 not_send: PhantomData<*mut ()>, 109 not_send: PhantomData<*mut ()>,
108} 110}
109 111
@@ -180,6 +182,53 @@ impl Spawner {
180 } 182 }
181} 183}
182 184
185/// Extension trait adding tracing capabilities to the Spawner
186///
187/// This trait provides an additional method to spawn tasks with an associated name,
188/// which can be useful for debugging and tracing purposes.
189pub trait SpawnerTraceExt {
190 /// Spawns a new task with a specified name.
191 ///
192 /// # Arguments
193 /// * `name` - Static string name to associate with the task
194 /// * `token` - Token representing the task to spawn
195 ///
196 /// # Returns
197 /// Result indicating whether the spawn was successful
198 fn spawn_named<S>(&self, name: &'static str, token: SpawnToken<S>) -> Result<(), SpawnError>;
199}
200
201/// Implementation of the SpawnerTraceExt trait for Spawner when trace is enabled
202#[cfg(feature = "trace")]
203impl SpawnerTraceExt for Spawner {
204 fn spawn_named<S>(&self, name: &'static str, token: SpawnToken<S>) -> Result<(), SpawnError> {
205 let task = token.raw_task;
206 core::mem::forget(token);
207
208 match task {
209 Some(task) => {
210 // Set the name and ID when trace is enabled
211 task.set_name(Some(name));
212 let task_id = task.as_ptr() as u32;
213 task.set_id(task_id);
214
215 unsafe { self.executor.spawn(task) };
216 Ok(())
217 }
218 None => Err(SpawnError::Busy),
219 }
220 }
221}
222
223/// Implementation of the SpawnerTraceExt trait for Spawner when trace is disabled
224#[cfg(not(feature = "trace"))]
225impl SpawnerTraceExt for Spawner {
226 fn spawn_named<S>(&self, _name: &'static str, token: SpawnToken<S>) -> Result<(), SpawnError> {
227 // When trace is disabled, just forward to regular spawn and ignore the name
228 self.spawn(token)
229 }
230}
231
183/// Handle to spawn tasks into an executor from any thread. 232/// Handle to spawn tasks into an executor from any thread.
184/// 233///
185/// This Spawner can be used from any thread (it is Send), but it can 234/// This Spawner can be used from any thread (it is Send), but it can
diff --git a/embassy-futures/Cargo.toml b/embassy-futures/Cargo.toml
index 47cefa56f..0deab0165 100644
--- a/embassy-futures/Cargo.toml
+++ b/embassy-futures/Cargo.toml
@@ -24,5 +24,5 @@ target = "thumbv7em-none-eabi"
24features = ["defmt"] 24features = ["defmt"]
25 25
26[dependencies] 26[dependencies]
27defmt = { version = "0.3", optional = true } 27defmt = { version = "1.0.1", optional = true }
28log = { version = "0.4.14", optional = true } 28log = { version = "0.4.14", optional = true }
diff --git a/embassy-hal-internal/Cargo.toml b/embassy-hal-internal/Cargo.toml
index d5ca95ac2..cc360682e 100644
--- a/embassy-hal-internal/Cargo.toml
+++ b/embassy-hal-internal/Cargo.toml
@@ -28,7 +28,7 @@ prio-bits-8 = []
28cortex-m = ["dep:cortex-m", "dep:critical-section"] 28cortex-m = ["dep:cortex-m", "dep:critical-section"]
29 29
30[dependencies] 30[dependencies]
31defmt = { version = "0.3", optional = true } 31defmt = { version = "1.0.1", optional = true }
32log = { version = "0.4.14", optional = true } 32log = { version = "0.4.14", optional = true }
33 33
34num-traits = { version = "0.2.14", default-features = false } 34num-traits = { version = "0.2.14", default-features = false }
diff --git a/embassy-hal-internal/src/macros.rs b/embassy-hal-internal/src/macros.rs
index cd2bc3cab..ce72ded5c 100644
--- a/embassy-hal-internal/src/macros.rs
+++ b/embassy-hal-internal/src/macros.rs
@@ -8,6 +8,8 @@ macro_rules! peripherals_definition {
8 $(#[$cfg])? 8 $(#[$cfg])?
9 #[allow(non_camel_case_types)] 9 #[allow(non_camel_case_types)]
10 #[doc = concat!(stringify!($name), " peripheral")] 10 #[doc = concat!(stringify!($name), " peripheral")]
11 #[derive(Debug)]
12 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
11 pub struct $name { _private: () } 13 pub struct $name { _private: () }
12 14
13 $(#[$cfg])? 15 $(#[$cfg])?
diff --git a/embassy-hal-internal/src/peripheral.rs b/embassy-hal-internal/src/peripheral.rs
index 803259bb8..b1868caf6 100644
--- a/embassy-hal-internal/src/peripheral.rs
+++ b/embassy-hal-internal/src/peripheral.rs
@@ -14,6 +14,8 @@ use core::ops::Deref;
14/// the driver code would be monomorphized two times. With Peri, the driver is generic 14/// the driver code would be monomorphized two times. With Peri, the driver is generic
15/// over a lifetime only. `SPI4` becomes `Peri<'static, SPI4>`, and `&mut SPI4` becomes 15/// over a lifetime only. `SPI4` becomes `Peri<'static, SPI4>`, and `&mut SPI4` becomes
16/// `Peri<'a, SPI4>`. Lifetimes don't cause monomorphization. 16/// `Peri<'a, SPI4>`. Lifetimes don't cause monomorphization.
17#[derive(Debug)]
18#[cfg_attr(feature = "defmt", derive(defmt::Format))]
17pub struct Peri<'a, T: PeripheralType> { 19pub struct Peri<'a, T: PeripheralType> {
18 inner: T, 20 inner: T,
19 _lifetime: PhantomData<&'a mut T>, 21 _lifetime: PhantomData<&'a mut T>,
diff --git a/embassy-imxrt/Cargo.toml b/embassy-imxrt/Cargo.toml
index f16002a8d..231a80251 100644
--- a/embassy-imxrt/Cargo.toml
+++ b/embassy-imxrt/Cargo.toml
@@ -71,7 +71,7 @@ embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", fe
71embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal", default-features = false } 71embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal", default-features = false }
72embassy-futures = { version = "0.1.1", path = "../embassy-futures" } 72embassy-futures = { version = "0.1.1", path = "../embassy-futures" }
73 73
74defmt = { version = "1.0", optional = true } 74defmt = { version = "1.0.1", optional = true }
75log = { version = "0.4.14", optional = true } 75log = { version = "0.4.14", optional = true }
76nb = "1.0.0" 76nb = "1.0.0"
77cfg-if = "1.0.0" 77cfg-if = "1.0.0"
@@ -80,9 +80,11 @@ cortex-m = "0.7.6"
80critical-section = "1.1" 80critical-section = "1.1"
81embedded-io = { version = "0.6.1" } 81embedded-io = { version = "0.6.1" }
82embedded-io-async = { version = "0.6.1" } 82embedded-io-async = { version = "0.6.1" }
83rand_core = "0.6.4"
84fixed = "1.23.1" 83fixed = "1.23.1"
85 84
85rand-core-06 = { package = "rand_core", version = "0.6" }
86rand-core-09 = { package = "rand_core", version = "0.9" }
87
86embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [ 88embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [
87 "unproven", 89 "unproven",
88] } 90] }
diff --git a/embassy-imxrt/src/crc.rs b/embassy-imxrt/src/crc.rs
new file mode 100644
index 000000000..24d6ba5bd
--- /dev/null
+++ b/embassy-imxrt/src/crc.rs
@@ -0,0 +1,190 @@
1//! Cyclic Redundancy Check (CRC)
2
3use core::marker::PhantomData;
4
5use crate::clocks::{enable_and_reset, SysconPeripheral};
6pub use crate::pac::crc_engine::mode::CrcPolynomial as Polynomial;
7use crate::{peripherals, Peri, PeripheralType};
8
9/// CRC driver.
10pub struct Crc<'d> {
11 info: Info,
12 _config: Config,
13 _lifetime: PhantomData<&'d ()>,
14}
15
16/// CRC configuration
17pub struct Config {
18 /// Polynomial to be used
19 pub polynomial: Polynomial,
20
21 /// Reverse bit order of input?
22 pub reverse_in: bool,
23
24 /// 1's complement input?
25 pub complement_in: bool,
26
27 /// Reverse CRC bit order?
28 pub reverse_out: bool,
29
30 /// 1's complement CRC?
31 pub complement_out: bool,
32
33 /// CRC Seed
34 pub seed: u32,
35}
36
37impl Config {
38 /// Create a new CRC config.
39 #[must_use]
40 pub fn new(
41 polynomial: Polynomial,
42 reverse_in: bool,
43 complement_in: bool,
44 reverse_out: bool,
45 complement_out: bool,
46 seed: u32,
47 ) -> Self {
48 Config {
49 polynomial,
50 reverse_in,
51 complement_in,
52 reverse_out,
53 complement_out,
54 seed,
55 }
56 }
57}
58
59impl Default for Config {
60 fn default() -> Self {
61 Self {
62 polynomial: Polynomial::CrcCcitt,
63 reverse_in: false,
64 complement_in: false,
65 reverse_out: false,
66 complement_out: false,
67 seed: 0xffff,
68 }
69 }
70}
71
72impl<'d> Crc<'d> {
73 /// Instantiates new CRC peripheral and initializes to default values.
74 pub fn new<T: Instance>(_peripheral: Peri<'d, T>, config: Config) -> Self {
75 // enable CRC clock
76 enable_and_reset::<T>();
77
78 let mut instance = Self {
79 info: T::info(),
80 _config: config,
81 _lifetime: PhantomData,
82 };
83
84 instance.reconfigure();
85 instance
86 }
87
88 /// Reconfigured the CRC peripheral.
89 fn reconfigure(&mut self) {
90 self.info.regs.mode().write(|w| {
91 w.crc_poly()
92 .variant(self._config.polynomial)
93 .bit_rvs_wr()
94 .variant(self._config.reverse_in)
95 .cmpl_wr()
96 .variant(self._config.complement_in)
97 .bit_rvs_sum()
98 .variant(self._config.reverse_out)
99 .cmpl_sum()
100 .variant(self._config.complement_out)
101 });
102
103 // Init CRC value
104 self.info
105 .regs
106 .seed()
107 .write(|w| unsafe { w.crc_seed().bits(self._config.seed) });
108 }
109
110 /// Feeds a byte into the CRC peripheral. Returns the computed checksum.
111 pub fn feed_byte(&mut self, byte: u8) -> u32 {
112 self.info.regs.wr_data8().write(|w| unsafe { w.bits(byte) });
113
114 self.info.regs.sum().read().bits()
115 }
116
117 /// Feeds an slice of bytes into the CRC peripheral. Returns the computed checksum.
118 pub fn feed_bytes(&mut self, bytes: &[u8]) -> u32 {
119 let (prefix, data, suffix) = unsafe { bytes.align_to::<u32>() };
120
121 for b in prefix {
122 self.info.regs.wr_data8().write(|w| unsafe { w.bits(*b) });
123 }
124
125 for d in data {
126 self.info.regs.wr_data32().write(|w| unsafe { w.bits(*d) });
127 }
128
129 for b in suffix {
130 self.info.regs.wr_data8().write(|w| unsafe { w.bits(*b) });
131 }
132
133 self.info.regs.sum().read().bits()
134 }
135
136 /// Feeds a halfword into the CRC peripheral. Returns the computed checksum.
137 pub fn feed_halfword(&mut self, halfword: u16) -> u32 {
138 self.info.regs.wr_data16().write(|w| unsafe { w.bits(halfword) });
139
140 self.info.regs.sum().read().bits()
141 }
142
143 /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum.
144 pub fn feed_halfwords(&mut self, halfwords: &[u16]) -> u32 {
145 for halfword in halfwords {
146 self.info.regs.wr_data16().write(|w| unsafe { w.bits(*halfword) });
147 }
148
149 self.info.regs.sum().read().bits()
150 }
151
152 /// Feeds a words into the CRC peripheral. Returns the computed checksum.
153 pub fn feed_word(&mut self, word: u32) -> u32 {
154 self.info.regs.wr_data32().write(|w| unsafe { w.bits(word) });
155
156 self.info.regs.sum().read().bits()
157 }
158
159 /// Feeds an slice of words into the CRC peripheral. Returns the computed checksum.
160 pub fn feed_words(&mut self, words: &[u32]) -> u32 {
161 for word in words {
162 self.info.regs.wr_data32().write(|w| unsafe { w.bits(*word) });
163 }
164
165 self.info.regs.sum().read().bits()
166 }
167}
168
169struct Info {
170 regs: crate::pac::CrcEngine,
171}
172
173trait SealedInstance {
174 fn info() -> Info;
175}
176
177/// CRC instance trait.
178#[allow(private_bounds)]
179pub trait Instance: SealedInstance + PeripheralType + SysconPeripheral + 'static + Send {}
180
181impl Instance for peripherals::CRC {}
182
183impl SealedInstance for peripherals::CRC {
184 fn info() -> Info {
185 // SAFETY: safe from single executor
186 Info {
187 regs: unsafe { crate::pac::CrcEngine::steal() },
188 }
189 }
190}
diff --git a/embassy-imxrt/src/dma.rs b/embassy-imxrt/src/dma.rs
new file mode 100644
index 000000000..e141447f3
--- /dev/null
+++ b/embassy-imxrt/src/dma.rs
@@ -0,0 +1,418 @@
1//! DMA driver.
2
3use core::future::Future;
4use core::pin::Pin;
5use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::{Context, Poll};
7
8use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker;
10use pac::dma0::channel::cfg::Periphreqen;
11use pac::dma0::channel::xfercfg::{Dstinc, Srcinc, Width};
12
13use crate::clocks::enable_and_reset;
14use crate::interrupt::InterruptExt;
15use crate::peripherals::DMA0;
16use crate::sealed::Sealed;
17use crate::{interrupt, pac, peripherals, BitIter};
18
19#[cfg(feature = "rt")]
20#[interrupt]
21fn DMA0() {
22 let reg = unsafe { crate::pac::Dma0::steal() };
23
24 if reg.intstat().read().activeerrint().bit() {
25 let err = reg.errint0().read().bits();
26
27 for channel in BitIter(err) {
28 error!("DMA error interrupt on channel {}!", channel);
29 reg.errint0().write(|w| unsafe { w.err().bits(1 << channel) });
30 CHANNEL_WAKERS[channel as usize].wake();
31 }
32 }
33
34 if reg.intstat().read().activeint().bit() {
35 let ia = reg.inta0().read().bits();
36
37 for channel in BitIter(ia) {
38 reg.inta0().write(|w| unsafe { w.ia().bits(1 << channel) });
39 CHANNEL_WAKERS[channel as usize].wake();
40 }
41 }
42}
43
44/// Initialize DMA controllers (DMA0 only, for now)
45pub(crate) unsafe fn init() {
46 let sysctl0 = crate::pac::Sysctl0::steal();
47 let dmactl0 = crate::pac::Dma0::steal();
48
49 enable_and_reset::<DMA0>();
50
51 interrupt::DMA0.disable();
52 interrupt::DMA0.set_priority(interrupt::Priority::P3);
53
54 dmactl0.ctrl().modify(|_, w| w.enable().set_bit());
55
56 // Set channel descriptor SRAM base address
57 // Descriptor base must be 1K aligned
58 let descriptor_base = core::ptr::addr_of!(DESCRIPTORS.descs) as u32;
59 dmactl0.srambase().write(|w| w.bits(descriptor_base));
60
61 // Ensure AHB priority it highest (M4 == DMAC0)
62 sysctl0.ahbmatrixprior().modify(|_, w| w.m4().bits(0));
63
64 interrupt::DMA0.unpend();
65 interrupt::DMA0.enable();
66}
67
68/// DMA read.
69///
70/// SAFETY: Slice must point to a valid location reachable by DMA.
71pub unsafe fn read<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const W, to: *mut [W]) -> Transfer<'a, C> {
72 let count = ((to.len() / W::size() as usize) - 1) as isize;
73
74 copy_inner(
75 ch,
76 from as *const u32,
77 (to as *mut u32).byte_offset(count * W::size()),
78 W::width(),
79 count,
80 false,
81 true,
82 true,
83 )
84}
85
86/// DMA write.
87///
88/// SAFETY: Slice must point to a valid location reachable by DMA.
89pub unsafe fn write<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const [W], to: *mut W) -> Transfer<'a, C> {
90 let count = ((from.len() / W::size() as usize) - 1) as isize;
91
92 copy_inner(
93 ch,
94 (from as *const u32).byte_offset(count * W::size()),
95 to as *mut u32,
96 W::width(),
97 count,
98 true,
99 false,
100 true,
101 )
102}
103
104/// DMA copy between slices.
105///
106/// SAFETY: Slices must point to locations reachable by DMA.
107pub unsafe fn copy<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: &[W], to: &mut [W]) -> Transfer<'a, C> {
108 let from_len = from.len();
109 let to_len = to.len();
110 assert_eq!(from_len, to_len);
111
112 let count = ((from_len / W::size() as usize) - 1) as isize;
113
114 copy_inner(
115 ch,
116 from.as_ptr().byte_offset(count * W::size()) as *const u32,
117 to.as_mut_ptr().byte_offset(count * W::size()) as *mut u32,
118 W::width(),
119 count,
120 true,
121 true,
122 false,
123 )
124}
125
126fn copy_inner<'a, C: Channel>(
127 ch: Peri<'a, C>,
128 from: *const u32,
129 to: *mut u32,
130 width: Width,
131 count: isize,
132 incr_read: bool,
133 incr_write: bool,
134 periph: bool,
135) -> Transfer<'a, C> {
136 let p = ch.regs();
137
138 unsafe {
139 DESCRIPTORS.descs[ch.number() as usize].src = from as u32;
140 DESCRIPTORS.descs[ch.number() as usize].dest = to as u32;
141 }
142
143 compiler_fence(Ordering::SeqCst);
144
145 p.errint0().write(|w| unsafe { w.err().bits(1 << ch.number()) });
146 p.inta0().write(|w| unsafe { w.ia().bits(1 << ch.number()) });
147
148 p.channel(ch.number().into()).cfg().write(|w| {
149 unsafe { w.chpriority().bits(0) }
150 .periphreqen()
151 .variant(match periph {
152 false => Periphreqen::Disabled,
153 true => Periphreqen::Enabled,
154 })
155 .hwtrigen()
156 .clear_bit()
157 });
158
159 p.intenset0().write(|w| unsafe { w.inten().bits(1 << ch.number()) });
160
161 p.channel(ch.number().into()).xfercfg().write(|w| {
162 unsafe { w.xfercount().bits(count as u16) }
163 .cfgvalid()
164 .set_bit()
165 .clrtrig()
166 .set_bit()
167 .reload()
168 .clear_bit()
169 .setinta()
170 .set_bit()
171 .width()
172 .variant(width)
173 .srcinc()
174 .variant(match incr_read {
175 false => Srcinc::NoIncrement,
176 true => Srcinc::WidthX1,
177 // REVISIT: what about WidthX2 and WidthX4?
178 })
179 .dstinc()
180 .variant(match incr_write {
181 false => Dstinc::NoIncrement,
182 true => Dstinc::WidthX1,
183 // REVISIT: what about WidthX2 and WidthX4?
184 })
185 });
186
187 p.enableset0().write(|w| unsafe { w.ena().bits(1 << ch.number()) });
188
189 p.channel(ch.number().into())
190 .xfercfg()
191 .modify(|_, w| w.swtrig().set_bit());
192
193 compiler_fence(Ordering::SeqCst);
194
195 Transfer::new(ch)
196}
197
198/// DMA transfer driver.
199#[must_use = "futures do nothing unless you `.await` or poll them"]
200pub struct Transfer<'a, C: Channel> {
201 channel: Peri<'a, C>,
202}
203
204impl<'a, C: Channel> Transfer<'a, C> {
205 pub(crate) fn new(channel: Peri<'a, C>) -> Self {
206 Self { channel }
207 }
208
209 pub(crate) fn abort(&mut self) -> usize {
210 let p = self.channel.regs();
211
212 p.abort0().write(|w| w.channel(self.channel.number()).set_bit());
213 while p.busy0().read().bsy().bits() & (1 << self.channel.number()) != 0 {}
214
215 p.enableclr0()
216 .write(|w| unsafe { w.clr().bits(1 << self.channel.number()) });
217
218 let width: u8 = p
219 .channel(self.channel.number().into())
220 .xfercfg()
221 .read()
222 .width()
223 .variant()
224 .unwrap()
225 .into();
226
227 let count = p
228 .channel(self.channel.number().into())
229 .xfercfg()
230 .read()
231 .xfercount()
232 .bits()
233 + 1;
234
235 usize::from(count) * usize::from(width)
236 }
237}
238
239impl<'a, C: Channel> Drop for Transfer<'a, C> {
240 fn drop(&mut self) {
241 self.abort();
242 }
243}
244
245impl<'a, C: Channel> Unpin for Transfer<'a, C> {}
246impl<'a, C: Channel> Future for Transfer<'a, C> {
247 type Output = ();
248
249 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
250 // Re-register the waker on each call to poll() because any calls to
251 // wake will deregister the waker.
252 CHANNEL_WAKERS[self.channel.number() as usize].register(cx.waker());
253
254 if self.channel.regs().active0().read().act().bits() & (1 << self.channel.number()) == 0 {
255 Poll::Ready(())
256 } else {
257 Poll::Pending
258 }
259 }
260}
261
262/// DMA channel descriptor
263#[derive(Copy, Clone)]
264#[repr(C)]
265struct Descriptor {
266 reserved: u32,
267 src: u32,
268 dest: u32,
269 link: u32,
270}
271
272impl Descriptor {
273 const fn new() -> Self {
274 Self {
275 reserved: 0,
276 src: 0,
277 dest: 0,
278 link: 0,
279 }
280 }
281}
282
283#[repr(align(1024))]
284struct Descriptors {
285 descs: [Descriptor; CHANNEL_COUNT],
286}
287
288impl Descriptors {
289 const fn new() -> Self {
290 Self {
291 descs: [const { Descriptor::new() }; CHANNEL_COUNT],
292 }
293 }
294}
295
296static mut DESCRIPTORS: Descriptors = Descriptors::new();
297static CHANNEL_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [const { AtomicWaker::new() }; CHANNEL_COUNT];
298pub(crate) const CHANNEL_COUNT: usize = 33;
299
300/// DMA channel interface.
301#[allow(private_bounds)]
302pub trait Channel: PeripheralType + Sealed + Into<AnyChannel> + Sized + 'static {
303 /// Channel number.
304 fn number(&self) -> u8;
305
306 /// Channel registry block.
307 fn regs(&self) -> &'static pac::dma0::RegisterBlock {
308 unsafe { &*crate::pac::Dma0::ptr() }
309 }
310}
311
312/// DMA word.
313#[allow(private_bounds)]
314pub trait Word: Sealed {
315 /// Transfer width.
316 fn width() -> Width;
317
318 /// Size in bytes for the width.
319 fn size() -> isize;
320}
321
322impl Sealed for u8 {}
323impl Word for u8 {
324 fn width() -> Width {
325 Width::Bit8
326 }
327
328 fn size() -> isize {
329 1
330 }
331}
332
333impl Sealed for u16 {}
334impl Word for u16 {
335 fn width() -> Width {
336 Width::Bit16
337 }
338
339 fn size() -> isize {
340 2
341 }
342}
343
344impl Sealed for u32 {}
345impl Word for u32 {
346 fn width() -> Width {
347 Width::Bit32
348 }
349
350 fn size() -> isize {
351 4
352 }
353}
354
355/// Type erased DMA channel.
356pub struct AnyChannel {
357 number: u8,
358}
359
360impl_peripheral!(AnyChannel);
361
362impl Sealed for AnyChannel {}
363impl Channel for AnyChannel {
364 fn number(&self) -> u8 {
365 self.number
366 }
367}
368
369macro_rules! channel {
370 ($name:ident, $num:expr) => {
371 impl Sealed for peripherals::$name {}
372 impl Channel for peripherals::$name {
373 fn number(&self) -> u8 {
374 $num
375 }
376 }
377
378 impl From<peripherals::$name> for crate::dma::AnyChannel {
379 fn from(val: peripherals::$name) -> Self {
380 Self { number: val.number() }
381 }
382 }
383 };
384}
385
386channel!(DMA0_CH0, 0);
387channel!(DMA0_CH1, 1);
388channel!(DMA0_CH2, 2);
389channel!(DMA0_CH3, 3);
390channel!(DMA0_CH4, 4);
391channel!(DMA0_CH5, 5);
392channel!(DMA0_CH6, 6);
393channel!(DMA0_CH7, 7);
394channel!(DMA0_CH8, 8);
395channel!(DMA0_CH9, 9);
396channel!(DMA0_CH10, 10);
397channel!(DMA0_CH11, 11);
398channel!(DMA0_CH12, 12);
399channel!(DMA0_CH13, 13);
400channel!(DMA0_CH14, 14);
401channel!(DMA0_CH15, 15);
402channel!(DMA0_CH16, 16);
403channel!(DMA0_CH17, 17);
404channel!(DMA0_CH18, 18);
405channel!(DMA0_CH19, 19);
406channel!(DMA0_CH20, 20);
407channel!(DMA0_CH21, 21);
408channel!(DMA0_CH22, 22);
409channel!(DMA0_CH23, 23);
410channel!(DMA0_CH24, 24);
411channel!(DMA0_CH25, 25);
412channel!(DMA0_CH26, 26);
413channel!(DMA0_CH27, 27);
414channel!(DMA0_CH28, 28);
415channel!(DMA0_CH29, 29);
416channel!(DMA0_CH30, 30);
417channel!(DMA0_CH31, 31);
418channel!(DMA0_CH32, 32);
diff --git a/embassy-imxrt/src/flexcomm/mod.rs b/embassy-imxrt/src/flexcomm/mod.rs
new file mode 100644
index 000000000..4473c9a77
--- /dev/null
+++ b/embassy-imxrt/src/flexcomm/mod.rs
@@ -0,0 +1,252 @@
1//! Implements Flexcomm interface wrapper for easier usage across modules
2
3pub mod uart;
4
5use paste::paste;
6
7use crate::clocks::{enable_and_reset, SysconPeripheral};
8use crate::peripherals::{
9 FLEXCOMM0, FLEXCOMM1, FLEXCOMM14, FLEXCOMM15, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7,
10};
11use crate::{pac, PeripheralType};
12
13/// clock selection option
14#[derive(Copy, Clone, Debug)]
15pub enum Clock {
16 /// SFRO
17 Sfro,
18
19 /// FFRO
20 Ffro,
21
22 /// `AUDIO_PLL`
23 AudioPll,
24
25 /// MASTER
26 Master,
27
28 /// FCn_FRG with Main clock source
29 FcnFrgMain,
30
31 /// FCn_FRG with Pll clock source
32 FcnFrgPll,
33
34 /// FCn_FRG with Sfro clock source
35 FcnFrgSfro,
36
37 /// FCn_FRG with Ffro clock source
38 FcnFrgFfro,
39
40 /// disabled
41 None,
42}
43
44/// do not allow implementation of trait outside this mod
45mod sealed {
46 /// trait does not get re-exported outside flexcomm mod, allowing us to safely expose only desired APIs
47 pub trait Sealed {}
48}
49
50/// primary low-level flexcomm interface
51pub(crate) trait FlexcommLowLevel: sealed::Sealed + PeripheralType + SysconPeripheral + 'static + Send {
52 // fetch the flexcomm register block for direct manipulation
53 fn reg() -> &'static pac::flexcomm0::RegisterBlock;
54
55 // set the clock select for this flexcomm instance and remove from reset
56 fn enable(clk: Clock);
57}
58
59macro_rules! impl_flexcomm {
60 ($($idx:expr),*) => {
61 $(
62 paste!{
63 impl sealed::Sealed for crate::peripherals::[<FLEXCOMM $idx>] {}
64
65 impl FlexcommLowLevel for crate::peripherals::[<FLEXCOMM $idx>] {
66 fn reg() -> &'static crate::pac::flexcomm0::RegisterBlock {
67 // SAFETY: safe from single executor, enforce
68 // via peripheral reference lifetime tracking
69 unsafe {
70 &*crate::pac::[<Flexcomm $idx>]::ptr()
71 }
72 }
73
74 fn enable(clk: Clock) {
75 // SAFETY: safe from single executor
76 let clkctl1 = unsafe { crate::pac::Clkctl1::steal() };
77
78 clkctl1.flexcomm($idx).fcfclksel().write(|w| match clk {
79 Clock::Sfro => w.sel().sfro_clk(),
80 Clock::Ffro => w.sel().ffro_clk(),
81 Clock::AudioPll => w.sel().audio_pll_clk(),
82 Clock::Master => w.sel().master_clk(),
83 Clock::FcnFrgMain => w.sel().fcn_frg_clk(),
84 Clock::FcnFrgPll => w.sel().fcn_frg_clk(),
85 Clock::FcnFrgSfro => w.sel().fcn_frg_clk(),
86 Clock::FcnFrgFfro => w.sel().fcn_frg_clk(),
87 Clock::None => w.sel().none(), // no clock? throw an error?
88 });
89
90 clkctl1.flexcomm($idx).frgclksel().write(|w| match clk {
91 Clock::FcnFrgMain => w.sel().main_clk(),
92 Clock::FcnFrgPll => w.sel().frg_pll_clk(),
93 Clock::FcnFrgSfro => w.sel().sfro_clk(),
94 Clock::FcnFrgFfro => w.sel().ffro_clk(),
95 _ => w.sel().none(), // not using frg ...
96 });
97
98 // todo: add support for frg div/mult
99 clkctl1
100 .flexcomm($idx)
101 .frgctl()
102 .write(|w|
103 // SAFETY: unsafe only used for .bits() call
104 unsafe { w.mult().bits(0) });
105
106 enable_and_reset::<[<FLEXCOMM $idx>]>();
107 }
108 }
109 }
110 )*
111 }
112}
113
114impl_flexcomm!(0, 1, 2, 3, 4, 5, 6, 7);
115
116// TODO: FLEXCOMM 14 is untested. Enable SPI support on FLEXCOMM14
117// Add special case FLEXCOMM14
118impl sealed::Sealed for crate::peripherals::FLEXCOMM14 {}
119
120impl FlexcommLowLevel for crate::peripherals::FLEXCOMM14 {
121 fn reg() -> &'static crate::pac::flexcomm0::RegisterBlock {
122 // SAFETY: safe from single executor, enforce
123 // via peripheral reference lifetime tracking
124 unsafe { &*crate::pac::Flexcomm14::ptr() }
125 }
126
127 fn enable(clk: Clock) {
128 // SAFETY: safe from single executor
129 let clkctl1 = unsafe { crate::pac::Clkctl1::steal() };
130
131 clkctl1.fc14fclksel().write(|w| match clk {
132 Clock::Sfro => w.sel().sfro_clk(),
133 Clock::Ffro => w.sel().ffro_clk(),
134 Clock::AudioPll => w.sel().audio_pll_clk(),
135 Clock::Master => w.sel().master_clk(),
136 Clock::FcnFrgMain => w.sel().fcn_frg_clk(),
137 Clock::FcnFrgPll => w.sel().fcn_frg_clk(),
138 Clock::FcnFrgSfro => w.sel().fcn_frg_clk(),
139 Clock::FcnFrgFfro => w.sel().fcn_frg_clk(),
140 Clock::None => w.sel().none(), // no clock? throw an error?
141 });
142
143 clkctl1.frg14clksel().write(|w| match clk {
144 Clock::FcnFrgMain => w.sel().main_clk(),
145 Clock::FcnFrgPll => w.sel().frg_pll_clk(),
146 Clock::FcnFrgSfro => w.sel().sfro_clk(),
147 Clock::FcnFrgFfro => w.sel().ffro_clk(),
148 _ => w.sel().none(), // not using frg ...
149 });
150
151 // todo: add support for frg div/mult
152 clkctl1.frg14ctl().write(|w|
153 // SAFETY: unsafe only used for .bits() call
154 unsafe { w.mult().bits(0) });
155
156 enable_and_reset::<FLEXCOMM14>();
157 }
158}
159
160// Add special case FLEXCOMM15
161impl sealed::Sealed for crate::peripherals::FLEXCOMM15 {}
162
163impl FlexcommLowLevel for crate::peripherals::FLEXCOMM15 {
164 fn reg() -> &'static crate::pac::flexcomm0::RegisterBlock {
165 // SAFETY: safe from single executor, enforce
166 // via peripheral reference lifetime tracking
167 unsafe { &*crate::pac::Flexcomm15::ptr() }
168 }
169
170 fn enable(clk: Clock) {
171 // SAFETY: safe from single executor
172 let clkctl1 = unsafe { crate::pac::Clkctl1::steal() };
173
174 clkctl1.fc15fclksel().write(|w| match clk {
175 Clock::Sfro => w.sel().sfro_clk(),
176 Clock::Ffro => w.sel().ffro_clk(),
177 Clock::AudioPll => w.sel().audio_pll_clk(),
178 Clock::Master => w.sel().master_clk(),
179 Clock::FcnFrgMain => w.sel().fcn_frg_clk(),
180 Clock::FcnFrgPll => w.sel().fcn_frg_clk(),
181 Clock::FcnFrgSfro => w.sel().fcn_frg_clk(),
182 Clock::FcnFrgFfro => w.sel().fcn_frg_clk(),
183 Clock::None => w.sel().none(), // no clock? throw an error?
184 });
185 clkctl1.frg15clksel().write(|w| match clk {
186 Clock::FcnFrgMain => w.sel().main_clk(),
187 Clock::FcnFrgPll => w.sel().frg_pll_clk(),
188 Clock::FcnFrgSfro => w.sel().sfro_clk(),
189 Clock::FcnFrgFfro => w.sel().ffro_clk(),
190 _ => w.sel().none(), // not using frg ...
191 });
192 // todo: add support for frg div/mult
193 clkctl1.frg15ctl().write(|w|
194 // SAFETY: unsafe only used for .bits() call
195 unsafe { w.mult().bits(0) });
196
197 enable_and_reset::<FLEXCOMM15>();
198 }
199}
200
201macro_rules! into_mode {
202 ($mode:ident, $($fc:ident),*) => {
203 paste! {
204 /// Sealed Mode trait
205 trait [<SealedInto $mode:camel>]: FlexcommLowLevel {}
206
207 /// Select mode of operation
208 #[allow(private_bounds)]
209 pub trait [<Into $mode:camel>]: [<SealedInto $mode:camel>] {
210 /// Set mode of operation
211 fn [<into_ $mode>]() {
212 Self::reg().pselid().write(|w| w.persel().[<$mode>]());
213 }
214 }
215 }
216
217 $(
218 paste!{
219 impl [<SealedInto $mode:camel>] for crate::peripherals::$fc {}
220 impl [<Into $mode:camel>] for crate::peripherals::$fc {}
221 }
222 )*
223 }
224}
225
226into_mode!(usart, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7);
227into_mode!(spi, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM14);
228into_mode!(i2c, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM15);
229
230into_mode!(
231 i2s_transmit,
232 FLEXCOMM0,
233 FLEXCOMM1,
234 FLEXCOMM2,
235 FLEXCOMM3,
236 FLEXCOMM4,
237 FLEXCOMM5,
238 FLEXCOMM6,
239 FLEXCOMM7
240);
241
242into_mode!(
243 i2s_receive,
244 FLEXCOMM0,
245 FLEXCOMM1,
246 FLEXCOMM2,
247 FLEXCOMM3,
248 FLEXCOMM4,
249 FLEXCOMM5,
250 FLEXCOMM6,
251 FLEXCOMM7
252);
diff --git a/embassy-imxrt/src/flexcomm/uart.rs b/embassy-imxrt/src/flexcomm/uart.rs
new file mode 100644
index 000000000..230b30d43
--- /dev/null
+++ b/embassy-imxrt/src/flexcomm/uart.rs
@@ -0,0 +1,1230 @@
1//! Universal Asynchronous Receiver Transmitter (UART) driver.
2
3use core::future::poll_fn;
4use core::marker::PhantomData;
5use core::sync::atomic::{compiler_fence, AtomicU8, Ordering};
6use core::task::Poll;
7
8use embassy_futures::select::{select, Either};
9use embassy_hal_internal::drop::OnDrop;
10use embassy_hal_internal::{Peri, PeripheralType};
11use embassy_sync::waitqueue::AtomicWaker;
12use paste::paste;
13
14use crate::dma::AnyChannel;
15use crate::flexcomm::Clock;
16use crate::gpio::{AnyPin, GpioPin as Pin};
17use crate::interrupt::typelevel::Interrupt;
18use crate::iopctl::{DriveMode, DriveStrength, Inverter, IopctlPin, Pull, SlewRate};
19use crate::pac::usart0::cfg::{Clkpol, Datalen, Loop, Paritysel as Parity, Stoplen, Syncen, Syncmst};
20use crate::pac::usart0::ctl::Cc;
21use crate::sealed::Sealed;
22use crate::{dma, interrupt};
23
24/// Driver move trait.
25#[allow(private_bounds)]
26pub trait Mode: Sealed {}
27
28/// Blocking mode.
29pub struct Blocking;
30impl Sealed for Blocking {}
31impl Mode for Blocking {}
32
33/// Async mode.
34pub struct Async;
35impl Sealed for Async {}
36impl Mode for Async {}
37
38/// Uart driver.
39pub struct Uart<'a, M: Mode> {
40 tx: UartTx<'a, M>,
41 rx: UartRx<'a, M>,
42}
43
44/// Uart TX driver.
45pub struct UartTx<'a, M: Mode> {
46 info: Info,
47 tx_dma: Option<Peri<'a, AnyChannel>>,
48 _phantom: PhantomData<(&'a (), M)>,
49}
50
51/// Uart RX driver.
52pub struct UartRx<'a, M: Mode> {
53 info: Info,
54 rx_dma: Option<Peri<'a, AnyChannel>>,
55 _phantom: PhantomData<(&'a (), M)>,
56}
57
58/// UART config
59#[derive(Clone, Copy)]
60pub struct Config {
61 /// Baudrate of the Uart
62 pub baudrate: u32,
63 /// data length
64 pub data_bits: Datalen,
65 /// Parity
66 pub parity: Parity,
67 /// Stop bits
68 pub stop_bits: Stoplen,
69 /// Polarity of the clock
70 pub clock_polarity: Clkpol,
71 /// Sync/ Async operation selection
72 pub operation: Syncen,
73 /// Sync master/slave mode selection (only applicable in sync mode)
74 pub sync_mode_master_select: Syncmst,
75 /// USART continuous Clock generation enable in synchronous master mode.
76 pub continuous_clock: Cc,
77 /// Normal/ loopback mode
78 pub loopback_mode: Loop,
79 /// Clock type
80 pub clock: Clock,
81}
82
83impl Default for Config {
84 /// Default configuration for single channel sampling.
85 fn default() -> Self {
86 Self {
87 baudrate: 115_200,
88 data_bits: Datalen::Bit8,
89 parity: Parity::NoParity,
90 stop_bits: Stoplen::Bit1,
91 clock_polarity: Clkpol::FallingEdge,
92 operation: Syncen::AsynchronousMode,
93 sync_mode_master_select: Syncmst::Slave,
94 continuous_clock: Cc::ClockOnCharacter,
95 loopback_mode: Loop::Normal,
96 clock: crate::flexcomm::Clock::Sfro,
97 }
98 }
99}
100
101/// Uart Errors
102#[derive(Debug, Copy, Clone, Eq, PartialEq)]
103#[cfg_attr(feature = "defmt", derive(defmt::Format))]
104pub enum Error {
105 /// Read error
106 Read,
107
108 /// Buffer overflow
109 Overrun,
110
111 /// Noise error
112 Noise,
113
114 /// Framing error
115 Framing,
116
117 /// Parity error
118 Parity,
119
120 /// Failure
121 Fail,
122
123 /// Invalid argument
124 InvalidArgument,
125
126 /// Uart baud rate cannot be supported with the given clock
127 UnsupportedBaudrate,
128
129 /// RX FIFO Empty
130 RxFifoEmpty,
131
132 /// TX FIFO Full
133 TxFifoFull,
134
135 /// TX Busy
136 TxBusy,
137}
138/// shorthand for -> `Result<T>`
139pub type Result<T> = core::result::Result<T, Error>;
140
141impl<'a, M: Mode> UartTx<'a, M> {
142 fn new_inner<T: Instance>(tx_dma: Option<Peri<'a, AnyChannel>>) -> Self {
143 let uarttx = Self {
144 info: T::info(),
145 tx_dma,
146 _phantom: PhantomData,
147 };
148 uarttx.info.refcnt.fetch_add(1, Ordering::Relaxed);
149 uarttx
150 }
151}
152
153impl<'a, M: Mode> Drop for UartTx<'a, M> {
154 fn drop(&mut self) {
155 if self.info.refcnt.fetch_sub(1, Ordering::Relaxed) == 1 {
156 while self.info.regs.stat().read().txidle().bit_is_clear() {}
157
158 self.info.regs.fifointenclr().modify(|_, w| {
159 w.txerr()
160 .set_bit()
161 .rxerr()
162 .set_bit()
163 .txlvl()
164 .set_bit()
165 .rxlvl()
166 .set_bit()
167 });
168
169 self.info
170 .regs
171 .fifocfg()
172 .modify(|_, w| w.dmatx().clear_bit().dmarx().clear_bit());
173
174 self.info.regs.cfg().modify(|_, w| w.enable().disabled());
175 }
176 }
177}
178
179impl<'a> UartTx<'a, Blocking> {
180 /// Create a new UART which can only send data
181 /// Unidirectional Uart - Tx only
182 pub fn new_blocking<T: Instance>(_inner: Peri<'a, T>, tx: Peri<'a, impl TxPin<T>>, config: Config) -> Result<Self> {
183 tx.as_tx();
184
185 let _tx = tx.into();
186 Uart::<Blocking>::init::<T>(Some(_tx), None, None, None, config)?;
187
188 Ok(Self::new_inner::<T>(None))
189 }
190
191 fn write_byte_internal(&mut self, byte: u8) -> Result<()> {
192 // SAFETY: unsafe only used for .bits()
193 self.info
194 .regs
195 .fifowr()
196 .write(|w| unsafe { w.txdata().bits(u16::from(byte)) });
197
198 Ok(())
199 }
200
201 fn blocking_write_byte(&mut self, byte: u8) -> Result<()> {
202 while self.info.regs.fifostat().read().txnotfull().bit_is_clear() {}
203
204 // Prevent the compiler from reordering write_byte_internal()
205 // before the loop above.
206 compiler_fence(Ordering::Release);
207
208 self.write_byte_internal(byte)
209 }
210
211 fn write_byte(&mut self, byte: u8) -> Result<()> {
212 if self.info.regs.fifostat().read().txnotfull().bit_is_clear() {
213 Err(Error::TxFifoFull)
214 } else {
215 self.write_byte_internal(byte)
216 }
217 }
218
219 /// Transmit the provided buffer blocking execution until done.
220 pub fn blocking_write(&mut self, buf: &[u8]) -> Result<()> {
221 for x in buf {
222 self.blocking_write_byte(*x)?;
223 }
224
225 Ok(())
226 }
227
228 /// Transmit the provided buffer. Non-blocking version, bails out
229 /// if it would block.
230 pub fn write(&mut self, buf: &[u8]) -> Result<()> {
231 for x in buf {
232 self.write_byte(*x)?;
233 }
234
235 Ok(())
236 }
237
238 /// Flush UART TX blocking execution until done.
239 pub fn blocking_flush(&mut self) -> Result<()> {
240 while self.info.regs.stat().read().txidle().bit_is_clear() {}
241 Ok(())
242 }
243
244 /// Flush UART TX.
245 pub fn flush(&mut self) -> Result<()> {
246 if self.info.regs.stat().read().txidle().bit_is_clear() {
247 Err(Error::TxBusy)
248 } else {
249 Ok(())
250 }
251 }
252}
253
254impl<'a, M: Mode> UartRx<'a, M> {
255 fn new_inner<T: Instance>(rx_dma: Option<Peri<'a, AnyChannel>>) -> Self {
256 let uartrx = Self {
257 info: T::info(),
258 rx_dma,
259 _phantom: PhantomData,
260 };
261 uartrx.info.refcnt.fetch_add(1, Ordering::Relaxed);
262 uartrx
263 }
264}
265
266impl<'a, M: Mode> Drop for UartRx<'a, M> {
267 fn drop(&mut self) {
268 if self.info.refcnt.fetch_sub(1, Ordering::Relaxed) == 1 {
269 while self.info.regs.stat().read().rxidle().bit_is_clear() {}
270
271 self.info.regs.fifointenclr().modify(|_, w| {
272 w.txerr()
273 .set_bit()
274 .rxerr()
275 .set_bit()
276 .txlvl()
277 .set_bit()
278 .rxlvl()
279 .set_bit()
280 });
281
282 self.info
283 .regs
284 .fifocfg()
285 .modify(|_, w| w.dmatx().clear_bit().dmarx().clear_bit());
286
287 self.info.regs.cfg().modify(|_, w| w.enable().disabled());
288 }
289 }
290}
291
292impl<'a> UartRx<'a, Blocking> {
293 /// Create a new blocking UART which can only receive data
294 pub fn new_blocking<T: Instance>(_inner: Peri<'a, T>, rx: Peri<'a, impl RxPin<T>>, config: Config) -> Result<Self> {
295 rx.as_rx();
296
297 let _rx = rx.into();
298 Uart::<Blocking>::init::<T>(None, Some(_rx), None, None, config)?;
299
300 Ok(Self::new_inner::<T>(None))
301 }
302}
303
304impl UartRx<'_, Blocking> {
305 fn read_byte_internal(&mut self) -> Result<u8> {
306 if self.info.regs.fifostat().read().rxerr().bit_is_set() {
307 self.info.regs.fifocfg().modify(|_, w| w.emptyrx().set_bit());
308 self.info.regs.fifostat().modify(|_, w| w.rxerr().set_bit());
309 Err(Error::Read)
310 } else if self.info.regs.stat().read().parityerrint().bit_is_set() {
311 self.info.regs.stat().modify(|_, w| w.parityerrint().clear_bit_by_one());
312 Err(Error::Parity)
313 } else if self.info.regs.stat().read().framerrint().bit_is_set() {
314 self.info.regs.stat().modify(|_, w| w.framerrint().clear_bit_by_one());
315 Err(Error::Framing)
316 } else if self.info.regs.stat().read().rxnoiseint().bit_is_set() {
317 self.info.regs.stat().modify(|_, w| w.rxnoiseint().clear_bit_by_one());
318 Err(Error::Noise)
319 } else {
320 let byte = self.info.regs.fiford().read().rxdata().bits() as u8;
321 Ok(byte)
322 }
323 }
324
325 fn read_byte(&mut self) -> Result<u8> {
326 if self.info.regs.fifostat().read().rxnotempty().bit_is_clear() {
327 Err(Error::RxFifoEmpty)
328 } else {
329 self.read_byte_internal()
330 }
331 }
332
333 fn blocking_read_byte(&mut self) -> Result<u8> {
334 while self.info.regs.fifostat().read().rxnotempty().bit_is_clear() {}
335
336 // Prevent the compiler from reordering read_byte_internal()
337 // before the loop above.
338 compiler_fence(Ordering::Acquire);
339
340 self.read_byte_internal()
341 }
342
343 /// Read from UART RX. Non-blocking version, bails out if it would
344 /// block.
345 pub fn read(&mut self, buf: &mut [u8]) -> Result<()> {
346 for b in buf.iter_mut() {
347 *b = self.read_byte()?;
348 }
349
350 Ok(())
351 }
352
353 /// Read from UART RX blocking execution until done.
354 pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<()> {
355 for b in buf.iter_mut() {
356 *b = self.blocking_read_byte()?;
357 }
358
359 Ok(())
360 }
361}
362
363impl<'a, M: Mode> Uart<'a, M> {
364 fn init<T: Instance>(
365 tx: Option<Peri<'a, AnyPin>>,
366 rx: Option<Peri<'a, AnyPin>>,
367 rts: Option<Peri<'a, AnyPin>>,
368 cts: Option<Peri<'a, AnyPin>>,
369 config: Config,
370 ) -> Result<()> {
371 T::enable(config.clock);
372 T::into_usart();
373
374 let regs = T::info().regs;
375
376 if tx.is_some() {
377 regs.fifocfg().modify(|_, w| w.emptytx().set_bit().enabletx().enabled());
378
379 // clear FIFO error
380 regs.fifostat().write(|w| w.txerr().set_bit());
381 }
382
383 if rx.is_some() {
384 regs.fifocfg().modify(|_, w| w.emptyrx().set_bit().enablerx().enabled());
385
386 // clear FIFO error
387 regs.fifostat().write(|w| w.rxerr().set_bit());
388 }
389
390 if rts.is_some() && cts.is_some() {
391 regs.cfg().modify(|_, w| w.ctsen().enabled());
392 }
393
394 Self::set_baudrate_inner::<T>(config.baudrate, config.clock)?;
395 Self::set_uart_config::<T>(config);
396
397 Ok(())
398 }
399
400 fn get_fc_freq(clock: Clock) -> Result<u32> {
401 match clock {
402 Clock::Sfro => Ok(16_000_000),
403 Clock::Ffro => Ok(48_000_000),
404 // We only support Sfro and Ffro now.
405 _ => Err(Error::InvalidArgument),
406 }
407 }
408
409 fn set_baudrate_inner<T: Instance>(baudrate: u32, clock: Clock) -> Result<()> {
410 // Get source clock frequency according to clock type.
411 let source_clock_hz = Self::get_fc_freq(clock)?;
412
413 if baudrate == 0 {
414 return Err(Error::InvalidArgument);
415 }
416
417 let regs = T::info().regs;
418
419 // If synchronous master mode is enabled, only configure the BRG value.
420 if regs.cfg().read().syncen().is_synchronous_mode() {
421 // Master
422 if regs.cfg().read().syncmst().is_master() {
423 // Calculate the BRG value
424 let brgval = (source_clock_hz / baudrate) - 1;
425
426 // SAFETY: unsafe only used for .bits()
427 regs.brg().write(|w| unsafe { w.brgval().bits(brgval as u16) });
428 }
429 } else {
430 // Smaller values of OSR can make the sampling position within a
431 // data bit less accurate and may potentially cause more noise
432 // errors or incorrect data.
433 let (_, osr, brg) = (8..16).rev().fold(
434 (u32::MAX, u32::MAX, u32::MAX),
435 |(best_diff, best_osr, best_brg), osrval| {
436 // Compare source_clock_hz agaist with ((osrval + 1) * baudrate) to make sure
437 // (source_clock_hz / ((osrval + 1) * baudrate)) is not less than 0.
438 if source_clock_hz < ((osrval + 1) * baudrate) {
439 (best_diff, best_osr, best_brg)
440 } else {
441 let brgval = (source_clock_hz / ((osrval + 1) * baudrate)) - 1;
442 // We know brgval will not be less than 0 now, it should have already been a valid u32 value,
443 // then compare it agaist with 65535.
444 if brgval > 65535 {
445 (best_diff, best_osr, best_brg)
446 } else {
447 // Calculate the baud rate based on the BRG value
448 let candidate = source_clock_hz / ((osrval + 1) * (brgval + 1));
449
450 // Calculate the difference between the
451 // current baud rate and the desired baud rate
452 let diff = (candidate as i32 - baudrate as i32).unsigned_abs();
453
454 // Check if the current calculated difference is the best so far
455 if diff < best_diff {
456 (diff, osrval, brgval)
457 } else {
458 (best_diff, best_osr, best_brg)
459 }
460 }
461 }
462 },
463 );
464
465 // Value over range
466 if brg > 65535 {
467 return Err(Error::UnsupportedBaudrate);
468 }
469
470 // SAFETY: unsafe only used for .bits()
471 regs.osr().write(|w| unsafe { w.osrval().bits(osr as u8) });
472
473 // SAFETY: unsafe only used for .bits()
474 regs.brg().write(|w| unsafe { w.brgval().bits(brg as u16) });
475 }
476
477 Ok(())
478 }
479
480 fn set_uart_config<T: Instance>(config: Config) {
481 let regs = T::info().regs;
482
483 regs.cfg().modify(|_, w| w.enable().disabled());
484
485 regs.cfg().modify(|_, w| {
486 w.datalen()
487 .variant(config.data_bits)
488 .stoplen()
489 .variant(config.stop_bits)
490 .paritysel()
491 .variant(config.parity)
492 .loop_()
493 .variant(config.loopback_mode)
494 .syncen()
495 .variant(config.operation)
496 .clkpol()
497 .variant(config.clock_polarity)
498 });
499
500 regs.cfg().modify(|_, w| w.enable().enabled());
501 }
502
503 /// Split the Uart into a transmitter and receiver, which is particularly
504 /// useful when having two tasks correlating to transmitting and receiving.
505 pub fn split(self) -> (UartTx<'a, M>, UartRx<'a, M>) {
506 (self.tx, self.rx)
507 }
508
509 /// Split the Uart into a transmitter and receiver by mutable reference,
510 /// which is particularly useful when having two tasks correlating to
511 /// transmitting and receiving.
512 pub fn split_ref(&mut self) -> (&mut UartTx<'a, M>, &mut UartRx<'a, M>) {
513 (&mut self.tx, &mut self.rx)
514 }
515}
516
517impl<'a> Uart<'a, Blocking> {
518 /// Create a new blocking UART
519 pub fn new_blocking<T: Instance>(
520 _inner: Peri<'a, T>,
521 tx: Peri<'a, impl TxPin<T>>,
522 rx: Peri<'a, impl RxPin<T>>,
523 config: Config,
524 ) -> Result<Self> {
525 tx.as_tx();
526 rx.as_rx();
527
528 let tx = tx.into();
529 let rx = rx.into();
530
531 Self::init::<T>(Some(tx), Some(rx), None, None, config)?;
532
533 Ok(Self {
534 tx: UartTx::new_inner::<T>(None),
535 rx: UartRx::new_inner::<T>(None),
536 })
537 }
538
539 /// Read from UART RX blocking execution until done.
540 pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<()> {
541 self.rx.blocking_read(buf)
542 }
543
544 /// Read from UART RX. Non-blocking version, bails out if it would
545 /// block.
546 pub fn read(&mut self, buf: &mut [u8]) -> Result<()> {
547 self.rx.read(buf)
548 }
549
550 /// Transmit the provided buffer blocking execution until done.
551 pub fn blocking_write(&mut self, buf: &[u8]) -> Result<()> {
552 self.tx.blocking_write(buf)
553 }
554
555 /// Transmit the provided buffer. Non-blocking version, bails out
556 /// if it would block.
557 pub fn write(&mut self, buf: &[u8]) -> Result<()> {
558 self.tx.write(buf)
559 }
560
561 /// Flush UART TX blocking execution until done.
562 pub fn blocking_flush(&mut self) -> Result<()> {
563 self.tx.blocking_flush()
564 }
565
566 /// Flush UART TX.
567 pub fn flush(&mut self) -> Result<()> {
568 self.tx.flush()
569 }
570}
571
572impl<'a> UartTx<'a, Async> {
573 /// Create a new DMA enabled UART which can only send data
574 pub fn new_async<T: Instance>(
575 _inner: Peri<'a, T>,
576 tx: Peri<'a, impl TxPin<T>>,
577 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'a,
578 tx_dma: Peri<'a, impl TxDma<T>>,
579 config: Config,
580 ) -> Result<Self> {
581 tx.as_tx();
582
583 let _tx = tx.into();
584 Uart::<Async>::init::<T>(Some(_tx), None, None, None, config)?;
585
586 T::Interrupt::unpend();
587 unsafe { T::Interrupt::enable() };
588
589 Ok(Self::new_inner::<T>(Some(tx_dma.into())))
590 }
591
592 /// Transmit the provided buffer asynchronously.
593 pub async fn write(&mut self, buf: &[u8]) -> Result<()> {
594 let regs = self.info.regs;
595
596 // Disable DMA on completion/cancellation
597 let _dma_guard = OnDrop::new(|| {
598 regs.fifocfg().modify(|_, w| w.dmatx().disabled());
599 });
600
601 for chunk in buf.chunks(1024) {
602 regs.fifocfg().modify(|_, w| w.dmatx().enabled());
603
604 let ch = self.tx_dma.as_mut().unwrap().reborrow();
605 let transfer = unsafe { dma::write(ch, chunk, regs.fifowr().as_ptr() as *mut u8) };
606
607 let res = select(
608 transfer,
609 poll_fn(|cx| {
610 UART_WAKERS[self.info.index].register(cx.waker());
611
612 self.info.regs.intenset().write(|w| {
613 w.framerren()
614 .set_bit()
615 .parityerren()
616 .set_bit()
617 .rxnoiseen()
618 .set_bit()
619 .aberren()
620 .set_bit()
621 });
622
623 let stat = self.info.regs.stat().read();
624
625 self.info.regs.stat().write(|w| {
626 w.framerrint()
627 .clear_bit_by_one()
628 .parityerrint()
629 .clear_bit_by_one()
630 .rxnoiseint()
631 .clear_bit_by_one()
632 .aberr()
633 .clear_bit_by_one()
634 });
635
636 if stat.framerrint().bit_is_set() {
637 Poll::Ready(Err(Error::Framing))
638 } else if stat.parityerrint().bit_is_set() {
639 Poll::Ready(Err(Error::Parity))
640 } else if stat.rxnoiseint().bit_is_set() {
641 Poll::Ready(Err(Error::Noise))
642 } else if stat.aberr().bit_is_set() {
643 Poll::Ready(Err(Error::Fail))
644 } else {
645 Poll::Pending
646 }
647 }),
648 )
649 .await;
650
651 match res {
652 Either::First(()) | Either::Second(Ok(())) => (),
653 Either::Second(e) => return e,
654 }
655 }
656
657 Ok(())
658 }
659
660 /// Flush UART TX asynchronously.
661 pub async fn flush(&mut self) -> Result<()> {
662 self.wait_on(
663 |me| {
664 if me.info.regs.stat().read().txidle().bit_is_set() {
665 Poll::Ready(Ok(()))
666 } else {
667 Poll::Pending
668 }
669 },
670 |me| {
671 me.info.regs.intenset().write(|w| w.txidleen().set_bit());
672 },
673 )
674 .await
675 }
676
677 /// Calls `f` to check if we are ready or not.
678 /// If not, `g` is called once the waker is set (to eg enable the required interrupts).
679 async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U
680 where
681 F: FnMut(&mut Self) -> Poll<U>,
682 G: FnMut(&mut Self),
683 {
684 poll_fn(|cx| {
685 // Register waker before checking condition, to ensure that wakes/interrupts
686 // aren't lost between f() and g()
687 UART_WAKERS[self.info.index].register(cx.waker());
688 let r = f(self);
689
690 if r.is_pending() {
691 g(self);
692 }
693
694 r
695 })
696 .await
697 }
698}
699
700impl<'a> UartRx<'a, Async> {
701 /// Create a new DMA enabled UART which can only receive data
702 pub fn new_async<T: Instance>(
703 _inner: Peri<'a, T>,
704 rx: Peri<'a, impl RxPin<T>>,
705 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'a,
706 rx_dma: Peri<'a, impl RxDma<T>>,
707 config: Config,
708 ) -> Result<Self> {
709 rx.as_rx();
710
711 let _rx = rx.into();
712 Uart::<Async>::init::<T>(None, Some(_rx), None, None, config)?;
713
714 T::Interrupt::unpend();
715 unsafe { T::Interrupt::enable() };
716
717 Ok(Self::new_inner::<T>(Some(rx_dma.into())))
718 }
719
720 /// Read from UART RX asynchronously.
721 pub async fn read(&mut self, buf: &mut [u8]) -> Result<()> {
722 let regs = self.info.regs;
723
724 // Disable DMA on completion/cancellation
725 let _dma_guard = OnDrop::new(|| {
726 regs.fifocfg().modify(|_, w| w.dmarx().disabled());
727 });
728
729 for chunk in buf.chunks_mut(1024) {
730 regs.fifocfg().modify(|_, w| w.dmarx().enabled());
731
732 let ch = self.rx_dma.as_mut().unwrap().reborrow();
733 let transfer = unsafe { dma::read(ch, regs.fiford().as_ptr() as *const u8, chunk) };
734
735 let res = select(
736 transfer,
737 poll_fn(|cx| {
738 UART_WAKERS[self.info.index].register(cx.waker());
739
740 self.info.regs.intenset().write(|w| {
741 w.framerren()
742 .set_bit()
743 .parityerren()
744 .set_bit()
745 .rxnoiseen()
746 .set_bit()
747 .aberren()
748 .set_bit()
749 });
750
751 let stat = self.info.regs.stat().read();
752
753 self.info.regs.stat().write(|w| {
754 w.framerrint()
755 .clear_bit_by_one()
756 .parityerrint()
757 .clear_bit_by_one()
758 .rxnoiseint()
759 .clear_bit_by_one()
760 .aberr()
761 .clear_bit_by_one()
762 });
763
764 if stat.framerrint().bit_is_set() {
765 Poll::Ready(Err(Error::Framing))
766 } else if stat.parityerrint().bit_is_set() {
767 Poll::Ready(Err(Error::Parity))
768 } else if stat.rxnoiseint().bit_is_set() {
769 Poll::Ready(Err(Error::Noise))
770 } else if stat.aberr().bit_is_set() {
771 Poll::Ready(Err(Error::Fail))
772 } else {
773 Poll::Pending
774 }
775 }),
776 )
777 .await;
778
779 match res {
780 Either::First(()) | Either::Second(Ok(())) => (),
781 Either::Second(e) => return e,
782 }
783 }
784
785 Ok(())
786 }
787}
788
789impl<'a> Uart<'a, Async> {
790 /// Create a new DMA enabled UART
791 pub fn new_async<T: Instance>(
792 _inner: Peri<'a, T>,
793 tx: Peri<'a, impl TxPin<T>>,
794 rx: Peri<'a, impl RxPin<T>>,
795 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'a,
796 tx_dma: Peri<'a, impl TxDma<T>>,
797 rx_dma: Peri<'a, impl RxDma<T>>,
798 config: Config,
799 ) -> Result<Self> {
800 tx.as_tx();
801 rx.as_rx();
802
803 let tx = tx.into();
804 let rx = rx.into();
805
806 T::Interrupt::unpend();
807 unsafe { T::Interrupt::enable() };
808
809 Self::init::<T>(Some(tx), Some(rx), None, None, config)?;
810
811 Ok(Self {
812 tx: UartTx::new_inner::<T>(Some(tx_dma.into())),
813 rx: UartRx::new_inner::<T>(Some(rx_dma.into())),
814 })
815 }
816
817 /// Create a new DMA enabled UART with hardware flow control (RTS/CTS)
818 pub fn new_with_rtscts<T: Instance>(
819 _inner: Peri<'a, T>,
820 tx: Peri<'a, impl TxPin<T>>,
821 rx: Peri<'a, impl RxPin<T>>,
822 rts: Peri<'a, impl RtsPin<T>>,
823 cts: Peri<'a, impl CtsPin<T>>,
824 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'a,
825 tx_dma: Peri<'a, impl TxDma<T>>,
826 rx_dma: Peri<'a, impl RxDma<T>>,
827 config: Config,
828 ) -> Result<Self> {
829 tx.as_tx();
830 rx.as_rx();
831 rts.as_rts();
832 cts.as_cts();
833
834 let tx = tx.into();
835 let rx = rx.into();
836 let rts = rts.into();
837 let cts = cts.into();
838
839 Self::init::<T>(Some(tx), Some(rx), Some(rts), Some(cts), config)?;
840
841 Ok(Self {
842 tx: UartTx::new_inner::<T>(Some(tx_dma.into())),
843 rx: UartRx::new_inner::<T>(Some(rx_dma.into())),
844 })
845 }
846
847 /// Read from UART RX.
848 pub async fn read(&mut self, buf: &mut [u8]) -> Result<()> {
849 self.rx.read(buf).await
850 }
851
852 /// Transmit the provided buffer.
853 pub async fn write(&mut self, buf: &[u8]) -> Result<()> {
854 self.tx.write(buf).await
855 }
856
857 /// Flush UART TX.
858 pub async fn flush(&mut self) -> Result<()> {
859 self.tx.flush().await
860 }
861}
862
863impl embedded_hal_02::serial::Read<u8> for UartRx<'_, Blocking> {
864 type Error = Error;
865
866 fn read(&mut self) -> core::result::Result<u8, nb::Error<Self::Error>> {
867 let mut buf = [0; 1];
868
869 match self.read(&mut buf) {
870 Ok(_) => Ok(buf[0]),
871 Err(Error::RxFifoEmpty) => Err(nb::Error::WouldBlock),
872 Err(e) => Err(nb::Error::Other(e)),
873 }
874 }
875}
876
877impl embedded_hal_02::serial::Write<u8> for UartTx<'_, Blocking> {
878 type Error = Error;
879
880 fn write(&mut self, word: u8) -> core::result::Result<(), nb::Error<Self::Error>> {
881 match self.write(&[word]) {
882 Ok(_) => Ok(()),
883 Err(Error::TxFifoFull) => Err(nb::Error::WouldBlock),
884 Err(e) => Err(nb::Error::Other(e)),
885 }
886 }
887
888 fn flush(&mut self) -> core::result::Result<(), nb::Error<Self::Error>> {
889 match self.flush() {
890 Ok(_) => Ok(()),
891 Err(Error::TxBusy) => Err(nb::Error::WouldBlock),
892 Err(e) => Err(nb::Error::Other(e)),
893 }
894 }
895}
896
897impl embedded_hal_02::blocking::serial::Write<u8> for UartTx<'_, Blocking> {
898 type Error = Error;
899
900 fn bwrite_all(&mut self, buffer: &[u8]) -> core::result::Result<(), Self::Error> {
901 self.blocking_write(buffer)
902 }
903
904 fn bflush(&mut self) -> core::result::Result<(), Self::Error> {
905 self.blocking_flush()
906 }
907}
908
909impl embedded_hal_02::serial::Read<u8> for Uart<'_, Blocking> {
910 type Error = Error;
911
912 fn read(&mut self) -> core::result::Result<u8, nb::Error<Self::Error>> {
913 embedded_hal_02::serial::Read::read(&mut self.rx)
914 }
915}
916
917impl embedded_hal_02::serial::Write<u8> for Uart<'_, Blocking> {
918 type Error = Error;
919
920 fn write(&mut self, word: u8) -> core::result::Result<(), nb::Error<Self::Error>> {
921 embedded_hal_02::serial::Write::write(&mut self.tx, word)
922 }
923
924 fn flush(&mut self) -> core::result::Result<(), nb::Error<Self::Error>> {
925 embedded_hal_02::serial::Write::flush(&mut self.tx)
926 }
927}
928
929impl embedded_hal_02::blocking::serial::Write<u8> for Uart<'_, Blocking> {
930 type Error = Error;
931
932 fn bwrite_all(&mut self, buffer: &[u8]) -> core::result::Result<(), Self::Error> {
933 self.blocking_write(buffer)
934 }
935
936 fn bflush(&mut self) -> core::result::Result<(), Self::Error> {
937 self.blocking_flush()
938 }
939}
940
941impl embedded_hal_nb::serial::Error for Error {
942 fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
943 match *self {
944 Self::Framing => embedded_hal_nb::serial::ErrorKind::FrameFormat,
945 Self::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun,
946 Self::Parity => embedded_hal_nb::serial::ErrorKind::Parity,
947 Self::Noise => embedded_hal_nb::serial::ErrorKind::Noise,
948 _ => embedded_hal_nb::serial::ErrorKind::Other,
949 }
950 }
951}
952
953impl embedded_hal_nb::serial::ErrorType for UartRx<'_, Blocking> {
954 type Error = Error;
955}
956
957impl embedded_hal_nb::serial::ErrorType for UartTx<'_, Blocking> {
958 type Error = Error;
959}
960
961impl embedded_hal_nb::serial::ErrorType for Uart<'_, Blocking> {
962 type Error = Error;
963}
964
965impl embedded_hal_nb::serial::Read for UartRx<'_, Blocking> {
966 fn read(&mut self) -> nb::Result<u8, Self::Error> {
967 let mut buf = [0; 1];
968
969 match self.read(&mut buf) {
970 Ok(_) => Ok(buf[0]),
971 Err(Error::RxFifoEmpty) => Err(nb::Error::WouldBlock),
972 Err(e) => Err(nb::Error::Other(e)),
973 }
974 }
975}
976
977impl embedded_hal_nb::serial::Write for UartTx<'_, Blocking> {
978 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
979 match self.write(&[word]) {
980 Ok(_) => Ok(()),
981 Err(Error::TxFifoFull) => Err(nb::Error::WouldBlock),
982 Err(e) => Err(nb::Error::Other(e)),
983 }
984 }
985
986 fn flush(&mut self) -> nb::Result<(), Self::Error> {
987 match self.flush() {
988 Ok(_) => Ok(()),
989 Err(Error::TxBusy) => Err(nb::Error::WouldBlock),
990 Err(e) => Err(nb::Error::Other(e)),
991 }
992 }
993}
994
995impl embedded_hal_nb::serial::Read for Uart<'_, Blocking> {
996 fn read(&mut self) -> core::result::Result<u8, nb::Error<Self::Error>> {
997 embedded_hal_02::serial::Read::read(&mut self.rx)
998 }
999}
1000
1001impl embedded_hal_nb::serial::Write for Uart<'_, Blocking> {
1002 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
1003 self.blocking_write(&[char]).map_err(nb::Error::Other)
1004 }
1005
1006 fn flush(&mut self) -> nb::Result<(), Self::Error> {
1007 self.blocking_flush().map_err(nb::Error::Other)
1008 }
1009}
1010
1011struct Info {
1012 regs: &'static crate::pac::usart0::RegisterBlock,
1013 index: usize,
1014 refcnt: AtomicU8,
1015}
1016
1017trait SealedInstance {
1018 fn info() -> Info;
1019 fn index() -> usize;
1020}
1021
1022/// UART interrupt handler.
1023pub struct InterruptHandler<T: Instance> {
1024 _phantom: PhantomData<T>,
1025}
1026
1027const UART_COUNT: usize = 8;
1028static UART_WAKERS: [AtomicWaker; UART_COUNT] = [const { AtomicWaker::new() }; UART_COUNT];
1029
1030impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
1031 unsafe fn on_interrupt() {
1032 let waker = &UART_WAKERS[T::index()];
1033 let regs = T::info().regs;
1034 let stat = regs.intstat().read();
1035
1036 if stat.txidle().bit_is_set()
1037 || stat.framerrint().bit_is_set()
1038 || stat.parityerrint().bit_is_set()
1039 || stat.rxnoiseint().bit_is_set()
1040 || stat.aberrint().bit_is_set()
1041 {
1042 regs.intenclr().write(|w| {
1043 w.txidleclr()
1044 .set_bit()
1045 .framerrclr()
1046 .set_bit()
1047 .parityerrclr()
1048 .set_bit()
1049 .rxnoiseclr()
1050 .set_bit()
1051 .aberrclr()
1052 .set_bit()
1053 });
1054 }
1055
1056 waker.wake();
1057 }
1058}
1059
1060/// UART instance trait.
1061#[allow(private_bounds)]
1062pub trait Instance: crate::flexcomm::IntoUsart + SealedInstance + PeripheralType + 'static + Send {
1063 /// Interrupt for this UART instance.
1064 type Interrupt: interrupt::typelevel::Interrupt;
1065}
1066
1067macro_rules! impl_instance {
1068 ($($n:expr),*) => {
1069 $(
1070 paste!{
1071 impl SealedInstance for crate::peripherals::[<FLEXCOMM $n>] {
1072 fn info() -> Info {
1073 Info {
1074 regs: unsafe { &*crate::pac::[<Usart $n>]::ptr() },
1075 index: $n,
1076 refcnt: AtomicU8::new(0),
1077 }
1078 }
1079
1080 #[inline]
1081 fn index() -> usize {
1082 $n
1083 }
1084 }
1085
1086 impl Instance for crate::peripherals::[<FLEXCOMM $n>] {
1087 type Interrupt = crate::interrupt::typelevel::[<FLEXCOMM $n>];
1088 }
1089 }
1090 )*
1091 };
1092}
1093
1094impl_instance!(0, 1, 2, 3, 4, 5, 6, 7);
1095
1096impl<T: Pin> Sealed for T {}
1097
1098/// io configuration trait for Uart Tx configuration
1099pub trait TxPin<T: Instance>: Pin + Sealed + PeripheralType {
1100 /// convert the pin to appropriate function for Uart Tx usage
1101 fn as_tx(&self);
1102}
1103
1104/// io configuration trait for Uart Rx configuration
1105pub trait RxPin<T: Instance>: Pin + Sealed + PeripheralType {
1106 /// convert the pin to appropriate function for Uart Rx usage
1107 fn as_rx(&self);
1108}
1109
1110/// io configuration trait for Uart Cts
1111pub trait CtsPin<T: Instance>: Pin + Sealed + PeripheralType {
1112 /// convert the pin to appropriate function for Uart Cts usage
1113 fn as_cts(&self);
1114}
1115
1116/// io configuration trait for Uart Rts
1117pub trait RtsPin<T: Instance>: Pin + Sealed + PeripheralType {
1118 /// convert the pin to appropriate function for Uart Rts usage
1119 fn as_rts(&self);
1120}
1121
1122macro_rules! impl_pin_trait {
1123 ($fcn:ident, $mode:ident, $($pin:ident, $fn:ident),*) => {
1124 paste! {
1125 $(
1126 impl [<$mode:camel Pin>]<crate::peripherals::$fcn> for crate::peripherals::$pin {
1127 fn [<as_ $mode>](&self) {
1128 // UM11147 table 507 pg 495
1129 self.set_function(crate::iopctl::Function::$fn)
1130 .set_pull(Pull::None)
1131 .enable_input_buffer()
1132 .set_slew_rate(SlewRate::Standard)
1133 .set_drive_strength(DriveStrength::Normal)
1134 .disable_analog_multiplex()
1135 .set_drive_mode(DriveMode::PushPull)
1136 .set_input_inverter(Inverter::Disabled);
1137 }
1138 }
1139 )*
1140 }
1141 };
1142}
1143
1144// FLEXCOMM0
1145impl_pin_trait!(FLEXCOMM0, tx, PIO0_1, F1, PIO3_1, F5);
1146impl_pin_trait!(FLEXCOMM0, rx, PIO0_2, F1, PIO3_2, F5);
1147impl_pin_trait!(FLEXCOMM0, cts, PIO0_3, F1, PIO3_3, F5);
1148impl_pin_trait!(FLEXCOMM0, rts, PIO0_4, F1, PIO3_4, F5);
1149
1150// FLEXCOMM1
1151impl_pin_trait!(FLEXCOMM1, tx, PIO0_8, F1, PIO7_26, F1);
1152impl_pin_trait!(FLEXCOMM1, rx, PIO0_9, F1, PIO7_27, F1);
1153impl_pin_trait!(FLEXCOMM1, cts, PIO0_10, F1, PIO7_28, F1);
1154impl_pin_trait!(FLEXCOMM1, rts, PIO0_11, F1, PIO7_29, F1);
1155
1156// FLEXCOMM2
1157impl_pin_trait!(FLEXCOMM2, tx, PIO0_15, F1, PIO7_30, F5);
1158impl_pin_trait!(FLEXCOMM2, rx, PIO0_16, F1, PIO7_31, F5);
1159impl_pin_trait!(FLEXCOMM2, cts, PIO0_17, F1, PIO4_8, F5);
1160impl_pin_trait!(FLEXCOMM2, rts, PIO0_18, F1);
1161
1162// FLEXCOMM3
1163impl_pin_trait!(FLEXCOMM3, tx, PIO0_22, F1);
1164impl_pin_trait!(FLEXCOMM3, rx, PIO0_23, F1);
1165impl_pin_trait!(FLEXCOMM3, cts, PIO0_24, F1);
1166impl_pin_trait!(FLEXCOMM3, rts, PIO0_25, F1);
1167
1168// FLEXCOMM4
1169impl_pin_trait!(FLEXCOMM4, tx, PIO0_29, F1);
1170impl_pin_trait!(FLEXCOMM4, rx, PIO0_30, F1);
1171impl_pin_trait!(FLEXCOMM4, cts, PIO0_31, F1);
1172impl_pin_trait!(FLEXCOMM4, rts, PIO1_0, F1);
1173
1174// FLEXCOMM5
1175impl_pin_trait!(FLEXCOMM5, tx, PIO1_4, F1, PIO3_16, F5);
1176impl_pin_trait!(FLEXCOMM5, rx, PIO1_5, F1, PIO3_17, F5);
1177impl_pin_trait!(FLEXCOMM5, cts, PIO1_6, F1, PIO3_18, F5);
1178impl_pin_trait!(FLEXCOMM5, rts, PIO1_7, F1, PIO3_23, F5);
1179
1180// FLEXCOMM6
1181impl_pin_trait!(FLEXCOMM6, tx, PIO3_26, F1);
1182impl_pin_trait!(FLEXCOMM6, rx, PIO3_27, F1);
1183impl_pin_trait!(FLEXCOMM6, cts, PIO3_28, F1);
1184impl_pin_trait!(FLEXCOMM6, rts, PIO3_29, F1);
1185
1186// FLEXCOMM7
1187impl_pin_trait!(FLEXCOMM7, tx, PIO4_1, F1);
1188impl_pin_trait!(FLEXCOMM7, rx, PIO4_2, F1);
1189impl_pin_trait!(FLEXCOMM7, cts, PIO4_3, F1);
1190impl_pin_trait!(FLEXCOMM7, rts, PIO4_4, F1);
1191
1192/// UART Tx DMA trait.
1193#[allow(private_bounds)]
1194pub trait TxDma<T: Instance>: crate::dma::Channel {}
1195
1196/// UART Rx DMA trait.
1197#[allow(private_bounds)]
1198pub trait RxDma<T: Instance>: crate::dma::Channel {}
1199
1200macro_rules! impl_dma {
1201 ($fcn:ident, $mode:ident, $dma:ident) => {
1202 paste! {
1203 impl [<$mode Dma>]<crate::peripherals::$fcn> for crate::peripherals::$dma {}
1204 }
1205 };
1206}
1207
1208impl_dma!(FLEXCOMM0, Rx, DMA0_CH0);
1209impl_dma!(FLEXCOMM0, Tx, DMA0_CH1);
1210
1211impl_dma!(FLEXCOMM1, Rx, DMA0_CH2);
1212impl_dma!(FLEXCOMM1, Tx, DMA0_CH3);
1213
1214impl_dma!(FLEXCOMM2, Rx, DMA0_CH4);
1215impl_dma!(FLEXCOMM2, Tx, DMA0_CH5);
1216
1217impl_dma!(FLEXCOMM3, Rx, DMA0_CH6);
1218impl_dma!(FLEXCOMM3, Tx, DMA0_CH7);
1219
1220impl_dma!(FLEXCOMM4, Rx, DMA0_CH8);
1221impl_dma!(FLEXCOMM4, Tx, DMA0_CH9);
1222
1223impl_dma!(FLEXCOMM5, Rx, DMA0_CH10);
1224impl_dma!(FLEXCOMM5, Tx, DMA0_CH11);
1225
1226impl_dma!(FLEXCOMM6, Rx, DMA0_CH12);
1227impl_dma!(FLEXCOMM6, Tx, DMA0_CH13);
1228
1229impl_dma!(FLEXCOMM7, Rx, DMA0_CH14);
1230impl_dma!(FLEXCOMM7, Tx, DMA0_CH15);
diff --git a/embassy-imxrt/src/gpio.rs b/embassy-imxrt/src/gpio.rs
index 6883c4ee0..e62fde8b1 100644
--- a/embassy-imxrt/src/gpio.rs
+++ b/embassy-imxrt/src/gpio.rs
@@ -13,7 +13,7 @@ use crate::clocks::enable_and_reset;
13use crate::iopctl::IopctlPin; 13use crate::iopctl::IopctlPin;
14pub use crate::iopctl::{AnyPin, DriveMode, DriveStrength, Function, Inverter, Pull, SlewRate}; 14pub use crate::iopctl::{AnyPin, DriveMode, DriveStrength, Function, Inverter, Pull, SlewRate};
15use crate::sealed::Sealed; 15use crate::sealed::Sealed;
16use crate::{interrupt, peripherals, Peri, PeripheralType}; 16use crate::{interrupt, peripherals, BitIter, Peri, PeripheralType};
17 17
18// This should be unique per IMXRT package 18// This should be unique per IMXRT package
19const PORT_COUNT: usize = 8; 19const PORT_COUNT: usize = 8;
@@ -64,24 +64,6 @@ fn GPIO_INTA() {
64} 64}
65 65
66#[cfg(feature = "rt")] 66#[cfg(feature = "rt")]
67struct BitIter(u32);
68
69#[cfg(feature = "rt")]
70impl Iterator for BitIter {
71 type Item = u32;
72
73 fn next(&mut self) -> Option<Self::Item> {
74 match self.0.trailing_zeros() {
75 32 => None,
76 b => {
77 self.0 &= !(1 << b);
78 Some(b)
79 }
80 }
81 }
82}
83
84#[cfg(feature = "rt")]
85fn irq_handler(port_wakers: &[Option<&PortWaker>]) { 67fn irq_handler(port_wakers: &[Option<&PortWaker>]) {
86 let reg = unsafe { crate::pac::Gpio::steal() }; 68 let reg = unsafe { crate::pac::Gpio::steal() };
87 69
diff --git a/embassy-imxrt/src/lib.rs b/embassy-imxrt/src/lib.rs
index ad9f81e88..5846afe5c 100644
--- a/embassy-imxrt/src/lib.rs
+++ b/embassy-imxrt/src/lib.rs
@@ -18,8 +18,12 @@ compile_error!(
18pub(crate) mod fmt; 18pub(crate) mod fmt;
19 19
20pub mod clocks; 20pub mod clocks;
21pub mod crc;
22pub mod dma;
23pub mod flexcomm;
21pub mod gpio; 24pub mod gpio;
22pub mod iopctl; 25pub mod iopctl;
26pub mod rng;
23 27
24#[cfg(feature = "_time-driver")] 28#[cfg(feature = "_time-driver")]
25pub mod time_driver; 29pub mod time_driver;
@@ -52,16 +56,20 @@ pub use crate::pac::NVIC_PRIO_BITS;
52/// ```rust,ignore 56/// ```rust,ignore
53/// use embassy_imxrt::{bind_interrupts, flexspi, peripherals}; 57/// use embassy_imxrt::{bind_interrupts, flexspi, peripherals};
54/// 58///
55/// bind_interrupts!(struct Irqs { 59/// bind_interrupts!(
56/// FLEXSPI_IRQ => flexspi::InterruptHandler<peripherals::FLEXSPI>; 60/// /// Binds the FLEXSPI interrupt.
57/// }); 61/// struct Irqs {
62/// FLEXSPI_IRQ => flexspi::InterruptHandler<peripherals::FLEXSPI>;
63/// }
64/// );
58/// ``` 65/// ```
59/// 66///
60// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. 67// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`.
61#[macro_export] 68#[macro_export]
62macro_rules! bind_interrupts { 69macro_rules! bind_interrupts {
63 ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { 70 ($(#[$attr:meta])* $vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
64 #[derive(Copy, Clone)] 71 #[derive(Copy, Clone)]
72 $(#[$attr])*
65 $vis struct $name; 73 $vis struct $name;
66 74
67 $( 75 $(
@@ -127,14 +135,16 @@ pub fn init(config: config::Config) -> Peripherals {
127 // before doing anything important. 135 // before doing anything important.
128 let peripherals = Peripherals::take(); 136 let peripherals = Peripherals::take();
129 137
138 #[cfg(feature = "_time-driver")]
139 time_driver::init(config.time_interrupt_priority);
140
130 unsafe { 141 unsafe {
131 if let Err(e) = clocks::init(config.clocks) { 142 if let Err(e) = clocks::init(config.clocks) {
132 error!("unable to initialize Clocks for reason: {:?}", e); 143 error!("unable to initialize Clocks for reason: {:?}", e);
133 // Panic here? 144 // Panic here?
134 } 145 }
146 dma::init();
135 } 147 }
136 #[cfg(feature = "_time-driver")]
137 time_driver::init(config.time_interrupt_priority);
138 gpio::init(); 148 gpio::init();
139 149
140 peripherals 150 peripherals
@@ -143,3 +153,21 @@ pub fn init(config: config::Config) -> Peripherals {
143pub(crate) mod sealed { 153pub(crate) mod sealed {
144 pub trait Sealed {} 154 pub trait Sealed {}
145} 155}
156
157#[cfg(feature = "rt")]
158struct BitIter(u32);
159
160#[cfg(feature = "rt")]
161impl Iterator for BitIter {
162 type Item = u32;
163
164 fn next(&mut self) -> Option<Self::Item> {
165 match self.0.trailing_zeros() {
166 32 => None,
167 b => {
168 self.0 &= !(1 << b);
169 Some(b)
170 }
171 }
172 }
173}
diff --git a/embassy-imxrt/src/rng.rs b/embassy-imxrt/src/rng.rs
new file mode 100644
index 000000000..75f243df9
--- /dev/null
+++ b/embassy-imxrt/src/rng.rs
@@ -0,0 +1,287 @@
1//! True Random Number Generator (TRNG)
2
3use core::future::poll_fn;
4use core::marker::PhantomData;
5use core::task::Poll;
6
7use embassy_futures::block_on;
8use embassy_sync::waitqueue::AtomicWaker;
9
10use crate::clocks::{enable_and_reset, SysconPeripheral};
11use crate::interrupt::typelevel::Interrupt;
12use crate::{interrupt, peripherals, Peri, PeripheralType};
13
14static RNG_WAKER: AtomicWaker = AtomicWaker::new();
15
16/// RNG ;error
17#[derive(Debug, PartialEq, Eq, Clone, Copy)]
18#[cfg_attr(feature = "defmt", derive(defmt::Format))]
19pub enum Error {
20 /// Seed error.
21 SeedError,
22
23 /// HW Error.
24 HwError,
25
26 /// Frequency Count Fail
27 FreqCountFail,
28}
29
30/// RNG interrupt handler.
31pub struct InterruptHandler<T: Instance> {
32 _phantom: PhantomData<T>,
33}
34
35impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
36 unsafe fn on_interrupt() {
37 let regs = T::info().regs;
38 let int_status = regs.int_status().read();
39
40 if int_status.ent_val().bit_is_set()
41 || int_status.hw_err().bit_is_set()
42 || int_status.frq_ct_fail().bit_is_set()
43 {
44 regs.int_ctrl().modify(|_, w| {
45 w.ent_val()
46 .ent_val_0()
47 .hw_err()
48 .hw_err_0()
49 .frq_ct_fail()
50 .frq_ct_fail_0()
51 });
52 RNG_WAKER.wake();
53 }
54 }
55}
56
57/// RNG driver.
58pub struct Rng<'d> {
59 info: Info,
60 _lifetime: PhantomData<&'d ()>,
61}
62
63impl<'d> Rng<'d> {
64 /// Create a new RNG driver.
65 pub fn new<T: Instance>(
66 _inner: Peri<'d, T>,
67 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
68 ) -> Self {
69 enable_and_reset::<T>();
70
71 let mut random = Self {
72 info: T::info(),
73 _lifetime: PhantomData,
74 };
75 random.init();
76
77 T::Interrupt::unpend();
78 unsafe { T::Interrupt::enable() };
79
80 random
81 }
82
83 /// Reset the RNG.
84 pub fn reset(&mut self) {
85 self.info.regs.mctl().write(|w| w.rst_def().set_bit().prgm().set_bit());
86 }
87
88 /// Fill the given slice with random values.
89 pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
90 // We have a total of 16 words (512 bits) of entropy at our
91 // disposal. The idea here is to read all bits and copy the
92 // necessary bytes to the slice.
93 for chunk in dest.chunks_mut(64) {
94 self.async_fill_chunk(chunk).await?;
95 }
96
97 Ok(())
98 }
99
100 async fn async_fill_chunk(&mut self, chunk: &mut [u8]) -> Result<(), Error> {
101 // wait for interrupt
102 let res = poll_fn(|cx| {
103 // Check if already ready.
104 // TODO: Is this necessary? Could we just check once after
105 // the waker has been registered?
106 if self.info.regs.int_status().read().ent_val().bit_is_set() {
107 return Poll::Ready(Ok(()));
108 }
109
110 RNG_WAKER.register(cx.waker());
111
112 self.unmask_interrupts();
113
114 let mctl = self.info.regs.mctl().read();
115
116 // Check again if interrupt fired
117 if mctl.ent_val().bit_is_set() {
118 Poll::Ready(Ok(()))
119 } else if mctl.err().bit_is_set() {
120 Poll::Ready(Err(Error::HwError))
121 } else if mctl.fct_fail().bit_is_set() {
122 Poll::Ready(Err(Error::FreqCountFail))
123 } else {
124 Poll::Pending
125 }
126 })
127 .await;
128
129 let bits = self.info.regs.mctl().read();
130
131 if bits.ent_val().bit_is_set() {
132 let mut entropy = [0; 16];
133
134 for (i, item) in entropy.iter_mut().enumerate() {
135 *item = self.info.regs.ent(i).read().bits();
136 }
137
138 // Read MCTL after reading ENT15
139 let _ = self.info.regs.mctl().read();
140
141 if entropy.iter().any(|e| *e == 0) {
142 return Err(Error::SeedError);
143 }
144
145 // SAFETY: entropy is the same for input and output types in
146 // native endianness.
147 let entropy: [u8; 64] = unsafe { core::mem::transmute(entropy) };
148
149 // write bytes to chunk
150 chunk.copy_from_slice(&entropy[..chunk.len()]);
151 }
152
153 res
154 }
155
156 fn mask_interrupts(&mut self) {
157 self.info.regs.int_mask().write(|w| {
158 w.ent_val()
159 .ent_val_0()
160 .hw_err()
161 .hw_err_0()
162 .frq_ct_fail()
163 .frq_ct_fail_0()
164 });
165 }
166
167 fn unmask_interrupts(&mut self) {
168 self.info.regs.int_mask().modify(|_, w| {
169 w.ent_val()
170 .ent_val_1()
171 .hw_err()
172 .hw_err_1()
173 .frq_ct_fail()
174 .frq_ct_fail_1()
175 });
176 }
177
178 fn enable_interrupts(&mut self) {
179 self.info.regs.int_ctrl().write(|w| {
180 w.ent_val()
181 .ent_val_1()
182 .hw_err()
183 .hw_err_1()
184 .frq_ct_fail()
185 .frq_ct_fail_1()
186 });
187 }
188
189 fn init(&mut self) {
190 self.mask_interrupts();
191
192 // Switch TRNG to programming mode
193 self.info.regs.mctl().modify(|_, w| w.prgm().set_bit());
194
195 self.enable_interrupts();
196
197 // Switch TRNG to Run Mode
198 self.info
199 .regs
200 .mctl()
201 .modify(|_, w| w.trng_acc().set_bit().prgm().clear_bit());
202 }
203
204 /// Generate a random u32
205 pub fn blocking_next_u32(&mut self) -> u32 {
206 let mut bytes = [0u8; 4];
207 block_on(self.async_fill_bytes(&mut bytes)).unwrap();
208 u32::from_ne_bytes(bytes)
209 }
210
211 /// Generate a random u64
212 pub fn blocking_next_u64(&mut self) -> u64 {
213 let mut bytes = [0u8; 8];
214 block_on(self.async_fill_bytes(&mut bytes)).unwrap();
215 u64::from_ne_bytes(bytes)
216 }
217
218 /// Fill a slice with random bytes.
219 pub fn blocking_fill_bytes(&mut self, dest: &mut [u8]) {
220 block_on(self.async_fill_bytes(dest)).unwrap();
221 }
222}
223
224impl<'d> rand_core_06::RngCore for Rng<'d> {
225 fn next_u32(&mut self) -> u32 {
226 self.blocking_next_u32()
227 }
228
229 fn next_u64(&mut self) -> u64 {
230 self.blocking_next_u64()
231 }
232
233 fn fill_bytes(&mut self, dest: &mut [u8]) {
234 self.blocking_fill_bytes(dest);
235 }
236
237 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
238 self.blocking_fill_bytes(dest);
239 Ok(())
240 }
241}
242
243impl<'d> rand_core_06::CryptoRng for Rng<'d> {}
244
245impl<'d> rand_core_09::RngCore for Rng<'d> {
246 fn next_u32(&mut self) -> u32 {
247 self.blocking_next_u32()
248 }
249
250 fn next_u64(&mut self) -> u64 {
251 self.blocking_next_u64()
252 }
253
254 fn fill_bytes(&mut self, dest: &mut [u8]) {
255 self.blocking_fill_bytes(dest);
256 }
257}
258
259impl<'d> rand_core_09::CryptoRng for Rng<'d> {}
260
261struct Info {
262 regs: crate::pac::Trng,
263}
264
265trait SealedInstance {
266 fn info() -> Info;
267}
268
269/// RNG instance trait.
270#[allow(private_bounds)]
271pub trait Instance: SealedInstance + PeripheralType + SysconPeripheral + 'static + Send {
272 /// Interrupt for this RNG instance.
273 type Interrupt: interrupt::typelevel::Interrupt;
274}
275
276impl Instance for peripherals::RNG {
277 type Interrupt = crate::interrupt::typelevel::RNG;
278}
279
280impl SealedInstance for peripherals::RNG {
281 fn info() -> Info {
282 // SAFETY: safe from single executor
283 Info {
284 regs: unsafe { crate::pac::Trng::steal() },
285 }
286 }
287}
diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml
index df996ff4b..1b189e05a 100644
--- a/embassy-mspm0/Cargo.toml
+++ b/embassy-mspm0/Cargo.toml
@@ -38,7 +38,7 @@ embassy-executor = { version = "0.7.0", path = "../embassy-executor", optional =
38embedded-hal = { version = "1.0" } 38embedded-hal = { version = "1.0" }
39embedded-hal-async = { version = "1.0" } 39embedded-hal-async = { version = "1.0" }
40 40
41defmt = { version = "0.3", optional = true } 41defmt = { version = "1.0.1", optional = true }
42fixed = "1.29" 42fixed = "1.29"
43log = { version = "0.4.14", optional = true } 43log = { version = "0.4.14", optional = true }
44cortex-m-rt = ">=0.6.15,<0.8" 44cortex-m-rt = ">=0.6.15,<0.8"
@@ -46,14 +46,14 @@ cortex-m = "0.7.6"
46critical-section = "1.2.0" 46critical-section = "1.2.0"
47 47
48# mspm0-metapac = { version = "" } 48# mspm0-metapac = { version = "" }
49mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-119240dd23ef5748d2a7bef219ca298d37ba604a" } 49mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-66a55c7bf38a2201ff48c299843e741f2d537f0b" }
50 50
51[build-dependencies] 51[build-dependencies]
52proc-macro2 = "1.0.94" 52proc-macro2 = "1.0.94"
53quote = "1.0.40" 53quote = "1.0.40"
54 54
55# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } 55# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] }
56mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-119240dd23ef5748d2a7bef219ca298d37ba604a", default-features = false, features = ["metadata"] } 56mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-66a55c7bf38a2201ff48c299843e741f2d537f0b", default-features = false, features = ["metadata"] }
57 57
58[features] 58[features]
59default = ["rt"] 59default = ["rt"]
@@ -120,14 +120,138 @@ time-driver-tima0 = ["_time-driver"]
120time-driver-tima1 = ["_time-driver"] 120time-driver-tima1 = ["_time-driver"]
121 121
122#! ## Chip-selection features 122#! ## Chip-selection features
123#! Select your chip by specifying the model as a feature, e.g. `mspm0g350x`. 123#! Select your chip by specifying the model as a feature, e.g. `mspm0g3507pm`.
124#! Check the `Cargo.toml` for the latest list of supported chips. 124#! Check the `Cargo.toml` for the latest list of supported chips.
125#! 125#!
126#! **Important:** Do not forget to adapt the target chip in your toolchain, 126#! **Important:** Do not forget to adapt the target chip in your toolchain,
127#! e.g. in `.cargo/config.toml`. 127#! e.g. in `.cargo/config.toml`.
128 128
129mspm0c110x = [ "mspm0-metapac/mspm0c110x" ] 129mspm0c1103dgs20 = ["mspm0-metapac/mspm0c1103dgs20"]
130mspm0g350x = [ "mspm0-metapac/mspm0g350x" ] 130mspm0c1103dsg = ["mspm0-metapac/mspm0c1103dsg"]
131mspm0g351x = [ "mspm0-metapac/mspm0g351x" ] 131mspm0c1103dyy = ["mspm0-metapac/mspm0c1103dyy"]
132mspm0l130x = [ "mspm0-metapac/mspm0l130x" ] 132mspm0c1103ruk = ["mspm0-metapac/mspm0c1103ruk"]
133mspm0l222x = [ "mspm0-metapac/mspm0l222x" ] 133mspm0c1104dgs20 = ["mspm0-metapac/mspm0c1104dgs20"]
134mspm0c1104dsg = ["mspm0-metapac/mspm0c1104dsg"]
135mspm0c1104dyy = ["mspm0-metapac/mspm0c1104dyy"]
136mspm0c1104ruk = ["mspm0-metapac/mspm0c1104ruk"]
137mspm0c1104ycj = ["mspm0-metapac/mspm0c1104ycj"]
138mspm0g1105dgs28 = ["mspm0-metapac/mspm0g1105dgs28"]
139mspm0g1105pm = ["mspm0-metapac/mspm0g1105pm"]
140mspm0g1105pt = ["mspm0-metapac/mspm0g1105pt"]
141mspm0g1105rge = ["mspm0-metapac/mspm0g1105rge"]
142mspm0g1105rgz = ["mspm0-metapac/mspm0g1105rgz"]
143mspm0g1105rhb = ["mspm0-metapac/mspm0g1105rhb"]
144mspm0g1106dgs28 = ["mspm0-metapac/mspm0g1106dgs28"]
145mspm0g1106pm = ["mspm0-metapac/mspm0g1106pm"]
146mspm0g1106pt = ["mspm0-metapac/mspm0g1106pt"]
147mspm0g1106rge = ["mspm0-metapac/mspm0g1106rge"]
148mspm0g1106rgz = ["mspm0-metapac/mspm0g1106rgz"]
149mspm0g1106rhb = ["mspm0-metapac/mspm0g1106rhb"]
150mspm0g1107dgs28 = ["mspm0-metapac/mspm0g1107dgs28"]
151mspm0g1107pm = ["mspm0-metapac/mspm0g1107pm"]
152mspm0g1107pt = ["mspm0-metapac/mspm0g1107pt"]
153mspm0g1107rge = ["mspm0-metapac/mspm0g1107rge"]
154mspm0g1107rgz = ["mspm0-metapac/mspm0g1107rgz"]
155mspm0g1107rhb = ["mspm0-metapac/mspm0g1107rhb"]
156mspm0g1107ycj = ["mspm0-metapac/mspm0g1107ycj"]
157mspm0g1505pm = ["mspm0-metapac/mspm0g1505pm"]
158mspm0g1505pt = ["mspm0-metapac/mspm0g1505pt"]
159mspm0g1505rge = ["mspm0-metapac/mspm0g1505rge"]
160mspm0g1505rgz = ["mspm0-metapac/mspm0g1505rgz"]
161mspm0g1505rhb = ["mspm0-metapac/mspm0g1505rhb"]
162mspm0g1506pm = ["mspm0-metapac/mspm0g1506pm"]
163mspm0g1506pt = ["mspm0-metapac/mspm0g1506pt"]
164mspm0g1506rge = ["mspm0-metapac/mspm0g1506rge"]
165mspm0g1506rgz = ["mspm0-metapac/mspm0g1506rgz"]
166mspm0g1506rhb = ["mspm0-metapac/mspm0g1506rhb"]
167mspm0g1507pm = ["mspm0-metapac/mspm0g1507pm"]
168mspm0g1507pt = ["mspm0-metapac/mspm0g1507pt"]
169mspm0g1507rge = ["mspm0-metapac/mspm0g1507rge"]
170mspm0g1507rgz = ["mspm0-metapac/mspm0g1507rgz"]
171mspm0g1507rhb = ["mspm0-metapac/mspm0g1507rhb"]
172mspm0g1507ycj = ["mspm0-metapac/mspm0g1507ycj"]
173mspm0g1519rgz = ["mspm0-metapac/mspm0g1519rgz"]
174mspm0g1519rhb = ["mspm0-metapac/mspm0g1519rhb"]
175mspm0g3105dgs20 = ["mspm0-metapac/mspm0g3105dgs20"]
176mspm0g3105dgs28 = ["mspm0-metapac/mspm0g3105dgs28"]
177mspm0g3105rhb = ["mspm0-metapac/mspm0g3105rhb"]
178mspm0g3106dgs20 = ["mspm0-metapac/mspm0g3106dgs20"]
179mspm0g3106dgs28 = ["mspm0-metapac/mspm0g3106dgs28"]
180mspm0g3106rhb = ["mspm0-metapac/mspm0g3106rhb"]
181mspm0g3107dgs20 = ["mspm0-metapac/mspm0g3107dgs20"]
182mspm0g3107dgs28 = ["mspm0-metapac/mspm0g3107dgs28"]
183mspm0g3107rhb = ["mspm0-metapac/mspm0g3107rhb"]
184mspm0g3505dgs28 = ["mspm0-metapac/mspm0g3505dgs28"]
185mspm0g3505pm = ["mspm0-metapac/mspm0g3505pm"]
186mspm0g3505pt = ["mspm0-metapac/mspm0g3505pt"]
187mspm0g3505rgz = ["mspm0-metapac/mspm0g3505rgz"]
188mspm0g3505rhb = ["mspm0-metapac/mspm0g3505rhb"]
189mspm0g3506dgs28 = ["mspm0-metapac/mspm0g3506dgs28"]
190mspm0g3506pm = ["mspm0-metapac/mspm0g3506pm"]
191mspm0g3506pt = ["mspm0-metapac/mspm0g3506pt"]
192mspm0g3506rgz = ["mspm0-metapac/mspm0g3506rgz"]
193mspm0g3506rhb = ["mspm0-metapac/mspm0g3506rhb"]
194mspm0g3507dgs28 = ["mspm0-metapac/mspm0g3507dgs28"]
195mspm0g3507pm = ["mspm0-metapac/mspm0g3507pm"]
196mspm0g3507pt = ["mspm0-metapac/mspm0g3507pt"]
197mspm0g3507rgz = ["mspm0-metapac/mspm0g3507rgz"]
198mspm0g3507rhb = ["mspm0-metapac/mspm0g3507rhb"]
199mspm0g3519pm = ["mspm0-metapac/mspm0g3519pm"]
200mspm0g3519pn = ["mspm0-metapac/mspm0g3519pn"]
201mspm0g3519pz = ["mspm0-metapac/mspm0g3519pz"]
202mspm0g3519rgz = ["mspm0-metapac/mspm0g3519rgz"]
203mspm0g3519rhb = ["mspm0-metapac/mspm0g3519rhb"]
204mspm0l1105dgs20 = ["mspm0-metapac/mspm0l1105dgs20"]
205mspm0l1105dgs28 = ["mspm0-metapac/mspm0l1105dgs28"]
206mspm0l1105dyy = ["mspm0-metapac/mspm0l1105dyy"]
207mspm0l1105rge = ["mspm0-metapac/mspm0l1105rge"]
208mspm0l1105rtr = ["mspm0-metapac/mspm0l1105rtr"]
209mspm0l1106dgs20 = ["mspm0-metapac/mspm0l1106dgs20"]
210mspm0l1106dgs28 = ["mspm0-metapac/mspm0l1106dgs28"]
211mspm0l1106dyy = ["mspm0-metapac/mspm0l1106dyy"]
212mspm0l1106rge = ["mspm0-metapac/mspm0l1106rge"]
213mspm0l1106rhb = ["mspm0-metapac/mspm0l1106rhb"]
214mspm0l1106rtr = ["mspm0-metapac/mspm0l1106rtr"]
215mspm0l1227pm = ["mspm0-metapac/mspm0l1227pm"]
216mspm0l1227pn = ["mspm0-metapac/mspm0l1227pn"]
217mspm0l1227pt = ["mspm0-metapac/mspm0l1227pt"]
218mspm0l1227rge = ["mspm0-metapac/mspm0l1227rge"]
219mspm0l1227rgz = ["mspm0-metapac/mspm0l1227rgz"]
220mspm0l1227rhb = ["mspm0-metapac/mspm0l1227rhb"]
221mspm0l1228pm = ["mspm0-metapac/mspm0l1228pm"]
222mspm0l1228pn = ["mspm0-metapac/mspm0l1228pn"]
223mspm0l1228pt = ["mspm0-metapac/mspm0l1228pt"]
224mspm0l1228rge = ["mspm0-metapac/mspm0l1228rge"]
225mspm0l1228rgz = ["mspm0-metapac/mspm0l1228rgz"]
226mspm0l1228rhb = ["mspm0-metapac/mspm0l1228rhb"]
227mspm0l1303rge = ["mspm0-metapac/mspm0l1303rge"]
228mspm0l1304dgs20 = ["mspm0-metapac/mspm0l1304dgs20"]
229mspm0l1304dgs28 = ["mspm0-metapac/mspm0l1304dgs28"]
230mspm0l1304dyy = ["mspm0-metapac/mspm0l1304dyy"]
231mspm0l1304rge = ["mspm0-metapac/mspm0l1304rge"]
232mspm0l1304rhb = ["mspm0-metapac/mspm0l1304rhb"]
233mspm0l1304rtr = ["mspm0-metapac/mspm0l1304rtr"]
234mspm0l1305dgs20 = ["mspm0-metapac/mspm0l1305dgs20"]
235mspm0l1305dgs28 = ["mspm0-metapac/mspm0l1305dgs28"]
236mspm0l1305dyy = ["mspm0-metapac/mspm0l1305dyy"]
237mspm0l1305rge = ["mspm0-metapac/mspm0l1305rge"]
238mspm0l1305rtr = ["mspm0-metapac/mspm0l1305rtr"]
239mspm0l1306dgs20 = ["mspm0-metapac/mspm0l1306dgs20"]
240mspm0l1306dgs28 = ["mspm0-metapac/mspm0l1306dgs28"]
241mspm0l1306dyy = ["mspm0-metapac/mspm0l1306dyy"]
242mspm0l1306rge = ["mspm0-metapac/mspm0l1306rge"]
243mspm0l1306rhb = ["mspm0-metapac/mspm0l1306rhb"]
244mspm0l1343dgs20 = ["mspm0-metapac/mspm0l1343dgs20"]
245mspm0l1344dgs20 = ["mspm0-metapac/mspm0l1344dgs20"]
246mspm0l1345dgs28 = ["mspm0-metapac/mspm0l1345dgs28"]
247mspm0l1346dgs28 = ["mspm0-metapac/mspm0l1346dgs28"]
248mspm0l2227pm = ["mspm0-metapac/mspm0l2227pm"]
249mspm0l2227pn = ["mspm0-metapac/mspm0l2227pn"]
250mspm0l2227pt = ["mspm0-metapac/mspm0l2227pt"]
251mspm0l2227rgz = ["mspm0-metapac/mspm0l2227rgz"]
252mspm0l2228pm = ["mspm0-metapac/mspm0l2228pm"]
253mspm0l2228pn = ["mspm0-metapac/mspm0l2228pn"]
254mspm0l2228pt = ["mspm0-metapac/mspm0l2228pt"]
255mspm0l2228rgz = ["mspm0-metapac/mspm0l2228rgz"]
256msps003f3pw20 = ["mspm0-metapac/msps003f3pw20"]
257msps003f4pw20 = ["mspm0-metapac/msps003f4pw20"]
diff --git a/embassy-mspm0/README.md b/embassy-mspm0/README.md
new file mode 100644
index 000000000..b2b8934aa
--- /dev/null
+++ b/embassy-mspm0/README.md
@@ -0,0 +1,28 @@
1# Embassy MSPM0 HAL
2
3The embassy-mspm0 HAL aims to provide a safe, idiomatic hardware abstraction layer for all MSPM0 and MSPS003 chips.
4
5* [Documentation](https://docs.embassy.dev/embassy-mspm0/) (**Important:** use docs.embassy.dev rather than docs.rs to see the specific docs for the chip you’re using!)
6* [Source](https://github.com/embassy-rs/embassy/tree/main/embassy-mspm0)
7* [Examples](https://github.com/embassy-rs/embassy/tree/main/examples)
8
9## Embedded-hal
10
11The `embassy-mspm0` HAL implements the traits from [embedded-hal](https://crates.io/crates/embedded-hal) (1.0) and [embedded-hal-async](https://crates.io/crates/embedded-hal-async), as well as [embedded-io](https://crates.io/crates/embedded-io) and [embedded-io-async](https://crates.io/crates/embedded-io-async).
12
13## A note on feature flag names
14
15Feature flag names for chips do not include temperature rating or distribution format.
16
17Usually chapter 10 of your device's datasheet will explain the device nomenclature and how to decode it. Feature names in embassy-mspm0 only use the following from device nomenclature:
18- MCU platform
19- Product family
20- Device subfamily
21- Flash memory
22- Package type
23
24This means for a part such as `MSPM0G3507SPMR`, the feature name is `mspm0g3507pm`. This also means that `MSPM0G3507QPMRQ1` uses the feature `mspm0g3507pm`, since the Q1 parts are just qualified variants of the base G3507 with a PM (QFP-64) package.
25
26## Interoperability
27
28This crate can run on any executor.
diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs
index 08209df2a..094769992 100644
--- a/embassy-mspm0/build.rs
+++ b/embassy-mspm0/build.rs
@@ -7,7 +7,7 @@ use std::sync::LazyLock;
7use std::{env, fs}; 7use std::{env, fs};
8 8
9use common::CfgSet; 9use common::CfgSet;
10use mspm0_metapac::metadata::METADATA; 10use mspm0_metapac::metadata::{ALL_CHIPS, METADATA};
11use proc_macro2::{Ident, Literal, Span, TokenStream}; 11use proc_macro2::{Ident, Literal, Span, TokenStream};
12use quote::{format_ident, quote}; 12use quote::{format_ident, quote};
13 13
@@ -24,6 +24,27 @@ fn generate_code() {
24 24
25 cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]); 25 cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]);
26 26
27 let chip_name = match env::vars()
28 .map(|(a, _)| a)
29 .filter(|x| x.starts_with("CARGO_FEATURE_MSPM0") || x.starts_with("CARGO_FEATURE_MSPS"))
30 .get_one()
31 {
32 Ok(x) => x,
33 Err(GetOneError::None) => panic!("No mspm0xx/mspsxx Cargo feature enabled"),
34 Err(GetOneError::Multiple) => panic!("Multiple mspm0xx/mspsxx Cargo features enabled"),
35 }
36 .strip_prefix("CARGO_FEATURE_")
37 .unwrap()
38 .to_ascii_lowercase()
39 .replace('_', "-");
40
41 eprintln!("chip: {chip_name}");
42
43 cfgs.enable_all(&get_chip_cfgs(&chip_name));
44 for chip in ALL_CHIPS {
45 cfgs.declare_all(&get_chip_cfgs(&chip));
46 }
47
27 let mut singletons = get_singletons(&mut cfgs); 48 let mut singletons = get_singletons(&mut cfgs);
28 49
29 time_driver(&mut singletons, &mut cfgs); 50 time_driver(&mut singletons, &mut cfgs);
@@ -44,6 +65,64 @@ fn generate_code() {
44 rustfmt(&out_file); 65 rustfmt(&out_file);
45} 66}
46 67
68fn get_chip_cfgs(chip_name: &str) -> Vec<String> {
69 let mut cfgs = Vec::new();
70
71 // GPIO on C110x is special as it does not belong to an interrupt group.
72 if chip_name.starts_with("mspm0c110") || chip_name.starts_with("msps003f") {
73 cfgs.push("mspm0c110x".to_string());
74 }
75
76 // Family ranges (temporary until int groups are generated)
77 //
78 // TODO: Remove this once int group stuff is generated.
79 if chip_name.starts_with("mspm0g110") {
80 cfgs.push("mspm0g110x".to_string());
81 }
82
83 if chip_name.starts_with("mspm0g150") {
84 cfgs.push("mspm0g150x".to_string());
85 }
86
87 if chip_name.starts_with("mspm0g151") {
88 cfgs.push("mspm0g151x".to_string());
89 }
90
91 if chip_name.starts_with("mspm0g310") {
92 cfgs.push("mspm0g310x".to_string());
93 }
94
95 if chip_name.starts_with("mspm0g350") {
96 cfgs.push("mspm0g350x".to_string());
97 }
98
99 if chip_name.starts_with("mspm0g351") {
100 cfgs.push("mspm0g351x".to_string());
101 }
102
103 if chip_name.starts_with("mspm0l110") {
104 cfgs.push("mspm0l110x".to_string());
105 }
106
107 if chip_name.starts_with("mspm0l122") {
108 cfgs.push("mspm0l122x".to_string());
109 }
110
111 if chip_name.starts_with("mspm0l130") {
112 cfgs.push("mspm0l130x".to_string());
113 }
114
115 if chip_name.starts_with("mspm0l134") {
116 cfgs.push("mspm0l134x".to_string());
117 }
118
119 if chip_name.starts_with("mspm0l222") {
120 cfgs.push("mspm0l222x".to_string());
121 }
122
123 cfgs
124}
125
47#[derive(Debug, Clone)] 126#[derive(Debug, Clone)]
48struct Singleton { 127struct Singleton {
49 name: String, 128 name: String,
@@ -146,7 +225,7 @@ fn make_valid_identifier(s: &str) -> Singleton {
146} 225}
147 226
148fn generate_pincm_mapping() -> TokenStream { 227fn generate_pincm_mapping() -> TokenStream {
149 let pincms = METADATA.pincm_mappings.iter().map(|mapping| { 228 let pincms = METADATA.pins.iter().map(|mapping| {
150 let port_letter = mapping.pin.strip_prefix("P").unwrap(); 229 let port_letter = mapping.pin.strip_prefix("P").unwrap();
151 let port_base = (port_letter.chars().next().unwrap() as u8 - b'A') * 32; 230 let port_base = (port_letter.chars().next().unwrap() as u8 - b'A') * 32;
152 // This assumes all ports are single letter length. 231 // This assumes all ports are single letter length.
@@ -174,11 +253,11 @@ fn generate_pincm_mapping() -> TokenStream {
174} 253}
175 254
176fn generate_pin() -> TokenStream { 255fn generate_pin() -> TokenStream {
177 let pin_impls = METADATA.pincm_mappings.iter().map(|pincm_mapping| { 256 let pin_impls = METADATA.pins.iter().map(|pin| {
178 let name = Ident::new(&pincm_mapping.pin, Span::call_site()); 257 let name = Ident::new(&pin.pin, Span::call_site());
179 let port_letter = pincm_mapping.pin.strip_prefix("P").unwrap(); 258 let port_letter = pin.pin.strip_prefix("P").unwrap();
180 let port_letter = port_letter.chars().next().unwrap(); 259 let port_letter = port_letter.chars().next().unwrap();
181 let pin_number = Literal::u8_unsuffixed(pincm_mapping.pin[2..].parse::<u8>().unwrap()); 260 let pin_number = Literal::u8_unsuffixed(pin.pin[2..].parse::<u8>().unwrap());
182 261
183 let port = Ident::new(&format!("Port{}", port_letter), Span::call_site()); 262 let port = Ident::new(&format!("Port{}", port_letter), Span::call_site());
184 263
diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs
index 3f895d962..19a6230b6 100644
--- a/embassy-mspm0/src/gpio.rs
+++ b/embassy-mspm0/src/gpio.rs
@@ -10,7 +10,7 @@ use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::pac::gpio::vals::*; 11use crate::pac::gpio::vals::*;
12use crate::pac::gpio::{self}; 12use crate::pac::gpio::{self};
13#[cfg(all(feature = "rt", feature = "mspm0c110x"))] 13#[cfg(all(feature = "rt", any(mspm0c110x, mspm0l110x)))]
14use crate::pac::interrupt; 14use crate::pac::interrupt;
15use crate::pac::{self}; 15use crate::pac::{self};
16 16
@@ -1120,7 +1120,7 @@ impl Iterator for BitIter {
1120} 1120}
1121 1121
1122// C110x has a dedicated interrupt just for GPIOA, as it does not have a GROUP1 interrupt. 1122// C110x has a dedicated interrupt just for GPIOA, as it does not have a GROUP1 interrupt.
1123#[cfg(all(feature = "rt", feature = "mspm0c110x"))] 1123#[cfg(all(feature = "rt", any(mspm0c110x, mspm0l110x)))]
1124#[interrupt] 1124#[interrupt]
1125fn GPIOA() { 1125fn GPIOA() {
1126 gpioa_interrupt(); 1126 gpioa_interrupt();
diff --git a/embassy-mspm0/src/int_group/g110x.rs b/embassy-mspm0/src/int_group/g110x.rs
new file mode 100644
index 000000000..9f8ac4d7b
--- /dev/null
+++ b/embassy-mspm0/src/int_group/g110x.rs
@@ -0,0 +1,47 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 }
47}
diff --git a/embassy-mspm0/src/int_group/g150x.rs b/embassy-mspm0/src/int_group/g150x.rs
new file mode 100644
index 000000000..706ba2078
--- /dev/null
+++ b/embassy-mspm0/src/int_group/g150x.rs
@@ -0,0 +1,51 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::COMP0 => todo!("implement COMP0"),
47 Group1::COMP1 => todo!("implement COMP1"),
48 Group1::COMP2 => todo!("implement COMP2"),
49 Group1::TRNG => todo!("implement TRNG"),
50 }
51}
diff --git a/embassy-mspm0/src/int_group/g151x.rs b/embassy-mspm0/src/int_group/g151x.rs
new file mode 100644
index 000000000..e785018a7
--- /dev/null
+++ b/embassy-mspm0/src/int_group/g151x.rs
@@ -0,0 +1,52 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::COMP0 => todo!("implement COMP0"),
47 Group1::COMP1 => todo!("implement COMP1"),
48 Group1::COMP2 => todo!("implement COMP2"),
49 Group1::TRNG => todo!("implement TRNG"),
50 Group1::GPIOC => crate::gpio::gpioc_interrupt(),
51 }
52}
diff --git a/embassy-mspm0/src/int_group/g310x.rs b/embassy-mspm0/src/int_group/g310x.rs
new file mode 100644
index 000000000..ad508d3a2
--- /dev/null
+++ b/embassy-mspm0/src/int_group/g310x.rs
@@ -0,0 +1,48 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::TRNG => todo!("implement TRNG"),
47 }
48}
diff --git a/embassy-mspm0/src/int_group/l11xx.rs b/embassy-mspm0/src/int_group/l11xx.rs
new file mode 100644
index 000000000..426a80c13
--- /dev/null
+++ b/embassy-mspm0/src/int_group/l11xx.rs
@@ -0,0 +1,25 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
diff --git a/embassy-mspm0/src/int_group/l12xx.rs b/embassy-mspm0/src/int_group/l12xx.rs
new file mode 100644
index 000000000..eeb2ce70d
--- /dev/null
+++ b/embassy-mspm0/src/int_group/l12xx.rs
@@ -0,0 +1,49 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
26
27#[cfg(feature = "rt")]
28#[interrupt]
29fn GROUP1() {
30 use mspm0_metapac::Group1;
31
32 let group = pac::CPUSS.int_group(1);
33
34 // Must subtract by 1 since NO_INTR is value 0
35 let iidx = group.iidx().read().stat().to_bits() - 1;
36
37 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
38 debug!("Invalid IIDX for group 1: {}", iidx);
39 return;
40 };
41
42 match group {
43 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
44 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
45 Group1::COMP0 => todo!("implement COMP0"),
46 Group1::TRNG => todo!("implement TRNG"),
47 Group1::GPIOC => crate::gpio::gpioc_interrupt(),
48 }
49}
diff --git a/embassy-mspm0/src/int_group/l130x.rs b/embassy-mspm0/src/int_group/l13xx.rs
index 8be5adcad..8be5adcad 100644
--- a/embassy-mspm0/src/int_group/l130x.rs
+++ b/embassy-mspm0/src/int_group/l13xx.rs
diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs
index e8f5971d5..f129e221b 100644
--- a/embassy-mspm0/src/lib.rs
+++ b/embassy-mspm0/src/lib.rs
@@ -1,6 +1,11 @@
1#![no_std] 1#![no_std]
2// Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc 2// Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc
3#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc, docsrs)))] 3#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc, docsrs)))]
4#![cfg_attr(
5 docsrs,
6 doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-mspm0'>browse the `embassy-mspm0` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only, while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n"
7)]
8#![doc = include_str!("../README.md")]
4 9
5// This mod MUST go first, so that the others see its macros. 10// This mod MUST go first, so that the others see its macros.
6pub(crate) mod fmt; 11pub(crate) mod fmt;
@@ -35,11 +40,17 @@ pub mod mode {
35mod time_driver; 40mod time_driver;
36 41
37// Interrupt group handlers. 42// Interrupt group handlers.
38#[cfg_attr(feature = "mspm0c110x", path = "int_group/c110x.rs")] 43#[cfg_attr(mspm0c110x, path = "int_group/c110x.rs")]
39#[cfg_attr(feature = "mspm0g350x", path = "int_group/g350x.rs")] 44#[cfg_attr(mspm0g110x, path = "int_group/g110x.rs")]
40#[cfg_attr(feature = "mspm0g351x", path = "int_group/g351x.rs")] 45#[cfg_attr(mspm0g150x, path = "int_group/g150x.rs")]
41#[cfg_attr(feature = "mspm0l130x", path = "int_group/l130x.rs")] 46#[cfg_attr(mspm0g350x, path = "int_group/g350x.rs")]
42#[cfg_attr(feature = "mspm0l222x", path = "int_group/l222x.rs")] 47#[cfg_attr(mspm0g151x, path = "int_group/g151x.rs")]
48#[cfg_attr(mspm0g351x, path = "int_group/g351x.rs")]
49#[cfg_attr(mspm0g310x, path = "int_group/g310x.rs")]
50#[cfg_attr(mspm0l110x, path = "int_group/l11xx.rs")]
51#[cfg_attr(mspm0l122x, path = "int_group/l12xx.rs")]
52#[cfg_attr(any(mspm0l130x, mspm0l134x), path = "int_group/l13xx.rs")]
53#[cfg_attr(mspm0l222x, path = "int_group/l222x.rs")]
43mod int_group; 54mod int_group;
44 55
45pub(crate) mod _generated { 56pub(crate) mod _generated {
@@ -109,7 +120,7 @@ pub fn init(_config: Config) -> Peripherals {
109 120
110 _generated::enable_group_interrupts(cs); 121 _generated::enable_group_interrupts(cs);
111 122
112 #[cfg(feature = "mspm0c110x")] 123 #[cfg(mspm0c110x)]
113 unsafe { 124 unsafe {
114 use crate::_generated::interrupt::typelevel::Interrupt; 125 use crate::_generated::interrupt::typelevel::Interrupt;
115 crate::interrupt::typelevel::GPIOA::enable(); 126 crate::interrupt::typelevel::GPIOA::enable();
diff --git a/embassy-net-adin1110/Cargo.toml b/embassy-net-adin1110/Cargo.toml
index 22d494b84..a620928cb 100644
--- a/embassy-net-adin1110/Cargo.toml
+++ b/embassy-net-adin1110/Cargo.toml
@@ -11,7 +11,7 @@ documentation = "https://docs.embassy.dev/embassy-net-adin1110"
11 11
12[dependencies] 12[dependencies]
13heapless = "0.8" 13heapless = "0.8"
14defmt = { version = "0.3", optional = true } 14defmt = { version = "1.0.1", optional = true }
15log = { version = "0.4", default-features = false, optional = true } 15log = { version = "0.4", default-features = false, optional = true }
16embedded-hal-1 = { package = "embedded-hal", version = "1.0" } 16embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
17embedded-hal-async = { version = "1.0" } 17embedded-hal-async = { version = "1.0" }
@@ -29,7 +29,7 @@ critical-section = { version = "1.1.2", features = ["std"] }
29futures-test = "0.3.28" 29futures-test = "0.3.28"
30 30
31[features] 31[features]
32defmt = [ "dep:defmt", "embedded-hal-1/defmt-03" ] 32defmt = ["dep:defmt", "embedded-hal-1/defmt-03"]
33log = ["dep:log"] 33log = ["dep:log"]
34 34
35[package.metadata.embassy_docs] 35[package.metadata.embassy_docs]
diff --git a/embassy-net-driver-channel/Cargo.toml b/embassy-net-driver-channel/Cargo.toml
index 5165621b7..beadbf3c9 100644
--- a/embassy-net-driver-channel/Cargo.toml
+++ b/embassy-net-driver-channel/Cargo.toml
@@ -22,7 +22,7 @@ target = "thumbv7em-none-eabi"
22features = ["defmt"] 22features = ["defmt"]
23 23
24[dependencies] 24[dependencies]
25defmt = { version = "0.3", optional = true } 25defmt = { version = "1.0.1", optional = true }
26log = { version = "0.4.14", optional = true } 26log = { version = "0.4.14", optional = true }
27 27
28embassy-sync = { version = "0.6.2", path = "../embassy-sync" } 28embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
diff --git a/embassy-net-driver/Cargo.toml b/embassy-net-driver/Cargo.toml
index 97e8a0db3..34bc6c91a 100644
--- a/embassy-net-driver/Cargo.toml
+++ b/embassy-net-driver/Cargo.toml
@@ -22,4 +22,4 @@ target = "thumbv7em-none-eabi"
22features = ["defmt"] 22features = ["defmt"]
23 23
24[dependencies] 24[dependencies]
25defmt = { version = "0.3", optional = true } 25defmt = { version = "1.0.1", optional = true }
diff --git a/embassy-net-enc28j60/Cargo.toml b/embassy-net-enc28j60/Cargo.toml
index 74f94816a..b26be1420 100644
--- a/embassy-net-enc28j60/Cargo.toml
+++ b/embassy-net-enc28j60/Cargo.toml
@@ -16,7 +16,7 @@ embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
16embassy-time = { version = "0.4.0", path = "../embassy-time" } 16embassy-time = { version = "0.4.0", path = "../embassy-time" }
17embassy-futures = { version = "0.1.0", path = "../embassy-futures" } 17embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
18 18
19defmt = { version = "0.3", optional = true } 19defmt = { version = "1.0.1", optional = true }
20log = { version = "0.4.14", optional = true } 20log = { version = "0.4.14", optional = true }
21 21
22[package.metadata.embassy_docs] 22[package.metadata.embassy_docs]
diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml
index bab0e6d7c..0cb99e67e 100644
--- a/embassy-net-esp-hosted/Cargo.toml
+++ b/embassy-net-esp-hosted/Cargo.toml
@@ -10,11 +10,11 @@ repository = "https://github.com/embassy-rs/embassy"
10documentation = "https://docs.embassy.dev/embassy-net-esp-hosted" 10documentation = "https://docs.embassy.dev/embassy-net-esp-hosted"
11 11
12[features] 12[features]
13defmt = [ "dep:defmt", "heapless/defmt-03" ] 13defmt = ["dep:defmt", "heapless/defmt-03"]
14log = [ "dep:log" ] 14log = ["dep:log"]
15 15
16[dependencies] 16[dependencies]
17defmt = { version = "0.3", optional = true } 17defmt = { version = "1.0.1", optional = true }
18log = { version = "0.4.14", optional = true } 18log = { version = "0.4.14", optional = true }
19 19
20embassy-time = { version = "0.4.0", path = "../embassy-time" } 20embassy-time = { version = "0.4.0", path = "../embassy-time" }
diff --git a/embassy-net-nrf91/Cargo.toml b/embassy-net-nrf91/Cargo.toml
index 99ec5a318..de12ac36f 100644
--- a/embassy-net-nrf91/Cargo.toml
+++ b/embassy-net-nrf91/Cargo.toml
@@ -10,20 +10,20 @@ repository = "https://github.com/embassy-rs/embassy"
10documentation = "https://docs.embassy.dev/embassy-net-nrf91" 10documentation = "https://docs.embassy.dev/embassy-net-nrf91"
11 11
12[features] 12[features]
13defmt = [ "dep:defmt", "heapless/defmt-03" ] 13defmt = ["dep:defmt", "heapless/defmt-03"]
14log = [ "dep:log" ] 14log = ["dep:log"]
15 15
16[dependencies] 16[dependencies]
17defmt = { version = "0.3", optional = true } 17defmt = { version = "1.0.1", optional = true }
18log = { version = "0.4.14", optional = true } 18log = { version = "0.4.14", optional = true }
19 19
20nrf-pac = "0.1.0" 20nrf-pac = "0.1.0"
21cortex-m = "0.7.7" 21cortex-m = "0.7.7"
22 22
23embassy-time = { version = "0.4.0", path = "../embassy-time" } 23embassy-time = { version = "0.4.0", path = "../embassy-time" }
24embassy-sync = { version = "0.6.2", path = "../embassy-sync"} 24embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
25embassy-futures = { version = "0.1.0", path = "../embassy-futures"} 25embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
26embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel"} 26embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" }
27 27
28heapless = "0.8" 28heapless = "0.8"
29embedded-io = "0.6.1" 29embedded-io = "0.6.1"
diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml
index 2d82e2ad0..ab713fed8 100644
--- a/embassy-net-ppp/Cargo.toml
+++ b/embassy-net-ppp/Cargo.toml
@@ -14,7 +14,7 @@ defmt = ["dep:defmt", "ppproto/defmt"]
14log = ["dep:log", "ppproto/log"] 14log = ["dep:log", "ppproto/log"]
15 15
16[dependencies] 16[dependencies]
17defmt = { version = "0.3", optional = true } 17defmt = { version = "1.0.1", optional = true }
18log = { version = "0.4.14", optional = true } 18log = { version = "0.4.14", optional = true }
19 19
20embedded-io-async = { version = "0.6.1" } 20embedded-io-async = { version = "0.6.1" }
diff --git a/embassy-net-wiznet/Cargo.toml b/embassy-net-wiznet/Cargo.toml
index 2ad5a6f48..a06a09302 100644
--- a/embassy-net-wiznet/Cargo.toml
+++ b/embassy-net-wiznet/Cargo.toml
@@ -15,7 +15,7 @@ embedded-hal-async = { version = "1.0" }
15embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" } 15embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" }
16embassy-time = { version = "0.4.0", path = "../embassy-time" } 16embassy-time = { version = "0.4.0", path = "../embassy-time" }
17embassy-futures = { version = "0.1.0", path = "../embassy-futures" } 17embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
18defmt = { version = "0.3", optional = true } 18defmt = { version = "1.0.1", optional = true }
19 19
20[package.metadata.embassy_docs] 20[package.metadata.embassy_docs]
21src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-wiznet-v$VERSION/embassy-net-wiznet/src/" 21src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-wiznet-v$VERSION/embassy-net-wiznet/src/"
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index c3bf1acbc..d96481f98 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -68,7 +68,7 @@ alloc = ["smoltcp/alloc"]
68 68
69[dependencies] 69[dependencies]
70 70
71defmt = { version = "0.3.8", optional = true } 71defmt = { version = "1.0.1", optional = true }
72log = { version = "0.4.14", optional = true } 72log = { version = "0.4.14", optional = true }
73 73
74smoltcp = { version = "0.12.0", default-features = false, features = [ 74smoltcp = { version = "0.12.0", default-features = false, features = [
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index 6ca099599..e4f40630e 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -154,15 +154,17 @@ embedded-hal-async = { version = "1.0" }
154embedded-io = { version = "0.6.0" } 154embedded-io = { version = "0.6.0" }
155embedded-io-async = { version = "0.6.1" } 155embedded-io-async = { version = "0.6.1" }
156 156
157rand-core-06 = { package = "rand_core", version = "0.6" }
158rand-core-09 = { package = "rand_core", version = "0.9" }
159
157nrf-pac = "0.1.0" 160nrf-pac = "0.1.0"
158 161
159defmt = { version = "0.3", optional = true } 162defmt = { version = "1.0.1", optional = true }
160bitflags = "2.4.2" 163bitflags = "2.4.2"
161log = { version = "0.4.14", optional = true } 164log = { version = "0.4.14", optional = true }
162cortex-m-rt = ">=0.6.15,<0.8" 165cortex-m-rt = ">=0.6.15,<0.8"
163cortex-m = "0.7.6" 166cortex-m = "0.7.6"
164critical-section = "1.1" 167critical-section = "1.1"
165rand_core = "0.6.3"
166fixed = "1.10.0" 168fixed = "1.10.0"
167embedded-storage = "0.3.1" 169embedded-storage = "0.3.1"
168embedded-storage-async = "0.4.1" 170embedded-storage-async = "0.4.1"
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs
index 0103fa7ae..99cf29487 100644
--- a/embassy-nrf/src/chips/nrf5340_app.rs
+++ b/embassy-nrf/src/chips/nrf5340_app.rs
@@ -262,6 +262,9 @@ embassy_hal_internal::peripherals! {
262 PPI_GROUP4, 262 PPI_GROUP4,
263 PPI_GROUP5, 263 PPI_GROUP5,
264 264
265 // IPC
266 IPC,
267
265 // GPIO port 0 268 // GPIO port 0
266 #[cfg(feature = "lfxo-pins-as-gpio")] 269 #[cfg(feature = "lfxo-pins-as-gpio")]
267 P0_00, 270 P0_00,
@@ -327,6 +330,8 @@ embassy_hal_internal::peripherals! {
327 EGU5, 330 EGU5,
328} 331}
329 332
333impl_ipc!(IPC, IPC, IPC);
334
330impl_usb!(USBD, USBD, USBD); 335impl_usb!(USBD, USBD, USBD);
331 336
332impl_uarte!(SERIAL0, UARTE0, SERIAL0); 337impl_uarte!(SERIAL0, UARTE0, SERIAL0);
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs
index 22d33d080..c2932be31 100644
--- a/embassy-nrf/src/chips/nrf5340_net.rs
+++ b/embassy-nrf/src/chips/nrf5340_net.rs
@@ -141,6 +141,9 @@ embassy_hal_internal::peripherals! {
141 PPI_GROUP4, 141 PPI_GROUP4,
142 PPI_GROUP5, 142 PPI_GROUP5,
143 143
144 // IPC
145 IPC,
146
144 // GPIO port 0 147 // GPIO port 0
145 P0_00, 148 P0_00,
146 P0_01, 149 P0_01,
@@ -200,6 +203,8 @@ embassy_hal_internal::peripherals! {
200 EGU0, 203 EGU0,
201} 204}
202 205
206impl_ipc!(IPC, IPC, IPC);
207
203impl_uarte!(SERIAL0, UARTE0, SERIAL0); 208impl_uarte!(SERIAL0, UARTE0, SERIAL0);
204impl_spim!(SERIAL0, SPIM0, SERIAL0); 209impl_spim!(SERIAL0, SPIM0, SERIAL0);
205impl_spis!(SERIAL0, SPIS0, SERIAL0); 210impl_spis!(SERIAL0, SPIS0, SERIAL0);
diff --git a/embassy-nrf/src/ipc.rs b/embassy-nrf/src/ipc.rs
new file mode 100644
index 000000000..a8a08c911
--- /dev/null
+++ b/embassy-nrf/src/ipc.rs
@@ -0,0 +1,363 @@
1//! InterProcessor Communication (IPC)
2
3#![macro_use]
4
5use core::future::poll_fn;
6use core::marker::PhantomData;
7use core::task::Poll;
8
9use embassy_hal_internal::{Peri, PeripheralType};
10use embassy_sync::waitqueue::AtomicWaker;
11
12use crate::interrupt::typelevel::Interrupt;
13use crate::{interrupt, pac, ppi};
14
15const EVENT_COUNT: usize = 16;
16
17/// IPC Event
18#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub enum EventNumber {
20 /// IPC Event 0
21 Event0 = 0,
22 /// IPC Event 1
23 Event1 = 1,
24 /// IPC Event 2
25 Event2 = 2,
26 /// IPC Event 3
27 Event3 = 3,
28 /// IPC Event 4
29 Event4 = 4,
30 /// IPC Event 5
31 Event5 = 5,
32 /// IPC Event 6
33 Event6 = 6,
34 /// IPC Event 7
35 Event7 = 7,
36 /// IPC Event 8
37 Event8 = 8,
38 /// IPC Event 9
39 Event9 = 9,
40 /// IPC Event 10
41 Event10 = 10,
42 /// IPC Event 11
43 Event11 = 11,
44 /// IPC Event 12
45 Event12 = 12,
46 /// IPC Event 13
47 Event13 = 13,
48 /// IPC Event 14
49 Event14 = 14,
50 /// IPC Event 15
51 Event15 = 15,
52}
53
54const EVENTS: [EventNumber; EVENT_COUNT] = [
55 EventNumber::Event0,
56 EventNumber::Event1,
57 EventNumber::Event2,
58 EventNumber::Event3,
59 EventNumber::Event4,
60 EventNumber::Event5,
61 EventNumber::Event6,
62 EventNumber::Event7,
63 EventNumber::Event8,
64 EventNumber::Event9,
65 EventNumber::Event10,
66 EventNumber::Event11,
67 EventNumber::Event12,
68 EventNumber::Event13,
69 EventNumber::Event14,
70 EventNumber::Event15,
71];
72
73/// IPC Channel
74#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
75pub enum IpcChannel {
76 /// IPC Channel 0
77 Channel0,
78 /// IPC Channel 1
79 Channel1,
80 /// IPC Channel 2
81 Channel2,
82 /// IPC Channel 3
83 Channel3,
84 /// IPC Channel 4
85 Channel4,
86 /// IPC Channel 5
87 Channel5,
88 /// IPC Channel 6
89 Channel6,
90 /// IPC Channel 7
91 Channel7,
92 /// IPC Channel 8
93 Channel8,
94 /// IPC Channel 9
95 Channel9,
96 /// IPC Channel 10
97 Channel10,
98 /// IPC Channel 11
99 Channel11,
100 /// IPC Channel 12
101 Channel12,
102 /// IPC Channel 13
103 Channel13,
104 /// IPC Channel 14
105 Channel14,
106 /// IPC Channel 15
107 Channel15,
108}
109
110impl IpcChannel {
111 fn mask(self) -> u32 {
112 1 << (self as u32)
113 }
114}
115
116/// Interrupt Handler
117pub struct InterruptHandler<T: Instance> {
118 _phantom: PhantomData<T>,
119}
120
121impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
122 unsafe fn on_interrupt() {
123 let regs = T::regs();
124
125 // Check if an event was generated, and if it was, trigger the corresponding waker
126 for event in EVENTS {
127 if regs.events_receive(event as usize).read() & 0x01 == 0x01 {
128 regs.intenclr().write(|w| w.0 = 0x01 << event as u32);
129 T::state().wakers[event as usize].wake();
130 }
131 }
132 }
133}
134
135/// IPC driver
136#[non_exhaustive]
137pub struct Ipc<'d, T: Instance> {
138 /// Event 0
139 pub event0: Event<'d, T>,
140 /// Event 1
141 pub event1: Event<'d, T>,
142 /// Event 2
143 pub event2: Event<'d, T>,
144 /// Event 3
145 pub event3: Event<'d, T>,
146 /// Event 4
147 pub event4: Event<'d, T>,
148 /// Event 5
149 pub event5: Event<'d, T>,
150 /// Event 6
151 pub event6: Event<'d, T>,
152 /// Event 7
153 pub event7: Event<'d, T>,
154 /// Event 8
155 pub event8: Event<'d, T>,
156 /// Event 9
157 pub event9: Event<'d, T>,
158 /// Event 10
159 pub event10: Event<'d, T>,
160 /// Event 11
161 pub event11: Event<'d, T>,
162 /// Event 12
163 pub event12: Event<'d, T>,
164 /// Event 13
165 pub event13: Event<'d, T>,
166 /// Event 14
167 pub event14: Event<'d, T>,
168 /// Event 15
169 pub event15: Event<'d, T>,
170}
171
172impl<'d, T: Instance> Ipc<'d, T> {
173 /// Create a new IPC driver.
174 pub fn new(
175 _p: Peri<'d, T>,
176 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
177 ) -> Self {
178 T::Interrupt::unpend();
179 unsafe { T::Interrupt::enable() };
180
181 let _phantom = PhantomData;
182 #[rustfmt::skip]
183 let r = Self { // attributes on expressions are experimental
184 event0: Event { number: EventNumber::Event0, _phantom },
185 event1: Event { number: EventNumber::Event1, _phantom },
186 event2: Event { number: EventNumber::Event2, _phantom },
187 event3: Event { number: EventNumber::Event3, _phantom },
188 event4: Event { number: EventNumber::Event4, _phantom },
189 event5: Event { number: EventNumber::Event5, _phantom },
190 event6: Event { number: EventNumber::Event6, _phantom },
191 event7: Event { number: EventNumber::Event7, _phantom },
192 event8: Event { number: EventNumber::Event8, _phantom },
193 event9: Event { number: EventNumber::Event9, _phantom },
194 event10: Event { number: EventNumber::Event10, _phantom },
195 event11: Event { number: EventNumber::Event11, _phantom },
196 event12: Event { number: EventNumber::Event12, _phantom },
197 event13: Event { number: EventNumber::Event13, _phantom },
198 event14: Event { number: EventNumber::Event14, _phantom },
199 event15: Event { number: EventNumber::Event15, _phantom },
200 };
201 r
202 }
203}
204
205/// IPC event
206pub struct Event<'d, T: Instance> {
207 number: EventNumber,
208 _phantom: PhantomData<&'d T>,
209}
210
211impl<'d, T: Instance> Event<'d, T> {
212 /// Trigger the event.
213 pub fn trigger(&self) {
214 let nr = self.number;
215 T::regs().tasks_send(nr as usize).write_value(1);
216 }
217
218 /// Wait for the event to be triggered.
219 pub async fn wait(&mut self) {
220 let regs = T::regs();
221 let nr = self.number as usize;
222 regs.intenset().write(|w| w.0 = 1 << nr);
223 poll_fn(|cx| {
224 T::state().wakers[nr].register(cx.waker());
225
226 if regs.events_receive(nr).read() == 1 {
227 regs.events_receive(nr).write_value(0x00);
228 Poll::Ready(())
229 } else {
230 Poll::Pending
231 }
232 })
233 .await;
234 }
235
236 /// Returns the [`EventNumber`] of the event.
237 pub fn number(&self) -> EventNumber {
238 self.number
239 }
240
241 /// Create a handle that can trigger the event.
242 pub fn trigger_handle(&self) -> EventTrigger<'d, T> {
243 EventTrigger {
244 number: self.number,
245 _phantom: PhantomData,
246 }
247 }
248
249 /// Configure the channels the event will broadcast to
250 pub fn configure_trigger<I: IntoIterator<Item = IpcChannel>>(&mut self, channels: I) {
251 T::regs().send_cnf(self.number as usize).write(|w| {
252 for channel in channels {
253 w.0 |= channel.mask();
254 }
255 })
256 }
257
258 /// Configure the channels the event will listen on
259 pub fn configure_wait<I: IntoIterator<Item = IpcChannel>>(&mut self, channels: I) {
260 T::regs().receive_cnf(self.number as usize).write(|w| {
261 for channel in channels {
262 w.0 |= channel.mask();
263 }
264 });
265 }
266
267 /// Get the task for the IPC event to use with PPI.
268 pub fn task(&self) -> ppi::Task<'d> {
269 let nr = self.number as usize;
270 let regs = T::regs();
271 ppi::Task::from_reg(regs.tasks_send(nr))
272 }
273
274 /// Get the event for the IPC event to use with PPI.
275 pub fn event(&self) -> ppi::Event<'d> {
276 let nr = self.number as usize;
277 let regs = T::regs();
278 ppi::Event::from_reg(regs.events_receive(nr))
279 }
280
281 /// Reborrow into a "child" Event.
282 ///
283 /// `self` will stay borrowed until the child Event is dropped.
284 pub fn reborrow(&mut self) -> Event<'_, T> {
285 Self { ..*self }
286 }
287
288 /// Steal an IPC event by number.
289 ///
290 /// # Safety
291 ///
292 /// The event number must not be in use by another [`Event`].
293 pub unsafe fn steal(number: EventNumber) -> Self {
294 Self {
295 number,
296 _phantom: PhantomData,
297 }
298 }
299}
300
301/// A handle that can trigger an IPC event.
302///
303/// This `struct` is returned by [`Event::trigger_handle`].
304#[derive(Debug, Copy, Clone)]
305pub struct EventTrigger<'d, T: Instance> {
306 number: EventNumber,
307 _phantom: PhantomData<&'d T>,
308}
309
310impl<T: Instance> EventTrigger<'_, T> {
311 /// Trigger the event.
312 pub fn trigger(&self) {
313 let nr = self.number;
314 T::regs().tasks_send(nr as usize).write_value(1);
315 }
316
317 /// Returns the [`EventNumber`] of the event.
318 pub fn number(&self) -> EventNumber {
319 self.number
320 }
321}
322
323pub(crate) struct State {
324 wakers: [AtomicWaker; EVENT_COUNT],
325}
326
327impl State {
328 pub(crate) const fn new() -> Self {
329 Self {
330 wakers: [const { AtomicWaker::new() }; EVENT_COUNT],
331 }
332 }
333}
334
335pub(crate) trait SealedInstance {
336 fn regs() -> pac::ipc::Ipc;
337 fn state() -> &'static State;
338}
339
340/// IPC peripheral instance.
341#[allow(private_bounds)]
342pub trait Instance: PeripheralType + SealedInstance + 'static + Send {
343 /// Interrupt for this peripheral.
344 type Interrupt: interrupt::typelevel::Interrupt;
345}
346
347macro_rules! impl_ipc {
348 ($type:ident, $pac_type:ident, $irq:ident) => {
349 impl crate::ipc::SealedInstance for peripherals::$type {
350 fn regs() -> pac::ipc::Ipc {
351 pac::$pac_type
352 }
353
354 fn state() -> &'static crate::ipc::State {
355 static STATE: crate::ipc::State = crate::ipc::State::new();
356 &STATE
357 }
358 }
359 impl crate::ipc::Instance for peripherals::$type {
360 type Interrupt = crate::interrupt::typelevel::$irq;
361 }
362 };
363}
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 07ba2f6d4..0c5dd059d 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -88,6 +88,8 @@ pub mod gpiote;
88#[cfg(not(feature = "_nrf54l"))] // TODO 88#[cfg(not(feature = "_nrf54l"))] // TODO
89#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] 89#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
90pub mod i2s; 90pub mod i2s;
91#[cfg(feature = "_nrf5340")]
92pub mod ipc;
91#[cfg(not(feature = "_nrf54l"))] // TODO 93#[cfg(not(feature = "_nrf54l"))] // TODO
92#[cfg(any( 94#[cfg(any(
93 feature = "nrf52832", 95 feature = "nrf52832",
@@ -198,9 +200,12 @@ mod chip;
198/// ```rust,ignore 200/// ```rust,ignore
199/// use embassy_nrf::{bind_interrupts, spim, peripherals}; 201/// use embassy_nrf::{bind_interrupts, spim, peripherals};
200/// 202///
201/// bind_interrupts!(struct Irqs { 203/// bind_interrupts!(
202/// SPIM3 => spim::InterruptHandler<peripherals::SPI3>; 204/// /// Binds the SPIM3 interrupt.
203/// }); 205/// struct Irqs {
206/// SPIM3 => spim::InterruptHandler<peripherals::SPI3>;
207/// }
208/// );
204/// ``` 209/// ```
205/// 210///
206/// Example of how to bind multiple interrupts in a single macro invocation: 211/// Example of how to bind multiple interrupts in a single macro invocation:
@@ -217,7 +222,7 @@ mod chip;
217// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. 222// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`.
218#[macro_export] 223#[macro_export]
219macro_rules! bind_interrupts { 224macro_rules! bind_interrupts {
220 ($vis:vis struct $name:ident { 225 ($(#[$attr:meta])* $vis:vis struct $name:ident {
221 $( 226 $(
222 $(#[cfg($cond_irq:meta)])? 227 $(#[cfg($cond_irq:meta)])?
223 $irq:ident => $( 228 $irq:ident => $(
@@ -227,6 +232,7 @@ macro_rules! bind_interrupts {
227 )* 232 )*
228 }) => { 233 }) => {
229 #[derive(Copy, Clone)] 234 #[derive(Copy, Clone)]
235 $(#[$attr])*
230 $vis struct $name; 236 $vis struct $name;
231 237
232 $( 238 $(
@@ -337,7 +343,7 @@ pub mod config {
337 /// 3.0 V 343 /// 3.0 V
338 _3V0 = 4, 344 _3V0 = 4,
339 /// 3.3 V 345 /// 3.3 V
340 _3v3 = 5, 346 _3V3 = 5,
341 //ERASED = 7, means 1.8V 347 //ERASED = 7, means 1.8V
342 } 348 }
343 349
@@ -369,7 +375,7 @@ pub mod config {
369 /// 3.0 V 375 /// 3.0 V
370 _3V0 = 4, 376 _3V0 = 4,
371 /// 3.3 V 377 /// 3.3 V
372 _3v3 = 5, 378 _3V3 = 5,
373 //ERASED = 7, means 1.8V 379 //ERASED = 7, means 1.8V
374 } 380 }
375 381
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index e75ffda00..7e42dc938 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -167,6 +167,21 @@ impl<'d, T: Instance> Rng<'d, T> {
167 167
168 self.stop(); 168 self.stop();
169 } 169 }
170
171 /// Generate a random u32
172 pub fn blocking_next_u32(&mut self) -> u32 {
173 let mut bytes = [0; 4];
174 self.blocking_fill_bytes(&mut bytes);
175 // We don't care about the endianness, so just use the native one.
176 u32::from_ne_bytes(bytes)
177 }
178
179 /// Generate a random u64
180 pub fn blocking_next_u64(&mut self) -> u64 {
181 let mut bytes = [0; 8];
182 self.blocking_fill_bytes(&mut bytes);
183 u64::from_ne_bytes(bytes)
184 }
170} 185}
171 186
172impl<'d, T: Instance> Drop for Rng<'d, T> { 187impl<'d, T: Instance> Drop for Rng<'d, T> {
@@ -180,31 +195,37 @@ impl<'d, T: Instance> Drop for Rng<'d, T> {
180 } 195 }
181} 196}
182 197
183impl<'d, T: Instance> rand_core::RngCore for Rng<'d, T> { 198impl<'d, T: Instance> rand_core_06::RngCore for Rng<'d, T> {
184 fn fill_bytes(&mut self, dest: &mut [u8]) { 199 fn fill_bytes(&mut self, dest: &mut [u8]) {
185 self.blocking_fill_bytes(dest); 200 self.blocking_fill_bytes(dest);
186 } 201 }
187
188 fn next_u32(&mut self) -> u32 { 202 fn next_u32(&mut self) -> u32 {
189 let mut bytes = [0; 4]; 203 self.blocking_next_u32()
190 self.blocking_fill_bytes(&mut bytes);
191 // We don't care about the endianness, so just use the native one.
192 u32::from_ne_bytes(bytes)
193 } 204 }
194
195 fn next_u64(&mut self) -> u64 { 205 fn next_u64(&mut self) -> u64 {
196 let mut bytes = [0; 8]; 206 self.blocking_next_u64()
197 self.blocking_fill_bytes(&mut bytes);
198 u64::from_ne_bytes(bytes)
199 } 207 }
200 208 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
201 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
202 self.blocking_fill_bytes(dest); 209 self.blocking_fill_bytes(dest);
203 Ok(()) 210 Ok(())
204 } 211 }
205} 212}
206 213
207impl<'d, T: Instance> rand_core::CryptoRng for Rng<'d, T> {} 214impl<'d, T: Instance> rand_core_06::CryptoRng for Rng<'d, T> {}
215
216impl<'d, T: Instance> rand_core_09::RngCore for Rng<'d, T> {
217 fn fill_bytes(&mut self, dest: &mut [u8]) {
218 self.blocking_fill_bytes(dest);
219 }
220 fn next_u32(&mut self) -> u32 {
221 self.blocking_next_u32()
222 }
223 fn next_u64(&mut self) -> u64 {
224 self.blocking_next_u64()
225 }
226}
227
228impl<'d, T: Instance> rand_core_09::CryptoRng for Rng<'d, T> {}
208 229
209/// Peripheral static state 230/// Peripheral static state
210pub(crate) struct State { 231pub(crate) struct State {
diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml
index cf36a67ec..86a989aa7 100644
--- a/embassy-nxp/Cargo.toml
+++ b/embassy-nxp/Cargo.toml
@@ -10,8 +10,11 @@ critical-section = "1.1.2"
10embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } 10embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
11embassy-sync = { version = "0.6.2", path = "../embassy-sync" } 11embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
12lpc55-pac = "0.5.0" 12lpc55-pac = "0.5.0"
13defmt = "0.3.8" 13defmt = { version = "1", optional = true }
14 14
15[features] 15[features]
16default = ["rt"] 16default = ["rt"]
17rt = ["lpc55-pac/rt"] \ No newline at end of file 17rt = ["lpc55-pac/rt"]
18
19## Enable [defmt support](https://docs.rs/defmt) and enables `defmt` debug-log messages and formatting in embassy drivers.
20defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt"]
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml
index b440591cf..3c18a8f77 100644
--- a/embassy-rp/Cargo.toml
+++ b/embassy-rp/Cargo.toml
@@ -26,7 +26,10 @@ features = ["defmt", "unstable-pac", "time-driver", "rp2040"]
26 26
27[features] 27[features]
28default = [ "rt" ] 28default = [ "rt" ]
29## Enable the rt feature of [`rp-pac`](https://docs.rs/rp-pac). This brings in the [`cortex-m-rt`](https://docs.rs/cortex-m-rt) crate, which adds startup code and minimal runtime initialization. 29
30## Enable the `rt` feature of [`rp-pac`](https://docs.rs/rp-pac).
31## With `rt` enabled the PAC provides interrupt vectors instead of letting [`cortex-m-rt`](https://docs.rs/cortex-m-rt) do that.
32## See <https://docs.rs/cortex-m-rt/latest/cortex_m_rt/#device> for more info.
30rt = [ "rp-pac/rt" ] 33rt = [ "rp-pac/rt" ]
31 34
32## Enable [defmt support](https://docs.rs/defmt) and enables `defmt` debug-log messages and formatting in embassy drivers. 35## Enable [defmt support](https://docs.rs/defmt) and enables `defmt` debug-log messages and formatting in embassy drivers.
@@ -142,7 +145,7 @@ embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", fe
142embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal" } 145embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal" }
143embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } 146embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" }
144atomic-polyfill = "1.0.1" 147atomic-polyfill = "1.0.1"
145defmt = { version = "0.3", optional = true } 148defmt = { version = "1.0.1", optional = true }
146log = { version = "0.4.14", optional = true } 149log = { version = "0.4.14", optional = true }
147nb = "1.1.0" 150nb = "1.1.0"
148cfg-if = "1.0.0" 151cfg-if = "1.0.0"
@@ -154,7 +157,6 @@ embedded-io = { version = "0.6.1" }
154embedded-io-async = { version = "0.6.1" } 157embedded-io-async = { version = "0.6.1" }
155embedded-storage = { version = "0.3" } 158embedded-storage = { version = "0.3" }
156embedded-storage-async = { version = "0.4.1" } 159embedded-storage-async = { version = "0.4.1" }
157rand_core = "0.6.4"
158fixed = "1.28.0" 160fixed = "1.28.0"
159 161
160rp-pac = { version = "7.0.0" } 162rp-pac = { version = "7.0.0" }
@@ -164,6 +166,9 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
164embedded-hal-async = { version = "1.0" } 166embedded-hal-async = { version = "1.0" }
165embedded-hal-nb = { version = "1.0" } 167embedded-hal-nb = { version = "1.0" }
166 168
169rand-core-06 = { package = "rand_core", version = "0.6" }
170rand-core-09 = { package = "rand_core", version = "0.9" }
171
167pio = { version = "0.3" } 172pio = { version = "0.3" }
168rp2040-boot2 = "0.3" 173rp2040-boot2 = "0.3"
169document-features = "0.2.10" 174document-features = "0.2.10"
diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs
index ec0c8c46c..2db8e63d7 100644
--- a/embassy-rp/src/adc.rs
+++ b/embassy-rp/src/adc.rs
@@ -21,6 +21,8 @@ static WAKER: AtomicWaker = AtomicWaker::new();
21#[derive(Default)] 21#[derive(Default)]
22pub struct Config {} 22pub struct Config {}
23 23
24#[derive(Debug)]
25#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24enum Source<'p> { 26enum Source<'p> {
25 Pin(Peri<'p, AnyPin>), 27 Pin(Peri<'p, AnyPin>),
26 TempSensor(Peri<'p, ADC_TEMP_SENSOR>), 28 TempSensor(Peri<'p, ADC_TEMP_SENSOR>),
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs
index 6694aab66..d79bffab3 100644
--- a/embassy-rp/src/clocks.rs
+++ b/embassy-rp/src/clocks.rs
@@ -38,7 +38,7 @@
38//! 38//!
39//! ## Examples 39//! ## Examples
40//! 40//!
41//! ### Standard 125MHz configuration 41//! ### Standard 125MHz (rp2040) or 150Mhz (rp235x) configuration
42//! ```rust,ignore 42//! ```rust,ignore
43//! let config = ClockConfig::crystal(12_000_000); 43//! let config = ClockConfig::crystal(12_000_000);
44//! ``` 44//! ```
@@ -82,6 +82,18 @@ use crate::{pac, reset, Peri};
82// be very useful until we have runtime clock reconfiguration. once this 82// be very useful until we have runtime clock reconfiguration. once this
83// happens we can resurrect the commented-out gpin bits. 83// happens we can resurrect the commented-out gpin bits.
84 84
85/// Clock error types.
86#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87#[cfg_attr(feature = "defmt", derive(defmt::Format))]
88pub enum ClockError {
89 /// PLL failed to lock within the timeout period.
90 PllLockTimedOut,
91 /// Could not find valid PLL parameters for system clock.
92 InvalidPllParameters,
93 /// Reading the core voltage failed due to an unexpected value in the register.
94 UnexpectedCoreVoltageRead,
95}
96
85struct Clocks { 97struct Clocks {
86 xosc: AtomicU32, 98 xosc: AtomicU32,
87 sys: AtomicU32, 99 sys: AtomicU32,
@@ -136,15 +148,16 @@ pub enum PeriClkSrc {
136 // Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1 as _ , 148 // Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1 as _ ,
137} 149}
138 150
139/// Core voltage regulator settings for RP2040. 151/// Core voltage regulator settings.
140/// 152///
141/// The RP2040 voltage regulator can be configured for different output voltages. 153/// The voltage regulator can be configured for different output voltages.
142/// Higher voltages allow for higher clock frequencies but increase power consumption and heat. 154/// Higher voltages allow for higher clock frequencies but increase power consumption and heat.
143#[cfg(feature = "rp2040")] 155#[cfg(feature = "rp2040")]
144#[derive(Clone, Copy, Debug, PartialEq, Eq)]
145#[repr(u8)] 156#[repr(u8)]
157#[derive(Clone, Copy, Debug, PartialEq, Eq)]
158#[cfg_attr(feature = "defmt", derive(defmt::Format))]
146pub enum CoreVoltage { 159pub enum CoreVoltage {
147 /// 0.80V - Suitable for lower frequencies 160 /// 0.80V
148 V0_80 = 0b0000, 161 V0_80 = 0b0000,
149 /// 0.85V 162 /// 0.85V
150 V0_85 = 0b0110, 163 V0_85 = 0b0110,
@@ -168,11 +181,58 @@ pub enum CoreVoltage {
168 V1_30 = 0b1111, 181 V1_30 = 0b1111,
169} 182}
170 183
171#[cfg(feature = "rp2040")] 184/// Core voltage regulator settings.
185///
186/// The voltage regulator can be configured for different output voltages.
187/// Higher voltages allow for higher clock frequencies but increase power consumption and heat.
188///
189/// **Note**: The maximum voltage is 1.30V, unless unlocked by setting unless the voltage limit
190/// is disabled using the disable_voltage_limit field in the vreg_ctrl register. For lack of practical use at this
191/// point in time, this is not implemented here. So the maximum voltage in this enum is 1.30V for now.
192#[cfg(feature = "_rp235x")]
193#[repr(u8)]
194#[derive(Clone, Copy, Debug, PartialEq, Eq)]
195#[cfg_attr(feature = "defmt", derive(defmt::Format))]
196pub enum CoreVoltage {
197 /// 0.55V
198 V0_55 = 0b00000,
199 /// 0.60V
200 V0_60 = 0b00001,
201 /// 0.65V
202 V0_65 = 0b00010,
203 /// 0.70V
204 V0_70 = 0b00011,
205 /// 0.75V
206 V0_75 = 0b00100,
207 /// 0.80V
208 V0_80 = 0b00101,
209 /// 0.85V
210 V0_85 = 0b00110,
211 /// 0.90V
212 V0_90 = 0b00111,
213 /// 0.95V
214 V0_95 = 0b01000,
215 /// 1.00V
216 V1_00 = 0b01001,
217 /// 1.05V
218 V1_05 = 0b01010,
219 /// 1.10V - Default voltage level
220 V1_10 = 0b01011,
221 /// 1.15V
222 V1_15 = 0b01100,
223 /// 1.20V
224 V1_20 = 0b01101,
225 /// 1.25V
226 V1_25 = 0b01110,
227 /// 1.30V
228 V1_30 = 0b01111,
229}
230
172impl CoreVoltage { 231impl CoreVoltage {
173 /// Get the recommended Brown-Out Detection (BOD) setting for this voltage. 232 /// Get the recommended Brown-Out Detection (BOD) setting for this voltage.
174 /// Sets the BOD threshold to approximately 80% of the core voltage. 233 /// Sets the BOD threshold to approximately 80% of the core voltage.
175 fn recommended_bod(self) -> u8 { 234 fn recommended_bod(self) -> u8 {
235 #[cfg(feature = "rp2040")]
176 match self { 236 match self {
177 CoreVoltage::V0_80 => 0b0100, // 0.645V (~81% of 0.80V) 237 CoreVoltage::V0_80 => 0b0100, // 0.645V (~81% of 0.80V)
178 CoreVoltage::V0_85 => 0b0101, // 0.688V (~81% of 0.85V) 238 CoreVoltage::V0_85 => 0b0101, // 0.688V (~81% of 0.85V)
@@ -180,12 +240,32 @@ impl CoreVoltage {
180 CoreVoltage::V0_95 => 0b0111, // 0.774V (~81% of 0.95V) 240 CoreVoltage::V0_95 => 0b0111, // 0.774V (~81% of 0.95V)
181 CoreVoltage::V1_00 => 0b1000, // 0.817V (~82% of 1.00V) 241 CoreVoltage::V1_00 => 0b1000, // 0.817V (~82% of 1.00V)
182 CoreVoltage::V1_05 => 0b1000, // 0.817V (~78% of 1.05V) 242 CoreVoltage::V1_05 => 0b1000, // 0.817V (~78% of 1.05V)
183 CoreVoltage::V1_10 => 0b1001, // 0.860V (~78% of 1.10V) 243 CoreVoltage::V1_10 => 0b1001, // 0.860V (~78% of 1.10V), the default
184 CoreVoltage::V1_15 => 0b1010, // 0.903V (~79% of 1.15V) 244 CoreVoltage::V1_15 => 0b1010, // 0.903V (~79% of 1.15V)
185 CoreVoltage::V1_20 => 0b1011, // 0.946V (~79% of 1.20V) 245 CoreVoltage::V1_20 => 0b1011, // 0.946V (~79% of 1.20V)
186 CoreVoltage::V1_25 => 0b1100, // 0.989V (~79% of 1.25V) 246 CoreVoltage::V1_25 => 0b1100, // 0.989V (~79% of 1.25V)
187 CoreVoltage::V1_30 => 0b1101, // 1.032V (~79% of 1.30V) 247 CoreVoltage::V1_30 => 0b1101, // 1.032V (~79% of 1.30V)
188 } 248 }
249 #[cfg(feature = "_rp235x")]
250 match self {
251 CoreVoltage::V0_55 => 0b00001, // 0.516V (~94% of 0.55V)
252 CoreVoltage::V0_60 => 0b00010, // 0.559V (~93% of 0.60V)
253 CoreVoltage::V0_65 => 0b00011, // 0.602V (~93% of 0.65V)
254 CoreVoltage::V0_70 => 0b00011, // 0.602V (~86% of 0.70V)
255 CoreVoltage::V0_75 => 0b00100, // 0.645V (~86% of 0.75V)
256 CoreVoltage::V0_80 => 0b00101, // 0.688V (~86% of 0.80V)
257 CoreVoltage::V0_85 => 0b00110, // 0.731V (~86% of 0.85V)
258 CoreVoltage::V0_90 => 0b00110, // 0.731V (~81% of 0.90V)
259 CoreVoltage::V0_95 => 0b00111, // 0.774V (~81% of 0.95V)
260 CoreVoltage::V1_00 => 0b01000, // 0.817V (~82% of 1.00V)
261 CoreVoltage::V1_05 => 0b01000, // 0.817V (~78% of 1.05V)
262 CoreVoltage::V1_10 => 0b01001, // 0.860V (~78% of 1.10V), the default
263 CoreVoltage::V1_15 => 0b01001, // 0.860V (~75% of 1.15V)
264 CoreVoltage::V1_20 => 0b01010, // 0.903V (~75% of 1.20V)
265 CoreVoltage::V1_25 => 0b01010, // 0.903V (~72% of 1.25V)
266 CoreVoltage::V1_30 => 0b01011, // 0.946V (~73% of 1.30V)
267 // all others: 0.946V (see CoreVoltage: we do not support setting Voltages higher than 1.30V at this point)
268 }
189 } 269 }
190} 270}
191 271
@@ -209,12 +289,10 @@ pub struct ClockConfig {
209 /// RTC clock configuration. 289 /// RTC clock configuration.
210 #[cfg(feature = "rp2040")] 290 #[cfg(feature = "rp2040")]
211 pub rtc_clk: Option<RtcClkConfig>, 291 pub rtc_clk: Option<RtcClkConfig>,
212 /// Core voltage scaling (RP2040 only). Defaults to 1.10V. 292 /// Core voltage scaling. Defaults to 1.10V.
213 #[cfg(feature = "rp2040")]
214 pub core_voltage: CoreVoltage, 293 pub core_voltage: CoreVoltage,
215 /// Voltage stabilization delay in microseconds. 294 /// Voltage stabilization delay in microseconds.
216 /// If not set, defaults will be used based on voltage level. 295 /// If not set, defaults will be used based on voltage level.
217 #[cfg(feature = "rp2040")]
218 pub voltage_stabilization_delay_us: Option<u32>, 296 pub voltage_stabilization_delay_us: Option<u32>,
219 // See above re gpin handling being commented out 297 // See above re gpin handling being commented out
220 // gpin0: Option<(u32, Gpin<'static, AnyPin>)>, 298 // gpin0: Option<(u32, Gpin<'static, AnyPin>)>,
@@ -250,9 +328,7 @@ impl Default for ClockConfig {
250 adc_clk: None, 328 adc_clk: None,
251 #[cfg(feature = "rp2040")] 329 #[cfg(feature = "rp2040")]
252 rtc_clk: None, 330 rtc_clk: None,
253 #[cfg(feature = "rp2040")]
254 core_voltage: CoreVoltage::V1_10, 331 core_voltage: CoreVoltage::V1_10,
255 #[cfg(feature = "rp2040")]
256 voltage_stabilization_delay_us: None, 332 voltage_stabilization_delay_us: None,
257 // See above re gpin handling being commented out 333 // See above re gpin handling being commented out
258 // gpin0: None, 334 // gpin0: None,
@@ -323,9 +399,7 @@ impl ClockConfig {
323 div_frac: 0, 399 div_frac: 0,
324 phase: 0, 400 phase: 0,
325 }), 401 }),
326 #[cfg(feature = "rp2040")]
327 core_voltage: CoreVoltage::V1_10, // Use hardware default (1.10V) 402 core_voltage: CoreVoltage::V1_10, // Use hardware default (1.10V)
328 #[cfg(feature = "rp2040")]
329 voltage_stabilization_delay_us: None, 403 voltage_stabilization_delay_us: None,
330 // See above re gpin handling being commented out 404 // See above re gpin handling being commented out
331 // gpin0: None, 405 // gpin0: None,
@@ -368,9 +442,7 @@ impl ClockConfig {
368 div_frac: 171, 442 div_frac: 171,
369 phase: 0, 443 phase: 0,
370 }), 444 }),
371 #[cfg(feature = "rp2040")]
372 core_voltage: CoreVoltage::V1_10, // Use hardware default (1.10V) 445 core_voltage: CoreVoltage::V1_10, // Use hardware default (1.10V)
373 #[cfg(feature = "rp2040")]
374 voltage_stabilization_delay_us: None, 446 voltage_stabilization_delay_us: None,
375 // See above re gpin handling being commented out 447 // See above re gpin handling being commented out
376 // gpin0: None, 448 // gpin0: None,
@@ -391,29 +463,42 @@ impl ClockConfig {
391 /// # Returns 463 /// # Returns
392 /// 464 ///
393 /// A ClockConfig configured to achieve the requested system frequency using the 465 /// A ClockConfig configured to achieve the requested system frequency using the
394 /// the usual 12Mhz crystal, or panic if no valid parameters can be found. 466 /// the usual 12Mhz crystal, or an error if no valid parameters can be found.
395 /// 467 ///
396 /// # Note on core voltage: 468 /// # Note on core voltage:
469 ///
470 /// **For RP2040**:
397 /// To date the only officially documented core voltages (see Datasheet section 2.15.3.1. Instances) are: 471 /// To date the only officially documented core voltages (see Datasheet section 2.15.3.1. Instances) are:
398 /// - Up to 133MHz: V1_10 (default) 472 /// - Up to 133MHz: V1_10 (default)
399 /// - Above 133MHz: V1_15, but in the context of the datasheet covering reaching up to 200Mhz 473 /// - Above 133MHz: V1_15, but in the context of the datasheet covering reaching up to 200Mhz
400 /// That way all other frequencies below 133MHz or above 200MHz are not explicitly documented and not covered here. 474 /// That way all other frequencies below 133MHz or above 200MHz are not explicitly documented and not covered here.
401 /// In case You want to go below 133MHz or above 200MHz and want a different voltage, You will have to set that manually and with caution. 475 /// In case You want to go below 133MHz or above 200MHz and want a different voltage, You will have to set that manually and with caution.
402 #[cfg(feature = "rp2040")] 476 ///
403 pub fn system_freq(hz: u32) -> Self { 477 /// **For RP235x**:
478 /// At this point in time there is no official manufacturer endorsement for running the chip on other core voltages and/or other clock speeds than the defaults.
479 /// Using this function is experimental and may not work as expected or even damage the chip.
480 ///
481 /// # Returns
482 ///
483 /// A Result containing either the configured ClockConfig or a ClockError.
484 pub fn system_freq(hz: u32) -> Result<Self, ClockError> {
404 // Start with the standard configuration from crystal() 485 // Start with the standard configuration from crystal()
405 const DEFAULT_CRYSTAL_HZ: u32 = 12_000_000; 486 const DEFAULT_CRYSTAL_HZ: u32 = 12_000_000;
406 let mut config = Self::crystal(DEFAULT_CRYSTAL_HZ); 487 let mut config = Self::crystal(DEFAULT_CRYSTAL_HZ);
407 488
408 // No need to modify anything if target frequency is already 125MHz 489 // No need to modify anything if target frequency is already 125MHz
409 // (which is what crystal() configures by default) 490 // (which is what crystal() configures by default)
491 #[cfg(feature = "rp2040")]
410 if hz == 125_000_000 { 492 if hz == 125_000_000 {
411 return config; 493 return Ok(config);
494 }
495 #[cfg(feature = "_rp235x")]
496 if hz == 150_000_000 {
497 return Ok(config);
412 } 498 }
413 499
414 // Find optimal PLL parameters for the requested frequency 500 // Find optimal PLL parameters for the requested frequency
415 let sys_pll_params = find_pll_params(DEFAULT_CRYSTAL_HZ, hz) 501 let sys_pll_params = find_pll_params(DEFAULT_CRYSTAL_HZ, hz).ok_or(ClockError::InvalidPllParameters)?;
416 .unwrap_or_else(|| panic!("Could not find valid PLL parameters for system clock"));
417 502
418 // Replace the sys_pll configuration with our custom parameters 503 // Replace the sys_pll configuration with our custom parameters
419 if let Some(xosc) = &mut config.xosc { 504 if let Some(xosc) = &mut config.xosc {
@@ -429,8 +514,16 @@ impl ClockConfig {
429 _ => CoreVoltage::V1_10, // Use default voltage (V1_10) 514 _ => CoreVoltage::V1_10, // Use default voltage (V1_10)
430 }; 515 };
431 } 516 }
517 #[cfg(feature = "_rp235x")]
518 {
519 config.core_voltage = match hz {
520 // There is no official support for running the chip on other core voltages and/or other clock speeds than the defaults.
521 // So for now we have not way of knowing what the voltage should be. Change this if the manufacturer provides more information.
522 _ => CoreVoltage::V1_10, // Use default voltage (V1_10)
523 };
524 }
432 525
433 config 526 Ok(config)
434 } 527 }
435 528
436 /// Configure with manual PLL settings for full control over system clock 529 /// Configure with manual PLL settings for full control over system clock
@@ -525,6 +618,7 @@ impl ClockConfig {
525#[repr(u16)] 618#[repr(u16)]
526#[non_exhaustive] 619#[non_exhaustive]
527#[derive(Clone, Copy, Debug, PartialEq, Eq)] 620#[derive(Clone, Copy, Debug, PartialEq, Eq)]
621#[cfg_attr(feature = "defmt", derive(defmt::Format))]
528pub enum RoscRange { 622pub enum RoscRange {
529 /// Low range. 623 /// Low range.
530 Low = pac::rosc::vals::FreqRange::LOW.0, 624 Low = pac::rosc::vals::FreqRange::LOW.0,
@@ -631,6 +725,7 @@ pub struct RefClkConfig {
631/// Reference clock source. 725/// Reference clock source.
632#[non_exhaustive] 726#[non_exhaustive]
633#[derive(Clone, Copy, Debug, PartialEq, Eq)] 727#[derive(Clone, Copy, Debug, PartialEq, Eq)]
728#[cfg_attr(feature = "defmt", derive(defmt::Format))]
634pub enum RefClkSrc { 729pub enum RefClkSrc {
635 /// XOSC. 730 /// XOSC.
636 Xosc, 731 Xosc,
@@ -646,6 +741,7 @@ pub enum RefClkSrc {
646/// SYS clock source. 741/// SYS clock source.
647#[non_exhaustive] 742#[non_exhaustive]
648#[derive(Clone, Copy, Debug, PartialEq, Eq)] 743#[derive(Clone, Copy, Debug, PartialEq, Eq)]
744#[cfg_attr(feature = "defmt", derive(defmt::Format))]
649pub enum SysClkSrc { 745pub enum SysClkSrc {
650 /// REF. 746 /// REF.
651 Ref, 747 Ref,
@@ -684,6 +780,7 @@ pub struct SysClkConfig {
684#[repr(u8)] 780#[repr(u8)]
685#[non_exhaustive] 781#[non_exhaustive]
686#[derive(Clone, Copy, Debug, PartialEq, Eq)] 782#[derive(Clone, Copy, Debug, PartialEq, Eq)]
783#[cfg_attr(feature = "defmt", derive(defmt::Format))]
687pub enum UsbClkSrc { 784pub enum UsbClkSrc {
688 /// PLL USB. 785 /// PLL USB.
689 PllUsb = ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB as _, 786 PllUsb = ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB as _,
@@ -712,6 +809,7 @@ pub struct UsbClkConfig {
712#[repr(u8)] 809#[repr(u8)]
713#[non_exhaustive] 810#[non_exhaustive]
714#[derive(Clone, Copy, Debug, PartialEq, Eq)] 811#[derive(Clone, Copy, Debug, PartialEq, Eq)]
812#[cfg_attr(feature = "defmt", derive(defmt::Format))]
715pub enum AdcClkSrc { 813pub enum AdcClkSrc {
716 /// PLL USB. 814 /// PLL USB.
717 PllUsb = ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB as _, 815 PllUsb = ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB as _,
@@ -740,6 +838,7 @@ pub struct AdcClkConfig {
740#[repr(u8)] 838#[repr(u8)]
741#[non_exhaustive] 839#[non_exhaustive]
742#[derive(Clone, Copy, Debug, PartialEq, Eq)] 840#[derive(Clone, Copy, Debug, PartialEq, Eq)]
841#[cfg_attr(feature = "defmt", derive(defmt::Format))]
743#[cfg(feature = "rp2040")] 842#[cfg(feature = "rp2040")]
744pub enum RtcClkSrc { 843pub enum RtcClkSrc {
745 /// PLL USB. 844 /// PLL USB.
@@ -791,7 +890,6 @@ pub struct RtcClkConfig {
791/// // Find parameters for 133MHz system clock from 12MHz crystal 890/// // Find parameters for 133MHz system clock from 12MHz crystal
792/// let pll_params = find_pll_params(12_000_000, 133_000_000).unwrap(); 891/// let pll_params = find_pll_params(12_000_000, 133_000_000).unwrap();
793/// ``` 892/// ```
794#[cfg(feature = "rp2040")]
795fn find_pll_params(input_hz: u32, target_hz: u32) -> Option<PllConfig> { 893fn find_pll_params(input_hz: u32, target_hz: u32) -> Option<PllConfig> {
796 // Fixed reference divider for system PLL 894 // Fixed reference divider for system PLL
797 const PLL_SYS_REFDIV: u8 = 1; 895 const PLL_SYS_REFDIV: u8 = 1;
@@ -925,18 +1023,31 @@ pub(crate) unsafe fn init(config: ClockConfig) {
925 }; 1023 };
926 CLOCKS.rosc.store(rosc_freq, Ordering::Relaxed); 1024 CLOCKS.rosc.store(rosc_freq, Ordering::Relaxed);
927 1025
928 // Set Core Voltage (RP2040 only), if we have config for it and we're not using the default 1026 // Set Core Voltage, if we have config for it and we're not using the default
929 #[cfg(feature = "rp2040")]
930 { 1027 {
931 let voltage = config.core_voltage; 1028 let voltage = config.core_voltage;
1029
1030 #[cfg(feature = "rp2040")]
932 let vreg = pac::VREG_AND_CHIP_RESET; 1031 let vreg = pac::VREG_AND_CHIP_RESET;
1032 #[cfg(feature = "_rp235x")]
1033 let vreg = pac::POWMAN;
1034
933 let current_vsel = vreg.vreg().read().vsel(); 1035 let current_vsel = vreg.vreg().read().vsel();
934 let target_vsel = voltage as u8; 1036 let target_vsel = voltage as u8;
935 1037
936 // If the target voltage is different from the current one, we need to change it 1038 // If the target voltage is different from the current one, we need to change it
937 if target_vsel != current_vsel { 1039 if target_vsel != current_vsel {
938 // Use modify() to preserve the HIZ and EN bits - otherwise we will disable the regulator when changing voltage 1040 // Set the voltage regulator to the target voltage
1041 #[cfg(feature = "rp2040")]
939 vreg.vreg().modify(|w| w.set_vsel(target_vsel)); 1042 vreg.vreg().modify(|w| w.set_vsel(target_vsel));
1043 #[cfg(feature = "_rp235x")]
1044 // For rp235x changes to the voltage regulator are protected by a password, see datasheet section 6.4 Power Management (POWMAN) Registers
1045 // The password is "5AFE" (0x5AFE), it must be set in the top 16 bits of the register
1046 vreg.vreg().modify(|w| {
1047 w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); // Set the password
1048 w.set_vsel(target_vsel);
1049 *w
1050 });
940 1051
941 // Wait for the voltage to stabilize. Use the provided delay or default based on voltage 1052 // Wait for the voltage to stabilize. Use the provided delay or default based on voltage
942 let settling_time_us = config.voltage_stabilization_delay_us.unwrap_or_else(|| { 1053 let settling_time_us = config.voltage_stabilization_delay_us.unwrap_or_else(|| {
@@ -955,7 +1066,14 @@ pub(crate) unsafe fn init(config: ClockConfig) {
955 } 1066 }
956 1067
957 // Only now set the BOD level. At this point the voltage is considered stable. 1068 // Only now set the BOD level. At this point the voltage is considered stable.
1069 #[cfg(feature = "rp2040")]
1070 vreg.bod().write(|w| {
1071 w.set_vsel(voltage.recommended_bod());
1072 w.set_en(true); // Enable brownout detection
1073 });
1074 #[cfg(feature = "_rp235x")]
958 vreg.bod().write(|w| { 1075 vreg.bod().write(|w| {
1076 w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); // Set the password
959 w.set_vsel(voltage.recommended_bod()); 1077 w.set_vsel(voltage.recommended_bod());
960 w.set_en(true); // Enable brownout detection 1078 w.set_en(true); // Enable brownout detection
961 }); 1079 });
@@ -970,14 +1088,14 @@ pub(crate) unsafe fn init(config: ClockConfig) {
970 let pll_sys_freq = match config.sys_pll { 1088 let pll_sys_freq = match config.sys_pll {
971 Some(sys_pll_config) => match configure_pll(pac::PLL_SYS, config.hz, sys_pll_config) { 1089 Some(sys_pll_config) => match configure_pll(pac::PLL_SYS, config.hz, sys_pll_config) {
972 Ok(freq) => freq, 1090 Ok(freq) => freq,
973 Err(e) => panic!("Failed to configure PLL_SYS: {}", e), 1091 Err(e) => panic!("Failed to configure PLL_SYS: {:?}", e),
974 }, 1092 },
975 None => 0, 1093 None => 0,
976 }; 1094 };
977 let pll_usb_freq = match config.usb_pll { 1095 let pll_usb_freq = match config.usb_pll {
978 Some(usb_pll_config) => match configure_pll(pac::PLL_USB, config.hz, usb_pll_config) { 1096 Some(usb_pll_config) => match configure_pll(pac::PLL_USB, config.hz, usb_pll_config) {
979 Ok(freq) => freq, 1097 Ok(freq) => freq,
980 Err(e) => panic!("Failed to configure PLL_USB: {}", e), 1098 Err(e) => panic!("Failed to configure PLL_USB: {:?}", e),
981 }, 1099 },
982 None => 0, 1100 None => 0,
983 }; 1101 };
@@ -1283,6 +1401,58 @@ pub fn clk_rtc_freq() -> u16 {
1283 CLOCKS.rtc.load(Ordering::Relaxed) 1401 CLOCKS.rtc.load(Ordering::Relaxed)
1284} 1402}
1285 1403
1404/// The core voltage of the chip.
1405///
1406/// Returns the current core voltage or an error if the voltage register
1407/// contains an unknown value.
1408pub fn core_voltage() -> Result<CoreVoltage, ClockError> {
1409 #[cfg(feature = "rp2040")]
1410 {
1411 let vreg = pac::VREG_AND_CHIP_RESET;
1412 let vsel = vreg.vreg().read().vsel();
1413 match vsel {
1414 0b0000 => Ok(CoreVoltage::V0_80),
1415 0b0110 => Ok(CoreVoltage::V0_85),
1416 0b0111 => Ok(CoreVoltage::V0_90),
1417 0b1000 => Ok(CoreVoltage::V0_95),
1418 0b1001 => Ok(CoreVoltage::V1_00),
1419 0b1010 => Ok(CoreVoltage::V1_05),
1420 0b1011 => Ok(CoreVoltage::V1_10),
1421 0b1100 => Ok(CoreVoltage::V1_15),
1422 0b1101 => Ok(CoreVoltage::V1_20),
1423 0b1110 => Ok(CoreVoltage::V1_25),
1424 0b1111 => Ok(CoreVoltage::V1_30),
1425 _ => Err(ClockError::UnexpectedCoreVoltageRead),
1426 }
1427 }
1428
1429 #[cfg(feature = "_rp235x")]
1430 {
1431 let vreg = pac::POWMAN;
1432 let vsel = vreg.vreg().read().vsel();
1433 match vsel {
1434 0b00000 => Ok(CoreVoltage::V0_55),
1435 0b00001 => Ok(CoreVoltage::V0_60),
1436 0b00010 => Ok(CoreVoltage::V0_65),
1437 0b00011 => Ok(CoreVoltage::V0_70),
1438 0b00100 => Ok(CoreVoltage::V0_75),
1439 0b00101 => Ok(CoreVoltage::V0_80),
1440 0b00110 => Ok(CoreVoltage::V0_85),
1441 0b00111 => Ok(CoreVoltage::V0_90),
1442 0b01000 => Ok(CoreVoltage::V0_95),
1443 0b01001 => Ok(CoreVoltage::V1_00),
1444 0b01010 => Ok(CoreVoltage::V1_05),
1445 0b01011 => Ok(CoreVoltage::V1_10),
1446 0b01100 => Ok(CoreVoltage::V1_15),
1447 0b01101 => Ok(CoreVoltage::V1_20),
1448 0b01110 => Ok(CoreVoltage::V1_25),
1449 0b01111 => Ok(CoreVoltage::V1_30),
1450 _ => Err(ClockError::UnexpectedCoreVoltageRead),
1451 // see CoreVoltage: we do not support setting Voltages higher than 1.30V at this point
1452 }
1453 }
1454}
1455
1286fn start_xosc(crystal_hz: u32, delay_multiplier: u32) { 1456fn start_xosc(crystal_hz: u32, delay_multiplier: u32) {
1287 let startup_delay = (((crystal_hz / 1000) * delay_multiplier) + 128) / 256; 1457 let startup_delay = (((crystal_hz / 1000) * delay_multiplier) + 128) / 256;
1288 pac::XOSC.startup().write(|w| w.set_delay(startup_delay as u16)); 1458 pac::XOSC.startup().write(|w| w.set_delay(startup_delay as u16));
@@ -1295,7 +1465,7 @@ fn start_xosc(crystal_hz: u32, delay_multiplier: u32) {
1295 1465
1296/// PLL (Phase-Locked Loop) configuration 1466/// PLL (Phase-Locked Loop) configuration
1297#[inline(always)] 1467#[inline(always)]
1298fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> Result<u32, &'static str> { 1468fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> Result<u32, ClockError> {
1299 // Calculate reference frequency 1469 // Calculate reference frequency
1300 let ref_freq = input_freq / config.refdiv as u32; 1470 let ref_freq = input_freq / config.refdiv as u32;
1301 1471
@@ -1366,7 +1536,7 @@ fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> Result
1366 timeout -= 1; 1536 timeout -= 1;
1367 if timeout == 0 { 1537 if timeout == 0 {
1368 // PLL failed to lock, return 0 to indicate failure 1538 // PLL failed to lock, return 0 to indicate failure
1369 return Err("PLL failed to lock"); 1539 return Err(ClockError::PllLockTimedOut);
1370 } 1540 }
1371 } 1541 }
1372 1542
@@ -1606,7 +1776,8 @@ impl<'d, T: GpoutPin> Drop for Gpout<'d, T> {
1606pub struct RoscRng; 1776pub struct RoscRng;
1607 1777
1608impl RoscRng { 1778impl RoscRng {
1609 fn next_u8() -> u8 { 1779 /// Get a random u8
1780 pub fn next_u8() -> u8 {
1610 let random_reg = pac::ROSC.randombit(); 1781 let random_reg = pac::ROSC.randombit();
1611 let mut acc = 0; 1782 let mut acc = 0;
1612 for _ in 0..u8::BITS { 1783 for _ in 0..u8::BITS {
@@ -1615,26 +1786,60 @@ impl RoscRng {
1615 } 1786 }
1616 acc 1787 acc
1617 } 1788 }
1789
1790 /// Get a random u32
1791 pub fn next_u32(&mut self) -> u32 {
1792 rand_core_09::impls::next_u32_via_fill(self)
1793 }
1794
1795 /// Get a random u64
1796 pub fn next_u64(&mut self) -> u64 {
1797 rand_core_09::impls::next_u64_via_fill(self)
1798 }
1799
1800 /// Fill a slice with random bytes
1801 pub fn fill_bytes(&mut self, dest: &mut [u8]) {
1802 dest.fill_with(Self::next_u8)
1803 }
1618} 1804}
1619 1805
1620impl rand_core::RngCore for RoscRng { 1806impl rand_core_06::RngCore for RoscRng {
1621 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { 1807 fn next_u32(&mut self) -> u32 {
1622 Ok(self.fill_bytes(dest)) 1808 self.next_u32()
1809 }
1810
1811 fn next_u64(&mut self) -> u64 {
1812 self.next_u64()
1813 }
1814
1815 fn fill_bytes(&mut self, dest: &mut [u8]) {
1816 self.fill_bytes(dest);
1817 }
1818
1819 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
1820 self.fill_bytes(dest);
1821 Ok(())
1623 } 1822 }
1823}
1624 1824
1825impl rand_core_06::CryptoRng for RoscRng {}
1826
1827impl rand_core_09::RngCore for RoscRng {
1625 fn next_u32(&mut self) -> u32 { 1828 fn next_u32(&mut self) -> u32 {
1626 rand_core::impls::next_u32_via_fill(self) 1829 self.next_u32()
1627 } 1830 }
1628 1831
1629 fn next_u64(&mut self) -> u64 { 1832 fn next_u64(&mut self) -> u64 {
1630 rand_core::impls::next_u64_via_fill(self) 1833 self.next_u64()
1631 } 1834 }
1632 1835
1633 fn fill_bytes(&mut self, dest: &mut [u8]) { 1836 fn fill_bytes(&mut self, dest: &mut [u8]) {
1634 dest.fill_with(Self::next_u8) 1837 self.fill_bytes(dest);
1635 } 1838 }
1636} 1839}
1637 1840
1841impl rand_core_09::CryptoRng for RoscRng {}
1842
1638/// Enter the `DORMANT` sleep state. This will stop *all* internal clocks 1843/// Enter the `DORMANT` sleep state. This will stop *all* internal clocks
1639/// and can only be exited through resets, dormant-wake GPIO interrupts, 1844/// and can only be exited through resets, dormant-wake GPIO interrupts,
1640/// and RTC interrupts. If RTC is clocked from an internal clock source 1845/// and RTC interrupts. If RTC is clocked from an internal clock source
@@ -1937,21 +2142,21 @@ mod tests {
1937 { 2142 {
1938 // Test automatic voltage scaling based on frequency 2143 // Test automatic voltage scaling based on frequency
1939 // Under 133 MHz should use default voltage (V1_10) 2144 // Under 133 MHz should use default voltage (V1_10)
1940 let config = ClockConfig::system_freq(125_000_000); 2145 let config = ClockConfig::system_freq(125_000_000).unwrap();
1941 assert_eq!(config.core_voltage, CoreVoltage::V1_10); 2146 assert_eq!(config.core_voltage, CoreVoltage::V1_10);
1942 2147
1943 // 133-200 MHz should use V1_15 2148 // 133-200 MHz should use V1_15
1944 let config = ClockConfig::system_freq(150_000_000); 2149 let config = ClockConfig::system_freq(150_000_000).unwrap();
1945 assert_eq!(config.core_voltage, CoreVoltage::V1_15); 2150 assert_eq!(config.core_voltage, CoreVoltage::V1_15);
1946 let config = ClockConfig::system_freq(200_000_000); 2151 let config = ClockConfig::system_freq(200_000_000).unwrap();
1947 assert_eq!(config.core_voltage, CoreVoltage::V1_15); 2152 assert_eq!(config.core_voltage, CoreVoltage::V1_15);
1948 2153
1949 // Above 200 MHz should use V1_25 2154 // Above 200 MHz should use V1_15
1950 let config = ClockConfig::system_freq(250_000_000); 2155 let config = ClockConfig::system_freq(250_000_000).unwrap();
1951 assert_eq!(config.core_voltage, CoreVoltage::V1_15); 2156 assert_eq!(config.core_voltage, CoreVoltage::V1_15);
1952 2157
1953 // Below 125 MHz should use V1_10 2158 // Below 125 MHz should use V1_10
1954 let config = ClockConfig::system_freq(100_000_000); 2159 let config = ClockConfig::system_freq(100_000_000).unwrap();
1955 assert_eq!(config.core_voltage, CoreVoltage::V1_10); 2160 assert_eq!(config.core_voltage, CoreVoltage::V1_10);
1956 } 2161 }
1957 } 2162 }
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index af0837f6a..2fb2d65c2 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -932,6 +932,8 @@ pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
932} 932}
933 933
934/// Type-erased GPIO pin 934/// Type-erased GPIO pin
935#[derive(Debug)]
936#[cfg_attr(feature = "defmt", derive(defmt::Format))]
935pub struct AnyPin { 937pub struct AnyPin {
936 pin_bank: u8, 938 pin_bank: u8,
937} 939}
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index f549446bc..f3c5a35bb 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -160,15 +160,18 @@ embassy_hal_internal::interrupt_mod!(
160/// ```rust,ignore 160/// ```rust,ignore
161/// use embassy_rp::{bind_interrupts, usb, peripherals}; 161/// use embassy_rp::{bind_interrupts, usb, peripherals};
162/// 162///
163/// bind_interrupts!(struct Irqs { 163/// bind_interrupts!(
164/// USBCTRL_IRQ => usb::InterruptHandler<peripherals::USB>; 164/// /// Binds the USB Interrupts.
165/// }); 165/// struct Irqs {
166/// USBCTRL_IRQ => usb::InterruptHandler<peripherals::USB>;
167/// }
168/// );
166/// ``` 169/// ```
167/// 170///
168// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. 171// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`.
169#[macro_export] 172#[macro_export]
170macro_rules! bind_interrupts { 173macro_rules! bind_interrupts {
171 ($vis:vis struct $name:ident { 174 ($(#[$attr:meta])* $vis:vis struct $name:ident {
172 $( 175 $(
173 $(#[cfg($cond_irq:meta)])? 176 $(#[cfg($cond_irq:meta)])?
174 $irq:ident => $( 177 $irq:ident => $(
@@ -178,6 +181,7 @@ macro_rules! bind_interrupts {
178 )* 181 )*
179 }) => { 182 }) => {
180 #[derive(Copy, Clone)] 183 #[derive(Copy, Clone)]
184 $(#[$attr])*
181 $vis struct $name; 185 $vis struct $name;
182 186
183 $( 187 $(
diff --git a/embassy-rp/src/pio_programs/i2s.rs b/embassy-rp/src/pio_programs/i2s.rs
index b967f0160..7ceed3fa6 100644
--- a/embassy-rp/src/pio_programs/i2s.rs
+++ b/embassy-rp/src/pio_programs/i2s.rs
@@ -9,6 +9,10 @@ use crate::pio::{
9use crate::Peri; 9use crate::Peri;
10 10
11/// This struct represents an i2s output driver program 11/// This struct represents an i2s output driver program
12///
13/// The sample bit-depth is set through scratch register `Y`.
14/// `Y` has to be set to sample bit-depth - 2.
15/// (14 = 16bit, 22 = 24bit, 30 = 32bit)
12pub struct PioI2sOutProgram<'d, PIO: Instance> { 16pub struct PioI2sOutProgram<'d, PIO: Instance> {
13 prg: LoadedProgram<'d, PIO>, 17 prg: LoadedProgram<'d, PIO>,
14} 18}
@@ -17,13 +21,13 @@ impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> {
17 /// Load the program into the given pio 21 /// Load the program into the given pio
18 pub fn new(common: &mut Common<'d, PIO>) -> Self { 22 pub fn new(common: &mut Common<'d, PIO>) -> Self {
19 let prg = pio::pio_asm!( 23 let prg = pio::pio_asm!(
20 ".side_set 2", 24 ".side_set 2", // side 0bWB - W = Word Clock, B = Bit Clock
21 " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock 25 " mov x, y side 0b01", // y stores sample depth - 2 (14 = 16bit, 22 = 24bit, 30 = 32bit)
22 "left_data:", 26 "left_data:",
23 " out pins, 1 side 0b00", 27 " out pins, 1 side 0b00",
24 " jmp x-- left_data side 0b01", 28 " jmp x-- left_data side 0b01",
25 " out pins 1 side 0b10", 29 " out pins 1 side 0b10",
26 " set x, 14 side 0b11", 30 " mov x, y side 0b11",
27 "right_data:", 31 "right_data:",
28 " out pins 1 side 0b10", 32 " out pins 1 side 0b10",
29 " jmp x-- right_data side 0b11", 33 " jmp x-- right_data side 0b11",
@@ -53,7 +57,6 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
53 lr_clock_pin: Peri<'d, impl PioPin>, 57 lr_clock_pin: Peri<'d, impl PioPin>,
54 sample_rate: u32, 58 sample_rate: u32,
55 bit_depth: u32, 59 bit_depth: u32,
56 channels: u32,
57 program: &PioI2sOutProgram<'d, P>, 60 program: &PioI2sOutProgram<'d, P>,
58 ) -> Self { 61 ) -> Self {
59 let data_pin = common.make_pio_pin(data_pin); 62 let data_pin = common.make_pio_pin(data_pin);
@@ -64,7 +67,7 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
64 let mut cfg = Config::default(); 67 let mut cfg = Config::default();
65 cfg.use_program(&program.prg, &[&bit_clock_pin, &left_right_clock_pin]); 68 cfg.use_program(&program.prg, &[&bit_clock_pin, &left_right_clock_pin]);
66 cfg.set_out_pins(&[&data_pin]); 69 cfg.set_out_pins(&[&data_pin]);
67 let clock_frequency = sample_rate * bit_depth * channels; 70 let clock_frequency = sample_rate * bit_depth * 2;
68 cfg.clock_divider = (crate::clocks::clk_sys_freq() as f64 / clock_frequency as f64 / 2.).to_fixed(); 71 cfg.clock_divider = (crate::clocks::clk_sys_freq() as f64 / clock_frequency as f64 / 2.).to_fixed();
69 cfg.shift_out = ShiftConfig { 72 cfg.shift_out = ShiftConfig {
70 threshold: 32, 73 threshold: 32,
@@ -78,6 +81,11 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
78 sm.set_config(&cfg); 81 sm.set_config(&cfg);
79 sm.set_pin_dirs(Direction::Out, &[&data_pin, &left_right_clock_pin, &bit_clock_pin]); 82 sm.set_pin_dirs(Direction::Out, &[&data_pin, &left_right_clock_pin, &bit_clock_pin]);
80 83
84 // Set the `y` register up to configure the sample depth
85 // The SM counts down to 0 and uses one clock cycle to set up the counter,
86 // which results in bit_depth - 2 as register value.
87 unsafe { sm.set_y(bit_depth - 2) };
88
81 sm.set_enable(true); 89 sm.set_enable(true);
82 90
83 Self { dma: dma.into(), sm } 91 Self { dma: dma.into(), sm }
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs
index 6dfb90fef..1e1ccc4c6 100644
--- a/embassy-rp/src/pwm.rs
+++ b/embassy-rp/src/pwm.rs
@@ -464,6 +464,10 @@ impl<'d> Drop for Pwm<'d> {
464 pac::PWM.ch(self.slice).csr().write_clear(|w| w.set_en(false)); 464 pac::PWM.ch(self.slice).csr().write_clear(|w| w.set_en(false));
465 if let Some(pin) = &self.pin_a { 465 if let Some(pin) = &self.pin_a {
466 pin.gpio().ctrl().write(|w| w.set_funcsel(31)); 466 pin.gpio().ctrl().write(|w| w.set_funcsel(31));
467 // Enable pin PULL-DOWN
468 pin.pad_ctrl().modify(|w| {
469 w.set_pde(true);
470 });
467 } 471 }
468 if let Some(pin) = &self.pin_b { 472 if let Some(pin) = &self.pin_b {
469 pin.gpio().ctrl().write(|w| w.set_funcsel(31)); 473 pin.gpio().ctrl().write(|w| w.set_funcsel(31));
@@ -472,6 +476,10 @@ impl<'d> Drop for Pwm<'d> {
472 pin.pad_ctrl().modify(|w| { 476 pin.pad_ctrl().modify(|w| {
473 w.set_ie(false); 477 w.set_ie(false);
474 }); 478 });
479 // Enable pin PULL-DOWN
480 pin.pad_ctrl().modify(|w| {
481 w.set_pde(true);
482 });
475 } 483 }
476 } 484 }
477} 485}
diff --git a/embassy-rp/src/trng.rs b/embassy-rp/src/trng.rs
index a8a0172be..a3f23c1f2 100644
--- a/embassy-rp/src/trng.rs
+++ b/embassy-rp/src/trng.rs
@@ -7,7 +7,6 @@ use core::task::Poll;
7 7
8use embassy_hal_internal::{Peri, PeripheralType}; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use rand_core::Error;
11 10
12use crate::interrupt::typelevel::{Binding, Interrupt}; 11use crate::interrupt::typelevel::{Binding, Interrupt};
13use crate::peripherals::TRNG; 12use crate::peripherals::TRNG;
@@ -369,7 +368,7 @@ impl<'d, T: Instance> Trng<'d, T> {
369 } 368 }
370} 369}
371 370
372impl<'d, T: Instance> rand_core::RngCore for Trng<'d, T> { 371impl<'d, T: Instance> rand_core_06::RngCore for Trng<'d, T> {
373 fn next_u32(&mut self) -> u32 { 372 fn next_u32(&mut self) -> u32 {
374 self.blocking_next_u32() 373 self.blocking_next_u32()
375 } 374 }
@@ -379,16 +378,32 @@ impl<'d, T: Instance> rand_core::RngCore for Trng<'d, T> {
379 } 378 }
380 379
381 fn fill_bytes(&mut self, dest: &mut [u8]) { 380 fn fill_bytes(&mut self, dest: &mut [u8]) {
382 self.blocking_fill_bytes(dest) 381 self.blocking_fill_bytes(dest);
383 } 382 }
384 383
385 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { 384 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
386 self.blocking_fill_bytes(dest); 385 self.blocking_fill_bytes(dest);
387 Ok(()) 386 Ok(())
388 } 387 }
389} 388}
390 389
391impl<'d, T: Instance> rand_core::CryptoRng for Trng<'d, T> {} 390impl<'d, T: Instance> rand_core_06::CryptoRng for Trng<'d, T> {}
391
392impl<'d, T: Instance> rand_core_09::RngCore for Trng<'d, T> {
393 fn next_u32(&mut self) -> u32 {
394 self.blocking_next_u32()
395 }
396
397 fn next_u64(&mut self) -> u64 {
398 self.blocking_next_u64()
399 }
400
401 fn fill_bytes(&mut self, dest: &mut [u8]) {
402 self.blocking_fill_bytes(dest);
403 }
404}
405
406impl<'d, T: Instance> rand_core_09::CryptoRng for Trng<'d, T> {}
392 407
393/// TRNG interrupt handler. 408/// TRNG interrupt handler.
394pub struct InterruptHandler<T: Instance> { 409pub struct InterruptHandler<T: Instance> {
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml
index 3bcfd11a9..81af6aedd 100644
--- a/embassy-stm32-wpan/Cargo.toml
+++ b/embassy-stm32-wpan/Cargo.toml
@@ -27,7 +27,7 @@ embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal" }
27embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal" } 27embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal" }
28embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver", optional=true } 28embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver", optional=true }
29 29
30defmt = { version = "0.3", optional = true } 30defmt = { version = "1.0.1", optional = true }
31log = { version = "0.4.17", optional = true } 31log = { version = "0.4.17", optional = true }
32 32
33cortex-m = "0.7.6" 33cortex-m = "0.7.6"
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 972307bec..413c92cce 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -19,16 +19,22 @@ flavors = [
19 { regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" }, 19 { regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" },
20 { regex_feature = "stm32f2.*", target = "thumbv7m-none-eabi" }, 20 { regex_feature = "stm32f2.*", target = "thumbv7m-none-eabi" },
21 { regex_feature = "stm32f3.*", target = "thumbv7em-none-eabi" }, 21 { regex_feature = "stm32f3.*", target = "thumbv7em-none-eabi" },
22 { regex_feature = "stm32f4.*", target = "thumbv7em-none-eabi", features = ["low-power"] }, 22 { regex_feature = "stm32f4[2367]..[ig]", target = "thumbv7em-none-eabi", features = ["low-power", "dual-bank"] },
23 { regex_feature = "stm32f4.*", target = "thumbv7em-none-eabi", features = ["low-power", "single-bank"] },
24 { regex_feature = "stm32f7[67]..[ig]", target = "thumbv7em-none-eabi", features = ["dual-bank"] },
23 { regex_feature = "stm32f7.*", target = "thumbv7em-none-eabi" }, 25 { regex_feature = "stm32f7.*", target = "thumbv7em-none-eabi" },
24 { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" }, 26 { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" },
27 { regex_feature = "stm32g0...c", target = "thumbv6m-none-eabi", features = ["dual-bank"] },
25 { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" }, 28 { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" },
29 { regex_feature = "stm32g4[78].*", target = "thumbv7em-none-eabi", features = ["low-power", "dual-bank"] },
26 { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] }, 30 { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] },
27 { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] }, 31 { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] },
28 { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" }, 32 { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" },
29 { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] }, 33 { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] },
30 { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" }, 34 { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" },
35 { regex_feature = "stm32l4[pqrs].*", target = "thumbv7em-none-eabi", features = ["dual-bank"] },
31 { regex_feature = "stm32l4.*", target = "thumbv7em-none-eabi" }, 36 { regex_feature = "stm32l4.*", target = "thumbv7em-none-eabi" },
37 { regex_feature = "stm32l5...e", target = "thumbv8m.main-none-eabihf", features = ["low-power", "dual-bank"] },
32 { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] }, 38 { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] },
33 { regex_feature = "stm32u0.*", target = "thumbv6m-none-eabi" }, 39 { regex_feature = "stm32u0.*", target = "thumbv6m-none-eabi" },
34 { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" }, 40 { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" },
@@ -38,7 +44,7 @@ flavors = [
38] 44]
39 45
40[package.metadata.docs.rs] 46[package.metadata.docs.rs]
41features = ["defmt", "unstable-pac", "exti", "time-driver-any", "time", "stm32h755zi-cm7"] 47features = ["defmt", "unstable-pac", "exti", "time-driver-any", "time", "stm32h755zi-cm7", "single-bank"]
42rustdoc-args = ["--cfg", "docsrs"] 48rustdoc-args = ["--cfg", "docsrs"]
43 49
44[dependencies] 50[dependencies]
@@ -63,13 +69,15 @@ embedded-can = "0.4"
63embedded-storage = "0.3.1" 69embedded-storage = "0.3.1"
64embedded-storage-async = { version = "0.4.1" } 70embedded-storage-async = { version = "0.4.1" }
65 71
72rand-core-06 = { package = "rand_core", version = "0.6" }
73rand-core-09 = { package = "rand_core", version = "0.9" }
66 74
67defmt = { version = "0.3", optional = true } 75
76defmt = { version = "1.0.1", optional = true }
68log = { version = "0.4.14", optional = true } 77log = { version = "0.4.14", optional = true }
69cortex-m-rt = ">=0.6.15,<0.8" 78cortex-m-rt = ">=0.6.15,<0.8"
70cortex-m = "0.7.6" 79cortex-m = "0.7.6"
71futures-util = { version = "0.3.30", default-features = false } 80futures-util = { version = "0.3.30", default-features = false }
72rand_core = "0.6.3"
73sdio-host = "0.9.0" 81sdio-host = "0.9.0"
74critical-section = "1.1" 82critical-section = "1.1"
75#stm32-metapac = { version = "16" } 83#stm32-metapac = { version = "16" }
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 8ed102c1b..1fce3085a 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -371,8 +371,8 @@ impl<'d, T: Instance> Adc<'d, T> {
371 /// let mut adc_pin1 = p.PA1.into(); 371 /// let mut adc_pin1 = p.PA1.into();
372 /// let mut measurements = [0u16; 2]; 372 /// let mut measurements = [0u16; 2];
373 /// 373 ///
374 /// adc.read_async( 374 /// adc.read(
375 /// p.DMA1_CH2, 375 /// p.DMA1_CH2.reborrow(),
376 /// [ 376 /// [
377 /// (&mut *adc_pin0, SampleTime::CYCLES160_5), 377 /// (&mut *adc_pin0, SampleTime::CYCLES160_5),
378 /// (&mut *adc_pin1, SampleTime::CYCLES160_5), 378 /// (&mut *adc_pin1, SampleTime::CYCLES160_5),
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 1c5ad16e9..313244e19 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -272,8 +272,8 @@ impl<'d, T: Instance> Adc<'d, T> {
272 /// let mut adc_pin1 = p.PA1.degrade_adc(); 272 /// let mut adc_pin1 = p.PA1.degrade_adc();
273 /// let mut measurements = [0u16; 2]; 273 /// let mut measurements = [0u16; 2];
274 /// 274 ///
275 /// adc.read_async( 275 /// adc.read(
276 /// p.DMA1_CH2, 276 /// p.DMA1_CH2.reborrow(),
277 /// [ 277 /// [
278 /// (&mut *adc_pin0, SampleTime::CYCLES160_5), 278 /// (&mut *adc_pin0, SampleTime::CYCLES160_5),
279 /// (&mut *adc_pin1, SampleTime::CYCLES160_5), 279 /// (&mut *adc_pin1, SampleTime::CYCLES160_5),
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index e455b275c..39e0d51b9 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -347,8 +347,8 @@ impl<'d, T: Instance> Adc<'d, T> {
347 /// let mut adc_pin2 = p.PA2.into(); 347 /// let mut adc_pin2 = p.PA2.into();
348 /// let mut measurements = [0u16; 2]; 348 /// let mut measurements = [0u16; 2];
349 /// 349 ///
350 /// adc.read_async( 350 /// adc.read(
351 /// p.DMA2_CH0, 351 /// p.DMA2_CH0.reborrow(),
352 /// [ 352 /// [
353 /// (&mut *adc_pin0, SampleTime::CYCLES112), 353 /// (&mut *adc_pin0, SampleTime::CYCLES112),
354 /// (&mut *adc_pin2, SampleTime::CYCLES112), 354 /// (&mut *adc_pin2, SampleTime::CYCLES112),
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 226293a9d..973acc9bb 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -163,18 +163,22 @@ pub use crate::_generated::interrupt;
163/// ```rust,ignore 163/// ```rust,ignore
164/// use embassy_stm32::{bind_interrupts, i2c, peripherals}; 164/// use embassy_stm32::{bind_interrupts, i2c, peripherals};
165/// 165///
166/// bind_interrupts!(struct Irqs { 166/// bind_interrupts!(
167/// I2C1 => i2c::EventInterruptHandler<peripherals::I2C1>, i2c::ErrorInterruptHandler<peripherals::I2C1>; 167/// /// Binds the I2C interrupts.
168/// I2C2_3 => i2c::EventInterruptHandler<peripherals::I2C2>, i2c::ErrorInterruptHandler<peripherals::I2C2>, 168/// struct Irqs {
169/// i2c::EventInterruptHandler<peripherals::I2C3>, i2c::ErrorInterruptHandler<peripherals::I2C3>; 169/// I2C1 => i2c::EventInterruptHandler<peripherals::I2C1>, i2c::ErrorInterruptHandler<peripherals::I2C1>;
170/// }); 170/// I2C2_3 => i2c::EventInterruptHandler<peripherals::I2C2>, i2c::ErrorInterruptHandler<peripherals::I2C2>,
171/// i2c::EventInterruptHandler<peripherals::I2C3>, i2c::ErrorInterruptHandler<peripherals::I2C3>;
172/// }
173/// );
171/// ``` 174/// ```
172 175
173// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. 176// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`.
174#[macro_export] 177#[macro_export]
175macro_rules! bind_interrupts { 178macro_rules! bind_interrupts {
176 ($vis:vis struct $name:ident { 179 ($(#[$outer:meta])* $vis:vis struct $name:ident {
177 $( 180 $(
181 $(#[$inner:meta])*
178 $(#[cfg($cond_irq:meta)])? 182 $(#[cfg($cond_irq:meta)])?
179 $irq:ident => $( 183 $irq:ident => $(
180 $(#[cfg($cond_handler:meta)])? 184 $(#[cfg($cond_handler:meta)])?
@@ -183,12 +187,14 @@ macro_rules! bind_interrupts {
183 )* 187 )*
184 }) => { 188 }) => {
185 #[derive(Copy, Clone)] 189 #[derive(Copy, Clone)]
190 $(#[$outer])*
186 $vis struct $name; 191 $vis struct $name;
187 192
188 $( 193 $(
189 #[allow(non_snake_case)] 194 #[allow(non_snake_case)]
190 #[no_mangle] 195 #[no_mangle]
191 $(#[cfg($cond_irq)])? 196 $(#[cfg($cond_irq)])?
197 $(#[$inner])*
192 unsafe extern "C" fn $irq() { 198 unsafe extern "C" fn $irq() {
193 $( 199 $(
194 $(#[cfg($cond_handler)])? 200 $(#[cfg($cond_handler)])?
@@ -600,17 +606,7 @@ fn init_hw(config: Config) -> Peripherals {
600 #[cfg(feature = "exti")] 606 #[cfg(feature = "exti")]
601 exti::init(cs); 607 exti::init(cs);
602 608
603 rcc::init(config.rcc); 609 rcc::init_rcc(cs, config.rcc);
604
605 // must be after rcc init
606 #[cfg(feature = "_time-driver")]
607 time_driver::init(cs);
608
609 #[cfg(feature = "low-power")]
610 {
611 crate::rcc::REFCOUNT_STOP2 = 0;
612 crate::rcc::REFCOUNT_STOP1 = 0;
613 }
614 } 610 }
615 611
616 p 612 p
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 150daa4a7..3733fed56 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -371,3 +371,32 @@ pub fn enable_and_reset<T: RccPeripheral>() {
371pub fn disable<T: RccPeripheral>() { 371pub fn disable<T: RccPeripheral>() {
372 T::RCC_INFO.disable(); 372 T::RCC_INFO.disable();
373} 373}
374
375/// Re-initialize the `embassy-stm32` clock configuration with the provided configuration.
376///
377/// This is useful when you need to alter the CPU clock after configuring peripherals.
378/// For instance, configure an external clock via spi or i2c.
379///
380/// Please not this only re-configures the rcc and the time driver (not GPIO, EXTI, etc).
381///
382/// This should only be called after `init`.
383#[cfg(not(feature = "_dual-core"))]
384pub fn reinit(config: Config) {
385 critical_section::with(|cs| init_rcc(cs, config))
386}
387
388pub(crate) fn init_rcc(_cs: CriticalSection, config: Config) {
389 unsafe {
390 init(config);
391
392 // must be after rcc init
393 #[cfg(feature = "_time-driver")]
394 crate::time_driver::init(_cs);
395
396 #[cfg(feature = "low-power")]
397 {
398 REFCOUNT_STOP2 = 0;
399 REFCOUNT_STOP1 = 0;
400 }
401 }
402}
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index 250a08a39..312f343b9 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -7,7 +7,6 @@ use core::task::Poll;
7 7
8use embassy_hal_internal::PeripheralType; 8use embassy_hal_internal::PeripheralType;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use rand_core::{CryptoRng, RngCore};
11 10
12use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
13use crate::{interrupt, pac, peripherals, rcc, Peri}; 12use crate::{interrupt, pac, peripherals, rcc, Peri};
@@ -184,10 +183,9 @@ impl<'d, T: Instance> Rng<'d, T> {
184 183
185 Ok(()) 184 Ok(())
186 } 185 }
187}
188 186
189impl<'d, T: Instance> RngCore for Rng<'d, T> { 187 /// Get a random u32
190 fn next_u32(&mut self) -> u32 { 188 pub fn next_u32(&mut self) -> u32 {
191 loop { 189 loop {
192 let sr = T::regs().sr().read(); 190 let sr = T::regs().sr().read();
193 if sr.seis() | sr.ceis() { 191 if sr.seis() | sr.ceis() {
@@ -198,13 +196,15 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> {
198 } 196 }
199 } 197 }
200 198
201 fn next_u64(&mut self) -> u64 { 199 /// Get a random u64
200 pub fn next_u64(&mut self) -> u64 {
202 let mut rand = self.next_u32() as u64; 201 let mut rand = self.next_u32() as u64;
203 rand |= (self.next_u32() as u64) << 32; 202 rand |= (self.next_u32() as u64) << 32;
204 rand 203 rand
205 } 204 }
206 205
207 fn fill_bytes(&mut self, dest: &mut [u8]) { 206 /// Fill a slice with random bytes
207 pub fn fill_bytes(&mut self, dest: &mut [u8]) {
208 for chunk in dest.chunks_mut(4) { 208 for chunk in dest.chunks_mut(4) {
209 let rand = self.next_u32(); 209 let rand = self.next_u32();
210 for (slot, num) in chunk.iter_mut().zip(rand.to_ne_bytes().iter()) { 210 for (slot, num) in chunk.iter_mut().zip(rand.to_ne_bytes().iter()) {
@@ -212,14 +212,53 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> {
212 } 212 }
213 } 213 }
214 } 214 }
215}
216
217impl<'d, T: Instance> Drop for Rng<'d, T> {
218 fn drop(&mut self) {
219 T::regs().cr().modify(|reg| {
220 reg.set_rngen(false);
221 });
222 rcc::disable::<T>();
223 }
224}
225
226impl<'d, T: Instance> rand_core_06::RngCore for Rng<'d, T> {
227 fn next_u32(&mut self) -> u32 {
228 self.next_u32()
229 }
230
231 fn next_u64(&mut self) -> u64 {
232 self.next_u64()
233 }
215 234
216 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { 235 fn fill_bytes(&mut self, dest: &mut [u8]) {
236 self.fill_bytes(dest);
237 }
238
239 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
217 self.fill_bytes(dest); 240 self.fill_bytes(dest);
218 Ok(()) 241 Ok(())
219 } 242 }
220} 243}
221 244
222impl<'d, T: Instance> CryptoRng for Rng<'d, T> {} 245impl<'d, T: Instance> rand_core_06::CryptoRng for Rng<'d, T> {}
246
247impl<'d, T: Instance> rand_core_09::RngCore for Rng<'d, T> {
248 fn next_u32(&mut self) -> u32 {
249 self.next_u32()
250 }
251
252 fn next_u64(&mut self) -> u64 {
253 self.next_u64()
254 }
255
256 fn fill_bytes(&mut self, dest: &mut [u8]) {
257 self.fill_bytes(dest);
258 }
259}
260
261impl<'d, T: Instance> rand_core_09::CryptoRng for Rng<'d, T> {}
223 262
224trait SealedInstance { 263trait SealedInstance {
225 fn regs() -> pac::rng::Rng; 264 fn regs() -> pac::rng::Rng;
diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml
index 92ee38ed9..65cade317 100644
--- a/embassy-sync/Cargo.toml
+++ b/embassy-sync/Cargo.toml
@@ -24,7 +24,7 @@ std = []
24turbowakers = [] 24turbowakers = []
25 25
26[dependencies] 26[dependencies]
27defmt = { version = "0.3", optional = true } 27defmt = { version = "1.0.1", optional = true }
28log = { version = "0.4.14", optional = true } 28log = { version = "0.4.14", optional = true }
29 29
30futures-sink = { version = "0.3", default-features = false, features = [] } 30futures-sink = { version = "0.3", default-features = false, features = [] }
diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml
index dc144ec3c..76983d880 100644
--- a/embassy-time/Cargo.toml
+++ b/embassy-time/Cargo.toml
@@ -420,7 +420,7 @@ tick-hz-5_242_880_000 = ["embassy-time-driver/tick-hz-5_242_880_000"]
420embassy-time-driver = { version = "0.2", path = "../embassy-time-driver" } 420embassy-time-driver = { version = "0.2", path = "../embassy-time-driver" }
421embassy-time-queue-utils = { version = "0.1", path = "../embassy-time-queue-utils", optional = true} 421embassy-time-queue-utils = { version = "0.1", path = "../embassy-time-queue-utils", optional = true}
422 422
423defmt = { version = "0.3", optional = true } 423defmt = { version = "1.0.1", optional = true }
424log = { version = "0.4.14", optional = true } 424log = { version = "0.4.14", optional = true }
425 425
426embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } 426embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
diff --git a/embassy-usb-dfu/Cargo.toml b/embassy-usb-dfu/Cargo.toml
index eba902c74..ccf8a16eb 100644
--- a/embassy-usb-dfu/Cargo.toml
+++ b/embassy-usb-dfu/Cargo.toml
@@ -26,7 +26,7 @@ flavors = [
26features = ["defmt", "cortex-m", "dfu"] 26features = ["defmt", "cortex-m", "dfu"]
27 27
28[dependencies] 28[dependencies]
29defmt = { version = "0.3.5", optional = true } 29defmt = { version = "1.0.1", optional = true }
30log = { version = "0.4.17", optional = true } 30log = { version = "0.4.17", optional = true }
31 31
32bitflags = "2.4.1" 32bitflags = "2.4.1"
diff --git a/embassy-usb-dfu/src/application.rs b/embassy-usb-dfu/src/application.rs
index 6ad07a78c..4b7b72073 100644
--- a/embassy-usb-dfu/src/application.rs
+++ b/embassy-usb-dfu/src/application.rs
@@ -2,7 +2,7 @@ use embassy_boot::BlockingFirmwareState;
2use embassy_time::{Duration, Instant}; 2use embassy_time::{Duration, Instant};
3use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; 3use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType};
4use embassy_usb::driver::Driver; 4use embassy_usb::driver::Driver;
5use embassy_usb::{Builder, Handler}; 5use embassy_usb::{Builder, FunctionBuilder, Handler};
6use embedded_storage::nor_flash::NorFlash; 6use embedded_storage::nor_flash::NorFlash;
7 7
8use crate::consts::{ 8use crate::consts::{
@@ -130,8 +130,14 @@ pub fn usb_dfu<'d, D: Driver<'d>, MARK: DfuMarker, RST: Reset>(
130 builder: &mut Builder<'d, D>, 130 builder: &mut Builder<'d, D>,
131 handler: &'d mut Control<MARK, RST>, 131 handler: &'d mut Control<MARK, RST>,
132 timeout: Duration, 132 timeout: Duration,
133 func_modifier: impl Fn(&mut FunctionBuilder<'_, 'd, D>),
133) { 134) {
134 let mut func = builder.function(0x00, 0x00, 0x00); 135 let mut func = builder.function(0x00, 0x00, 0x00);
136
137 // Here we give users the opportunity to add their own function level MSOS headers for instance.
138 // This is useful when DFU functionality is part of a composite USB device.
139 func_modifier(&mut func);
140
135 let mut iface = func.interface(); 141 let mut iface = func.interface();
136 let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None); 142 let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None);
137 let timeout = timeout.as_millis() as u16; 143 let timeout = timeout.as_millis() as u16;
diff --git a/embassy-usb-dfu/src/dfu.rs b/embassy-usb-dfu/src/dfu.rs
index a98d6ab40..0f39d906b 100644
--- a/embassy-usb-dfu/src/dfu.rs
+++ b/embassy-usb-dfu/src/dfu.rs
@@ -1,7 +1,7 @@
1use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterError}; 1use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterError};
2use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; 2use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType};
3use embassy_usb::driver::Driver; 3use embassy_usb::driver::Driver;
4use embassy_usb::{Builder, Handler}; 4use embassy_usb::{Builder, FunctionBuilder, Handler};
5use embedded_storage::nor_flash::{NorFlash, NorFlashErrorKind}; 5use embedded_storage::nor_flash::{NorFlash, NorFlashErrorKind};
6 6
7use crate::consts::{ 7use crate::consts::{
@@ -186,8 +186,14 @@ impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Ha
186pub fn usb_dfu<'d, D: Driver<'d>, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize>( 186pub fn usb_dfu<'d, D: Driver<'d>, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize>(
187 builder: &mut Builder<'d, D>, 187 builder: &mut Builder<'d, D>,
188 handler: &'d mut Control<'d, DFU, STATE, RST, BLOCK_SIZE>, 188 handler: &'d mut Control<'d, DFU, STATE, RST, BLOCK_SIZE>,
189 func_modifier: impl Fn(&mut FunctionBuilder<'_, 'd, D>),
189) { 190) {
190 let mut func = builder.function(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU); 191 let mut func = builder.function(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU);
192
193 // Here we give users the opportunity to add their own function level MSOS headers for instance.
194 // This is useful when DFU functionality is part of a composite USB device.
195 func_modifier(&mut func);
196
191 let mut iface = func.interface(); 197 let mut iface = func.interface();
192 let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU, None); 198 let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU, None);
193 alt.descriptor( 199 alt.descriptor(
diff --git a/embassy-usb-driver/Cargo.toml b/embassy-usb-driver/Cargo.toml
index edb6551b0..e40421649 100644
--- a/embassy-usb-driver/Cargo.toml
+++ b/embassy-usb-driver/Cargo.toml
@@ -19,5 +19,5 @@ target = "thumbv7em-none-eabi"
19features = ["defmt"] 19features = ["defmt"]
20 20
21[dependencies] 21[dependencies]
22defmt = { version = "0.3", optional = true }
23embedded-io-async = "0.6.1" 22embedded-io-async = "0.6.1"
23defmt = { version = "1", optional = true }
diff --git a/embassy-usb-synopsys-otg/Cargo.toml b/embassy-usb-synopsys-otg/Cargo.toml
index f9703a54a..98fc044ce 100644
--- a/embassy-usb-synopsys-otg/Cargo.toml
+++ b/embassy-usb-synopsys-otg/Cargo.toml
@@ -21,5 +21,5 @@ critical-section = "1.1"
21embassy-sync = { version = "0.6.2", path = "../embassy-sync" } 21embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
22embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } 22embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" }
23 23
24defmt = { version = "0.3", optional = true } 24defmt = { version = "1.0.1", optional = true }
25log = { version = "0.4.14", optional = true } 25log = { version = "0.4.14", optional = true }
diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml
index 4950fbe2a..e52f4602d 100644
--- a/embassy-usb/Cargo.toml
+++ b/embassy-usb/Cargo.toml
@@ -51,10 +51,10 @@ embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" }
51embassy-sync = { version = "0.6.2", path = "../embassy-sync" } 51embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
52embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" } 52embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" }
53 53
54defmt = { version = "0.3", optional = true } 54defmt = { version = "1", optional = true }
55embedded-io-async = "0.6.1"
56log = { version = "0.4.14", optional = true } 55log = { version = "0.4.14", optional = true }
57heapless = "0.8" 56heapless = "0.8"
57embedded-io-async = "0.6.1"
58 58
59# for HID 59# for HID
60usbd-hid = { version = "0.8.1", optional = true } 60usbd-hid = { version = "0.8.1", optional = true }
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml
index 4ae0e6a77..244ce9591 100644
--- a/examples/boot/application/nrf/Cargo.toml
+++ b/examples/boot/application/nrf/Cargo.toml
@@ -13,8 +13,8 @@ embassy-boot = { version = "0.4.0", path = "../../../../embassy-boot", features
13embassy-boot-nrf = { version = "0.4.0", path = "../../../../embassy-boot-nrf", features = [] } 13embassy-boot-nrf = { version = "0.4.0", path = "../../../../embassy-boot-nrf", features = [] }
14embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 14embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
15 15
16defmt = { version = "0.3", optional = true } 16defmt = { version = "1.0.1", optional = true }
17defmt-rtt = { version = "0.4", optional = true } 17defmt-rtt = { version = "1.0.0", optional = true }
18panic-reset = { version = "0.1.1" } 18panic-reset = { version = "0.1.1" }
19embedded-hal = { version = "0.2.6" } 19embedded-hal = { version = "0.2.6" }
20 20
diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml
index 3c0d207d1..24f4218f1 100644
--- a/examples/boot/application/rp/Cargo.toml
+++ b/examples/boot/application/rp/Cargo.toml
@@ -12,9 +12,9 @@ embassy-rp = { version = "0.4.0", path = "../../../../embassy-rp", features = ["
12embassy-boot-rp = { version = "0.5.0", path = "../../../../embassy-boot-rp", features = [] } 12embassy-boot-rp = { version = "0.5.0", path = "../../../../embassy-boot-rp", features = [] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17panic-probe = { version = "0.3", features = ["print-defmt"], optional = true } 17panic-probe = { version = "1.0.0", features = ["print-defmt"], optional = true }
18panic-reset = { version = "0.1.1", optional = true } 18panic-reset = { version = "0.1.1", optional = true }
19embedded-hal = { version = "0.2.6" } 19embedded-hal = { version = "0.2.6" }
20 20
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index f32727ea8..1e209eb9c 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" }
13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index d62c67742..877e239fa 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19embedded-storage = "0.3.1" 19embedded-storage = "0.3.1"
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index dd3a32e45..f28723835 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19embedded-storage = "0.3.1" 19embedded-storage = "0.3.1"
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index 0b9e9b96a..f1cb55223 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index 490541a2e..7c53e011d 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index c3aa31161..9f5060802 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml
index a89e2bb6e..d1cea8520 100644
--- a/examples/boot/application/stm32wb-dfu/Cargo.toml
+++ b/examples/boot/application/stm32wb-dfu/Cargo.toml
@@ -14,8 +14,8 @@ embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded
14embassy-usb = { version = "0.4.0", path = "../../../../embassy-usb" } 14embassy-usb = { version = "0.4.0", path = "../../../../embassy-usb" }
15embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] } 15embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] }
16 16
17defmt = { version = "0.3", optional = true } 17defmt = { version = "1.0.1", optional = true }
18defmt-rtt = { version = "0.4", optional = true } 18defmt-rtt = { version = "1.0.0", optional = true }
19panic-reset = { version = "0.1.1" } 19panic-reset = { version = "0.1.1" }
20embedded-hal = { version = "0.2.6" } 20embedded-hal = { version = "0.2.6" }
21 21
diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs
index dda2b795b..5e7b71f5a 100644
--- a/examples/boot/application/stm32wb-dfu/src/main.rs
+++ b/examples/boot/application/stm32wb-dfu/src/main.rs
@@ -13,7 +13,7 @@ use embassy_stm32::usb::{self, Driver};
13use embassy_stm32::{bind_interrupts, peripherals}; 13use embassy_stm32::{bind_interrupts, peripherals};
14use embassy_sync::blocking_mutex::Mutex; 14use embassy_sync::blocking_mutex::Mutex;
15use embassy_time::Duration; 15use embassy_time::Duration;
16use embassy_usb::Builder; 16use embassy_usb::{msos, Builder};
17use embassy_usb_dfu::consts::DfuAttributes; 17use embassy_usb_dfu::consts::DfuAttributes;
18use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate}; 18use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate};
19use panic_reset as _; 19use panic_reset as _;
@@ -22,6 +22,11 @@ bind_interrupts!(struct Irqs {
22 USB_LP => usb::InterruptHandler<peripherals::USB>; 22 USB_LP => usb::InterruptHandler<peripherals::USB>;
23}); 23});
24 24
25// This is a randomly generated GUID to allow clients on Windows to find your device.
26//
27// N.B. update to a custom GUID for your own device!
28const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"];
29
25#[embassy_executor::main] 30#[embassy_executor::main]
26async fn main(_spawner: Spawner) { 31async fn main(_spawner: Spawner) {
27 let mut config = embassy_stm32::Config::default(); 32 let mut config = embassy_stm32::Config::default();
@@ -54,7 +59,28 @@ async fn main(_spawner: Spawner) {
54 &mut control_buf, 59 &mut control_buf,
55 ); 60 );
56 61
57 usb_dfu(&mut builder, &mut state, Duration::from_millis(2500)); 62 // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows.
63 // Otherwise users need to do this manually using a tool like Zadig.
64 //
65 // It seems these always need to be at added at the device level for this to work and for
66 // composite devices they also need to be added on the function level (as shown later).
67 //
68 builder.msos_descriptor(msos::windows_version::WIN8_1, 2);
69 builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
70 builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new(
71 "DeviceInterfaceGUIDs",
72 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
73 ));
74
75 usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), |func| {
76 // You likely don't have to add these function level headers if your USB device is not composite
77 // (i.e. if your device does not expose another interface in addition to DFU)
78 func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
79 func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new(
80 "DeviceInterfaceGUIDs",
81 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
82 ));
83 });
58 84
59 let mut dev = builder.build(); 85 let mut dev = builder.build();
60 dev.run().await 86 dev.run().await
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index f4d7ae712..54331dd69 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/bootloader/nrf/Cargo.toml b/examples/boot/bootloader/nrf/Cargo.toml
index 34a0553e3..4c2712718 100644
--- a/examples/boot/bootloader/nrf/Cargo.toml
+++ b/examples/boot/bootloader/nrf/Cargo.toml
@@ -6,8 +6,8 @@ description = "Bootloader for nRF chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-nrf = { path = "../../../../embassy-nrf", features = [] } 12embassy-nrf = { path = "../../../../embassy-nrf", features = [] }
13embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" } 13embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" }
diff --git a/examples/boot/bootloader/rp/Cargo.toml b/examples/boot/bootloader/rp/Cargo.toml
index 7c9c3c779..c57b90793 100644
--- a/examples/boot/bootloader/rp/Cargo.toml
+++ b/examples/boot/bootloader/rp/Cargo.toml
@@ -6,8 +6,8 @@ description = "Example bootloader for RP2040 chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-rp = { path = "../../../../embassy-rp", features = ["rp2040"] } 12embassy-rp = { path = "../../../../embassy-rp", features = ["rp2040"] }
13embassy-boot-rp = { path = "../../../../embassy-boot-rp" } 13embassy-boot-rp = { path = "../../../../embassy-boot-rp" }
diff --git a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml
index 4beb9c61c..a3ca96aec 100644
--- a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml
+++ b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml
@@ -6,8 +6,8 @@ description = "Example bootloader for dual-bank flash STM32 chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } 12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } 13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
diff --git a/examples/boot/bootloader/stm32/Cargo.toml b/examples/boot/bootloader/stm32/Cargo.toml
index 9abad8636..bdefa2cb5 100644
--- a/examples/boot/bootloader/stm32/Cargo.toml
+++ b/examples/boot/bootloader/stm32/Cargo.toml
@@ -6,8 +6,8 @@ description = "Example bootloader for STM32 chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } 12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } 13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
diff --git a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
index 01343b86b..389f43641 100644
--- a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
+++ b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
@@ -6,8 +6,8 @@ description = "Example USB DFUbootloader for the STM32WB series of chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } 12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } 13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs
index 28216806e..0b643079f 100644
--- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs
+++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs
@@ -20,7 +20,9 @@ bind_interrupts!(struct Irqs {
20 USB_LP => usb::InterruptHandler<peripherals::USB>; 20 USB_LP => usb::InterruptHandler<peripherals::USB>;
21}); 21});
22 22
23// This is a randomly generated GUID to allow clients on Windows to find our device 23// This is a randomly generated GUID to allow clients on Windows to find your device.
24//
25// N.B. update to a custom GUID for your own device!
24const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"]; 26const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"];
25 27
26#[entry] 28#[entry]
@@ -68,7 +70,8 @@ fn main() -> ! {
68 // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. 70 // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows.
69 // Otherwise users need to do this manually using a tool like Zadig. 71 // Otherwise users need to do this manually using a tool like Zadig.
70 // 72 //
71 // It seems it is important for the DFU class that these headers be on the Device level. 73 // It seems these always need to be at added at the device level for this to work and for
74 // composite devices they also need to be added on the function level (as shown later).
72 // 75 //
73 builder.msos_descriptor(msos::windows_version::WIN8_1, 2); 76 builder.msos_descriptor(msos::windows_version::WIN8_1, 2);
74 builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); 77 builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
@@ -77,7 +80,15 @@ fn main() -> ! {
77 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), 80 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
78 )); 81 ));
79 82
80 usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state); 83 usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, |func| {
84 // You likely don't have to add these function level headers if your USB device is not composite
85 // (i.e. if your device does not expose another interface in addition to DFU)
86 func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
87 func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new(
88 "DeviceInterfaceGUIDs",
89 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
90 ));
91 });
81 92
82 let mut dev = builder.build(); 93 let mut dev = builder.build();
83 embassy_futures::block_on(dev.run()); 94 embassy_futures::block_on(dev.run());
diff --git a/examples/lpc55s69/Cargo.toml b/examples/lpc55s69/Cargo.toml
index f5a6e6995..30ce0b799 100644
--- a/examples/lpc55s69/Cargo.toml
+++ b/examples/lpc55s69/Cargo.toml
@@ -10,12 +10,12 @@ embassy-nxp = { version = "0.1.0", path = "../../embassy-nxp", features = ["rt"]
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
13panic-halt = "0.2.0" 13panic-halt = "1.0.0"
14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
15cortex-m-rt = { version = "0.7.0"} 15cortex-m-rt = { version = "0.7.0"}
16defmt = "0.3" 16defmt = "1.0.1"
17defmt-rtt = "0.4" 17defmt-rtt = "1.0.0"
18panic-probe = { version = "0.3.2", features = ["print-defmt"] } 18panic-probe = { version = "1.0.0", features = ["print-defmt"] }
19panic-semihosting = "0.6.0" 19panic-semihosting = "0.6.0"
20 20
21[profile.release] 21[profile.release]
diff --git a/examples/mimxrt6/Cargo.toml b/examples/mimxrt6/Cargo.toml
index b0c56f003..40cc0fb44 100644
--- a/examples/mimxrt6/Cargo.toml
+++ b/examples/mimxrt6/Cargo.toml
@@ -7,8 +7,8 @@ license = "MIT or Apache-2.0"
7[dependencies] 7[dependencies]
8cortex-m = { version = "0.7.7", features = ["inline-asm", "critical-section-single-core"] } 8cortex-m = { version = "0.7.7", features = ["inline-asm", "critical-section-single-core"] }
9cortex-m-rt = "0.7.3" 9cortex-m-rt = "0.7.3"
10defmt = "1.0" 10defmt = "1.0.1"
11defmt-rtt = "1.0" 11defmt-rtt = "1.0.0"
12 12
13embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 13embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
14embassy-futures = { version = "0.1.1", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.1", path = "../../embassy-futures" }
@@ -19,8 +19,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
19embedded-hal-async = "1.0.0" 19embedded-hal-async = "1.0.0"
20 20
21mimxrt600-fcb = "0.2.2" 21mimxrt600-fcb = "0.2.2"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23rand = { version = "0.8.5", default-features = false }
24 23
25# cargo build/run 24# cargo build/run
26[profile.dev] 25[profile.dev]
diff --git a/examples/mimxrt6/src/bin/crc.rs b/examples/mimxrt6/src/bin/crc.rs
new file mode 100644
index 000000000..005a250e5
--- /dev/null
+++ b/examples/mimxrt6/src/bin/crc.rs
@@ -0,0 +1,175 @@
1#![no_std]
2#![no_main]
3
4extern crate embassy_imxrt_examples;
5
6use defmt::*;
7use embassy_executor::Spawner;
8use embassy_imxrt::crc::{Config, Crc, Polynomial};
9use {defmt_rtt as _, panic_probe as _};
10
11#[embassy_executor::main]
12async fn main(_spawner: Spawner) {
13 let mut p = embassy_imxrt::init(Default::default());
14 let data = b"123456789";
15
16 info!("Initializing CRC");
17
18 // CRC-CCITT
19 let mut crc = Crc::new(p.CRC.reborrow(), Default::default());
20 let output = crc.feed_bytes(data);
21 defmt::assert_eq!(output, 0x29b1);
22
23 // CRC16-ARC
24 let mut crc = Crc::new(
25 p.CRC.reborrow(),
26 Config {
27 polynomial: Polynomial::Crc16,
28 reverse_in: true,
29 reverse_out: true,
30 complement_out: false,
31 seed: 0,
32 ..Default::default()
33 },
34 );
35 let output = crc.feed_bytes(data);
36 defmt::assert_eq!(output, 0xbb3d);
37
38 // CRC16-CMS
39 let mut crc = Crc::new(
40 p.CRC.reborrow(),
41 Config {
42 polynomial: Polynomial::Crc16,
43 reverse_in: false,
44 reverse_out: false,
45 complement_out: false,
46 seed: 0xffff,
47 ..Default::default()
48 },
49 );
50 let output = crc.feed_bytes(data);
51 defmt::assert_eq!(output, 0xaee7);
52
53 // CRC16-DDS-110
54 let mut crc = Crc::new(
55 p.CRC.reborrow(),
56 Config {
57 polynomial: Polynomial::Crc16,
58 reverse_in: false,
59 reverse_out: false,
60 complement_out: false,
61 seed: 0x800d,
62 ..Default::default()
63 },
64 );
65 let output = crc.feed_bytes(data);
66 defmt::assert_eq!(output, 0x9ecf);
67
68 // CRC16-MAXIM-DOW
69 let mut crc = Crc::new(
70 p.CRC.reborrow(),
71 Config {
72 polynomial: Polynomial::Crc16,
73 reverse_in: true,
74 reverse_out: true,
75 complement_out: true,
76 seed: 0,
77 ..Default::default()
78 },
79 );
80 let output = crc.feed_bytes(data);
81 defmt::assert_eq!(output, 0x44c2);
82
83 // CRC16-MODBUS
84 let mut crc = Crc::new(
85 p.CRC.reborrow(),
86 Config {
87 polynomial: Polynomial::Crc16,
88 reverse_in: true,
89 reverse_out: true,
90 complement_out: false,
91 seed: 0xffff,
92 ..Default::default()
93 },
94 );
95 let output = crc.feed_bytes(data);
96 defmt::assert_eq!(output, 0x4b37);
97
98 // CRC32-BZIP2
99 let mut crc = Crc::new(
100 p.CRC.reborrow(),
101 Config {
102 polynomial: Polynomial::Crc32,
103 reverse_in: false,
104 reverse_out: false,
105 complement_out: true,
106 seed: 0xffff_ffff,
107 ..Default::default()
108 },
109 );
110 let output = crc.feed_bytes(data);
111 defmt::assert_eq!(output, 0xfc89_1918);
112
113 // CRC32-CKSUM
114 let mut crc = Crc::new(
115 p.CRC.reborrow(),
116 Config {
117 polynomial: Polynomial::Crc32,
118 reverse_in: false,
119 reverse_out: false,
120 complement_out: true,
121 seed: 0,
122 ..Default::default()
123 },
124 );
125 let output = crc.feed_bytes(data);
126 defmt::assert_eq!(output, 0x765e_7680);
127
128 // CRC32-ISO-HDLC
129 let mut crc = Crc::new(
130 p.CRC.reborrow(),
131 Config {
132 polynomial: Polynomial::Crc32,
133 reverse_in: true,
134 reverse_out: true,
135 complement_out: true,
136 seed: 0xffff_ffff,
137 ..Default::default()
138 },
139 );
140 let output = crc.feed_bytes(data);
141 defmt::assert_eq!(output, 0xcbf4_3926);
142
143 // CRC32-JAMCRC
144 let mut crc = Crc::new(
145 p.CRC.reborrow(),
146 Config {
147 polynomial: Polynomial::Crc32,
148 reverse_in: true,
149 reverse_out: true,
150 complement_out: false,
151 seed: 0xffff_ffff,
152 ..Default::default()
153 },
154 );
155 let output = crc.feed_bytes(data);
156 defmt::assert_eq!(output, 0x340b_c6d9);
157
158 // CRC32-MPEG-2
159 let mut crc = Crc::new(
160 p.CRC.reborrow(),
161 Config {
162 polynomial: Polynomial::Crc32,
163 reverse_in: false,
164 reverse_out: false,
165 complement_out: false,
166 seed: 0xffff_ffff,
167 ..Default::default()
168 },
169 );
170 let output = crc.feed_bytes(data);
171 defmt::assert_eq!(output, 0x0376_e6e7);
172
173 info!("end program");
174 cortex_m::asm::bkpt();
175}
diff --git a/examples/mimxrt6/src/bin/rng.rs b/examples/mimxrt6/src/bin/rng.rs
new file mode 100644
index 000000000..9468dd109
--- /dev/null
+++ b/examples/mimxrt6/src/bin/rng.rs
@@ -0,0 +1,39 @@
1#![no_std]
2#![no_main]
3
4extern crate embassy_imxrt_examples;
5
6use defmt::*;
7use embassy_executor::Spawner;
8use embassy_imxrt::rng::Rng;
9use embassy_imxrt::{bind_interrupts, peripherals, rng};
10use {defmt_rtt as _, panic_probe as _};
11
12bind_interrupts!(struct Irqs {
13 RNG => rng::InterruptHandler<peripherals::RNG>;
14});
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let p = embassy_imxrt::init(Default::default());
19
20 info!("Initializing RNG");
21 let mut rng = Rng::new(p.RNG, Irqs);
22 let mut buf = [0u8; 65];
23
24 // Async interface
25 unwrap!(rng.async_fill_bytes(&mut buf).await);
26 info!("random bytes: {:02x}", buf);
27
28 // RngCore interface
29 let mut random_bytes = [0; 16];
30
31 let random_u32 = rng.blocking_next_u32();
32 let random_u64 = rng.blocking_next_u64();
33
34 rng.blocking_fill_bytes(&mut random_bytes);
35
36 info!("random_u32 {}", random_u32);
37 info!("random_u64 {}", random_u64);
38 info!("random_bytes {}", random_bytes);
39}
diff --git a/examples/mimxrt6/src/bin/uart-async.rs b/examples/mimxrt6/src/bin/uart-async.rs
new file mode 100644
index 000000000..58e31f379
--- /dev/null
+++ b/examples/mimxrt6/src/bin/uart-async.rs
@@ -0,0 +1,87 @@
1#![no_std]
2#![no_main]
3
4extern crate embassy_imxrt_examples;
5
6use defmt::info;
7use embassy_executor::Spawner;
8use embassy_imxrt::flexcomm::uart::{self, Async, Uart};
9use embassy_imxrt::{bind_interrupts, peripherals};
10use embassy_time::Timer;
11use {defmt_rtt as _, panic_probe as _};
12
13bind_interrupts!(struct Irqs {
14 FLEXCOMM2 => uart::InterruptHandler<peripherals::FLEXCOMM2>;
15 FLEXCOMM4 => uart::InterruptHandler<peripherals::FLEXCOMM4>;
16});
17
18const BUFLEN: usize = 16;
19
20#[embassy_executor::task]
21async fn usart4_task(mut uart: Uart<'static, Async>) {
22 info!("RX Task");
23
24 loop {
25 let mut rx_buf = [0; BUFLEN];
26 uart.read(&mut rx_buf).await.unwrap();
27 info!("usart4: rx_buf {:02x}", rx_buf);
28
29 Timer::after_millis(10).await;
30
31 let tx_buf = [0xaa; BUFLEN];
32 uart.write(&tx_buf).await.unwrap();
33 info!("usart4: tx_buf {:02x}", tx_buf);
34 }
35}
36
37#[embassy_executor::task]
38async fn usart2_task(mut uart: Uart<'static, Async>) {
39 info!("TX Task");
40
41 loop {
42 let tx_buf = [0x55; BUFLEN];
43 uart.write(&tx_buf).await.unwrap();
44 info!("usart2: tx_buf {:02x}", tx_buf);
45
46 Timer::after_millis(10).await;
47
48 let mut rx_buf = [0x00; BUFLEN];
49 uart.read(&mut rx_buf).await.unwrap();
50 info!("usart2: rx_buf {:02x}", rx_buf);
51 }
52}
53
54#[embassy_executor::main]
55async fn main(spawner: Spawner) {
56 let p = embassy_imxrt::init(Default::default());
57
58 info!("UART test start");
59
60 let usart4 = Uart::new_with_rtscts(
61 p.FLEXCOMM4,
62 p.PIO0_29,
63 p.PIO0_30,
64 p.PIO1_0,
65 p.PIO0_31,
66 Irqs,
67 p.DMA0_CH9,
68 p.DMA0_CH8,
69 Default::default(),
70 )
71 .unwrap();
72 spawner.must_spawn(usart4_task(usart4));
73
74 let usart2 = Uart::new_with_rtscts(
75 p.FLEXCOMM2,
76 p.PIO0_15,
77 p.PIO0_16,
78 p.PIO0_18,
79 p.PIO0_17,
80 Irqs,
81 p.DMA0_CH5,
82 p.DMA0_CH4,
83 Default::default(),
84 )
85 .unwrap();
86 spawner.must_spawn(usart2_task(usart2));
87}
diff --git a/examples/mimxrt6/src/bin/uart.rs b/examples/mimxrt6/src/bin/uart.rs
new file mode 100644
index 000000000..d6a75f85d
--- /dev/null
+++ b/examples/mimxrt6/src/bin/uart.rs
@@ -0,0 +1,55 @@
1#![no_std]
2#![no_main]
3
4extern crate embassy_imxrt_examples;
5
6use defmt::info;
7use embassy_executor::Spawner;
8use embassy_imxrt::flexcomm::uart::{Blocking, Uart, UartRx, UartTx};
9use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _};
11
12#[embassy_executor::task]
13async fn usart4_task(mut uart: UartRx<'static, Blocking>) {
14 info!("RX Task");
15
16 loop {
17 let mut buf = [0; 8];
18
19 Timer::after_millis(10).await;
20
21 uart.blocking_read(&mut buf).unwrap();
22
23 let s = core::str::from_utf8(&buf).unwrap();
24
25 info!("Received '{}'", s);
26 }
27}
28
29#[embassy_executor::task]
30async fn usart2_task(mut uart: UartTx<'static, Blocking>) {
31 info!("TX Task");
32
33 loop {
34 let buf = "Testing\0".as_bytes();
35
36 uart.blocking_write(buf).unwrap();
37
38 Timer::after_millis(10).await;
39 }
40}
41
42#[embassy_executor::main]
43async fn main(spawner: Spawner) {
44 let p = embassy_imxrt::init(Default::default());
45
46 info!("UART test start");
47
48 let usart4 = Uart::new_blocking(p.FLEXCOMM4, p.PIO0_29, p.PIO0_30, Default::default()).unwrap();
49
50 let (_, usart4) = usart4.split();
51 spawner.must_spawn(usart4_task(usart4));
52
53 let usart2 = UartTx::new_blocking(p.FLEXCOMM2, p.PIO0_15, Default::default()).unwrap();
54 spawner.must_spawn(usart2_task(usart2));
55}
diff --git a/examples/mspm0c1104/Cargo.toml b/examples/mspm0c1104/Cargo.toml
index ba64a578d..7d419af51 100644
--- a/examples/mspm0c1104/Cargo.toml
+++ b/examples/mspm0c1104/Cargo.toml
@@ -5,16 +5,16 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0c110x", "defmt", "rt", "time-driver-any"] } 8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0c1104dgs20", "defmt", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } 9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0" 12panic-halt = "1.0.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"} 14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] } 17panic-probe = { version = "1.0.0", features = ["print-defmt"] }
18panic-semihosting = "0.6.0" 18panic-semihosting = "0.6.0"
19 19
20# The chip only has 1KB of ram, so we must optimize binaries regardless 20# The chip only has 1KB of ram, so we must optimize binaries regardless
diff --git a/examples/mspm0c1104/README.md b/examples/mspm0c1104/README.md
index e5c9f961d..86b6c3918 100644
--- a/examples/mspm0c1104/README.md
+++ b/examples/mspm0c1104/README.md
@@ -1,4 +1,4 @@
1# Examples for MSPM0C110x family 1# Examples for MSPM0C1104
2 2
3Run individual examples with 3Run individual examples with
4``` 4```
@@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0C1104](https://www.t
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. 15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16 16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for C1104 it should be `probe-rs run --chip MSPM0C1104`. (use `probe-rs chip list` to find your chip) 17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for C1104 it should be `probe-rs run --chip MSPM0C1104`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for C1104 it should be `mspm0c1104`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. 18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0C1104 it should be `mspm0c1104dgs20`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. 19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic 20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21 21
diff --git a/examples/mspm0g3507/Cargo.toml b/examples/mspm0g3507/Cargo.toml
index f6fed091d..5a02b7249 100644
--- a/examples/mspm0g3507/Cargo.toml
+++ b/examples/mspm0g3507/Cargo.toml
@@ -5,16 +5,16 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g350x", "defmt", "rt", "time-driver-any"] } 8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g3507pm", "defmt", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } 9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0" 12panic-halt = "1.0.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"} 14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] } 17panic-probe = { version = "1.0.0", features = ["print-defmt"] }
18panic-semihosting = "0.6.0" 18panic-semihosting = "0.6.0"
19 19
20[profile.release] 20[profile.release]
diff --git a/examples/mspm0g3507/README.md b/examples/mspm0g3507/README.md
index 5e8a83212..be91dc5a0 100644
--- a/examples/mspm0g3507/README.md
+++ b/examples/mspm0g3507/README.md
@@ -1,4 +1,4 @@
1# Examples for MSPM0C350x family 1# Examples for MSPM0M3507
2 2
3Run individual examples with 3Run individual examples with
4``` 4```
@@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0G3507](https://www.t
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. 15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16 16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G3507 it should be `probe-rs run --chip MSPM0G3507`. (use `probe-rs chip list` to find your chip) 17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G3507 it should be `probe-rs run --chip MSPM0G3507`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for G3507 it should be `mspm0g3507`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. 18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0G3507 it should be `mspm0g3507pm`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. 19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic 20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21 21
diff --git a/examples/mspm0g3519/Cargo.toml b/examples/mspm0g3519/Cargo.toml
index 1662e1f8d..fc647a4ce 100644
--- a/examples/mspm0g3519/Cargo.toml
+++ b/examples/mspm0g3519/Cargo.toml
@@ -5,16 +5,16 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g351x", "defmt", "rt", "time-driver-any"] } 8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g3519pz", "defmt", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } 9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0" 12panic-halt = "1.0.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"} 14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] } 17panic-probe = { version = "1.0.0", features = ["print-defmt"] }
18panic-semihosting = "0.6.0" 18panic-semihosting = "0.6.0"
19 19
20[profile.release] 20[profile.release]
diff --git a/examples/mspm0g3519/README.md b/examples/mspm0g3519/README.md
index 5034b1913..c392c9e25 100644
--- a/examples/mspm0g3519/README.md
+++ b/examples/mspm0g3519/README.md
@@ -1,4 +1,4 @@
1# Examples for MSPM0G351x family 1# Examples for MSPM0G3519
2 2
3Run individual examples with 3Run individual examples with
4``` 4```
@@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0G3519](https://www.t
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. 15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16 16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G3519 it should be `probe-rs run --chip MSPM0G3519`. (use `probe-rs chip list` to find your chip) 17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G3519 it should be `probe-rs run --chip MSPM0G3519`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for G3519 it should be `mspm0g3519`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. 18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0G3519 it should be `mspm0g3519pz`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. 19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic 20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21 21
diff --git a/examples/mspm0l1306/Cargo.toml b/examples/mspm0l1306/Cargo.toml
index 609b3f205..6f2f33b1e 100644
--- a/examples/mspm0l1306/Cargo.toml
+++ b/examples/mspm0l1306/Cargo.toml
@@ -5,16 +5,16 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l130x", "defmt", "rt", "time-driver-any"] } 8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l1306rhb", "defmt", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } 9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0" 12panic-halt = "1.0.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"} 14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] } 17panic-probe = { version = "1.0.0", features = ["print-defmt"] }
18panic-semihosting = "0.6.0" 18panic-semihosting = "0.6.0"
19 19
20[profile.release] 20[profile.release]
diff --git a/examples/mspm0l1306/README.md b/examples/mspm0l1306/README.md
index 5a55d721e..4d698e0fa 100644
--- a/examples/mspm0l1306/README.md
+++ b/examples/mspm0l1306/README.md
@@ -1,4 +1,4 @@
1# Examples for MSPM0L130x family 1# Examples for MSPM0L1306
2 2
3Run individual examples with 3Run individual examples with
4``` 4```
@@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0L1306](https://www.t
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. 15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16 16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L1306 it should be `probe-rs run --chip MSPM0L1306`. (use `probe-rs chip list` to find your chip) 17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L1306 it should be `probe-rs run --chip MSPM0L1306`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for L1306 it should be `mspm0l1306`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. 18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0L1306 it should be `mspm0l1306rhb`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. 19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic 20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21 21
diff --git a/examples/mspm0l2228/Cargo.toml b/examples/mspm0l2228/Cargo.toml
index bbca011a1..a68b5bfe9 100644
--- a/examples/mspm0l2228/Cargo.toml
+++ b/examples/mspm0l2228/Cargo.toml
@@ -5,16 +5,16 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l222x", "defmt", "rt", "time-driver-any"] } 8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l2228pn", "defmt", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } 9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0" 12panic-halt = "1.0.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"} 14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] } 17panic-probe = { version = "1.0.0", features = ["print-defmt"] }
18panic-semihosting = "0.6.0" 18panic-semihosting = "0.6.0"
19 19
20[profile.release] 20[profile.release]
diff --git a/examples/mspm0l2228/README.md b/examples/mspm0l2228/README.md
index c73fa13b6..191022258 100644
--- a/examples/mspm0l2228/README.md
+++ b/examples/mspm0l2228/README.md
@@ -1,4 +1,4 @@
1# Examples for MSPM0L222x family 1# Examples for MSPM0L2228
2 2
3Run individual examples with 3Run individual examples with
4``` 4```
@@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0L2228](https://www.t
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. 15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16 16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L2228 it should be `probe-rs run --chip MSPM0L2228`. (use `probe-rs chip list` to find your chip) 17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L2228 it should be `probe-rs run --chip MSPM0L2228`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for L2228 it should be `mspm0l2228`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. 18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for LP-MSPM0L2228 it should be `mspm0l2228pn`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. 19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic 20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21 21
diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml
index af12212cd..dcbaf87f8 100644
--- a/examples/nrf-rtos-trace/Cargo.toml
+++ b/examples/nrf-rtos-trace/Cargo.toml
@@ -22,8 +22,7 @@ embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["nrf5
22 22
23cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 23cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
24cortex-m-rt = "0.7.0" 24cortex-m-rt = "0.7.0"
25panic-probe = { version = "0.3" } 25panic-probe = "1.0.0"
26rand = { version = "0.8.4", default-features = false }
27serde = { version = "1.0.136", default-features = false } 26serde = { version = "1.0.136", default-features = false }
28rtos-trace = "0.1.3" 27rtos-trace = "0.1.3"
29systemview-target = { version = "0.1.2", features = ["callbacks-app", "callbacks-os", "log", "cortex-m"] } 28systemview-target = { version = "0.1.2", features = ["callbacks-app", "callbacks-os", "log", "cortex-m"] }
diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml
index 97b5b924a..91f78737f 100644
--- a/examples/nrf51/Cargo.toml
+++ b/examples/nrf51/Cargo.toml
@@ -9,12 +9,12 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] } 10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] }
11 11
12defmt = "0.3" 12defmt = "1.0.1"
13defmt-rtt = "0.4" 13defmt-rtt = "1.0.0"
14 14
15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
16cortex-m-rt = "0.7" 16cortex-m-rt = "0.7"
17panic-probe = { version = "0.3", features = ["print-defmt"] } 17panic-probe = { version = "1.0.0", features = ["print-defmt"] }
18 18
19[profile.release] 19[profile.release]
20debug = 2 20debug = 2
diff --git a/examples/nrf52810/Cargo.toml b/examples/nrf52810/Cargo.toml
index cd59b86c3..5373278c1 100644
--- a/examples/nrf52810/Cargo.toml
+++ b/examples/nrf52810/Cargo.toml
@@ -11,14 +11,14 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
12embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 12embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
13 13
14defmt = "0.3" 14defmt = "1.0.1"
15defmt-rtt = "0.4" 15defmt-rtt = "1.0.0"
16 16
17fixed = "1.10.0" 17fixed = "1.10.0"
18static_cell = { version = "2" } 18static_cell = { version = "2" }
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21panic-probe = { version = "0.3", features = ["print-defmt"] } 21panic-probe = { version = "1.0.0", features = ["print-defmt"] }
22 22
23[profile.release] 23[profile.release]
24debug = 2 24debug = 2
diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml
index ac3d2006c..2eef012b7 100644
--- a/examples/nrf52840-rtic/Cargo.toml
+++ b/examples/nrf52840-rtic/Cargo.toml
@@ -13,12 +13,12 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "d
13embassy-time-queue-utils = { version = "0.1", path = "../../embassy-time-queue-utils", features = ["generic-queue-8"] } 13embassy-time-queue-utils = { version = "0.1", path = "../../embassy-time-queue-utils", features = ["generic-queue-8"] }
14embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 14embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
15 15
16defmt = "0.3" 16defmt = "1.0.1"
17defmt-rtt = "0.4" 17defmt-rtt = "1.0.0"
18 18
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21panic-probe = { version = "0.3", features = ["print-defmt"] } 21panic-probe = { version = "1.0.0", features = ["print-defmt"] }
22 22
23[profile.release] 23[profile.release]
24debug = 2 24debug = 2
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml
index 902193f3a..92127a8b0 100644
--- a/examples/nrf52840/Cargo.toml
+++ b/examples/nrf52840/Cargo.toml
@@ -17,15 +17,15 @@ embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
17embassy-net-esp-hosted = { version = "0.2.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } 17embassy-net-esp-hosted = { version = "0.2.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] }
18embassy-net-enc28j60 = { version = "0.2.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } 18embassy-net-enc28j60 = { version = "0.2.0", path = "../../embassy-net-enc28j60", features = ["defmt"] }
19 19
20defmt = "0.3" 20defmt = "1.0.1"
21defmt-rtt = "0.4" 21defmt-rtt = "1.0.0"
22 22
23fixed = "1.10.0" 23fixed = "1.10.0"
24static_cell = { version = "2" } 24static_cell = { version = "2" }
25cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 25cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
26cortex-m-rt = "0.7.0" 26cortex-m-rt = "0.7.0"
27panic-probe = { version = "0.3", features = ["print-defmt"] } 27panic-probe = { version = "1.0.0", features = ["print-defmt"] }
28rand = { version = "0.8.4", default-features = false } 28rand = { version = "0.9.0", default-features = false }
29embedded-storage = "0.3.1" 29embedded-storage = "0.3.1"
30usbd-hid = "0.8.1" 30usbd-hid = "0.8.1"
31serde = { version = "1.0.136", default-features = false } 31serde = { version = "1.0.136", default-features = false }
diff --git a/examples/nrf52840/src/bin/rng.rs b/examples/nrf52840/src/bin/rng.rs
index 326054c9a..f32d17cd9 100644..100755
--- a/examples/nrf52840/src/bin/rng.rs
+++ b/examples/nrf52840/src/bin/rng.rs
@@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) {
22 defmt::info!("Some random bytes: {:?}", bytes); 22 defmt::info!("Some random bytes: {:?}", bytes);
23 23
24 // Sync API with `rand` 24 // Sync API with `rand`
25 defmt::info!("A random number from 1 to 10: {:?}", rng.gen_range(1..=10)); 25 defmt::info!("A random number from 1 to 10: {:?}", rng.random_range(1..=10));
26 26
27 let mut bytes = [0; 1024]; 27 let mut bytes = [0; 1024];
28 rng.fill_bytes(&mut bytes).await; 28 rng.fill_bytes(&mut bytes).await;
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml
index 459c43221..42d7766b7 100644
--- a/examples/nrf5340/Cargo.toml
+++ b/examples/nrf5340/Cargo.toml
@@ -14,14 +14,13 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
15embedded-io-async = { version = "0.6.1" } 15embedded-io-async = { version = "0.6.1" }
16 16
17defmt = "0.3" 17defmt = "1.0.1"
18defmt-rtt = "0.4" 18defmt-rtt = "1.0.0"
19 19
20static_cell = "2" 20static_cell = "2"
21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
22cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
23panic-probe = { version = "0.3", features = ["print-defmt"] } 23panic-probe = { version = "1.0.0", features = ["print-defmt"] }
24rand = { version = "0.8.4", default-features = false }
25embedded-storage = "0.3.1" 24embedded-storage = "0.3.1"
26usbd-hid = "0.8.1" 25usbd-hid = "0.8.1"
27serde = { version = "1.0.136", default-features = false } 26serde = { version = "1.0.136", default-features = false }
diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml
index 8848065d8..4b229d06d 100644
--- a/examples/nrf54l15/Cargo.toml
+++ b/examples/nrf54l15/Cargo.toml
@@ -9,9 +9,9 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11 11
12defmt = "0.3" 12defmt = "1.0.1"
13defmt-rtt = "0.4" 13defmt-rtt = "1.0.0"
14panic-probe = { version = "0.3", features = ["print-defmt"] } 14panic-probe = { version = "1.0.0", features = ["print-defmt"] }
15 15
16cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 16cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
17cortex-m-rt = "0.7.0" 17cortex-m-rt = "0.7.0"
diff --git a/examples/nrf9151/ns/Cargo.toml b/examples/nrf9151/ns/Cargo.toml
index 03f38fd63..a083aa5e7 100644
--- a/examples/nrf9151/ns/Cargo.toml
+++ b/examples/nrf9151/ns/Cargo.toml
@@ -9,12 +9,12 @@ embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", feat
9embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-ns", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 10embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-ns", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11 11
12defmt = "0.3" 12defmt = "1.0.1"
13defmt-rtt = "0.4" 13defmt-rtt = "1.0.0"
14 14
15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
16cortex-m-rt = "0.7.0" 16cortex-m-rt = "0.7.0"
17panic-probe = { version = "0.3", features = ["print-defmt"] } 17panic-probe = { version = "1.0.0", features = ["print-defmt"] }
18 18
19[profile.release] 19[profile.release]
20debug = 2 20debug = 2
diff --git a/examples/nrf9151/s/Cargo.toml b/examples/nrf9151/s/Cargo.toml
index ba88f6da3..ae98631ef 100644
--- a/examples/nrf9151/s/Cargo.toml
+++ b/examples/nrf9151/s/Cargo.toml
@@ -9,12 +9,12 @@ embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", feat
9embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 10embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11 11
12defmt = "0.3" 12defmt = "1.0.1"
13defmt-rtt = "0.4" 13defmt-rtt = "1.0.0"
14 14
15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
16cortex-m-rt = "0.7.0" 16cortex-m-rt = "0.7.0"
17panic-probe = { version = "0.3", features = ["print-defmt"] } 17panic-probe = { version = "1.0.0", features = ["print-defmt"] }
18 18
19[profile.release] 19[profile.release]
20debug = 2 20debug = 2
diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml
index a720f2d61..25aedf624 100644
--- a/examples/nrf9160/Cargo.toml
+++ b/examples/nrf9160/Cargo.toml
@@ -11,13 +11,13 @@ embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defm
11embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] } 11embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] }
12embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "proto-ipv4", "medium-ip"] } 12embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "proto-ipv4", "medium-ip"] }
13 13
14defmt = "0.3" 14defmt = "1.0.1"
15defmt-rtt = "0.4" 15defmt-rtt = "1.0.0"
16 16
17heapless = "0.8" 17heapless = "0.8"
18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
19cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
20panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "1.0.0", features = ["print-defmt"] }
21static_cell = { version = "2" } 21static_cell = { version = "2" }
22embedded-io = "0.6.1" 22embedded-io = "0.6.1"
23embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } 23embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 45ca30e4c..d19dd9dc7 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -19,8 +19,8 @@ embassy-usb-logger = { version = "0.4.0", path = "../../embassy-usb-logger" }
19cyw43 = { version = "0.3.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] } 19cyw43 = { version = "0.3.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] }
20cyw43-pio = { version = "0.4.0", path = "../../cyw43-pio", features = ["defmt"] } 20cyw43-pio = { version = "0.4.0", path = "../../cyw43-pio", features = ["defmt"] }
21 21
22defmt = "0.3" 22defmt = "1.0.1"
23defmt-rtt = "0.4" 23defmt-rtt = "1.0.0"
24fixed = "1.23.1" 24fixed = "1.23.1"
25fixed-macro = "1.2" 25fixed-macro = "1.2"
26 26
@@ -36,7 +36,7 @@ assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev
36cortex-m = { version = "0.7.6", features = ["inline-asm"] } 36cortex-m = { version = "0.7.6", features = ["inline-asm"] }
37cortex-m-rt = "0.7.0" 37cortex-m-rt = "0.7.0"
38critical-section = "1.1" 38critical-section = "1.1"
39panic-probe = { version = "0.3", features = ["print-defmt"] } 39panic-probe = { version = "1.0.0", features = ["print-defmt"] }
40display-interface-spi = "0.5.0" 40display-interface-spi = "0.5.0"
41embedded-graphics = "0.8.1" 41embedded-graphics = "0.8.1"
42mipidsi = "0.8.0" 42mipidsi = "0.8.0"
@@ -45,7 +45,6 @@ byte-slice-cast = { version = "1.2.0", default-features = false }
45smart-leds = "0.4.0" 45smart-leds = "0.4.0"
46heapless = "0.8" 46heapless = "0.8"
47usbd-hid = "0.8.1" 47usbd-hid = "0.8.1"
48rand_core = "0.6.4"
49 48
50embedded-hal-1 = { package = "embedded-hal", version = "1.0" } 49embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
51embedded-hal-async = "1.0" 50embedded-hal-async = "1.0"
@@ -55,7 +54,7 @@ embedded-storage = { version = "0.3" }
55static_cell = "2.1" 54static_cell = "2.1"
56portable-atomic = { version = "1.5", features = ["critical-section"] } 55portable-atomic = { version = "1.5", features = ["critical-section"] }
57log = "0.4" 56log = "0.4"
58rand = { version = "0.8.5", default-features = false } 57rand = { version = "0.9.0", default-features = false }
59embedded-sdmmc = "0.7.0" 58embedded-sdmmc = "0.7.0"
60 59
61[profile.release] 60[profile.release]
diff --git a/examples/rp/src/bin/adc.rs b/examples/rp/src/bin/adc.rs
index 1bb7c2249..015915586 100644
--- a/examples/rp/src/bin/adc.rs
+++ b/examples/rp/src/bin/adc.rs
@@ -12,9 +12,12 @@ use embassy_rp::gpio::Pull;
12use embassy_time::Timer; 12use embassy_time::Timer;
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
14 14
15bind_interrupts!(struct Irqs { 15bind_interrupts!(
16 ADC_IRQ_FIFO => InterruptHandler; 16 /// Binds the ADC interrupts.
17}); 17 struct Irqs {
18 ADC_IRQ_FIFO => InterruptHandler;
19 }
20);
18 21
19#[embassy_executor::main] 22#[embassy_executor::main]
20async fn main(_spawner: Spawner) { 23async fn main(_spawner: Spawner) {
diff --git a/examples/rp/src/bin/ethernet_w5500_icmp.rs b/examples/rp/src/bin/ethernet_w5500_icmp.rs
index 5c42b2dde..e434b3bbc 100644
--- a/examples/rp/src/bin/ethernet_w5500_icmp.rs
+++ b/examples/rp/src/bin/ethernet_w5500_icmp.rs
@@ -21,7 +21,6 @@ use embassy_rp::peripherals::SPI0;
21use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 21use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
22use embassy_time::{Delay, Instant, Timer}; 22use embassy_time::{Delay, Instant, Timer};
23use embedded_hal_bus::spi::ExclusiveDevice; 23use embedded_hal_bus::spi::ExclusiveDevice;
24use rand::RngCore;
25use static_cell::StaticCell; 24use static_cell::StaticCell;
26use {defmt_rtt as _, panic_probe as _}; 25use {defmt_rtt as _, panic_probe as _};
27 26
diff --git a/examples/rp/src/bin/ethernet_w5500_icmp_ping.rs b/examples/rp/src/bin/ethernet_w5500_icmp_ping.rs
index 0724311f9..0ec594fd5 100644
--- a/examples/rp/src/bin/ethernet_w5500_icmp_ping.rs
+++ b/examples/rp/src/bin/ethernet_w5500_icmp_ping.rs
@@ -23,7 +23,6 @@ use embassy_rp::peripherals::SPI0;
23use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 23use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
24use embassy_time::{Delay, Duration}; 24use embassy_time::{Delay, Duration};
25use embedded_hal_bus::spi::ExclusiveDevice; 25use embedded_hal_bus::spi::ExclusiveDevice;
26use rand::RngCore;
27use static_cell::StaticCell; 26use static_cell::StaticCell;
28use {defmt_rtt as _, panic_probe as _}; 27use {defmt_rtt as _, panic_probe as _};
29 28
diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs
index 2bea9fc9d..27e2f3c30 100644
--- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs
+++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs
@@ -18,7 +18,6 @@ use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
18use embassy_time::{Delay, Duration}; 18use embassy_time::{Delay, Duration};
19use embedded_hal_bus::spi::ExclusiveDevice; 19use embedded_hal_bus::spi::ExclusiveDevice;
20use embedded_io_async::Write; 20use embedded_io_async::Write;
21use rand::RngCore;
22use static_cell::StaticCell; 21use static_cell::StaticCell;
23use {defmt_rtt as _, panic_probe as _}; 22use {defmt_rtt as _, panic_probe as _};
24 23
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
index 78d1b0b83..ba82f2a60 100644
--- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
+++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
@@ -20,7 +20,6 @@ use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
20use embassy_time::{Delay, Duration, Timer}; 20use embassy_time::{Delay, Duration, Timer};
21use embedded_hal_bus::spi::ExclusiveDevice; 21use embedded_hal_bus::spi::ExclusiveDevice;
22use embedded_io_async::Write; 22use embedded_io_async::Write;
23use rand::RngCore;
24use static_cell::StaticCell; 23use static_cell::StaticCell;
25use {defmt_rtt as _, panic_probe as _}; 24use {defmt_rtt as _, panic_probe as _};
26 25
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
index 25a38c714..5c56dcafa 100644
--- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
+++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
@@ -19,7 +19,6 @@ use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
19use embassy_time::{Delay, Duration}; 19use embassy_time::{Delay, Duration};
20use embedded_hal_bus::spi::ExclusiveDevice; 20use embedded_hal_bus::spi::ExclusiveDevice;
21use embedded_io_async::Write; 21use embedded_io_async::Write;
22use rand::RngCore;
23use static_cell::StaticCell; 22use static_cell::StaticCell;
24use {defmt_rtt as _, panic_probe as _}; 23use {defmt_rtt as _, panic_probe as _};
25 24
diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs
index 683e29222..c5fc8de1d 100644
--- a/examples/rp/src/bin/ethernet_w5500_udp.rs
+++ b/examples/rp/src/bin/ethernet_w5500_udp.rs
@@ -18,7 +18,6 @@ use embassy_rp::peripherals::SPI0;
18use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 18use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
19use embassy_time::Delay; 19use embassy_time::Delay;
20use embedded_hal_bus::spi::ExclusiveDevice; 20use embedded_hal_bus::spi::ExclusiveDevice;
21use rand::RngCore;
22use static_cell::StaticCell; 21use static_cell::StaticCell;
23use {defmt_rtt as _, panic_probe as _}; 22use {defmt_rtt as _, panic_probe as _};
24 23
diff --git a/examples/rp/src/bin/orchestrate_tasks.rs b/examples/rp/src/bin/orchestrate_tasks.rs
index 5e2775793..c35679251 100644
--- a/examples/rp/src/bin/orchestrate_tasks.rs
+++ b/examples/rp/src/bin/orchestrate_tasks.rs
@@ -29,7 +29,6 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
29use embassy_sync::mutex::Mutex; 29use embassy_sync::mutex::Mutex;
30use embassy_sync::{channel, signal}; 30use embassy_sync::{channel, signal};
31use embassy_time::{Duration, Timer}; 31use embassy_time::{Duration, Timer};
32use rand::RngCore;
33use {defmt_rtt as _, panic_probe as _}; 32use {defmt_rtt as _, panic_probe as _};
34 33
35// Hardware resource assignment. See other examples for different ways of doing this. 34// Hardware resource assignment. See other examples for different ways of doing this.
diff --git a/examples/rp/src/bin/overclock.rs b/examples/rp/src/bin/overclock.rs
index 9c78e0c9d..83b17308b 100644
--- a/examples/rp/src/bin/overclock.rs
+++ b/examples/rp/src/bin/overclock.rs
@@ -7,7 +7,7 @@
7 7
8use defmt::*; 8use defmt::*;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_rp::clocks::{clk_sys_freq, ClockConfig}; 10use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig};
11use embassy_rp::config::Config; 11use embassy_rp::config::Config;
12use embassy_rp::gpio::{Level, Output}; 12use embassy_rp::gpio::{Level, Output};
13use embassy_time::{Duration, Instant, Timer}; 13use embassy_time::{Duration, Instant, Timer};
@@ -18,10 +18,7 @@ const COUNT_TO: i64 = 10_000_000;
18#[embassy_executor::main] 18#[embassy_executor::main]
19async fn main(_spawner: Spawner) -> ! { 19async fn main(_spawner: Spawner) -> ! {
20 // Set up for clock frequency of 200 MHz, setting all necessary defaults. 20 // Set up for clock frequency of 200 MHz, setting all necessary defaults.
21 let config = Config::new(ClockConfig::system_freq(200_000_000)); 21 let config = Config::new(ClockConfig::system_freq(200_000_000).unwrap());
22
23 // Show the voltage scale for verification
24 info!("System core voltage: {}", Debug2Format(&config.clocks.core_voltage));
25 22
26 // Initialize the peripherals 23 // Initialize the peripherals
27 let p = embassy_rp::init(config); 24 let p = embassy_rp::init(config);
@@ -29,6 +26,9 @@ async fn main(_spawner: Spawner) -> ! {
29 // Show CPU frequency for verification 26 // Show CPU frequency for verification
30 let sys_freq = clk_sys_freq(); 27 let sys_freq = clk_sys_freq();
31 info!("System clock frequency: {} MHz", sys_freq / 1_000_000); 28 info!("System clock frequency: {} MHz", sys_freq / 1_000_000);
29 // Show core voltage for verification
30 let core_voltage = core_voltage().unwrap();
31 info!("Core voltage: {}", core_voltage);
32 32
33 // LED to indicate the system is running 33 // LED to indicate the system is running
34 let mut led = Output::new(p.PIN_25, Level::Low); 34 let mut led = Output::new(p.PIN_25, Level::Low);
diff --git a/examples/rp/src/bin/overclock_manual.rs b/examples/rp/src/bin/overclock_manual.rs
index 35160b250..dea5cfb3c 100644
--- a/examples/rp/src/bin/overclock_manual.rs
+++ b/examples/rp/src/bin/overclock_manual.rs
@@ -7,8 +7,7 @@
7 7
8use defmt::*; 8use defmt::*;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_rp::clocks; 10use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig, CoreVoltage, PllConfig};
11use embassy_rp::clocks::{ClockConfig, CoreVoltage, PllConfig};
12use embassy_rp::config::Config; 11use embassy_rp::config::Config;
13use embassy_rp::gpio::{Level, Output}; 12use embassy_rp::gpio::{Level, Output};
14use embassy_time::{Duration, Instant, Timer}; 13use embassy_time::{Duration, Instant, Timer};
@@ -41,9 +40,12 @@ async fn main(_spawner: Spawner) -> ! {
41 // Initialize with our manual overclock configuration 40 // Initialize with our manual overclock configuration
42 let p = embassy_rp::init(configure_manual_overclock()); 41 let p = embassy_rp::init(configure_manual_overclock());
43 42
44 // Verify the actual system clock frequency 43 // Show CPU frequency for verification
45 let sys_freq = clocks::clk_sys_freq(); 44 let sys_freq = clk_sys_freq();
46 info!("System clock frequency: {} MHz", sys_freq / 1_000_000); 45 info!("System clock frequency: {} MHz", sys_freq / 1_000_000);
46 // Show core voltage for verification
47 let core_voltage = core_voltage().unwrap();
48 info!("Core voltage: {}", core_voltage);
47 49
48 // LED to indicate the system is running 50 // LED to indicate the system is running
49 let mut led = Output::new(p.PIN_25, Level::Low); 51 let mut led = Output::new(p.PIN_25, Level::Low);
diff --git a/examples/rp/src/bin/pio_i2s.rs b/examples/rp/src/bin/pio_i2s.rs
index 192c8f854..695a74cc3 100644
--- a/examples/rp/src/bin/pio_i2s.rs
+++ b/examples/rp/src/bin/pio_i2s.rs
@@ -27,7 +27,6 @@ bind_interrupts!(struct Irqs {
27 27
28const SAMPLE_RATE: u32 = 48_000; 28const SAMPLE_RATE: u32 = 48_000;
29const BIT_DEPTH: u32 = 16; 29const BIT_DEPTH: u32 = 16;
30const CHANNELS: u32 = 2;
31 30
32#[embassy_executor::main] 31#[embassy_executor::main]
33async fn main(_spawner: Spawner) { 32async fn main(_spawner: Spawner) {
@@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) {
50 left_right_clock_pin, 49 left_right_clock_pin,
51 SAMPLE_RATE, 50 SAMPLE_RATE,
52 BIT_DEPTH, 51 BIT_DEPTH,
53 CHANNELS,
54 &program, 52 &program,
55 ); 53 );
56 54
diff --git a/examples/rp/src/bin/sharing.rs b/examples/rp/src/bin/sharing.rs
index 497c4f845..856be6ace 100644
--- a/examples/rp/src/bin/sharing.rs
+++ b/examples/rp/src/bin/sharing.rs
@@ -27,7 +27,6 @@ use embassy_rp::{bind_interrupts, interrupt};
27use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 27use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
28use embassy_sync::{blocking_mutex, mutex}; 28use embassy_sync::{blocking_mutex, mutex};
29use embassy_time::{Duration, Ticker}; 29use embassy_time::{Duration, Ticker};
30use rand::RngCore;
31use static_cell::{ConstStaticCell, StaticCell}; 30use static_cell::{ConstStaticCell, StaticCell};
32use {defmt_rtt as _, panic_probe as _}; 31use {defmt_rtt as _, panic_probe as _};
33 32
diff --git a/examples/rp/src/bin/spi_gc9a01.rs b/examples/rp/src/bin/spi_gc9a01.rs
index 30afc253d..fdef09d4b 100644
--- a/examples/rp/src/bin/spi_gc9a01.rs
+++ b/examples/rp/src/bin/spi_gc9a01.rs
@@ -26,7 +26,6 @@ use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle};
26use mipidsi::models::GC9A01; 26use mipidsi::models::GC9A01;
27use mipidsi::options::{ColorInversion, ColorOrder}; 27use mipidsi::options::{ColorInversion, ColorOrder};
28use mipidsi::Builder; 28use mipidsi::Builder;
29use rand_core::RngCore;
30use {defmt_rtt as _, panic_probe as _}; 29use {defmt_rtt as _, panic_probe as _};
31 30
32const DISPLAY_FREQ: u32 = 64_000_000; 31const DISPLAY_FREQ: u32 = 64_000_000;
diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs
index 2add20bc6..171f21a75 100644
--- a/examples/rp/src/bin/usb_ethernet.rs
+++ b/examples/rp/src/bin/usb_ethernet.rs
@@ -17,7 +17,6 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState
17use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; 17use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
18use embassy_usb::{Builder, Config, UsbDevice}; 18use embassy_usb::{Builder, Config, UsbDevice};
19use embedded_io_async::Write; 19use embedded_io_async::Write;
20use rand::RngCore;
21use static_cell::StaticCell; 20use static_cell::StaticCell;
22use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
23 22
diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs
index 5ee650910..4454c593c 100644..100755
--- a/examples/rp/src/bin/usb_hid_mouse.rs
+++ b/examples/rp/src/bin/usb_hid_mouse.rs
@@ -85,8 +85,8 @@ async fn main(_spawner: Spawner) {
85 _ = Timer::after_secs(1).await; 85 _ = Timer::after_secs(1).await;
86 let report = MouseReport { 86 let report = MouseReport {
87 buttons: 0, 87 buttons: 0,
88 x: rng.gen_range(-100..100), // random small x movement 88 x: rng.random_range(-100..100), // random small x movement
89 y: rng.gen_range(-100..100), // random small y movement 89 y: rng.random_range(-100..100), // random small y movement
90 wheel: 0, 90 wheel: 0,
91 pan: 0, 91 pan: 0,
92 }; 92 };
diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs
index e97ddb4c1..856838a8c 100644
--- a/examples/rp/src/bin/wifi_ap_tcp_server.rs
+++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs
@@ -19,7 +19,6 @@ use embassy_rp::peripherals::{DMA_CH0, PIO0};
19use embassy_rp::pio::{InterruptHandler, Pio}; 19use embassy_rp::pio::{InterruptHandler, Pio};
20use embassy_time::Duration; 20use embassy_time::Duration;
21use embedded_io_async::Write; 21use embedded_io_async::Write;
22use rand::RngCore;
23use static_cell::StaticCell; 22use static_cell::StaticCell;
24use {defmt_rtt as _, panic_probe as _}; 23use {defmt_rtt as _, panic_probe as _};
25 24
diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs
index 7e3c663fe..fbc957e0e 100644
--- a/examples/rp/src/bin/wifi_tcp_server.rs
+++ b/examples/rp/src/bin/wifi_tcp_server.rs
@@ -20,7 +20,6 @@ use embassy_rp::peripherals::{DMA_CH0, PIO0};
20use embassy_rp::pio::{InterruptHandler, Pio}; 20use embassy_rp::pio::{InterruptHandler, Pio};
21use embassy_time::{Duration, Timer}; 21use embassy_time::{Duration, Timer};
22use embedded_io_async::Write; 22use embedded_io_async::Write;
23use rand::RngCore;
24use static_cell::StaticCell; 23use static_cell::StaticCell;
25use {defmt_rtt as _, panic_probe as _}; 24use {defmt_rtt as _, panic_probe as _};
26 25
diff --git a/examples/rp/src/bin/wifi_webrequest.rs b/examples/rp/src/bin/wifi_webrequest.rs
index f1b398b65..1efd1cd28 100644
--- a/examples/rp/src/bin/wifi_webrequest.rs
+++ b/examples/rp/src/bin/wifi_webrequest.rs
@@ -20,7 +20,6 @@ use embassy_rp::gpio::{Level, Output};
20use embassy_rp::peripherals::{DMA_CH0, PIO0}; 20use embassy_rp::peripherals::{DMA_CH0, PIO0};
21use embassy_rp::pio::{InterruptHandler, Pio}; 21use embassy_rp::pio::{InterruptHandler, Pio};
22use embassy_time::{Duration, Timer}; 22use embassy_time::{Duration, Timer};
23use rand::RngCore;
24use reqwless::client::{HttpClient, TlsConfig, TlsVerify}; 23use reqwless::client::{HttpClient, TlsConfig, TlsVerify};
25use reqwless::request::Method; 24use reqwless::request::Method;
26use serde::Deserialize; 25use serde::Deserialize;
diff --git a/examples/rp235x/Cargo.toml b/examples/rp235x/Cargo.toml
index 345a915af..ae64489ae 100644
--- a/examples/rp235x/Cargo.toml
+++ b/examples/rp235x/Cargo.toml
@@ -19,8 +19,8 @@ embassy-usb-logger = { version = "0.4.0", path = "../../embassy-usb-logger" }
19cyw43 = { version = "0.3.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] } 19cyw43 = { version = "0.3.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] }
20cyw43-pio = { version = "0.4.0", path = "../../cyw43-pio", features = ["defmt"] } 20cyw43-pio = { version = "0.4.0", path = "../../cyw43-pio", features = ["defmt"] }
21 21
22defmt = "0.3" 22defmt = "1.0.1"
23defmt-rtt = "0.4" 23defmt-rtt = "1.0.0"
24fixed = "1.23.1" 24fixed = "1.23.1"
25fixed-macro = "1.2" 25fixed-macro = "1.2"
26 26
@@ -37,7 +37,7 @@ tb6612fng = "1.0.0"
37cortex-m = { version = "0.7.6", features = ["inline-asm"] } 37cortex-m = { version = "0.7.6", features = ["inline-asm"] }
38cortex-m-rt = "0.7.0" 38cortex-m-rt = "0.7.0"
39critical-section = "1.1" 39critical-section = "1.1"
40panic-probe = { version = "0.3", features = ["print-defmt"] } 40panic-probe = { version = "1.0.0", features = ["print-defmt"] }
41display-interface-spi = "0.5.0" 41display-interface-spi = "0.5.0"
42embedded-graphics = "0.8.1" 42embedded-graphics = "0.8.1"
43mipidsi = "0.8.0" 43mipidsi = "0.8.0"
@@ -55,7 +55,6 @@ embedded-storage = { version = "0.3" }
55static_cell = "2.1" 55static_cell = "2.1"
56portable-atomic = { version = "1.5", features = ["critical-section"] } 56portable-atomic = { version = "1.5", features = ["critical-section"] }
57log = "0.4" 57log = "0.4"
58rand = { version = "0.8.5", default-features = false }
59embedded-sdmmc = "0.7.0" 58embedded-sdmmc = "0.7.0"
60 59
61[profile.release] 60[profile.release]
diff --git a/examples/rp235x/src/bin/overclock.rs b/examples/rp235x/src/bin/overclock.rs
new file mode 100644
index 000000000..5fd97ef97
--- /dev/null
+++ b/examples/rp235x/src/bin/overclock.rs
@@ -0,0 +1,74 @@
1//! # Overclocking the RP2350 to 200 MHz
2//!
3//! This example demonstrates how to configure the RP2350 to run at 200 MHz instead of the default 150 MHz.
4//!
5//! ## Note
6//!
7//! As of yet there is no official support for running the RP235x at higher clock frequencies and/or other core voltages than the default.
8//! Doing so may cause unexpected behavior and/or damage the chip.
9
10#![no_std]
11#![no_main]
12
13use defmt::*;
14use embassy_executor::Spawner;
15use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig, CoreVoltage};
16use embassy_rp::config::Config;
17use embassy_rp::gpio::{Level, Output};
18use embassy_time::{Duration, Instant, Timer};
19use {defmt_rtt as _, panic_probe as _};
20
21const COUNT_TO: i64 = 10_000_000;
22
23#[embassy_executor::main]
24async fn main(_spawner: Spawner) -> ! {
25 // Set up for clock frequency of 200 MHz, setting all necessary defaults.
26 let mut config = Config::new(ClockConfig::system_freq(200_000_000).unwrap());
27
28 // since for the rp235x there is no official support for higher clock frequencies, `system_freq()` will not set a voltage for us.
29 // We need to guess the core voltage, that is needed for the higher clock frequency. Going with a small increase from the default 1.1V here, based on
30 // what we know about the RP2040. This is not guaranteed to be correct.
31 config.clocks.core_voltage = CoreVoltage::V1_15;
32
33 // Initialize the peripherals
34 let p = embassy_rp::init(config);
35
36 // Show CPU frequency for verification
37 let sys_freq = clk_sys_freq();
38 info!("System clock frequency: {} MHz", sys_freq / 1_000_000);
39 // Show core voltage for verification
40 let core_voltage = core_voltage().unwrap();
41 info!("Core voltage: {}", core_voltage);
42
43 // LED to indicate the system is running
44 let mut led = Output::new(p.PIN_25, Level::Low);
45
46 loop {
47 // Reset the counter at the start of measurement period
48 let mut counter = 0;
49
50 // Turn LED on while counting
51 led.set_high();
52
53 let start = Instant::now();
54
55 // This is a busy loop that will take some time to complete
56 while counter < COUNT_TO {
57 counter += 1;
58 }
59
60 let elapsed = Instant::now() - start;
61
62 // Report the elapsed time
63 led.set_low();
64 info!(
65 "At {}Mhz: Elapsed time to count to {}: {}ms",
66 sys_freq / 1_000_000,
67 counter,
68 elapsed.as_millis()
69 );
70
71 // Wait 2 seconds before starting the next measurement
72 Timer::after(Duration::from_secs(2)).await;
73 }
74}
diff --git a/examples/rp235x/src/bin/pio_i2s.rs b/examples/rp235x/src/bin/pio_i2s.rs
index 5a4bcfcac..cfcb0221d 100644
--- a/examples/rp235x/src/bin/pio_i2s.rs
+++ b/examples/rp235x/src/bin/pio_i2s.rs
@@ -27,7 +27,6 @@ bind_interrupts!(struct Irqs {
27 27
28const SAMPLE_RATE: u32 = 48_000; 28const SAMPLE_RATE: u32 = 48_000;
29const BIT_DEPTH: u32 = 16; 29const BIT_DEPTH: u32 = 16;
30const CHANNELS: u32 = 2;
31 30
32#[embassy_executor::main] 31#[embassy_executor::main]
33async fn main(_spawner: Spawner) { 32async fn main(_spawner: Spawner) {
@@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) {
50 left_right_clock_pin, 49 left_right_clock_pin,
51 SAMPLE_RATE, 50 SAMPLE_RATE,
52 BIT_DEPTH, 51 BIT_DEPTH,
53 CHANNELS,
54 &program, 52 &program,
55 ); 53 );
56 54
diff --git a/examples/rp235x/src/bin/sharing.rs b/examples/rp235x/src/bin/sharing.rs
index 497c4f845..856be6ace 100644
--- a/examples/rp235x/src/bin/sharing.rs
+++ b/examples/rp235x/src/bin/sharing.rs
@@ -27,7 +27,6 @@ use embassy_rp::{bind_interrupts, interrupt};
27use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 27use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
28use embassy_sync::{blocking_mutex, mutex}; 28use embassy_sync::{blocking_mutex, mutex};
29use embassy_time::{Duration, Ticker}; 29use embassy_time::{Duration, Ticker};
30use rand::RngCore;
31use static_cell::{ConstStaticCell, StaticCell}; 30use static_cell::{ConstStaticCell, StaticCell};
32use {defmt_rtt as _, panic_probe as _}; 31use {defmt_rtt as _, panic_probe as _};
33 32
diff --git a/examples/rp235x/src/bin/trng.rs b/examples/rp235x/src/bin/trng.rs
index ad19aef3e..100d6b104 100644
--- a/examples/rp235x/src/bin/trng.rs
+++ b/examples/rp235x/src/bin/trng.rs
@@ -10,7 +10,6 @@ use embassy_rp::gpio::{Level, Output};
10use embassy_rp::peripherals::TRNG; 10use embassy_rp::peripherals::TRNG;
11use embassy_rp::trng::Trng; 11use embassy_rp::trng::Trng;
12use embassy_time::Timer; 12use embassy_time::Timer;
13use rand::RngCore;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
16bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
@@ -33,8 +32,8 @@ async fn main(_spawner: Spawner) {
33 info!("Random bytes async {}", &randomness); 32 info!("Random bytes async {}", &randomness);
34 trng.blocking_fill_bytes(&mut randomness); 33 trng.blocking_fill_bytes(&mut randomness);
35 info!("Random bytes blocking {}", &randomness); 34 info!("Random bytes blocking {}", &randomness);
36 let random_u32 = trng.next_u32(); 35 let random_u32 = trng.blocking_next_u32();
37 let random_u64 = trng.next_u64(); 36 let random_u64 = trng.blocking_next_u64();
38 info!("Random u32 {} u64 {}", random_u32, random_u64); 37 info!("Random u32 {} u64 {}", random_u32, random_u64);
39 // Random number of blinks between 0 and 31 38 // Random number of blinks between 0 and 31
40 let blinks = random_u32 % 32; 39 let blinks = random_u32 % 32;
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index f00953167..ff4b2fbbd 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -21,7 +21,7 @@ futures = { version = "0.3.17" }
21log = "0.4.14" 21log = "0.4.14"
22nix = "0.26.2" 22nix = "0.26.2"
23clap = { version = "3.0.0-beta.5", features = ["derive"] } 23clap = { version = "3.0.0-beta.5", features = ["derive"] }
24rand_core = { version = "0.6.3", features = ["std"] } 24rand_core = { version = "0.9.1", features = ["std", "os_rng"] }
25heapless = { version = "0.8", default-features = false } 25heapless = { version = "0.8", default-features = false }
26static_cell = "2" 26static_cell = "2"
27 27
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs
index 6e50b1a01..232cf494b 100644
--- a/examples/std/src/bin/net.rs
+++ b/examples/std/src/bin/net.rs
@@ -9,7 +9,7 @@ use embassy_time::Duration;
9use embedded_io_async::Write; 9use embedded_io_async::Write;
10use heapless::Vec; 10use heapless::Vec;
11use log::*; 11use log::*;
12use rand_core::{OsRng, RngCore}; 12use rand_core::{OsRng, TryRngCore};
13use static_cell::StaticCell; 13use static_cell::StaticCell;
14 14
15#[derive(Parser)] 15#[derive(Parser)]
@@ -48,7 +48,7 @@ async fn main_task(spawner: Spawner) {
48 48
49 // Generate random seed 49 // Generate random seed
50 let mut seed = [0; 8]; 50 let mut seed = [0; 8];
51 OsRng.fill_bytes(&mut seed); 51 OsRng.try_fill_bytes(&mut seed).unwrap();
52 let seed = u64::from_le_bytes(seed); 52 let seed = u64::from_le_bytes(seed);
53 53
54 // Init network stack 54 // Init network stack
diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs
index a42c5dbb7..cf90731dd 100644
--- a/examples/std/src/bin/net_dns.rs
+++ b/examples/std/src/bin/net_dns.rs
@@ -5,7 +5,7 @@ use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
5use embassy_net_tuntap::TunTapDevice; 5use embassy_net_tuntap::TunTapDevice;
6use heapless::Vec; 6use heapless::Vec;
7use log::*; 7use log::*;
8use rand_core::{OsRng, RngCore}; 8use rand_core::{OsRng, TryRngCore};
9use static_cell::StaticCell; 9use static_cell::StaticCell;
10 10
11#[derive(Parser)] 11#[derive(Parser)]
@@ -45,7 +45,7 @@ async fn main_task(spawner: Spawner) {
45 45
46 // Generate random seed 46 // Generate random seed
47 let mut seed = [0; 8]; 47 let mut seed = [0; 8];
48 OsRng.fill_bytes(&mut seed); 48 OsRng.try_fill_bytes(&mut seed).unwrap();
49 let seed = u64::from_le_bytes(seed); 49 let seed = u64::from_le_bytes(seed);
50 50
51 // Init network stack 51 // Init network stack
diff --git a/examples/std/src/bin/net_ppp.rs b/examples/std/src/bin/net_ppp.rs
index f667e8d4c..ac3aea6ff 100644
--- a/examples/std/src/bin/net_ppp.rs
+++ b/examples/std/src/bin/net_ppp.rs
@@ -23,7 +23,7 @@ use futures::io::BufReader;
23use heapless::Vec; 23use heapless::Vec;
24use log::*; 24use log::*;
25use nix::sys::termios; 25use nix::sys::termios;
26use rand_core::{OsRng, RngCore}; 26use rand_core::{OsRng, TryRngCore};
27use static_cell::StaticCell; 27use static_cell::StaticCell;
28 28
29use crate::serial_port::SerialPort; 29use crate::serial_port::SerialPort;
@@ -89,7 +89,7 @@ async fn main_task(spawner: Spawner) {
89 89
90 // Generate random seed 90 // Generate random seed
91 let mut seed = [0; 8]; 91 let mut seed = [0; 8];
92 OsRng.fill_bytes(&mut seed); 92 OsRng.try_fill_bytes(&mut seed).unwrap();
93 let seed = u64::from_le_bytes(seed); 93 let seed = u64::from_le_bytes(seed);
94 94
95 // Init network stack 95 // Init network stack
diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs
index 02d4d3efb..53632a5b4 100644
--- a/examples/std/src/bin/net_udp.rs
+++ b/examples/std/src/bin/net_udp.rs
@@ -5,7 +5,7 @@ use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
5use embassy_net_tuntap::TunTapDevice; 5use embassy_net_tuntap::TunTapDevice;
6use heapless::Vec; 6use heapless::Vec;
7use log::*; 7use log::*;
8use rand_core::{OsRng, RngCore}; 8use rand_core::{OsRng, TryRngCore};
9use static_cell::StaticCell; 9use static_cell::StaticCell;
10 10
11#[derive(Parser)] 11#[derive(Parser)]
@@ -44,7 +44,7 @@ async fn main_task(spawner: Spawner) {
44 44
45 // Generate random seed 45 // Generate random seed
46 let mut seed = [0; 8]; 46 let mut seed = [0; 8];
47 OsRng.fill_bytes(&mut seed); 47 OsRng.try_fill_bytes(&mut seed).unwrap();
48 let seed = u64::from_le_bytes(seed); 48 let seed = u64::from_le_bytes(seed);
49 49
50 // Init network stack 50 // Init network stack
diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs
index 18646a083..961c20e2d 100644
--- a/examples/std/src/bin/tcp_accept.rs
+++ b/examples/std/src/bin/tcp_accept.rs
@@ -7,7 +7,7 @@ use embassy_time::{Duration, Timer};
7use embedded_io_async::Write as _; 7use embedded_io_async::Write as _;
8use heapless::Vec; 8use heapless::Vec;
9use log::*; 9use log::*;
10use rand_core::{OsRng, RngCore}; 10use rand_core::{OsRng, TryRngCore};
11use static_cell::StaticCell; 11use static_cell::StaticCell;
12 12
13#[derive(Parser)] 13#[derive(Parser)]
@@ -46,7 +46,7 @@ async fn main_task(spawner: Spawner) {
46 46
47 // Generate random seed 47 // Generate random seed
48 let mut seed = [0; 8]; 48 let mut seed = [0; 8];
49 OsRng.fill_bytes(&mut seed); 49 OsRng.try_fill_bytes(&mut seed).unwrap();
50 let seed = u64::from_le_bytes(seed); 50 let seed = u64::from_le_bytes(seed);
51 51
52 // Init network stack 52 // Init network stack
diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml
index 767b742f7..71f1cfda1 100644
--- a/examples/stm32c0/Cargo.toml
+++ b/examples/stm32c0/Cargo.toml
@@ -11,13 +11,13 @@ embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["de
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13 13
14defmt = "0.3" 14defmt = "1.0.1"
15defmt-rtt = "0.4" 15defmt-rtt = "1.0.0"
16 16
17cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 17cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
18cortex-m-rt = "0.7.0" 18cortex-m-rt = "0.7.0"
19embedded-hal = "0.2.6" 19embedded-hal = "0.2.6"
20panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "1.0.0", features = ["print-defmt"] }
21heapless = { version = "0.8", default-features = false } 21heapless = { version = "0.8", default-features = false }
22 22
23[profile.release] 23[profile.release]
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml
index 932a97dc8..534e8c33d 100644
--- a/examples/stm32f0/Cargo.toml
+++ b/examples/stm32f0/Cargo.toml
@@ -9,9 +9,9 @@ license = "MIT OR Apache-2.0"
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "memory-x", "stm32f091rc", "time-driver-tim2", "exti", "unstable-pac"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "memory-x", "stm32f091rc", "time-driver-tim2", "exti", "unstable-pac"] }
10cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 10cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
11cortex-m-rt = "0.7.0" 11cortex-m-rt = "0.7.0"
12defmt = "0.3" 12defmt = "1.0.1"
13defmt-rtt = "0.4" 13defmt-rtt = "1.0.0"
14panic-probe = { version = "0.3", features = ["print-defmt"] } 14panic-probe = { version = "1.0.0", features = ["print-defmt"] }
15embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 15embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
16embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 16embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
17embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 17embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml
index fe800bc80..f856d2620 100644
--- a/examples/stm32f1/Cargo.toml
+++ b/examples/stm32f1/Cargo.toml
@@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de
13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15 15
16defmt = "0.3" 16defmt = "1.0.1"
17defmt-rtt = "0.4" 17defmt-rtt = "1.0.0"
18 18
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "0.2.6"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23heapless = { version = "0.8", default-features = false } 23heapless = { version = "0.8", default-features = false }
24nb = "1.0.0" 24nb = "1.0.0"
25static_cell = "2.0.0" 25static_cell = "2.0.0"
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml
index 26be3f485..f26cbfadc 100644
--- a/examples/stm32f2/Cargo.toml
+++ b/examples/stm32f2/Cargo.toml
@@ -11,13 +11,13 @@ embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["de
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13 13
14defmt = "0.3" 14defmt = "1.0.1"
15defmt-rtt = "0.4" 15defmt-rtt = "1.0.0"
16 16
17cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 17cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
18cortex-m-rt = "0.7.0" 18cortex-m-rt = "0.7.0"
19embedded-hal = "0.2.6" 19embedded-hal = "0.2.6"
20panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "1.0.0", features = ["print-defmt"] }
21heapless = { version = "0.8", default-features = false } 21heapless = { version = "0.8", default-features = false }
22nb = "1.0.0" 22nb = "1.0.0"
23 23
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml
index 31bf040b0..4c1dd881f 100644
--- a/examples/stm32f3/Cargo.toml
+++ b/examples/stm32f3/Cargo.toml
@@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de
13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15 15
16defmt = "0.3" 16defmt = "1.0.1"
17defmt-rtt = "0.4" 17defmt-rtt = "1.0.0"
18 18
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "0.2.6"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23heapless = { version = "0.8", default-features = false } 23heapless = { version = "0.8", default-features = false }
24nb = "1.0.0" 24nb = "1.0.0"
25embedded-storage = "0.3.1" 25embedded-storage = "0.3.1"
diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml
index 5fb6d60c5..c28855b3a 100644
--- a/examples/stm32f334/Cargo.toml
+++ b/examples/stm32f334/Cargo.toml
@@ -12,13 +12,13 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [
12embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 12embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
14 14
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17 17
18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
19cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
20embedded-hal = "0.2.6" 20embedded-hal = "0.2.6"
21panic-probe = { version = "0.3", features = ["print-defmt"] } 21panic-probe = { version = "1.0.0", features = ["print-defmt"] }
22heapless = { version = "0.8", default-features = false } 22heapless = { version = "0.8", default-features = false }
23nb = "1.0.0" 23nb = "1.0.0"
24embedded-storage = "0.3.1" 24embedded-storage = "0.3.1"
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index 7aa4354ca..7374f8813 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -15,8 +15,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm
15embassy-net-wiznet = { version = "0.2.0", path = "../../embassy-net-wiznet", features = ["defmt"] } 15embassy-net-wiznet = { version = "0.2.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
17 17
18defmt = "0.3" 18defmt = "1.0.1"
19defmt-rtt = "0.4" 19defmt-rtt = "1.0.0"
20 20
21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
22cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
@@ -24,7 +24,7 @@ embedded-hal = "0.2.6"
24embedded-hal-bus = { version = "0.2", features = ["async"] } 24embedded-hal-bus = { version = "0.2", features = ["async"] }
25embedded-io = { version = "0.6.0" } 25embedded-io = { version = "0.6.0" }
26embedded-io-async = { version = "0.6.1" } 26embedded-io-async = { version = "0.6.1" }
27panic-probe = { version = "0.3", features = ["print-defmt"] } 27panic-probe = { version = "1.0.0", features = ["print-defmt"] }
28futures-util = { version = "0.3.30", default-features = false } 28futures-util = { version = "0.3.30", default-features = false }
29heapless = { version = "0.8", default-features = false } 29heapless = { version = "0.8", default-features = false }
30critical-section = "1.1" 30critical-section = "1.1"
diff --git a/examples/stm32f469/Cargo.toml b/examples/stm32f469/Cargo.toml
index 4d403bae8..87a3b8f75 100644
--- a/examples/stm32f469/Cargo.toml
+++ b/examples/stm32f469/Cargo.toml
@@ -10,13 +10,13 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
12 12
13defmt = "0.3" 13defmt = "1.0.1"
14defmt-rtt = "0.4" 14defmt-rtt = "1.0.0"
15 15
16cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 16cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
17cortex-m-rt = "0.7.0" 17cortex-m-rt = "0.7.0"
18embedded-hal = "1.0.0" 18embedded-hal = "1.0.0"
19panic-probe = { version = "0.3", features = ["print-defmt"] } 19panic-probe = { version = "1.0.0", features = ["print-defmt"] }
20 20
21[profile.release] 21[profile.release]
22debug = 2 22debug = 2
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index 1a46931d9..bce521f30 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -15,16 +15,15 @@ embedded-io-async = { version = "0.6.1" }
15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
17 17
18defmt = "0.3" 18defmt = "1.0.1"
19defmt-rtt = "0.4" 19defmt-rtt = "1.0.0"
20 20
21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
22cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
23embedded-hal = "0.2.6" 23embedded-hal = "0.2.6"
24panic-probe = { version = "0.3", features = ["print-defmt"] } 24panic-probe = { version = "1.0.0", features = ["print-defmt"] }
25heapless = { version = "0.8", default-features = false } 25heapless = { version = "0.8", default-features = false }
26nb = "1.0.0" 26nb = "1.0.0"
27rand_core = "0.6.3"
28critical-section = "1.1" 27critical-section = "1.1"
29embedded-storage = "0.3.1" 28embedded-storage = "0.3.1"
30static_cell = "2" 29static_cell = "2"
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index 17ab7fc00..67a2b34bb 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -12,7 +12,6 @@ use embassy_stm32::time::Hertz;
12use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; 12use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
13use embassy_time::Timer; 13use embassy_time::Timer;
14use embedded_io_async::Write; 14use embedded_io_async::Write;
15use rand_core::RngCore;
16use static_cell::StaticCell; 15use static_cell::StaticCell;
17use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
18 17
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml
index 319d84179..5e09b237e 100644
--- a/examples/stm32g0/Cargo.toml
+++ b/examples/stm32g0/Cargo.toml
@@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de
13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } 13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15 15
16defmt = "0.3" 16defmt = "1.0.1"
17defmt-rtt = "0.4" 17defmt-rtt = "1.0.0"
18 18
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "0.2.6"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23heapless = { version = "0.8", default-features = false } 23heapless = { version = "0.8", default-features = false }
24portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } 24portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] }
25 25
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml
index aa01d84e2..582553a29 100644
--- a/examples/stm32g4/Cargo.toml
+++ b/examples/stm32g4/Cargo.toml
@@ -14,14 +14,14 @@ embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defm
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15usbd-hid = "0.8.1" 15usbd-hid = "0.8.1"
16 16
17defmt = "0.3" 17defmt = "1.0.1"
18defmt-rtt = "0.4" 18defmt-rtt = "1.0.0"
19 19
20cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
21cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
22embedded-hal = "0.2.6" 22embedded-hal = "0.2.6"
23embedded-can = { version = "0.4" } 23embedded-can = { version = "0.4" }
24panic-probe = { version = "0.3", features = ["print-defmt"] } 24panic-probe = { version = "1.0.0", features = ["print-defmt"] }
25heapless = { version = "0.8", default-features = false } 25heapless = { version = "0.8", default-features = false }
26static_cell = "2.0.0" 26static_cell = "2.0.0"
27 27
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml
index 5631ff746..3e022e4e5 100644
--- a/examples/stm32h5/Cargo.toml
+++ b/examples/stm32h5/Cargo.toml
@@ -14,8 +14,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
16 16
17defmt = "0.3" 17defmt = "1.0.1"
18defmt-rtt = "0.4" 18defmt-rtt = "1.0.0"
19 19
20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
21cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
@@ -24,9 +24,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
24embedded-hal-async = { version = "1.0" } 24embedded-hal-async = { version = "1.0" }
25embedded-io-async = { version = "0.6.1" } 25embedded-io-async = { version = "0.6.1" }
26embedded-nal-async = "0.8.0" 26embedded-nal-async = "0.8.0"
27panic-probe = { version = "0.3", features = ["print-defmt"] } 27panic-probe = { version = "1.0.0", features = ["print-defmt"] }
28heapless = { version = "0.8", default-features = false } 28heapless = { version = "0.8", default-features = false }
29rand_core = "0.6.3"
30critical-section = "1.1" 29critical-section = "1.1"
31micromath = "2.0.0" 30micromath = "2.0.0"
32stm32-fmc = "0.3.0" 31stm32-fmc = "0.3.0"
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs
index 4034b552c..1d85cc1e7 100644
--- a/examples/stm32h5/src/bin/eth.rs
+++ b/examples/stm32h5/src/bin/eth.rs
@@ -15,7 +15,6 @@ use embassy_stm32::time::Hertz;
15use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; 15use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
16use embassy_time::Timer; 16use embassy_time::Timer;
17use embedded_io_async::Write; 17use embedded_io_async::Write;
18use rand_core::RngCore;
19use static_cell::StaticCell; 18use static_cell::StaticCell;
20use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
21 20
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 2f98542bb..520d0c8e6 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -15,8 +15,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm
15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
17 17
18defmt = "0.3" 18defmt = "1.0.1"
19defmt-rtt = "0.4" 19defmt-rtt = "1.0.0"
20 20
21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
22cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
@@ -25,9 +25,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
25embedded-hal-async = { version = "1.0" } 25embedded-hal-async = { version = "1.0" }
26embedded-nal-async = "0.8.0" 26embedded-nal-async = "0.8.0"
27embedded-io-async = { version = "0.6.1" } 27embedded-io-async = { version = "0.6.1" }
28panic-probe = { version = "0.3", features = ["print-defmt"] } 28panic-probe = { version = "1.0.0", features = ["print-defmt"] }
29heapless = { version = "0.8", default-features = false } 29heapless = { version = "0.8", default-features = false }
30rand_core = "0.6.3"
31critical-section = "1.1" 30critical-section = "1.1"
32micromath = "2.0.0" 31micromath = "2.0.0"
33stm32-fmc = "0.3.0" 32stm32-fmc = "0.3.0"
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index da7aa4af5..fc14c1a70 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -11,7 +11,6 @@ use embassy_stm32::rng::Rng;
11use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; 11use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
12use embassy_time::Timer; 12use embassy_time::Timer;
13use embedded_io_async::Write; 13use embedded_io_async::Write;
14use rand_core::RngCore;
15use static_cell::StaticCell; 14use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
17 16
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index 10485109a..46301a478 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -14,7 +14,6 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
14use embassy_time::Timer; 14use embassy_time::Timer;
15use embedded_io_async::Write; 15use embedded_io_async::Write;
16use embedded_nal_async::TcpConnect; 16use embedded_nal_async::TcpConnect;
17use rand_core::RngCore;
18use static_cell::StaticCell; 17use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
20 19
diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs
index 849173615..99cd1a158 100644
--- a/examples/stm32h7/src/bin/eth_client_mii.rs
+++ b/examples/stm32h7/src/bin/eth_client_mii.rs
@@ -14,7 +14,6 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
14use embassy_time::Timer; 14use embassy_time::Timer;
15use embedded_io_async::Write; 15use embedded_io_async::Write;
16use embedded_nal_async::TcpConnect; 16use embedded_nal_async::TcpConnect;
17use rand_core::RngCore;
18use static_cell::StaticCell; 17use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
20 19
diff --git a/examples/stm32h723/Cargo.toml b/examples/stm32h723/Cargo.toml
index 749fd78ae..1eb706b4d 100644
--- a/examples/stm32h723/Cargo.toml
+++ b/examples/stm32h723/Cargo.toml
@@ -12,8 +12,8 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
14 14
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17 17
18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
19cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
@@ -22,9 +22,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
22embedded-hal-async = { version = "1.0" } 22embedded-hal-async = { version = "1.0" }
23embedded-nal-async = "0.8.0" 23embedded-nal-async = "0.8.0"
24embedded-io-async = { version = "0.6.1" } 24embedded-io-async = { version = "0.6.1" }
25panic-probe = { version = "0.3", features = ["print-defmt"] } 25panic-probe = { version = "1.0.0", features = ["print-defmt"] }
26heapless = { version = "0.8", default-features = false } 26heapless = { version = "0.8", default-features = false }
27rand_core = "0.6.3"
28critical-section = "1.1" 27critical-section = "1.1"
29static_cell = "2" 28static_cell = "2"
30chrono = { version = "^0.4", default-features = false } 29chrono = { version = "^0.4", default-features = false }
diff --git a/examples/stm32h735/Cargo.toml b/examples/stm32h735/Cargo.toml
index 4d31dedf1..2ce989e6f 100644
--- a/examples/stm32h735/Cargo.toml
+++ b/examples/stm32h735/Cargo.toml
@@ -12,12 +12,12 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
14 14
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17 17
18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
19cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
20panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "1.0.0", features = ["print-defmt"] }
21heapless = { version = "0.8", default-features = false } 21heapless = { version = "0.8", default-features = false }
22embedded-graphics = { version = "0.8.1" } 22embedded-graphics = { version = "0.8.1" }
23tinybmp = { version = "0.5" } 23tinybmp = { version = "0.5" }
diff --git a/examples/stm32h742/Cargo.toml b/examples/stm32h742/Cargo.toml
index e2e0094b8..c3bf39e13 100644
--- a/examples/stm32h742/Cargo.toml
+++ b/examples/stm32h742/Cargo.toml
@@ -39,8 +39,8 @@ embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = [
39] } 39] }
40embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 40embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
41 41
42defmt = "0.3" 42defmt = "1.0.1"
43defmt-rtt = "0.4" 43defmt-rtt = "1.0.0"
44 44
45cortex-m = { version = "0.7.6", features = [ 45cortex-m = { version = "0.7.6", features = [
46 "inline-asm", 46 "inline-asm",
@@ -48,10 +48,9 @@ cortex-m = { version = "0.7.6", features = [
48] } 48] }
49cortex-m-rt = "0.7.0" 49cortex-m-rt = "0.7.0"
50embedded-hal = "0.2.6" 50embedded-hal = "0.2.6"
51panic-probe = { version = "0.3", features = ["print-defmt"] } 51panic-probe = { version = "1.0.0", features = ["print-defmt"] }
52heapless = { version = "0.8", default-features = false } 52heapless = { version = "0.8", default-features = false }
53nb = "1.0.0" 53nb = "1.0.0"
54rand_core = "0.6.3"
55critical-section = "1.1" 54critical-section = "1.1"
56embedded-storage = "0.3.1" 55embedded-storage = "0.3.1"
57static_cell = "2" 56static_cell = "2"
diff --git a/examples/stm32h755cm4/Cargo.toml b/examples/stm32h755cm4/Cargo.toml
index d2b9b1f0e..96bdd6a48 100644
--- a/examples/stm32h755cm4/Cargo.toml
+++ b/examples/stm32h755cm4/Cargo.toml
@@ -27,7 +27,6 @@ embedded-nal-async = "0.8.0"
27embedded-io-async = { version = "0.6.1" } 27embedded-io-async = { version = "0.6.1" }
28panic-probe = { version = "1.0.0", features = ["print-defmt"] } 28panic-probe = { version = "1.0.0", features = ["print-defmt"] }
29heapless = { version = "0.8", default-features = false } 29heapless = { version = "0.8", default-features = false }
30rand_core = "0.6.3"
31critical-section = "1.1" 30critical-section = "1.1"
32micromath = "2.0.0" 31micromath = "2.0.0"
33stm32-fmc = "0.3.0" 32stm32-fmc = "0.3.0"
diff --git a/examples/stm32h755cm7/Cargo.toml b/examples/stm32h755cm7/Cargo.toml
index 2e34f0928..ed4bb9a23 100644
--- a/examples/stm32h755cm7/Cargo.toml
+++ b/examples/stm32h755cm7/Cargo.toml
@@ -27,7 +27,6 @@ embedded-nal-async = "0.8.0"
27embedded-io-async = { version = "0.6.1" } 27embedded-io-async = { version = "0.6.1" }
28panic-probe = { version = "1.0.0", features = ["print-defmt"] } 28panic-probe = { version = "1.0.0", features = ["print-defmt"] }
29heapless = { version = "0.8", default-features = false } 29heapless = { version = "0.8", default-features = false }
30rand_core = "0.6.3"
31critical-section = "1.1" 30critical-section = "1.1"
32micromath = "2.0.0" 31micromath = "2.0.0"
33stm32-fmc = "0.3.0" 32stm32-fmc = "0.3.0"
diff --git a/examples/stm32h7b0/Cargo.toml b/examples/stm32h7b0/Cargo.toml
index e5f2dfe86..e4f1080ac 100644
--- a/examples/stm32h7b0/Cargo.toml
+++ b/examples/stm32h7b0/Cargo.toml
@@ -14,8 +14,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
16 16
17defmt = "0.3" 17defmt = "1.0.1"
18defmt-rtt = "0.4" 18defmt-rtt = "1.0.0"
19 19
20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
21cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
@@ -24,9 +24,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
24embedded-hal-async = { version = "1.0" } 24embedded-hal-async = { version = "1.0" }
25embedded-nal-async = "0.8.0" 25embedded-nal-async = "0.8.0"
26embedded-io-async = { version = "0.6.1" } 26embedded-io-async = { version = "0.6.1" }
27panic-probe = { version = "0.3", features = ["print-defmt"] } 27panic-probe = { version = "1.0.0", features = ["print-defmt"] }
28heapless = { version = "0.8", default-features = false } 28heapless = { version = "0.8", default-features = false }
29rand_core = "0.6.3"
30critical-section = "1.1" 29critical-section = "1.1"
31micromath = "2.0.0" 30micromath = "2.0.0"
32stm32-fmc = "0.3.0" 31stm32-fmc = "0.3.0"
diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml
index 22d59be04..58f8b1274 100644
--- a/examples/stm32h7rs/Cargo.toml
+++ b/examples/stm32h7rs/Cargo.toml
@@ -14,8 +14,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
16 16
17defmt = "0.3" 17defmt = "1.0.1"
18defmt-rtt = "0.4" 18defmt-rtt = "1.0.0"
19 19
20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
21cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
@@ -24,9 +24,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
24embedded-hal-async = { version = "1.0" } 24embedded-hal-async = { version = "1.0" }
25embedded-nal-async = "0.8.0" 25embedded-nal-async = "0.8.0"
26embedded-io-async = { version = "0.6.1" } 26embedded-io-async = { version = "0.6.1" }
27panic-probe = { version = "0.3", features = ["print-defmt"] } 27panic-probe = { version = "1.0.0", features = ["print-defmt"] }
28heapless = { version = "0.8", default-features = false } 28heapless = { version = "0.8", default-features = false }
29rand_core = "0.6.3"
30critical-section = "1.1" 29critical-section = "1.1"
31micromath = "2.0.0" 30micromath = "2.0.0"
32stm32-fmc = "0.3.0" 31stm32-fmc = "0.3.0"
diff --git a/examples/stm32h7rs/src/bin/eth.rs b/examples/stm32h7rs/src/bin/eth.rs
index f2bd9575e..6d246bb09 100644
--- a/examples/stm32h7rs/src/bin/eth.rs
+++ b/examples/stm32h7rs/src/bin/eth.rs
@@ -11,7 +11,6 @@ use embassy_stm32::rng::Rng;
11use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; 11use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
12use embassy_time::Timer; 12use embassy_time::Timer;
13use heapless::Vec; 13use heapless::Vec;
14use rand_core::RngCore;
15use static_cell::StaticCell; 14use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
17 16
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index 189b0e8d4..ce54ad9fb 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -11,8 +11,8 @@ embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["de
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13 13
14defmt = "0.3" 14defmt = "1.0.1"
15defmt-rtt = "0.4" 15defmt-rtt = "1.0.0"
16 16
17embedded-storage = "0.3.1" 17embedded-storage = "0.3.1"
18embedded-io = { version = "0.6.0" } 18embedded-io = { version = "0.6.0" }
@@ -20,7 +20,7 @@ embedded-io-async = { version = "0.6.1" }
20 20
21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
22cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
23panic-probe = { version = "0.3", features = ["print-defmt"] } 23panic-probe = { version = "1.0.0", features = ["print-defmt"] }
24heapless = { version = "0.8", default-features = false } 24heapless = { version = "0.8", default-features = false }
25embedded-hal = "0.2.6" 25embedded-hal = "0.2.6"
26static_cell = { version = "2" } 26static_cell = { version = "2" }
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml
index 6066b6dc7..a780f9290 100644
--- a/examples/stm32l1/Cargo.toml
+++ b/examples/stm32l1/Cargo.toml
@@ -12,13 +12,13 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [
12embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 12embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
14 14
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17 17
18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
19cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
20embedded-hal = "0.2.6" 20embedded-hal = "0.2.6"
21panic-probe = { version = "0.3", features = ["print-defmt"] } 21panic-probe = { version = "1.0.0", features = ["print-defmt"] }
22heapless = { version = "0.8", default-features = false } 22heapless = { version = "0.8", default-features = false }
23embedded-storage = "0.3.1" 23embedded-storage = "0.3.1"
24 24
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index 239bfcd79..5c4dce482 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -18,8 +18,8 @@ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
18embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } 18embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
19embedded-io = { version = "0.6.0", features = ["defmt-03"] } 19embedded-io = { version = "0.6.0", features = ["defmt-03"] }
20 20
21defmt = "0.3" 21defmt = "1.0.1"
22defmt-rtt = "0.4" 22defmt-rtt = "1.0.0"
23 23
24cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 24cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
25cortex-m-rt = "0.7.0" 25cortex-m-rt = "0.7.0"
@@ -27,10 +27,9 @@ embedded-hal = "0.2.6"
27embedded-hal-1 = { package = "embedded-hal", version = "1.0" } 27embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
28embedded-hal-async = { version = "1.0" } 28embedded-hal-async = { version = "1.0" }
29embedded-hal-bus = { version = "0.1", features = ["async"] } 29embedded-hal-bus = { version = "0.1", features = ["async"] }
30panic-probe = { version = "0.3", features = ["print-defmt"] } 30panic-probe = { version = "1.0.0", features = ["print-defmt"] }
31heapless = { version = "0.8", default-features = false } 31heapless = { version = "0.8", default-features = false }
32chrono = { version = "^0.4", default-features = false } 32chrono = { version = "^0.4", default-features = false }
33rand = { version = "0.8.5", default-features = false }
34static_cell = "2" 33static_cell = "2"
35 34
36micromath = "2.0.0" 35micromath = "2.0.0"
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
index 4a7c01f9f..354ac90b2 100644
--- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
+++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
@@ -38,7 +38,6 @@ use embedded_io::Write as bWrite;
38use embedded_io_async::Write; 38use embedded_io_async::Write;
39use heapless::Vec; 39use heapless::Vec;
40use panic_probe as _; 40use panic_probe as _;
41use rand::RngCore;
42use static_cell::StaticCell; 41use static_cell::StaticCell;
43 42
44bind_interrupts!(struct Irqs { 43bind_interrupts!(struct Irqs {
diff --git a/examples/stm32l432/Cargo.toml b/examples/stm32l432/Cargo.toml
index e155b3e66..ac7e507de 100644
--- a/examples/stm32l432/Cargo.toml
+++ b/examples/stm32l432/Cargo.toml
@@ -10,8 +10,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = [ "defmt" ] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = [ "defmt" ] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = [ "arch-cortex-m", "executor-thread", "defmt" ] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = [ "arch-cortex-m", "executor-thread", "defmt" ] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "tick-hz-32_768" ] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "tick-hz-32_768" ] }
13defmt = "0.3" 13defmt = "1.0.1"
14defmt-rtt = "0.4" 14defmt-rtt = "1.0.0"
15 15
16cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 16cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
17cortex-m-rt = "0.7.0" 17cortex-m-rt = "0.7.0"
@@ -19,7 +19,7 @@ embedded-hal = "0.2.6"
19embedded-hal-1 = { package = "embedded-hal", version = "1.0" } 19embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
20embedded-hal-async = { version = "1.0" } 20embedded-hal-async = { version = "1.0" }
21embedded-hal-bus = { version = "0.1", features = ["async"] } 21embedded-hal-bus = { version = "0.1", features = ["async"] }
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23 23
24[profile.release] 24[profile.release]
25debug = 2 25debug = 2
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index 4c372a554..138276b7f 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -15,15 +15,14 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm
15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
16usbd-hid = "0.8.1" 16usbd-hid = "0.8.1"
17 17
18defmt = "0.3" 18defmt = "1.0.1"
19defmt-rtt = "0.4" 19defmt-rtt = "1.0.0"
20panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "1.0.0", features = ["print-defmt"] }
21 21
22cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 22cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
23cortex-m-rt = "0.7.0" 23cortex-m-rt = "0.7.0"
24embedded-hal = "0.2.6" 24embedded-hal = "0.2.6"
25heapless = { version = "0.8", default-features = false } 25heapless = { version = "0.8", default-features = false }
26rand_core = { version = "0.6.3", default-features = false }
27embedded-io-async = { version = "0.6.1" } 26embedded-io-async = { version = "0.6.1" }
28static_cell = "2" 27static_cell = "2"
29 28
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs
index 809ec6ab1..6c72132c6 100644
--- a/examples/stm32l5/src/bin/usb_ethernet.rs
+++ b/examples/stm32l5/src/bin/usb_ethernet.rs
@@ -12,7 +12,6 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState
12use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; 12use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
13use embassy_usb::{Builder, UsbDevice}; 13use embassy_usb::{Builder, UsbDevice};
14use embedded_io_async::Write; 14use embedded_io_async::Write;
15use rand_core::RngCore;
16use static_cell::StaticCell; 15use static_cell::StaticCell;
17use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
18 17
diff --git a/examples/stm32u0/Cargo.toml b/examples/stm32u0/Cargo.toml
index efcb9bf4d..86cff2321 100644
--- a/examples/stm32u0/Cargo.toml
+++ b/examples/stm32u0/Cargo.toml
@@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de
13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } 13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15 15
16defmt = "0.3" 16defmt = "1.0.1"
17defmt-rtt = "0.4" 17defmt-rtt = "1.0.0"
18 18
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "0.2.6"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23heapless = { version = "0.8", default-features = false } 23heapless = { version = "0.8", default-features = false }
24 24
25micromath = "2.0.0" 25micromath = "2.0.0"
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml
index 886c5cb2e..94f77ce2f 100644
--- a/examples/stm32u5/Cargo.toml
+++ b/examples/stm32u5/Cargo.toml
@@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de
13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15 15
16defmt = "0.3" 16defmt = "1.0.1"
17defmt-rtt = "0.4" 17defmt-rtt = "1.0.0"
18 18
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "0.2.6"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23heapless = { version = "0.8", default-features = false } 23heapless = { version = "0.8", default-features = false }
24embedded-graphics = { version = "0.8.1" } 24embedded-graphics = { version = "0.8.1" }
25tinybmp = { version = "0.6.0" } 25tinybmp = { version = "0.6.0" }
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index 96f66f3af..a83871d4d 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -11,15 +11,15 @@ embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", fea
11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } 12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } 14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true }
15 15
16defmt = "0.3" 16defmt = "1.0.1"
17defmt-rtt = "0.4" 17defmt-rtt = "1.0.0"
18 18
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "1.0.0"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23heapless = { version = "0.8", default-features = false } 23heapless = { version = "0.8", default-features = false }
24static_cell = "2" 24static_cell = "2"
25 25
diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml
index 60b09adb4..b87ca88bf 100644
--- a/examples/stm32wba/Cargo.toml
+++ b/examples/stm32wba/Cargo.toml
@@ -9,15 +9,15 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [
9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
12embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } 12embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true }
13 13
14defmt = "0.3" 14defmt = "1.0.1"
15defmt-rtt = "0.4" 15defmt-rtt = "1.0.0"
16 16
17cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 17cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
18cortex-m-rt = "0.7.0" 18cortex-m-rt = "0.7.0"
19embedded-hal = "0.2.6" 19embedded-hal = "1.0.0"
20panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "1.0.0", features = ["print-defmt"] }
21heapless = { version = "0.8", default-features = false } 21heapless = { version = "0.8", default-features = false }
22static_cell = "2" 22static_cell = "2"
23 23
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml
index 6b677914e..1b6a23bed 100644
--- a/examples/stm32wl/Cargo.toml
+++ b/examples/stm32wl/Cargo.toml
@@ -12,14 +12,14 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
14 14
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17 17
18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
19cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
20embedded-hal = "0.2.6" 20embedded-hal = "0.2.6"
21embedded-storage = "0.3.1" 21embedded-storage = "0.3.1"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "1.0.0", features = ["print-defmt"] }
23heapless = { version = "0.8", default-features = false } 23heapless = { version = "0.8", default-features = false }
24chrono = { version = "^0.4", default-features = false } 24chrono = { version = "^0.4", default-features = false }
25 25
diff --git a/rustfmt.toml b/rustfmt.toml
index 592ad27ff..2561562fd 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,4 +1,4 @@
1group_imports = "StdExternalCrate" 1group_imports = "StdExternalCrate"
2imports_granularity = "Module" 2imports_granularity = "Module"
3edition = "2021" 3edition = "2021"
4max_width=120 4max_width = 120
diff --git a/tests/mspm0/Cargo.toml b/tests/mspm0/Cargo.toml
index 0566807d7..386536bee 100644
--- a/tests/mspm0/Cargo.toml
+++ b/tests/mspm0/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[features] 7[features]
8mspm0g3507 = [ "embassy-mspm0/mspm0g350x" ] 8mspm0g3507 = [ "embassy-mspm0/mspm0g3507pm" ]
9 9
10[dependencies] 10[dependencies]
11teleprobe-meta = "1.1" 11teleprobe-meta = "1.1"
@@ -23,7 +23,7 @@ cortex-m = { version = "0.7.6", features = [ "inline-asm", "critical-section-sin
23cortex-m-rt = "0.7.0" 23cortex-m-rt = "0.7.0"
24embedded-hal = { package = "embedded-hal", version = "1.0" } 24embedded-hal = { package = "embedded-hal", version = "1.0" }
25embedded-hal-async = { version = "1.0" } 25embedded-hal-async = { version = "1.0" }
26panic-probe = { version = "0.3.0", features = ["print-defmt"] } 26panic-probe = { version = "1.0.0", features = ["print-defmt"] }
27static_cell = "2" 27static_cell = "2"
28portable-atomic = { version = "1.5", features = ["critical-section"] } 28portable-atomic = { version = "1.5", features = ["critical-section"] }
29 29
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml
index 410d62bdd..32087940e 100644
--- a/tests/nrf/Cargo.toml
+++ b/tests/nrf/Cargo.toml
@@ -21,12 +21,12 @@ embedded-hal-bus = { version = "0.1", features = ["async"] }
21static_cell = "2" 21static_cell = "2"
22perf-client = { path = "../perf-client" } 22perf-client = { path = "../perf-client" }
23 23
24defmt = "0.3" 24defmt = "1.0.1"
25defmt-rtt = "0.4" 25defmt-rtt = "1.0.0"
26 26
27cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 27cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
28cortex-m-rt = "0.7.0" 28cortex-m-rt = "0.7.0"
29panic-probe = { version = "0.3", features = ["print-defmt"] } 29panic-probe = { version = "1.0.0", features = ["print-defmt"] }
30portable-atomic = { version = "1.6.0" } 30portable-atomic = { version = "1.6.0" }
31 31
32[features] 32[features]
diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml
index 9620972c3..e31d6361b 100644
--- a/tests/perf-client/Cargo.toml
+++ b/tests/perf-client/Cargo.toml
@@ -7,4 +7,4 @@ edition = "2021"
7embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } 7embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] }
8embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", ] } 8embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", ] }
9embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 9embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
10defmt = "0.3" 10defmt = "1.0.1"
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index 1335aa84b..2c2ed73cc 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -24,8 +24,8 @@ cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] }
24cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] } 24cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] }
25perf-client = { path = "../perf-client" } 25perf-client = { path = "../perf-client" }
26 26
27defmt = "0.3" 27defmt = "1.0.1"
28defmt-rtt = "0.4" 28defmt-rtt = "1.0.0"
29 29
30cortex-m = { version = "0.7.6" } 30cortex-m = { version = "0.7.6" }
31cortex-m-rt = "0.7.0" 31cortex-m-rt = "0.7.0"
@@ -33,12 +33,11 @@ embedded-hal = "0.2.6"
33embedded-hal-1 = { package = "embedded-hal", version = "1.0" } 33embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
34embedded-hal-async = { version = "1.0" } 34embedded-hal-async = { version = "1.0" }
35embedded-hal-bus = { version = "0.1", features = ["async"] } 35embedded-hal-bus = { version = "0.1", features = ["async"] }
36panic-probe = { version = "0.3.0", features = ["print-defmt"] } 36panic-probe = { version = "1.0.0", features = ["print-defmt"] }
37embedded-io-async = { version = "0.6.1" } 37embedded-io-async = { version = "0.6.1" }
38embedded-storage = { version = "0.3" } 38embedded-storage = { version = "0.3" }
39static_cell = "2" 39static_cell = "2"
40portable-atomic = { version = "1.5", features = ["critical-section"] } 40portable-atomic = { version = "1.5", features = ["critical-section"] }
41rand = { version = "0.8.5", default-features = false }
42 41
43# bootsel not currently supported on 2350 42# bootsel not currently supported on 2350
44[[bin]] 43[[bin]]
diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs
index ae2adfa55..89e0ad32e 100644
--- a/tests/rp/src/bin/ethernet_w5100s_perf.rs
+++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs
@@ -14,7 +14,6 @@ use embassy_rp::peripherals::SPI0;
14use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 14use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
15use embassy_time::Delay; 15use embassy_time::Delay;
16use embedded_hal_bus::spi::ExclusiveDevice; 16use embedded_hal_bus::spi::ExclusiveDevice;
17use rand::RngCore;
18use static_cell::StaticCell; 17use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
20 19
diff --git a/tests/rp/src/bin/overclock.rs b/tests/rp/src/bin/overclock.rs
index be8e85a3f..167a26eb2 100644
--- a/tests/rp/src/bin/overclock.rs
+++ b/tests/rp/src/bin/overclock.rs
@@ -7,14 +7,8 @@ teleprobe_meta::target!(b"rpi-pico");
7teleprobe_meta::target!(b"pimoroni-pico-plus-2"); 7teleprobe_meta::target!(b"pimoroni-pico-plus-2");
8 8
9use defmt::info; 9use defmt::info;
10#[cfg(feature = "rp2040")]
11use defmt::{assert, assert_eq};
12use embassy_executor::Spawner; 10use embassy_executor::Spawner;
13use embassy_rp::clocks; 11use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig, CoreVoltage};
14#[cfg(feature = "rp2040")]
15use embassy_rp::clocks::ClockConfig;
16#[cfg(feature = "rp2040")]
17use embassy_rp::clocks::CoreVoltage;
18use embassy_rp::config::Config; 12use embassy_rp::config::Config;
19use embassy_time::Instant; 13use embassy_time::Instant;
20use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
@@ -23,23 +17,26 @@ const COUNT_TO: i64 = 10_000_000;
23 17
24#[embassy_executor::main] 18#[embassy_executor::main]
25async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
26 #[cfg(feature = "rp2040")]
27 let mut config = Config::default(); 20 let mut config = Config::default();
28 #[cfg(not(feature = "rp2040"))]
29 let config = Config::default();
30 21
31 // Initialize with 200MHz clock configuration for RP2040, other chips will use default clock 22 // Initialize with 200MHz clock configuration
32 #[cfg(feature = "rp2040")] 23 config.clocks = ClockConfig::system_freq(200_000_000).unwrap();
24
25 // if we are rp235x, we need to manually set the core voltage. rp2040 should do this automatically
26 #[cfg(feature = "rp235xb")]
33 { 27 {
34 config.clocks = ClockConfig::system_freq(200_000_000); 28 config.clocks.core_voltage = CoreVoltage::V1_15;
35 let voltage = config.clocks.core_voltage;
36 assert!(matches!(voltage, CoreVoltage::V1_15), "Expected voltage scale V1_15");
37 } 29 }
38 30
39 let _p = embassy_rp::init(config); 31 let _p = embassy_rp::init(config);
40 32
33 // We should be at core voltage of 1.15V
34 assert_eq!(core_voltage().unwrap(), CoreVoltage::V1_15, "Core voltage is not 1.15V");
35 // We should be at 200MHz
36 assert_eq!(clk_sys_freq(), 200_000_000, "System clock frequency is not 200MHz");
37
41 // Test the system speed 38 // Test the system speed
42 let (time_elapsed, clk_sys_freq) = { 39 let time_elapsed = {
43 let mut counter = 0; 40 let mut counter = 0;
44 let start = Instant::now(); 41 let start = Instant::now();
45 while counter < COUNT_TO { 42 while counter < COUNT_TO {
@@ -47,24 +44,26 @@ async fn main(_spawner: Spawner) {
47 } 44 }
48 let elapsed = Instant::now() - start; 45 let elapsed = Instant::now() - start;
49 46
50 (elapsed.as_millis(), clocks::clk_sys_freq()) 47 elapsed.as_millis()
51 }; 48 };
52 49
53 // Report the elapsed time, so that the compiler doesn't optimize it away for chips other than RP2040 50 // Tests will fail if unused variables are detected:
51 // Report the elapsed time, so that the compiler doesn't optimize it away for the chip not on test
54 info!( 52 info!(
55 "At {}Mhz: Elapsed time to count to {}: {}ms", 53 "At {}Mhz: Elapsed time to count to {}: {}ms",
56 clk_sys_freq / 1_000_000, 54 clk_sys_freq() / 1_000_000,
57 COUNT_TO, 55 COUNT_TO,
58 time_elapsed 56 time_elapsed
59 ); 57 );
60 58
59 // Check if the elapsed time is within expected limits
60 // for rp2040 we expect about 600ms
61 #[cfg(feature = "rp2040")] 61 #[cfg(feature = "rp2040")]
62 { 62 // allow 1% error
63 // we should be at 200MHz 63 assert!(time_elapsed < 606, "Elapsed time is too long");
64 assert_eq!(clk_sys_freq, 200_000_000, "System clock frequency is not 200MHz"); 64 // for rp235x we expect about 450ms
65 // At 200MHz, the time to count to 10_000_000 should be at 600ms, testing with 1% margin 65 #[cfg(feature = "rp235xb")]
66 assert!(time_elapsed <= 606, "Elapsed time is too long"); 66 assert!(time_elapsed < 455, "Elapsed time is too long");
67 }
68 67
69 cortex_m::asm::bkpt(); 68 cortex_m::asm::bkpt();
70} 69}
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 3a347e279..6036a5a97 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -70,8 +70,8 @@ embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", opt
70embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } 70embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
71perf-client = { path = "../perf-client" } 71perf-client = { path = "../perf-client" }
72 72
73defmt = "0.3" 73defmt = "1.0.1"
74defmt-rtt = "0.4" 74defmt-rtt = "1.0.0"
75 75
76cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 76cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
77cortex-m-rt = "0.7.0" 77cortex-m-rt = "0.7.0"
@@ -80,9 +80,9 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
80embedded-hal-async = { version = "1.0" } 80embedded-hal-async = { version = "1.0" }
81embedded-can = { version = "0.4" } 81embedded-can = { version = "0.4" }
82micromath = "2.0.0" 82micromath = "2.0.0"
83panic-probe = { version = "0.3.0", features = ["print-defmt"] } 83panic-probe = { version = "1.0.0", features = ["print-defmt"] }
84rand_core = { version = "0.6", default-features = false } 84rand_core = { version = "0.9.1", default-features = false }
85rand_chacha = { version = "0.3", default-features = false } 85rand_chacha = { version = "0.9.0", default-features = false }
86static_cell = "2" 86static_cell = "2"
87portable-atomic = { version = "1.5", features = [] } 87portable-atomic = { version = "1.5", features = [] }
88 88
diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs
index a7e76fd8e..bcb362b42 100644
--- a/tests/stm32/src/bin/eth.rs
+++ b/tests/stm32/src/bin/eth.rs
@@ -11,7 +11,6 @@ use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue};
11use embassy_stm32::peripherals::ETH; 11use embassy_stm32::peripherals::ETH;
12use embassy_stm32::rng::Rng; 12use embassy_stm32::rng::Rng;
13use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; 13use embassy_stm32::{bind_interrupts, eth, peripherals, rng};
14use rand_core::RngCore;
15use static_cell::StaticCell; 14use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
17 16
diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml
index 7b54a4f52..bda55ad32 100644
--- a/tests/utils/Cargo.toml
+++ b/tests/utils/Cargo.toml
@@ -4,5 +4,5 @@ version = "0.1.0"
4edition = "2021" 4edition = "2021"
5 5
6[dependencies] 6[dependencies]
7rand = "0.8" 7rand = "0.9"
8serial = "0.4" 8serial = "0.4"