aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.github/ci/test.sh2
-rw-r--r--README.md11
-rwxr-xr-xci.sh2
-rwxr-xr-xcyw43-firmware/43439A0.binbin224190 -> 230321 bytes
-rwxr-xr-xcyw43-firmware/43439A0_clm.binbin4752 -> 4752 bytes
-rw-r--r--cyw43-firmware/README.md6
-rw-r--r--cyw43-pio/src/lib.rs8
-rw-r--r--embassy-hal-internal/Cargo.toml (renamed from embassy-hal-common/Cargo.toml)2
-rw-r--r--embassy-hal-internal/README.md16
-rw-r--r--embassy-hal-internal/build.rs (renamed from embassy-hal-common/build.rs)0
-rw-r--r--embassy-hal-internal/src/atomic_ring_buffer.rs (renamed from embassy-hal-common/src/atomic_ring_buffer.rs)0
-rw-r--r--embassy-hal-internal/src/drop.rs (renamed from embassy-hal-common/src/drop.rs)0
-rw-r--r--embassy-hal-internal/src/fmt.rs (renamed from embassy-hal-common/src/fmt.rs)0
-rw-r--r--embassy-hal-internal/src/interrupt.rs (renamed from embassy-hal-common/src/interrupt.rs)0
-rw-r--r--embassy-hal-internal/src/lib.rs (renamed from embassy-hal-common/src/lib.rs)1
-rw-r--r--embassy-hal-internal/src/macros.rs (renamed from embassy-hal-common/src/macros.rs)0
-rw-r--r--embassy-hal-internal/src/peripheral.rs (renamed from embassy-hal-common/src/peripheral.rs)0
-rw-r--r--embassy-hal-internal/src/ratio.rs (renamed from embassy-hal-common/src/ratio.rs)0
-rw-r--r--embassy-hal-internal/src/ring_buffer.rs (renamed from embassy-hal-common/src/ring_buffer.rs)0
-rw-r--r--embassy-lora/Cargo.toml14
-rw-r--r--embassy-net-esp-hosted/src/control.rs2
-rw-r--r--embassy-net/src/lib.rs10
-rw-r--r--embassy-nrf/Cargo.toml2
-rw-r--r--embassy-nrf/src/buffered_uarte.rs4
-rw-r--r--embassy-nrf/src/chips/nrf52805.rs4
-rw-r--r--embassy-nrf/src/chips/nrf52810.rs4
-rw-r--r--embassy-nrf/src/chips/nrf52811.rs4
-rw-r--r--embassy-nrf/src/chips/nrf52820.rs4
-rw-r--r--embassy-nrf/src/chips/nrf52832.rs4
-rw-r--r--embassy-nrf/src/chips/nrf52833.rs4
-rw-r--r--embassy-nrf/src/chips/nrf52840.rs4
-rw-r--r--embassy-nrf/src/chips/nrf5340_app.rs4
-rw-r--r--embassy-nrf/src/chips/nrf5340_net.rs4
-rw-r--r--embassy-nrf/src/chips/nrf9160.rs4
-rw-r--r--embassy-nrf/src/gpio.rs2
-rw-r--r--embassy-nrf/src/gpiote.rs2
-rw-r--r--embassy-nrf/src/i2s.rs4
-rw-r--r--embassy-nrf/src/lib.rs4
-rw-r--r--embassy-nrf/src/nvmc.rs2
-rw-r--r--embassy-nrf/src/pdm.rs4
-rw-r--r--embassy-nrf/src/ppi/dppi.rs2
-rw-r--r--embassy-nrf/src/ppi/mod.rs2
-rw-r--r--embassy-nrf/src/ppi/ppi.rs2
-rw-r--r--embassy-nrf/src/pwm.rs2
-rw-r--r--embassy-nrf/src/qdec.rs2
-rw-r--r--embassy-nrf/src/qspi.rs4
-rw-r--r--embassy-nrf/src/rng.rs4
-rw-r--r--embassy-nrf/src/saadc.rs4
-rw-r--r--embassy-nrf/src/spim.rs2
-rw-r--r--embassy-nrf/src/spis.rs2
-rw-r--r--embassy-nrf/src/temp.rs4
-rw-r--r--embassy-nrf/src/timer.rs2
-rw-r--r--embassy-nrf/src/twim.rs2
-rw-r--r--embassy-nrf/src/twis.rs2
-rw-r--r--embassy-nrf/src/uarte.rs4
-rw-r--r--embassy-nrf/src/usb/mod.rs2
-rw-r--r--embassy-rp/Cargo.toml4
-rw-r--r--embassy-rp/src/adc.rs2
-rw-r--r--embassy-rp/src/clocks.rs2
-rw-r--r--embassy-rp/src/dma.rs2
-rw-r--r--embassy-rp/src/flash.rs2
-rw-r--r--embassy-rp/src/gpio.rs2
-rw-r--r--embassy-rp/src/i2c.rs2
-rw-r--r--embassy-rp/src/lib.rs78
-rw-r--r--embassy-rp/src/multicore.rs33
-rw-r--r--embassy-rp/src/pio.rs62
-rw-r--r--embassy-rp/src/pwm.rs2
-rw-r--r--embassy-rp/src/relocate.rs5
-rw-r--r--embassy-rp/src/rtc/mod.rs2
-rw-r--r--embassy-rp/src/spi.rs2
-rw-r--r--embassy-rp/src/uart/buffered.rs2
-rw-r--r--embassy-rp/src/uart/mod.rs2
-rw-r--r--embassy-stm32-wpan/Cargo.toml6
-rw-r--r--embassy-stm32-wpan/src/lib.rs2
-rw-r--r--embassy-stm32/Cargo.toml58
-rw-r--r--embassy-stm32/build.rs40
-rw-r--r--embassy-stm32/src/adc/f1.rs2
-rw-r--r--embassy-stm32/src/adc/v1.rs2
-rw-r--r--embassy-stm32/src/adc/v2.rs2
-rw-r--r--embassy-stm32/src/adc/v3.rs2
-rw-r--r--embassy-stm32/src/adc/v4.rs2
-rw-r--r--embassy-stm32/src/can/bxcan.rs168
-rw-r--r--embassy-stm32/src/can/fdcan.rs2
-rw-r--r--embassy-stm32/src/crc/v1.rs2
-rw-r--r--embassy-stm32/src/crc/v2v3.rs2
-rw-r--r--embassy-stm32/src/dac/mod.rs71
-rw-r--r--embassy-stm32/src/dcmi.rs2
-rw-r--r--embassy-stm32/src/dma/bdma.rs46
-rw-r--r--embassy-stm32/src/dma/dma.rs65
-rw-r--r--embassy-stm32/src/dma/gpdma.rs2
-rw-r--r--embassy-stm32/src/dma/mod.rs2
-rw-r--r--embassy-stm32/src/dma/ringbuffer.rs18
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs2
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs2
-rw-r--r--embassy-stm32/src/exti.rs2
-rw-r--r--embassy-stm32/src/flash/asynch.rs4
-rw-r--r--embassy-stm32/src/flash/common.rs4
-rw-r--r--embassy-stm32/src/flash/f4.rs2
-rw-r--r--embassy-stm32/src/fmc.rs2
-rw-r--r--embassy-stm32/src/gpio.rs2
-rw-r--r--embassy-stm32/src/i2c/v1.rs2
-rw-r--r--embassy-stm32/src/i2c/v2.rs4
-rw-r--r--embassy-stm32/src/i2s.rs2
-rw-r--r--embassy-stm32/src/ipcc.rs56
-rw-r--r--embassy-stm32/src/lib.rs8
-rw-r--r--embassy-stm32/src/pwm/mod.rs269
-rw-r--r--embassy-stm32/src/qspi/mod.rs2
-rw-r--r--embassy-stm32/src/rcc/f4.rs2
-rw-r--r--embassy-stm32/src/rcc/h7.rs2
-rw-r--r--embassy-stm32/src/rcc/l4.rs2
-rw-r--r--embassy-stm32/src/rcc/mod.rs8
-rw-r--r--embassy-stm32/src/rcc/wb.rs342
-rw-r--r--embassy-stm32/src/rng.rs2
-rw-r--r--embassy-stm32/src/rtc/mod.rs2
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs7
-rw-r--r--embassy-stm32/src/spi/mod.rs2
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs (renamed from embassy-stm32/src/pwm/complementary_pwm.rs)2
-rw-r--r--embassy-stm32/src/timer/mod.rs273
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs (renamed from embassy-stm32/src/pwm/simple_pwm.rs)2
-rw-r--r--embassy-stm32/src/usart/buffered.rs2
-rw-r--r--embassy-stm32/src/usart/mod.rs6
-rw-r--r--embassy-stm32/src/usart/ringbuffered.rs2
-rw-r--r--embassy-stm32/src/usb/usb.rs2
-rw-r--r--embassy-stm32/src/usb_otg/usb.rs2
-rw-r--r--embassy-stm32/src/wdg/mod.rs2
-rw-r--r--examples/nrf-rtos-trace/Cargo.toml3
-rw-r--r--examples/nrf52840-rtic/Cargo.toml3
-rw-r--r--examples/nrf52840/Cargo.toml4
-rw-r--r--examples/nrf5340/Cargo.toml3
-rw-r--r--examples/rp/Cargo.toml5
-rw-r--r--examples/rp/src/bin/pio_async.rs10
-rw-r--r--examples/rp/src/bin/pio_dma.rs4
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs7
-rw-r--r--examples/rp/src/bin/pio_uart.rs392
-rw-r--r--examples/rp/src/bin/pio_ws2812.rs4
-rw-r--r--examples/std/Cargo.toml3
-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/stm32f4/Cargo.toml5
-rw-r--r--examples/stm32f4/src/bin/can.rs7
-rw-r--r--examples/stm32f4/src/bin/dac.rs2
-rw-r--r--examples/stm32f4/src/bin/pwm.rs4
-rw-r--r--examples/stm32f4/src/bin/pwm_complementary.rs6
-rw-r--r--examples/stm32f7/Cargo.toml6
-rw-r--r--examples/stm32f7/build.rs40
-rw-r--r--examples/stm32f7/memory.x12
-rw-r--r--examples/stm32g0/Cargo.toml6
-rw-r--r--examples/stm32g4/Cargo.toml7
-rw-r--r--examples/stm32g4/src/bin/pwm.rs4
-rw-r--r--examples/stm32h5/Cargo.toml3
-rw-r--r--examples/stm32h5/memory.x5
-rw-r--r--examples/stm32h7/.cargo/config.toml2
-rw-r--r--examples/stm32h7/Cargo.toml3
-rw-r--r--examples/stm32h7/memory.x5
-rw-r--r--examples/stm32h7/src/bin/dac.rs2
-rw-r--r--examples/stm32h7/src/bin/dac_dma.rs140
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs2
-rw-r--r--examples/stm32h7/src/bin/pwm.rs4
-rw-r--r--examples/stm32l0/Cargo.toml7
-rw-r--r--examples/stm32l1/Cargo.toml3
-rw-r--r--examples/stm32l4/Cargo.toml6
-rw-r--r--examples/stm32l4/build.rs30
-rw-r--r--examples/stm32l4/memory.x7
-rw-r--r--examples/stm32l4/src/bin/dac.rs2
-rw-r--r--examples/stm32l5/Cargo.toml6
-rw-r--r--examples/stm32u5/Cargo.toml6
-rw-r--r--examples/stm32wb/Cargo.toml10
-rw-r--r--examples/stm32wl/Cargo.toml7
-rw-r--r--examples/wasm/Cargo.toml3
-rw-r--r--tests/nrf/src/bin/wifi_esp_hosted_perf.rs6
-rw-r--r--tests/rp/src/bin/cyw43-perf.rs4
-rw-r--r--tests/rp/src/bin/pio_irq.rs4
-rw-r--r--tests/rp/src/bin/pio_multi_load.rs126
-rw-r--r--tests/stm32/Cargo.toml13
-rw-r--r--tests/stm32/src/bin/dac.rs81
-rw-r--r--tests/stm32/src/bin/wpan_ble.rs6
-rw-r--r--tests/stm32/src/bin/wpan_mac.rs6
-rw-r--r--tests/stm32/src/common.rs1
181 files changed, 2094 insertions, 878 deletions
diff --git a/.github/ci/test.sh b/.github/ci/test.sh
index d014e4bd7..2892bcf8d 100755
--- a/.github/ci/test.sh
+++ b/.github/ci/test.sh
@@ -13,7 +13,7 @@ hashtime save /ci/cache/filetime.json
13 13
14cargo test --manifest-path ./embassy-sync/Cargo.toml 14cargo test --manifest-path ./embassy-sync/Cargo.toml
15cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml 15cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml
16cargo test --manifest-path ./embassy-hal-common/Cargo.toml 16cargo test --manifest-path ./embassy-hal-internal/Cargo.toml
17cargo test --manifest-path ./embassy-time/Cargo.toml --features generic-queue 17cargo test --manifest-path ./embassy-time/Cargo.toml --features generic-queue
18 18
19cargo test --manifest-path ./embassy-boot/boot/Cargo.toml 19cargo test --manifest-path ./embassy-boot/boot/Cargo.toml
diff --git a/README.md b/README.md
index b05e55aa5..c4c01dfbc 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@ The <a href="https://docs.embassy.dev/embassy-net/">embassy-net</a> network stac
33 33
34- **Bluetooth** - 34- **Bluetooth** -
35The <a href="https://github.com/embassy-rs/nrf-softdevice">nrf-softdevice</a> crate provides Bluetooth Low Energy 4.x and 5.x support for nRF52 microcontrollers. 35The <a href="https://github.com/embassy-rs/nrf-softdevice">nrf-softdevice</a> crate provides Bluetooth Low Energy 4.x and 5.x support for nRF52 microcontrollers.
36The <a href="https://github.com/embassy-rs/embassy/tree/main/embassy-stm32-wpan">embassy-stm32-wpan</a> crate provides Bluetooth Low Energy 5.x support for stm32wb microcontrollers.
36 37
37- **LoRa** - 38- **LoRa** -
38<a href="https://docs.embassy.dev/embassy-lora/">embassy-lora</a> supports LoRa networking. 39<a href="https://docs.embassy.dev/embassy-lora/">embassy-lora</a> supports LoRa networking.
@@ -111,6 +112,12 @@ cargo install probe-rs --features cli
111cd examples/nrf52840 112cd examples/nrf52840
112``` 113```
113 114
115- Ensure `Cargo.toml` sets the right feature for the name of the chip you are programming.
116 If this name is incorrect, the example may fail to run or immediately crash
117 after being programmed.
118
119- Ensure `.cargo/config.toml` contains the name of the chip you are programming.
120
114- Run the example 121- Run the example
115 122
116For example: 123For example:
@@ -119,6 +126,8 @@ For example:
119cargo run --release --bin blinky 126cargo run --release --bin blinky
120``` 127```
121 128
129For more help getting started, see [Getting Started][1] and [Running the Examples][2].
130
122## Developing Embassy with Rust Analyzer based editors 131## Developing Embassy with Rust Analyzer based editors
123 132
124The [Rust Analyzer](https://rust-analyzer.github.io/) is used by [Visual Studio Code](https://code.visualstudio.com/) 133The [Rust Analyzer](https://rust-analyzer.github.io/) is used by [Visual Studio Code](https://code.visualstudio.com/)
@@ -151,3 +160,5 @@ This work is licensed under either of
151 160
152at your option. 161at your option.
153 162
163[1]: https://github.com/embassy-rs/embassy/wiki/Getting-Started
164[2]: https://github.com/embassy-rs/embassy/wiki/Running-the-Examples
diff --git a/ci.sh b/ci.sh
index 6c10a0630..32ae7855e 100755
--- a/ci.sh
+++ b/ci.sh
@@ -27,6 +27,8 @@ cargo batch \
27 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \ 27 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \
28 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits,nightly \ 28 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits,nightly \
29 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \ 29 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
30 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ieee802154 \
31 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,medium-ieee802154 \
30 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits \ 32 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits \
31 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,nightly \ 33 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,nightly \
32 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits,nightly \ 34 --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits,nightly \
diff --git a/cyw43-firmware/43439A0.bin b/cyw43-firmware/43439A0.bin
index b46b3beff..017375277 100755
--- a/cyw43-firmware/43439A0.bin
+++ b/cyw43-firmware/43439A0.bin
Binary files differ
diff --git a/cyw43-firmware/43439A0_clm.bin b/cyw43-firmware/43439A0_clm.bin
index 6e3ba786b..1fedd753a 100755
--- a/cyw43-firmware/43439A0_clm.bin
+++ b/cyw43-firmware/43439A0_clm.bin
Binary files differ
diff --git a/cyw43-firmware/README.md b/cyw43-firmware/README.md
index 7381fdc56..db3d9c9cf 100644
--- a/cyw43-firmware/README.md
+++ b/cyw43-firmware/README.md
@@ -2,4 +2,8 @@
2 2
3Firmware obtained from https://github.com/Infineon/wifi-host-driver/tree/master/WiFi_Host_Driver/resources/firmware/COMPONENT_43439 3Firmware obtained from https://github.com/Infineon/wifi-host-driver/tree/master/WiFi_Host_Driver/resources/firmware/COMPONENT_43439
4 4
5Licensed under the [Infineon Permissive Binary License](./LICENSE-permissive-binary-license-1.0.txt) \ No newline at end of file 5Licensed under the [Infineon Permissive Binary License](./LICENSE-permissive-binary-license-1.0.txt)
6
7## Changelog
8
9* 2023-07-28: synced with `ad3bad0` - Update 43439 fw from 7.95.55 ot 7.95.62
diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs
index dca30c74d..830a5b44a 100644
--- a/cyw43-pio/src/lib.rs
+++ b/cyw43-pio/src/lib.rs
@@ -8,7 +8,6 @@ use cyw43::SpiBusCyw43;
8use embassy_rp::dma::Channel; 8use embassy_rp::dma::Channel;
9use embassy_rp::gpio::{Drive, Level, Output, Pin, Pull, SlewRate}; 9use embassy_rp::gpio::{Drive, Level, Output, Pin, Pull, SlewRate};
10use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; 10use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine};
11use embassy_rp::relocate::RelocatedProgram;
12use embassy_rp::{pio_instr_util, Peripheral, PeripheralRef}; 11use embassy_rp::{pio_instr_util, Peripheral, PeripheralRef};
13use fixed::FixedU32; 12use fixed::FixedU32;
14use pio_proc::pio_asm; 13use pio_proc::pio_asm;
@@ -88,8 +87,6 @@ where
88 ".wrap" 87 ".wrap"
89 ); 88 );
90 89
91 let relocated = RelocatedProgram::new(&program.program);
92
93 let mut pin_io: embassy_rp::pio::Pin<PIO> = common.make_pio_pin(dio); 90 let mut pin_io: embassy_rp::pio::Pin<PIO> = common.make_pio_pin(dio);
94 pin_io.set_pull(Pull::None); 91 pin_io.set_pull(Pull::None);
95 pin_io.set_schmitt(true); 92 pin_io.set_schmitt(true);
@@ -102,7 +99,8 @@ where
102 pin_clk.set_slew_rate(SlewRate::Fast); 99 pin_clk.set_slew_rate(SlewRate::Fast);
103 100
104 let mut cfg = Config::default(); 101 let mut cfg = Config::default();
105 cfg.use_program(&common.load_program(&relocated), &[&pin_clk]); 102 let loaded_program = common.load_program(&program.program);
103 cfg.use_program(&loaded_program, &[&pin_clk]);
106 cfg.set_out_pins(&[&pin_io]); 104 cfg.set_out_pins(&[&pin_io]);
107 cfg.set_in_pins(&[&pin_io]); 105 cfg.set_in_pins(&[&pin_io]);
108 cfg.set_set_pins(&[&pin_io]); 106 cfg.set_set_pins(&[&pin_io]);
@@ -142,7 +140,7 @@ where
142 sm, 140 sm,
143 irq, 141 irq,
144 dma: dma.into_ref(), 142 dma: dma.into_ref(),
145 wrap_target: relocated.wrap().target, 143 wrap_target: loaded_program.wrap.target,
146 } 144 }
147 } 145 }
148 146
diff --git a/embassy-hal-common/Cargo.toml b/embassy-hal-internal/Cargo.toml
index 18c758d7b..42e03199c 100644
--- a/embassy-hal-common/Cargo.toml
+++ b/embassy-hal-internal/Cargo.toml
@@ -1,5 +1,5 @@
1[package] 1[package]
2name = "embassy-hal-common" 2name = "embassy-hal-internal"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2021"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
diff --git a/embassy-hal-internal/README.md b/embassy-hal-internal/README.md
new file mode 100644
index 000000000..d6539701b
--- /dev/null
+++ b/embassy-hal-internal/README.md
@@ -0,0 +1,16 @@
1# embassy-macros
2
3An [Embassy](https://embassy.dev) project.
4
5Internal implementation details for Embassy HALs. DO NOT USE DIRECTLY. Embassy HALs (`embassy-nrf`, `embassy-stm32`, `embassy-rp`) already reexport
6everything you need to use them effectively.
7
8## License
9
10This work is licensed under either of
11
12- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
13 <http://www.apache.org/licenses/LICENSE-2.0>)
14- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
15
16at your option.
diff --git a/embassy-hal-common/build.rs b/embassy-hal-internal/build.rs
index 6fe82b44f..6fe82b44f 100644
--- a/embassy-hal-common/build.rs
+++ b/embassy-hal-internal/build.rs
diff --git a/embassy-hal-common/src/atomic_ring_buffer.rs b/embassy-hal-internal/src/atomic_ring_buffer.rs
index ea84925c4..ea84925c4 100644
--- a/embassy-hal-common/src/atomic_ring_buffer.rs
+++ b/embassy-hal-internal/src/atomic_ring_buffer.rs
diff --git a/embassy-hal-common/src/drop.rs b/embassy-hal-internal/src/drop.rs
index 7cd16aaec..7cd16aaec 100644
--- a/embassy-hal-common/src/drop.rs
+++ b/embassy-hal-internal/src/drop.rs
diff --git a/embassy-hal-common/src/fmt.rs b/embassy-hal-internal/src/fmt.rs
index 066970813..066970813 100644
--- a/embassy-hal-common/src/fmt.rs
+++ b/embassy-hal-internal/src/fmt.rs
diff --git a/embassy-hal-common/src/interrupt.rs b/embassy-hal-internal/src/interrupt.rs
index b970aa2cd..b970aa2cd 100644
--- a/embassy-hal-common/src/interrupt.rs
+++ b/embassy-hal-internal/src/interrupt.rs
diff --git a/embassy-hal-common/src/lib.rs b/embassy-hal-internal/src/lib.rs
index 235964aa4..3640ea184 100644
--- a/embassy-hal-common/src/lib.rs
+++ b/embassy-hal-internal/src/lib.rs
@@ -1,5 +1,6 @@
1#![no_std] 1#![no_std]
2#![allow(clippy::new_without_default)] 2#![allow(clippy::new_without_default)]
3#![doc = include_str!("../README.md")]
3 4
4// This mod MUST go first, so that the others see its macros. 5// This mod MUST go first, so that the others see its macros.
5pub(crate) mod fmt; 6pub(crate) mod fmt;
diff --git a/embassy-hal-common/src/macros.rs b/embassy-hal-internal/src/macros.rs
index f06b46002..f06b46002 100644
--- a/embassy-hal-common/src/macros.rs
+++ b/embassy-hal-internal/src/macros.rs
diff --git a/embassy-hal-common/src/peripheral.rs b/embassy-hal-internal/src/peripheral.rs
index 38b4c452e..38b4c452e 100644
--- a/embassy-hal-common/src/peripheral.rs
+++ b/embassy-hal-internal/src/peripheral.rs
diff --git a/embassy-hal-common/src/ratio.rs b/embassy-hal-internal/src/ratio.rs
index 9a8808a33..9a8808a33 100644
--- a/embassy-hal-common/src/ratio.rs
+++ b/embassy-hal-internal/src/ratio.rs
diff --git a/embassy-hal-common/src/ring_buffer.rs b/embassy-hal-internal/src/ring_buffer.rs
index fcad68bb1..fcad68bb1 100644
--- a/embassy-hal-common/src/ring_buffer.rs
+++ b/embassy-hal-internal/src/ring_buffer.rs
diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml
index e4524af5b..402ad2d70 100644
--- a/embassy-lora/Cargo.toml
+++ b/embassy-lora/Cargo.toml
@@ -12,7 +12,7 @@ target = "thumbv7em-none-eabi"
12 12
13[features] 13[features]
14stm32wl = ["dep:embassy-stm32"] 14stm32wl = ["dep:embassy-stm32"]
15time = [] 15time = ["embassy-time", "lorawan-device"]
16defmt = ["dep:defmt", "lorawan-device/defmt"] 16defmt = ["dep:defmt", "lorawan-device/defmt"]
17 17
18[dependencies] 18[dependencies]
@@ -20,18 +20,12 @@ defmt = ["dep:defmt", "lorawan-device/defmt"]
20defmt = { version = "0.3", optional = true } 20defmt = { version = "0.3", optional = true }
21log = { version = "0.4.14", optional = true } 21log = { version = "0.4.14", optional = true }
22 22
23embassy-time = { version = "0.1.2", path = "../embassy-time" } 23embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
24embassy-sync = { version = "0.2.0", path = "../embassy-sync" } 24embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
25embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } 25embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
26embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" }
27embedded-hal-async = { version = "=0.2.0-alpha.2" } 26embedded-hal-async = { version = "=0.2.0-alpha.2" }
28embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false }
29futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
30embedded-hal = { version = "0.2", features = ["unproven"] } 27embedded-hal = { version = "0.2", features = ["unproven"] }
31bit_field = { version = "0.10" }
32 28
29futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
33lora-phy = { version = "1" } 30lora-phy = { version = "1" }
34lorawan-device = { version = "0.10.0", default-features = false, features = ["async"] } 31lorawan-device = { version = "0.10.0", default-features = false, features = ["async"], optional = true }
35
36[patch.crates-io]
37lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs
index 79f8cde7b..37f220da0 100644
--- a/embassy-net-esp-hosted/src/control.rs
+++ b/embassy-net-esp-hosted/src/control.rs
@@ -1,5 +1,4 @@
1use ch::driver::LinkState; 1use ch::driver::LinkState;
2use defmt::Debug2Format;
3use embassy_net_driver_channel as ch; 2use embassy_net_driver_channel as ch;
4use heapless::String; 3use heapless::String;
5 4
@@ -57,7 +56,6 @@ impl<'a> Control<'a> {
57 let proto::CtrlMsgPayload::RespConnectAp(resp) = resp.payload.unwrap() else { 56 let proto::CtrlMsgPayload::RespConnectAp(resp) = resp.payload.unwrap() else {
58 panic!("unexpected resp") 57 panic!("unexpected resp")
59 }; 58 };
60 debug!("======= {:?}", Debug2Format(&resp));
61 assert_eq!(resp.resp, 0); 59 assert_eq!(resp.resp, 0);
62 self.state_ch.set_link_state(LinkState::Up); 60 self.state_ch.set_link_state(LinkState::Up);
63 } 61 }
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index 81c751a2c..3f9150168 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -32,12 +32,14 @@ pub use smoltcp::iface::MulticastError;
32use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage}; 32use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage};
33#[cfg(feature = "dhcpv4")] 33#[cfg(feature = "dhcpv4")]
34use smoltcp::socket::dhcpv4::{self, RetryConfig}; 34use smoltcp::socket::dhcpv4::{self, RetryConfig};
35#[cfg(feature = "medium-ethernet")]
36pub use smoltcp::wire::EthernetAddress;
37#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
38pub use smoltcp::wire::HardwareAddress;
35#[cfg(feature = "udp")] 39#[cfg(feature = "udp")]
36pub use smoltcp::wire::IpListenEndpoint; 40pub use smoltcp::wire::IpListenEndpoint;
37#[cfg(feature = "medium-ethernet")]
38pub use smoltcp::wire::{EthernetAddress, HardwareAddress};
39#[cfg(feature = "medium-ieee802154")] 41#[cfg(feature = "medium-ieee802154")]
40pub use smoltcp::wire::{HardwareAddress, Ieee802154Address}; 42pub use smoltcp::wire::{Ieee802154Address, Ieee802154Frame};
41pub use smoltcp::wire::{IpAddress, IpCidr, IpEndpoint}; 43pub use smoltcp::wire::{IpAddress, IpCidr, IpEndpoint};
42#[cfg(feature = "proto-ipv4")] 44#[cfg(feature = "proto-ipv4")]
43pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; 45pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr};
@@ -583,7 +585,7 @@ impl SocketStack {
583impl<D: Driver + 'static> Inner<D> { 585impl<D: Driver + 'static> Inner<D> {
584 #[cfg(feature = "proto-ipv4")] 586 #[cfg(feature = "proto-ipv4")]
585 fn apply_config_v4(&mut self, s: &mut SocketStack, config: StaticConfigV4) { 587 fn apply_config_v4(&mut self, s: &mut SocketStack, config: StaticConfigV4) {
586 #[cfg(feature = "medium-ethernet")] 588 #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
587 let medium = self.device.capabilities().medium; 589 let medium = self.device.capabilities().medium;
588 590
589 debug!("Acquired IP configuration:"); 591 debug!("Acquired IP configuration:");
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index 57dd22f1c..d10cd2c34 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -93,7 +93,7 @@ _gpio-p1 = []
93[dependencies] 93[dependencies]
94embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } 94embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
95embassy-sync = { version = "0.2.0", path = "../embassy-sync" } 95embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
96embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-3"] } 96embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] }
97embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } 97embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
98embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true } 98embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true }
99 99
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 9bc1c1e7a..5a0a3c7c0 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -15,8 +15,8 @@ use core::slice;
15use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering}; 15use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering};
16use core::task::Poll; 16use core::task::Poll;
17 17
18use embassy_hal_common::atomic_ring_buffer::RingBuffer; 18use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
19use embassy_hal_common::{into_ref, PeripheralRef}; 19use embassy_hal_internal::{into_ref, PeripheralRef};
20use embassy_sync::waitqueue::AtomicWaker; 20use embassy_sync::waitqueue::AtomicWaker;
21// Re-export SVD variants to allow user to directly set values 21// Re-export SVD variants to allow user to directly set values
22pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 22pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs
index 8776000c8..70e4b4863 100644
--- a/embassy-nrf/src/chips/nrf52805.rs
+++ b/embassy-nrf/src/chips/nrf52805.rs
@@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 192 * 1024;
8 8
9pub const RESET_PIN: u32 = 21; 9pub const RESET_PIN: u32 = 21;
10 10
11embassy_hal_common::peripherals! { 11embassy_hal_internal::peripherals! {
12 // RTC 12 // RTC
13 RTC0, 13 RTC0,
14 RTC1, 14 RTC1,
@@ -208,7 +208,7 @@ impl_ppi_channel!(PPI_CH31, 31 => static);
208impl_saadc_input!(P0_04, ANALOG_INPUT2); 208impl_saadc_input!(P0_04, ANALOG_INPUT2);
209impl_saadc_input!(P0_05, ANALOG_INPUT3); 209impl_saadc_input!(P0_05, ANALOG_INPUT3);
210 210
211embassy_hal_common::interrupt_mod!( 211embassy_hal_internal::interrupt_mod!(
212 POWER_CLOCK, 212 POWER_CLOCK,
213 RADIO, 213 RADIO,
214 UARTE0_UART0, 214 UARTE0_UART0,
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs
index 5519e8953..7416d3912 100644
--- a/embassy-nrf/src/chips/nrf52810.rs
+++ b/embassy-nrf/src/chips/nrf52810.rs
@@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 192 * 1024;
8 8
9pub const RESET_PIN: u32 = 21; 9pub const RESET_PIN: u32 = 21;
10 10
11embassy_hal_common::peripherals! { 11embassy_hal_internal::peripherals! {
12 // RTC 12 // RTC
13 RTC0, 13 RTC0,
14 RTC1, 14 RTC1,
@@ -234,7 +234,7 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5);
234impl_saadc_input!(P0_30, ANALOG_INPUT6); 234impl_saadc_input!(P0_30, ANALOG_INPUT6);
235impl_saadc_input!(P0_31, ANALOG_INPUT7); 235impl_saadc_input!(P0_31, ANALOG_INPUT7);
236 236
237embassy_hal_common::interrupt_mod!( 237embassy_hal_internal::interrupt_mod!(
238 POWER_CLOCK, 238 POWER_CLOCK,
239 RADIO, 239 RADIO,
240 UARTE0_UART0, 240 UARTE0_UART0,
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs
index d5367c59a..588010685 100644
--- a/embassy-nrf/src/chips/nrf52811.rs
+++ b/embassy-nrf/src/chips/nrf52811.rs
@@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 192 * 1024;
8 8
9pub const RESET_PIN: u32 = 21; 9pub const RESET_PIN: u32 = 21;
10 10
11embassy_hal_common::peripherals! { 11embassy_hal_internal::peripherals! {
12 // RTC 12 // RTC
13 RTC0, 13 RTC0,
14 RTC1, 14 RTC1,
@@ -236,7 +236,7 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5);
236impl_saadc_input!(P0_30, ANALOG_INPUT6); 236impl_saadc_input!(P0_30, ANALOG_INPUT6);
237impl_saadc_input!(P0_31, ANALOG_INPUT7); 237impl_saadc_input!(P0_31, ANALOG_INPUT7);
238 238
239embassy_hal_common::interrupt_mod!( 239embassy_hal_internal::interrupt_mod!(
240 POWER_CLOCK, 240 POWER_CLOCK,
241 RADIO, 241 RADIO,
242 UARTE0_UART0, 242 UARTE0_UART0,
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs
index 785170447..0ecddaf31 100644
--- a/embassy-nrf/src/chips/nrf52820.rs
+++ b/embassy-nrf/src/chips/nrf52820.rs
@@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 256 * 1024;
8 8
9pub const RESET_PIN: u32 = 18; 9pub const RESET_PIN: u32 = 18;
10 10
11embassy_hal_common::peripherals! { 11embassy_hal_internal::peripherals! {
12 // USB 12 // USB
13 USBD, 13 USBD,
14 14
@@ -224,7 +224,7 @@ impl_ppi_channel!(PPI_CH29, 29 => static);
224impl_ppi_channel!(PPI_CH30, 30 => static); 224impl_ppi_channel!(PPI_CH30, 30 => static);
225impl_ppi_channel!(PPI_CH31, 31 => static); 225impl_ppi_channel!(PPI_CH31, 31 => static);
226 226
227embassy_hal_common::interrupt_mod!( 227embassy_hal_internal::interrupt_mod!(
228 POWER_CLOCK, 228 POWER_CLOCK,
229 RADIO, 229 RADIO,
230 UARTE0_UART0, 230 UARTE0_UART0,
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs
index b77564a5c..ae39628d2 100644
--- a/embassy-nrf/src/chips/nrf52832.rs
+++ b/embassy-nrf/src/chips/nrf52832.rs
@@ -12,7 +12,7 @@ pub const FLASH_SIZE: usize = 512 * 1024;
12 12
13pub const RESET_PIN: u32 = 21; 13pub const RESET_PIN: u32 = 21;
14 14
15embassy_hal_common::peripherals! { 15embassy_hal_internal::peripherals! {
16 // RTC 16 // RTC
17 RTC0, 17 RTC0,
18 RTC1, 18 RTC1,
@@ -263,7 +263,7 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
263 263
264impl_i2s!(I2S, I2S, I2S); 264impl_i2s!(I2S, I2S, I2S);
265 265
266embassy_hal_common::interrupt_mod!( 266embassy_hal_internal::interrupt_mod!(
267 POWER_CLOCK, 267 POWER_CLOCK,
268 RADIO, 268 RADIO,
269 UARTE0_UART0, 269 UARTE0_UART0,
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs
index bff7f4ebb..b8830b338 100644
--- a/embassy-nrf/src/chips/nrf52833.rs
+++ b/embassy-nrf/src/chips/nrf52833.rs
@@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 512 * 1024;
8 8
9pub const RESET_PIN: u32 = 18; 9pub const RESET_PIN: u32 = 18;
10 10
11embassy_hal_common::peripherals! { 11embassy_hal_internal::peripherals! {
12 // USB 12 // USB
13 USBD, 13 USBD,
14 14
@@ -306,7 +306,7 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
306 306
307impl_i2s!(I2S, I2S, I2S); 307impl_i2s!(I2S, I2S, I2S);
308 308
309embassy_hal_common::interrupt_mod!( 309embassy_hal_internal::interrupt_mod!(
310 POWER_CLOCK, 310 POWER_CLOCK,
311 RADIO, 311 RADIO,
312 UARTE0_UART0, 312 UARTE0_UART0,
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs
index 9b0050823..a490cb079 100644
--- a/embassy-nrf/src/chips/nrf52840.rs
+++ b/embassy-nrf/src/chips/nrf52840.rs
@@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 1024 * 1024;
8 8
9pub const RESET_PIN: u32 = 18; 9pub const RESET_PIN: u32 = 18;
10 10
11embassy_hal_common::peripherals! { 11embassy_hal_internal::peripherals! {
12 // USB 12 // USB
13 USBD, 13 USBD,
14 14
@@ -311,7 +311,7 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
311 311
312impl_i2s!(I2S, I2S, I2S); 312impl_i2s!(I2S, I2S, I2S);
313 313
314embassy_hal_common::interrupt_mod!( 314embassy_hal_internal::interrupt_mod!(
315 POWER_CLOCK, 315 POWER_CLOCK,
316 RADIO, 316 RADIO,
317 UARTE0_UART0, 317 UARTE0_UART0,
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs
index 410ae921c..afc2c4a7e 100644
--- a/embassy-nrf/src/chips/nrf5340_app.rs
+++ b/embassy-nrf/src/chips/nrf5340_app.rs
@@ -218,7 +218,7 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 1024;
218 218
219pub const FLASH_SIZE: usize = 1024 * 1024; 219pub const FLASH_SIZE: usize = 1024 * 1024;
220 220
221embassy_hal_common::peripherals! { 221embassy_hal_internal::peripherals! {
222 // USB 222 // USB
223 USBD, 223 USBD,
224 224
@@ -506,7 +506,7 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
506impl_saadc_input!(P0_19, ANALOG_INPUT6); 506impl_saadc_input!(P0_19, ANALOG_INPUT6);
507impl_saadc_input!(P0_20, ANALOG_INPUT7); 507impl_saadc_input!(P0_20, ANALOG_INPUT7);
508 508
509embassy_hal_common::interrupt_mod!( 509embassy_hal_internal::interrupt_mod!(
510 FPU, 510 FPU,
511 CACHE, 511 CACHE,
512 SPU, 512 SPU,
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs
index 6ac783085..dee666a61 100644
--- a/embassy-nrf/src/chips/nrf5340_net.rs
+++ b/embassy-nrf/src/chips/nrf5340_net.rs
@@ -109,7 +109,7 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 1024;
109 109
110pub const FLASH_SIZE: usize = 256 * 1024; 110pub const FLASH_SIZE: usize = 256 * 1024;
111 111
112embassy_hal_common::peripherals! { 112embassy_hal_internal::peripherals! {
113 // RTC 113 // RTC
114 RTC0, 114 RTC0,
115 RTC1, 115 RTC1,
@@ -342,7 +342,7 @@ impl_ppi_channel!(PPI_CH29, 29 => configurable);
342impl_ppi_channel!(PPI_CH30, 30 => configurable); 342impl_ppi_channel!(PPI_CH30, 30 => configurable);
343impl_ppi_channel!(PPI_CH31, 31 => configurable); 343impl_ppi_channel!(PPI_CH31, 31 => configurable);
344 344
345embassy_hal_common::interrupt_mod!( 345embassy_hal_internal::interrupt_mod!(
346 CLOCK_POWER, 346 CLOCK_POWER,
347 RADIO, 347 RADIO,
348 RNG, 348 RNG,
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs
index 67ea032ff..495285ba3 100644
--- a/embassy-nrf/src/chips/nrf9160.rs
+++ b/embassy-nrf/src/chips/nrf9160.rs
@@ -169,7 +169,7 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 1024;
169 169
170pub const FLASH_SIZE: usize = 1024 * 1024; 170pub const FLASH_SIZE: usize = 1024 * 1024;
171 171
172embassy_hal_common::peripherals! { 172embassy_hal_internal::peripherals! {
173 // RTC 173 // RTC
174 RTC0, 174 RTC0,
175 RTC1, 175 RTC1,
@@ -368,7 +368,7 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
368impl_saadc_input!(P0_19, ANALOG_INPUT6); 368impl_saadc_input!(P0_19, ANALOG_INPUT6);
369impl_saadc_input!(P0_20, ANALOG_INPUT7); 369impl_saadc_input!(P0_20, ANALOG_INPUT7);
370 370
371embassy_hal_common::interrupt_mod!( 371embassy_hal_internal::interrupt_mod!(
372 SPU, 372 SPU,
373 CLOCK_POWER, 373 CLOCK_POWER,
374 UARTE0_SPIM0_SPIS0_TWIM0_TWIS0, 374 UARTE0_SPIM0_SPIS0_TWIM0_TWIS0,
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index 895ab9340..ea2b76096 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -5,7 +5,7 @@ use core::convert::Infallible;
5use core::hint::unreachable_unchecked; 5use core::hint::unreachable_unchecked;
6 6
7use cfg_if::cfg_if; 7use cfg_if::cfg_if;
8use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 8use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
9 9
10use self::sealed::Pin as _; 10use self::sealed::Pin as _;
11use crate::pac::p0 as gpio; 11use crate::pac::p0 as gpio;
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 6550f2abd..7488bc085 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -4,7 +4,7 @@ use core::convert::Infallible;
4use core::future::{poll_fn, Future}; 4use core::future::{poll_fn, Future};
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; 7use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::gpio::sealed::Pin as _; 10use crate::gpio::sealed::Pin as _;
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs
index fea38c4c0..907acdf4c 100644
--- a/embassy-nrf/src/i2s.rs
+++ b/embassy-nrf/src/i2s.rs
@@ -9,8 +9,8 @@ use core::ops::{Deref, DerefMut};
9use core::sync::atomic::{compiler_fence, Ordering}; 9use core::sync::atomic::{compiler_fence, Ordering};
10use core::task::Poll; 10use core::task::Poll;
11 11
12use embassy_hal_common::drop::OnDrop; 12use embassy_hal_internal::drop::OnDrop;
13use embassy_hal_common::{into_ref, PeripheralRef}; 13use embassy_hal_internal::{into_ref, PeripheralRef};
14 14
15use crate::gpio::{AnyPin, Pin as GpioPin}; 15use crate::gpio::{AnyPin, Pin as GpioPin};
16use crate::interrupt::typelevel::Interrupt; 16use crate::interrupt::typelevel::Interrupt;
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index d23759f9d..355a00497 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -98,7 +98,7 @@ mod chip;
98/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) 98/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
99/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to 99/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
100/// prove at compile-time that the right interrupts have been bound. 100/// prove at compile-time that the right interrupts have been bound.
101// developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`. 101// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`.
102#[macro_export] 102#[macro_export]
103macro_rules! bind_interrupts { 103macro_rules! bind_interrupts {
104 ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { 104 ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
@@ -127,7 +127,7 @@ pub use chip::pac;
127#[cfg(not(feature = "unstable-pac"))] 127#[cfg(not(feature = "unstable-pac"))]
128pub(crate) use chip::pac; 128pub(crate) use chip::pac;
129pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; 129pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE};
130pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 130pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
131 131
132pub use crate::chip::interrupt; 132pub use crate::chip::interrupt;
133pub use crate::pac::NVIC_PRIO_BITS; 133pub use crate::pac::NVIC_PRIO_BITS;
diff --git a/embassy-nrf/src/nvmc.rs b/embassy-nrf/src/nvmc.rs
index 91a5a272f..de840b886 100644
--- a/embassy-nrf/src/nvmc.rs
+++ b/embassy-nrf/src/nvmc.rs
@@ -2,7 +2,7 @@
2 2
3use core::{ptr, slice}; 3use core::{ptr, slice};
4 4
5use embassy_hal_common::{into_ref, PeripheralRef}; 5use embassy_hal_internal::{into_ref, PeripheralRef};
6use embedded_storage::nor_flash::{ 6use embedded_storage::nor_flash::{
7 ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, 7 ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
8}; 8};
diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs
index 217884d1c..01f41e9f9 100644
--- a/embassy-nrf/src/pdm.rs
+++ b/embassy-nrf/src/pdm.rs
@@ -6,8 +6,8 @@ use core::marker::PhantomData;
6use core::sync::atomic::{compiler_fence, Ordering}; 6use core::sync::atomic::{compiler_fence, Ordering};
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_hal_common::drop::OnDrop; 9use embassy_hal_internal::drop::OnDrop;
10use embassy_hal_common::{into_ref, PeripheralRef}; 10use embassy_hal_internal::{into_ref, PeripheralRef};
11use fixed::types::I7F1; 11use fixed::types::I7F1;
12use futures::future::poll_fn; 12use futures::future::poll_fn;
13 13
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs
index 40ccb2f09..0bc7f821e 100644
--- a/embassy-nrf/src/ppi/dppi.rs
+++ b/embassy-nrf/src/ppi/dppi.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::into_ref; 1use embassy_hal_internal::into_ref;
2 2
3use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; 3use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
4use crate::{pac, Peripheral}; 4use crate::{pac, Peripheral};
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs
index ff6593bd5..5b4a64388 100644
--- a/embassy-nrf/src/ppi/mod.rs
+++ b/embassy-nrf/src/ppi/mod.rs
@@ -18,7 +18,7 @@
18use core::marker::PhantomData; 18use core::marker::PhantomData;
19use core::ptr::NonNull; 19use core::ptr::NonNull;
20 20
21use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 21use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
22 22
23use crate::{peripherals, Peripheral}; 23use crate::{peripherals, Peripheral};
24 24
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs
index 1fe898625..3e9e9fc81 100644
--- a/embassy-nrf/src/ppi/ppi.rs
+++ b/embassy-nrf/src/ppi/ppi.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::into_ref; 1use embassy_hal_internal::into_ref;
2 2
3use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task}; 3use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};
4use crate::{pac, Peripheral}; 4use crate::{pac, Peripheral};
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs
index c8c81fa01..2f0397632 100644
--- a/embassy-nrf/src/pwm.rs
+++ b/embassy-nrf/src/pwm.rs
@@ -4,7 +4,7 @@
4 4
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6 6
7use embassy_hal_common::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8 8
9use crate::gpio::sealed::Pin as _; 9use crate::gpio::sealed::Pin as _;
10use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; 10use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs
index 8bac87d37..2aa50a2ba 100644
--- a/embassy-nrf/src/qdec.rs
+++ b/embassy-nrf/src/qdec.rs
@@ -6,7 +6,7 @@ use core::future::poll_fn;
6use core::marker::PhantomData; 6use core::marker::PhantomData;
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_hal_common::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
10 10
11use crate::gpio::sealed::Pin as _; 11use crate::gpio::sealed::Pin as _;
12use crate::gpio::{AnyPin, Pin as GpioPin}; 12use crate::gpio::{AnyPin, Pin as GpioPin};
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index baefc7967..36ee33f6d 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -7,8 +7,8 @@ use core::marker::PhantomData;
7use core::ptr; 7use core::ptr;
8use core::task::Poll; 8use core::task::Poll;
9 9
10use embassy_hal_common::drop::OnDrop; 10use embassy_hal_internal::drop::OnDrop;
11use embassy_hal_common::{into_ref, PeripheralRef}; 11use embassy_hal_internal::{into_ref, PeripheralRef};
12use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; 12use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
13 13
14use crate::gpio::{self, Pin as GpioPin}; 14use crate::gpio::{self, Pin as GpioPin};
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index 923b8b467..e2803f0d3 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -8,8 +8,8 @@ use core::ptr;
8use core::sync::atomic::{AtomicPtr, Ordering}; 8use core::sync::atomic::{AtomicPtr, Ordering};
9use core::task::Poll; 9use core::task::Poll;
10 10
11use embassy_hal_common::drop::OnDrop; 11use embassy_hal_internal::drop::OnDrop;
12use embassy_hal_common::{into_ref, PeripheralRef}; 12use embassy_hal_internal::{into_ref, PeripheralRef};
13use embassy_sync::waitqueue::AtomicWaker; 13use embassy_sync::waitqueue::AtomicWaker;
14 14
15use crate::interrupt::typelevel::Interrupt; 15use crate::interrupt::typelevel::Interrupt;
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index 23292924c..662b05614 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -6,8 +6,8 @@ use core::future::poll_fn;
6use core::sync::atomic::{compiler_fence, Ordering}; 6use core::sync::atomic::{compiler_fence, Ordering};
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_hal_common::drop::OnDrop; 9use embassy_hal_internal::drop::OnDrop;
10use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 10use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
11use embassy_sync::waitqueue::AtomicWaker; 11use embassy_sync::waitqueue::AtomicWaker;
12use pac::{saadc, SAADC}; 12use pac::{saadc, SAADC};
13use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; 13use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A};
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index b7dc332e9..4673a0175 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -8,7 +8,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
8use core::task::Poll; 8use core::task::Poll;
9 9
10use embassy_embedded_hal::SetConfig; 10use embassy_embedded_hal::SetConfig;
11use embassy_hal_common::{into_ref, PeripheralRef}; 11use embassy_hal_internal::{into_ref, PeripheralRef};
12pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 12pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
13pub use pac::spim0::frequency::FREQUENCY_A as Frequency; 13pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
14 14
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs
index aa438415a..212825121 100644
--- a/embassy-nrf/src/spis.rs
+++ b/embassy-nrf/src/spis.rs
@@ -7,7 +7,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_embedded_hal::SetConfig; 9use embassy_embedded_hal::SetConfig;
10use embassy_hal_common::{into_ref, PeripheralRef}; 10use embassy_hal_internal::{into_ref, PeripheralRef};
11pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 11pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
12 12
13use crate::chip::FORCE_COPY_BUFFER_SIZE; 13use crate::chip::FORCE_COPY_BUFFER_SIZE;
diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs
index 491e92c04..cec46d8d0 100644
--- a/embassy-nrf/src/temp.rs
+++ b/embassy-nrf/src/temp.rs
@@ -3,8 +3,8 @@
3use core::future::poll_fn; 3use core::future::poll_fn;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_common::drop::OnDrop; 6use embassy_hal_internal::drop::OnDrop;
7use embassy_hal_common::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9use fixed::types::I30F2; 9use fixed::types::I30F2;
10 10
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index 04748238d..3dbfdac42 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -6,7 +6,7 @@
6 6
7#![macro_use] 7#![macro_use]
8 8
9use embassy_hal_common::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
10 10
11use crate::ppi::{Event, Task}; 11use crate::ppi::{Event, Task};
12use crate::{pac, Peripheral}; 12use crate::{pac, Peripheral};
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index 2ad0d19b1..fdea480e3 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -9,7 +9,7 @@ use core::sync::atomic::Ordering::SeqCst;
9use core::task::Poll; 9use core::task::Poll;
10 10
11use embassy_embedded_hal::SetConfig; 11use embassy_embedded_hal::SetConfig;
12use embassy_hal_common::{into_ref, PeripheralRef}; 12use embassy_hal_internal::{into_ref, PeripheralRef};
13use embassy_sync::waitqueue::AtomicWaker; 13use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")] 14#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant}; 15use embassy_time::{Duration, Instant};
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs
index a115d5616..c6c020557 100644
--- a/embassy-nrf/src/twis.rs
+++ b/embassy-nrf/src/twis.rs
@@ -8,7 +8,7 @@ use core::sync::atomic::compiler_fence;
8use core::sync::atomic::Ordering::SeqCst; 8use core::sync::atomic::Ordering::SeqCst;
9use core::task::Poll; 9use core::task::Poll;
10 10
11use embassy_hal_common::{into_ref, PeripheralRef}; 11use embassy_hal_internal::{into_ref, PeripheralRef};
12use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
13#[cfg(feature = "time")] 13#[cfg(feature = "time")]
14use embassy_time::{Duration, Instant}; 14use embassy_time::{Duration, Instant};
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 48d57fea4..e79df3561 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -18,8 +18,8 @@ use core::marker::PhantomData;
18use core::sync::atomic::{compiler_fence, Ordering}; 18use core::sync::atomic::{compiler_fence, Ordering};
19use core::task::Poll; 19use core::task::Poll;
20 20
21use embassy_hal_common::drop::OnDrop; 21use embassy_hal_internal::drop::OnDrop;
22use embassy_hal_common::{into_ref, PeripheralRef}; 22use embassy_hal_internal::{into_ref, PeripheralRef};
23use pac::uarte0::RegisterBlock; 23use pac::uarte0::RegisterBlock;
24// Re-export SVD variants to allow user to directly set values. 24// Re-export SVD variants to allow user to directly set values.
25pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 25pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs
index 76cf40ac7..e26b49db3 100644
--- a/embassy-nrf/src/usb/mod.rs
+++ b/embassy-nrf/src/usb/mod.rs
@@ -11,7 +11,7 @@ use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
11use core::task::Poll; 11use core::task::Poll;
12 12
13use cortex_m::peripheral::NVIC; 13use cortex_m::peripheral::NVIC;
14use embassy_hal_common::{into_ref, PeripheralRef}; 14use embassy_hal_internal::{into_ref, PeripheralRef};
15use embassy_sync::waitqueue::AtomicWaker; 15use embassy_sync::waitqueue::AtomicWaker;
16use embassy_usb_driver as driver; 16use embassy_usb_driver as driver;
17use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported}; 17use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported};
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml
index 8f3ed885d..b53c7a01a 100644
--- a/embassy-rp/Cargo.toml
+++ b/embassy-rp/Cargo.toml
@@ -16,7 +16,7 @@ flavors = [
16default = [ "rt" ] 16default = [ "rt" ]
17rt = [ "rp-pac/rt" ] 17rt = [ "rp-pac/rt" ]
18 18
19defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-common/defmt"] 19defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-internal/defmt"]
20 20
21# critical section that is safe for multicore use 21# critical section that is safe for multicore use
22critical-section-impl = ["critical-section/restore-state-u8"] 22critical-section-impl = ["critical-section/restore-state-u8"]
@@ -58,7 +58,7 @@ unstable-traits = ["embedded-hal-1", "embedded-hal-nb"]
58embassy-sync = { version = "0.2.0", path = "../embassy-sync" } 58embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
59embassy-time = { version = "0.1.2", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } 59embassy-time = { version = "0.1.2", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] }
60embassy-futures = { version = "0.1.0", path = "../embassy-futures" } 60embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
61embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-2"] } 61embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
62embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } 62embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
63embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } 63embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
64atomic-polyfill = "1.0.1" 64atomic-polyfill = "1.0.1"
diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs
index 95780c068..4fba31169 100644
--- a/embassy-rp/src/adc.rs
+++ b/embassy-rp/src/adc.rs
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
3use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use crate::gpio::sealed::Pin as GpioPin; 9use crate::gpio::sealed::Pin as GpioPin;
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs
index acb21dce5..976d06de7 100644
--- a/embassy-rp/src/clocks.rs
+++ b/embassy-rp/src/clocks.rs
@@ -1,7 +1,7 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2use core::sync::atomic::{AtomicU16, AtomicU32, Ordering}; 2use core::sync::atomic::{AtomicU16, AtomicU32, Ordering};
3 3
4use embassy_hal_common::{into_ref, PeripheralRef}; 4use embassy_hal_internal::{into_ref, PeripheralRef};
5use pac::clocks::vals::*; 5use pac::clocks::vals::*;
6 6
7use crate::gpio::sealed::Pin; 7use crate::gpio::sealed::Pin;
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs
index 1a458778c..c8f741804 100644
--- a/embassy-rp/src/dma.rs
+++ b/embassy-rp/src/dma.rs
@@ -4,7 +4,7 @@ use core::pin::Pin;
4use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; 7use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9use pac::dma::vals::DataSize; 9use pac::dma::vals::DataSize;
10 10
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs
index 96d2d4541..0ed6808eb 100644
--- a/embassy-rp/src/flash.rs
+++ b/embassy-rp/src/flash.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::Peripheral; 3use embassy_hal_internal::Peripheral;
4use embedded_storage::nor_flash::{ 4use embedded_storage::nor_flash::{
5 check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, 5 check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind,
6 ReadNorFlash, 6 ReadNorFlash,
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index a3d330cdc..2807eb678 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -3,7 +3,7 @@ use core::future::Future;
3use core::pin::Pin as FuturePin; 3use core::pin::Pin as FuturePin;
4use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
5 5
6use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 6use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use crate::interrupt::InterruptExt; 9use crate::interrupt::InterruptExt;
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs
index 9b85b2345..536ad747d 100644
--- a/embassy-rp/src/i2c.rs
+++ b/embassy-rp/src/i2c.rs
@@ -2,7 +2,7 @@ use core::future;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_common::{into_ref, PeripheralRef}; 5use embassy_hal_internal::{into_ref, PeripheralRef};
6use embassy_sync::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
7use pac::i2c; 7use pac::i2c;
8 8
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 4f205a16e..45156458d 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -33,10 +33,10 @@ pub mod watchdog;
33// TODO: move `pio_instr_util` and `relocate` to inside `pio` 33// TODO: move `pio_instr_util` and `relocate` to inside `pio`
34pub mod pio; 34pub mod pio;
35pub mod pio_instr_util; 35pub mod pio_instr_util;
36pub mod relocate; 36pub(crate) mod relocate;
37 37
38// Reexports 38// Reexports
39pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 39pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
40#[cfg(feature = "unstable-pac")] 40#[cfg(feature = "unstable-pac")]
41pub use rp_pac as pac; 41pub use rp_pac as pac;
42#[cfg(not(feature = "unstable-pac"))] 42#[cfg(not(feature = "unstable-pac"))]
@@ -45,7 +45,7 @@ pub(crate) use rp_pac as pac;
45#[cfg(feature = "rt")] 45#[cfg(feature = "rt")]
46pub use crate::pac::NVIC_PRIO_BITS; 46pub use crate::pac::NVIC_PRIO_BITS;
47 47
48embassy_hal_common::interrupt_mod!( 48embassy_hal_internal::interrupt_mod!(
49 TIMER_IRQ_0, 49 TIMER_IRQ_0,
50 TIMER_IRQ_1, 50 TIMER_IRQ_1,
51 TIMER_IRQ_2, 51 TIMER_IRQ_2,
@@ -85,7 +85,7 @@ embassy_hal_common::interrupt_mod!(
85/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) 85/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
86/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to 86/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
87/// prove at compile-time that the right interrupts have been bound. 87/// prove at compile-time that the right interrupts have been bound.
88// developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`. 88// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`.
89#[macro_export] 89#[macro_export]
90macro_rules! bind_interrupts { 90macro_rules! bind_interrupts {
91 ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { 91 ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
@@ -107,7 +107,7 @@ macro_rules! bind_interrupts {
107 }; 107 };
108} 108}
109 109
110embassy_hal_common::peripherals! { 110embassy_hal_internal::peripherals! {
111 PIN_0, 111 PIN_0,
112 PIN_1, 112 PIN_1,
113 PIN_2, 113 PIN_2,
@@ -219,6 +219,74 @@ select_bootloader! {
219 default => BOOT_LOADER_W25Q080 219 default => BOOT_LOADER_W25Q080
220} 220}
221 221
222/// Installs a stack guard for the CORE0 stack in MPU region 0.
223/// Will fail if the MPU is already confgigured. This function requires
224/// a `_stack_end` symbol to be defined by the linker script, and expexcts
225/// `_stack_end` to be located at the lowest address (largest depth) of
226/// the stack.
227///
228/// This method can *only* set up stack guards on the currently
229/// executing core. Stack guards for CORE1 are set up automatically,
230/// only CORE0 should ever use this.
231///
232/// # Usage
233///
234/// ```no_run
235/// #![feature(type_alias_impl_trait)]
236/// use embassy_rp::install_core0_stack_guard;
237/// use embassy_executor::{Executor, Spawner};
238///
239/// #[embassy_executor::main]
240/// async fn main(_spawner: Spawner) {
241/// // set up by the linker as follows:
242/// //
243/// // MEMORY {
244/// // STACK0: ORIGIN = 0x20040000, LENGTH = 4K
245/// // }
246/// //
247/// // _stack_end = ORIGIN(STACK0);
248/// // _stack_start = _stack_end + LENGTH(STACK0);
249/// //
250/// install_core0_stack_guard().expect("MPU already configured");
251/// let p = embassy_rp::init(Default::default());
252///
253/// // ...
254/// }
255/// ```
256pub fn install_core0_stack_guard() -> Result<(), ()> {
257 extern "C" {
258 static mut _stack_end: usize;
259 }
260 unsafe { install_stack_guard(&mut _stack_end as *mut usize) }
261}
262
263#[inline(always)]
264fn install_stack_guard(stack_bottom: *mut usize) -> Result<(), ()> {
265 let core = unsafe { cortex_m::Peripherals::steal() };
266
267 // Fail if MPU is already configured
268 if core.MPU.ctrl.read() != 0 {
269 return Err(());
270 }
271
272 // The minimum we can protect is 32 bytes on a 32 byte boundary, so round up which will
273 // just shorten the valid stack range a tad.
274 let addr = (stack_bottom as u32 + 31) & !31;
275 // Mask is 1 bit per 32 bytes of the 256 byte range... clear the bit for the segment we want
276 let subregion_select = 0xff ^ (1 << ((addr >> 5) & 7));
277 unsafe {
278 core.MPU.ctrl.write(5); // enable mpu with background default map
279 core.MPU.rbar.write((addr & !0xff) | (1 << 4)); // set address and update RNR
280 core.MPU.rasr.write(
281 1 // enable region
282 | (0x7 << 1) // size 2^(7 + 1) = 256
283 | (subregion_select << 8)
284 | 0x10000000, // XN = disable instruction fetch; no other bits means no permissions
285 );
286 }
287 Ok(())
288}
289
222pub mod config { 290pub mod config {
223 use crate::clocks::ClockConfig; 291 use crate::clocks::ClockConfig;
224 292
diff --git a/embassy-rp/src/multicore.rs b/embassy-rp/src/multicore.rs
index 468e8470a..915761801 100644
--- a/embassy-rp/src/multicore.rs
+++ b/embassy-rp/src/multicore.rs
@@ -52,41 +52,20 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
52 52
53use crate::interrupt::InterruptExt; 53use crate::interrupt::InterruptExt;
54use crate::peripherals::CORE1; 54use crate::peripherals::CORE1;
55use crate::{gpio, interrupt, pac}; 55use crate::{gpio, install_stack_guard, interrupt, pac};
56 56
57const PAUSE_TOKEN: u32 = 0xDEADBEEF; 57const PAUSE_TOKEN: u32 = 0xDEADBEEF;
58const RESUME_TOKEN: u32 = !0xDEADBEEF; 58const RESUME_TOKEN: u32 = !0xDEADBEEF;
59static IS_CORE1_INIT: AtomicBool = AtomicBool::new(false); 59static IS_CORE1_INIT: AtomicBool = AtomicBool::new(false);
60 60
61#[inline(always)] 61#[inline(always)]
62fn install_stack_guard(stack_bottom: *mut usize) { 62fn core1_setup(stack_bottom: *mut usize) {
63 let core = unsafe { cortex_m::Peripherals::steal() }; 63 if let Err(_) = install_stack_guard(stack_bottom) {
64 64 // currently only happens if the MPU was already set up, which
65 // Trap if MPU is already configured 65 // would indicate that the core is already in use from outside
66 if core.MPU.ctrl.read() != 0 { 66 // embassy, somehow. trap if so since we can't deal with that.
67 cortex_m::asm::udf(); 67 cortex_m::asm::udf();
68 } 68 }
69
70 // The minimum we can protect is 32 bytes on a 32 byte boundary, so round up which will
71 // just shorten the valid stack range a tad.
72 let addr = (stack_bottom as u32 + 31) & !31;
73 // Mask is 1 bit per 32 bytes of the 256 byte range... clear the bit for the segment we want
74 let subregion_select = 0xff ^ (1 << ((addr >> 5) & 7));
75 unsafe {
76 core.MPU.ctrl.write(5); // enable mpu with background default map
77 core.MPU.rbar.write((addr & !0xff) | 0x8);
78 core.MPU.rasr.write(
79 1 // enable region
80 | (0x7 << 1) // size 2^(7 + 1) = 256
81 | (subregion_select << 8)
82 | 0x10000000, // XN = disable instruction fetch; no other bits means no permissions
83 );
84 }
85}
86
87#[inline(always)]
88fn core1_setup(stack_bottom: *mut usize) {
89 install_stack_guard(stack_bottom);
90 unsafe { 69 unsafe {
91 gpio::init(); 70 gpio::init();
92 } 71 }
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs
index 72a2f44ed..3de398af7 100644
--- a/embassy-rp/src/pio.rs
+++ b/embassy-rp/src/pio.rs
@@ -5,13 +5,13 @@ use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use atomic_polyfill::{AtomicU32, AtomicU8}; 7use atomic_polyfill::{AtomicU32, AtomicU8};
8use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 8use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use fixed::types::extra::U8; 10use fixed::types::extra::U8;
11use fixed::FixedU32; 11use fixed::FixedU32;
12use pac::io::vals::Gpio0ctrlFuncsel; 12use pac::io::vals::Gpio0ctrlFuncsel;
13use pac::pio::vals::SmExecctrlStatusSel; 13use pac::pio::vals::SmExecctrlStatusSel;
14use pio::{SideSet, Wrap}; 14use pio::{Program, SideSet, Wrap};
15 15
16use crate::dma::{Channel, Transfer, Word}; 16use crate::dma::{Channel, Transfer, Word};
17use crate::gpio::sealed::Pin as SealedPin; 17use crate::gpio::sealed::Pin as SealedPin;
@@ -734,23 +734,67 @@ pub struct InstanceMemory<'d, PIO: Instance> {
734 734
735pub struct LoadedProgram<'d, PIO: Instance> { 735pub struct LoadedProgram<'d, PIO: Instance> {
736 pub used_memory: InstanceMemory<'d, PIO>, 736 pub used_memory: InstanceMemory<'d, PIO>,
737 origin: u8, 737 pub origin: u8,
738 wrap: Wrap, 738 pub wrap: Wrap,
739 side_set: SideSet, 739 pub side_set: SideSet,
740}
741
742#[derive(Clone, Copy, PartialEq, Eq, Debug)]
743#[cfg_attr(feature = "defmt", derive(defmt::Format))]
744pub enum LoadError {
745 /// Insufficient consecutive free instruction space to load program.
746 InsufficientSpace,
747 /// Loading the program would overwrite an instruction address already
748 /// used by another program.
749 AddressInUse(usize),
740} 750}
741 751
742impl<'d, PIO: Instance> Common<'d, PIO> { 752impl<'d, PIO: Instance> Common<'d, PIO> {
743 pub fn load_program<const SIZE: usize>(&mut self, prog: &RelocatedProgram<SIZE>) -> LoadedProgram<'d, PIO> { 753 /// Load a PIO program. This will automatically relocate the program to
754 /// an available chunk of free instruction memory if the program origin
755 /// was not explicitly specified, otherwise it will attempt to load the
756 /// program only at its origin.
757 pub fn load_program<const SIZE: usize>(&mut self, prog: &Program<SIZE>) -> LoadedProgram<'d, PIO> {
744 match self.try_load_program(prog) { 758 match self.try_load_program(prog) {
745 Ok(r) => r, 759 Ok(r) => r,
746 Err(at) => panic!("Trying to write already used PIO instruction memory at {}", at), 760 Err(e) => panic!("Failed to load PIO program: {:?}", e),
747 } 761 }
748 } 762 }
749 763
764 /// Load a PIO program. This will automatically relocate the program to
765 /// an available chunk of free instruction memory if the program origin
766 /// was not explicitly specified, otherwise it will attempt to load the
767 /// program only at its origin.
750 pub fn try_load_program<const SIZE: usize>( 768 pub fn try_load_program<const SIZE: usize>(
751 &mut self, 769 &mut self,
752 prog: &RelocatedProgram<SIZE>, 770 prog: &Program<SIZE>,
771 ) -> Result<LoadedProgram<'d, PIO>, LoadError> {
772 match prog.origin {
773 Some(origin) => self
774 .try_load_program_at(prog, origin)
775 .map_err(|a| LoadError::AddressInUse(a)),
776 None => {
777 // naively search for free space, allowing wraparound since
778 // PIO does support that. with only 32 instruction slots it
779 // doesn't make much sense to do anything more fancy.
780 let mut origin = 0;
781 while origin < 32 {
782 match self.try_load_program_at(prog, origin as _) {
783 Ok(r) => return Ok(r),
784 Err(a) => origin = a + 1,
785 }
786 }
787 Err(LoadError::InsufficientSpace)
788 }
789 }
790 }
791
792 fn try_load_program_at<const SIZE: usize>(
793 &mut self,
794 prog: &Program<SIZE>,
795 origin: u8,
753 ) -> Result<LoadedProgram<'d, PIO>, usize> { 796 ) -> Result<LoadedProgram<'d, PIO>, usize> {
797 let prog = RelocatedProgram::new_with_origin(prog, origin);
754 let used_memory = self.try_write_instr(prog.origin() as _, prog.code())?; 798 let used_memory = self.try_write_instr(prog.origin() as _, prog.code())?;
755 Ok(LoadedProgram { 799 Ok(LoadedProgram {
756 used_memory, 800 used_memory,
@@ -760,7 +804,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
760 }) 804 })
761 } 805 }
762 806
763 pub fn try_write_instr<I>(&mut self, start: usize, instrs: I) -> Result<InstanceMemory<'d, PIO>, usize> 807 fn try_write_instr<I>(&mut self, start: usize, instrs: I) -> Result<InstanceMemory<'d, PIO>, usize>
764 where 808 where
765 I: Iterator<Item = u16>, 809 I: Iterator<Item = u16>,
766 { 810 {
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs
index 20bb88446..c0ddb2a90 100644
--- a/embassy-rp/src/pwm.rs
+++ b/embassy-rp/src/pwm.rs
@@ -1,6 +1,6 @@
1//! Pulse Width Modulation (PWM) 1//! Pulse Width Modulation (PWM)
2 2
3use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 3use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
4use fixed::traits::ToFixed; 4use fixed::traits::ToFixed;
5use fixed::FixedU16; 5use fixed::FixedU16;
6use pac::pwm::regs::{ChDiv, Intr}; 6use pac::pwm::regs::{ChDiv, Intr};
diff --git a/embassy-rp/src/relocate.rs b/embassy-rp/src/relocate.rs
index 9cb279ccd..b35b4ed72 100644
--- a/embassy-rp/src/relocate.rs
+++ b/embassy-rp/src/relocate.rs
@@ -41,11 +41,6 @@ pub struct RelocatedProgram<'a, const PROGRAM_SIZE: usize> {
41} 41}
42 42
43impl<'a, const PROGRAM_SIZE: usize> RelocatedProgram<'a, PROGRAM_SIZE> { 43impl<'a, const PROGRAM_SIZE: usize> RelocatedProgram<'a, PROGRAM_SIZE> {
44 pub fn new(program: &Program<PROGRAM_SIZE>) -> RelocatedProgram<PROGRAM_SIZE> {
45 let origin = program.origin.unwrap_or(0);
46 RelocatedProgram { program, origin }
47 }
48
49 pub fn new_with_origin(program: &Program<PROGRAM_SIZE>, origin: u8) -> RelocatedProgram<PROGRAM_SIZE> { 44 pub fn new_with_origin(program: &Program<PROGRAM_SIZE>, origin: u8) -> RelocatedProgram<PROGRAM_SIZE> {
50 RelocatedProgram { program, origin } 45 RelocatedProgram { program, origin }
51 } 46 }
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs
index 1b33fdf8d..60ca8627b 100644
--- a/embassy-rp/src/rtc/mod.rs
+++ b/embassy-rp/src/rtc/mod.rs
@@ -1,6 +1,6 @@
1mod filter; 1mod filter;
2 2
3use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 3use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
4 4
5pub use self::filter::DateTimeFilter; 5pub use self::filter::DateTimeFilter;
6 6
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index af101cf4a..544b542e8 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
3 3
4use embassy_embedded_hal::SetConfig; 4use embassy_embedded_hal::SetConfig;
5use embassy_futures::join::join; 5use embassy_futures::join::join;
6use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
7pub use embedded_hal_02::spi::{Phase, Polarity}; 7pub use embedded_hal_02::spi::{Phase, Polarity};
8 8
9use crate::dma::{AnyChannel, Channel}; 9use crate::dma::{AnyChannel, Channel};
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs
index 30eeb5476..9d96db12c 100644
--- a/embassy-rp/src/uart/buffered.rs
+++ b/embassy-rp/src/uart/buffered.rs
@@ -3,7 +3,7 @@ use core::slice;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use atomic_polyfill::{AtomicU8, Ordering}; 5use atomic_polyfill::{AtomicU8, Ordering};
6use embassy_hal_common::atomic_ring_buffer::RingBuffer; 6use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8use embassy_time::{Duration, Timer}; 8use embassy_time::{Duration, Timer};
9 9
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs
index 7b94bce5e..69c6ac2f1 100644
--- a/embassy-rp/src/uart/mod.rs
+++ b/embassy-rp/src/uart/mod.rs
@@ -4,7 +4,7 @@ use core::task::Poll;
4 4
5use atomic_polyfill::{AtomicU16, Ordering}; 5use atomic_polyfill::{AtomicU16, Ordering};
6use embassy_futures::select::{select, Either}; 6use embassy_futures::select::{select, Either};
7use embassy_hal_common::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9use embassy_time::{Duration, Timer}; 9use embassy_time::{Duration, Timer};
10use pac::uart::regs::Uartris; 10use pac::uart::regs::Uartris;
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml
index 6cd122200..96c474845 100644
--- a/embassy-stm32-wpan/Cargo.toml
+++ b/embassy-stm32-wpan/Cargo.toml
@@ -15,7 +15,7 @@ embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" }
15embassy-sync = { version = "0.2.0", path = "../embassy-sync" } 15embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
16embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } 16embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
17embassy-futures = { version = "0.1.0", path = "../embassy-futures" } 17embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
18embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common" } 18embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" }
19embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } 19embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" }
20embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true } 20embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true }
21 21
@@ -26,12 +26,12 @@ aligned = "0.4.1"
26 26
27bit_field = "0.10.2" 27bit_field = "0.10.2"
28stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } 28stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] }
29stm32wb-hci = { version = "0.1.3", optional = true } 29stm32wb-hci = { version = "0.1.4", optional = true }
30futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 30futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
31bitflags = { version = "2.3.3", optional = true } 31bitflags = { version = "2.3.3", optional = true }
32 32
33[features] 33[features]
34defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "stm32wb-hci?/defmt"] 34defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "stm32wb-hci?/defmt"]
35 35
36ble = ["dep:stm32wb-hci"] 36ble = ["dep:stm32wb-hci"]
37mac = ["dep:bitflags", "dep:embassy-net-driver" ] 37mac = ["dep:bitflags", "dep:embassy-net-driver" ]
diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs
index 6836d7a8b..5ecce2cc2 100644
--- a/embassy-stm32-wpan/src/lib.rs
+++ b/embassy-stm32-wpan/src/lib.rs
@@ -8,7 +8,7 @@ pub mod fmt;
8use core::mem::MaybeUninit; 8use core::mem::MaybeUninit;
9use core::sync::atomic::{compiler_fence, Ordering}; 9use core::sync::atomic::{compiler_fence, Ordering};
10 10
11use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 11use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
12use embassy_stm32::interrupt; 12use embassy_stm32::interrupt;
13use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; 13use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler};
14use embassy_stm32::peripherals::IPCC; 14use embassy_stm32::peripherals::IPCC;
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 0fb6fdb56..ba279f795 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -34,7 +34,7 @@ flavors = [
34embassy-sync = { version = "0.2.0", path = "../embassy-sync" } 34embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
35embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } 35embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
36embassy-futures = { version = "0.1.0", path = "../embassy-futures" } 36embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
37embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-4"] } 37embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] }
38embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } 38embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
39embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } 39embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
40embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } 40embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
@@ -67,6 +67,7 @@ cfg-if = "1.0.0"
67embedded-io = { version = "0.4.0", features = ["async"], optional = true } 67embedded-io = { version = "0.4.0", features = ["async"], optional = true }
68chrono = { version = "^0.4", default-features = false, optional = true} 68chrono = { version = "^0.4", default-features = false, optional = true}
69bit_field = "0.10.2" 69bit_field = "0.10.2"
70document-features = "0.2.7"
70 71
71[dev-dependencies] 72[dev-dependencies]
72critical-section = { version = "1.1", features = ["std"] } 73critical-section = { version = "1.1", features = ["std"] }
@@ -78,40 +79,63 @@ stm32-metapac = { version = "13", default-features = false, features = ["metadat
78 79
79[features] 80[features]
80default = ["rt"] 81default = ["rt"]
82
83## Enable `stm32-metapac`'s `rt` feature
81rt = ["stm32-metapac/rt"] 84rt = ["stm32-metapac/rt"]
82 85
83defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"] 86## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging
84memory-x = ["stm32-metapac/memory-x"] 87defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"]
88
85exti = [] 89exti = []
86 90
87# Enables additional driver features that depend on embassy-time 91## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/)
92memory-x = ["stm32-metapac/memory-x"]
93
94## Enable nightly-only features
95nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io", "dep:embassy-usb-driver", "embassy-embedded-hal/nightly"]
96
97## Re-export stm32-metapac at `embassy_stm32::pac`.
98## This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
99## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC.
100## There are no plans to make this stable.
101unstable-pac = []
102
103## Implement embedded-hal 1.0 alpha traits.
104## Implement embedded-hal-async traits if `nightly` is set as well.
105unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"]
106
107#! ## Time
108
109## Enables additional driver features that depend on embassy-time
88time = ["dep:embassy-time"] 110time = ["dep:embassy-time"]
89 111
90# Features starting with `_` are for internal use only. They're not intended 112# Features starting with `_` are for internal use only. They're not intended
91# to be enabled by other crates, and are not covered by semver guarantees. 113# to be enabled by other crates, and are not covered by semver guarantees.
92_time-driver = ["time"] 114_time-driver = ["time"]
115
116## Use any time driver
93time-driver-any = ["_time-driver"] 117time-driver-any = ["_time-driver"]
118## Use TIM2 as time driver
94time-driver-tim2 = ["_time-driver"] 119time-driver-tim2 = ["_time-driver"]
120## Use TIM3 as time driver
95time-driver-tim3 = ["_time-driver"] 121time-driver-tim3 = ["_time-driver"]
122## Use TIM4 as time driver
96time-driver-tim4 = ["_time-driver"] 123time-driver-tim4 = ["_time-driver"]
124## Use TIM5 as time driver
97time-driver-tim5 = ["_time-driver"] 125time-driver-tim5 = ["_time-driver"]
126## Use TIM12 as time driver
98time-driver-tim12 = ["_time-driver"] 127time-driver-tim12 = ["_time-driver"]
128## Use TIM15 as time driver
99time-driver-tim15 = ["_time-driver"] 129time-driver-tim15 = ["_time-driver"]
100 130
101# Enable nightly-only features
102nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io", "dep:embassy-usb-driver", "embassy-embedded-hal/nightly"]
103
104# Reexport stm32-metapac at `embassy_stm32::pac`.
105# This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
106# If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC.
107# There are no plans to make this stable.
108unstable-pac = []
109 131
110# Implement embedded-hal 1.0 alpha traits. 132#! ## Chip-selection features
111# Implement embedded-hal-async traits if `nightly` is set as well. 133#! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`.
112unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"] 134#! Check the `Cargo.toml` for the latest list of supported chips.
135#!
136#! **Important:** Do not forget to adapt the target chip in your toolchain,
137#! e.g. in `.cargo/config.toml`.
113 138
114# Chip-selection features
115stm32c011d6 = [ "stm32-metapac/stm32c011d6" ] 139stm32c011d6 = [ "stm32-metapac/stm32c011d6" ]
116stm32c011f4 = [ "stm32-metapac/stm32c011f4" ] 140stm32c011f4 = [ "stm32-metapac/stm32c011f4" ]
117stm32c011f6 = [ "stm32-metapac/stm32c011f6" ] 141stm32c011f6 = [ "stm32-metapac/stm32c011f6" ]
@@ -1445,4 +1469,4 @@ stm32wle5cb = [ "stm32-metapac/stm32wle5cb" ]
1445stm32wle5cc = [ "stm32-metapac/stm32wle5cc" ] 1469stm32wle5cc = [ "stm32-metapac/stm32wle5cc" ]
1446stm32wle5j8 = [ "stm32-metapac/stm32wle5j8" ] 1470stm32wle5j8 = [ "stm32-metapac/stm32wle5j8" ]
1447stm32wle5jb = [ "stm32-metapac/stm32wle5jb" ] 1471stm32wle5jb = [ "stm32-metapac/stm32wle5jb" ]
1448stm32wle5jc = [ "stm32-metapac/stm32wle5jc" ] \ No newline at end of file 1472stm32wle5jc = [ "stm32-metapac/stm32wle5jc" ]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index c2b84797d..9b3caefd5 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -138,7 +138,7 @@ fn main() {
138 let singleton_tokens: Vec<_> = singletons.iter().map(|s| format_ident!("{}", s)).collect(); 138 let singleton_tokens: Vec<_> = singletons.iter().map(|s| format_ident!("{}", s)).collect();
139 139
140 g.extend(quote! { 140 g.extend(quote! {
141 embassy_hal_common::peripherals_definition!(#(#singleton_tokens),*); 141 embassy_hal_internal::peripherals_definition!(#(#singleton_tokens),*);
142 }); 142 });
143 143
144 let singleton_tokens: Vec<_> = singletons 144 let singleton_tokens: Vec<_> = singletons
@@ -148,7 +148,7 @@ fn main() {
148 .collect(); 148 .collect();
149 149
150 g.extend(quote! { 150 g.extend(quote! {
151 embassy_hal_common::peripherals_struct!(#(#singleton_tokens),*); 151 embassy_hal_internal::peripherals_struct!(#(#singleton_tokens),*);
152 }); 152 });
153 153
154 // ======== 154 // ========
@@ -160,7 +160,7 @@ fn main() {
160 } 160 }
161 161
162 g.extend(quote! { 162 g.extend(quote! {
163 embassy_hal_common::interrupt_mod!( 163 embassy_hal_internal::interrupt_mod!(
164 #( 164 #(
165 #irqs, 165 #irqs,
166 )* 166 )*
@@ -211,7 +211,7 @@ fn main() {
211 let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); 211 let region_type = format_ident!("{}", get_flash_region_type_name(region.name));
212 flash_regions.extend(quote! { 212 flash_regions.extend(quote! {
213 #[cfg(flash)] 213 #[cfg(flash)]
214 pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>); 214 pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>);
215 }); 215 });
216 } 216 }
217 217
@@ -243,7 +243,7 @@ fn main() {
243 243
244 #[cfg(flash)] 244 #[cfg(flash)]
245 impl<'d, MODE> FlashLayout<'d, MODE> { 245 impl<'d, MODE> FlashLayout<'d, MODE> {
246 pub(crate) fn new(p: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self { 246 pub(crate) fn new(p: embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self {
247 Self { 247 Self {
248 #(#inits),*, 248 #(#inits),*,
249 _mode: core::marker::PhantomData, 249 _mode: core::marker::PhantomData,
@@ -572,21 +572,21 @@ fn main() {
572 (("fmc", "Clk"), quote!(crate::fmc::ClkPin)), 572 (("fmc", "Clk"), quote!(crate::fmc::ClkPin)),
573 (("fmc", "BA0"), quote!(crate::fmc::BA0Pin)), 573 (("fmc", "BA0"), quote!(crate::fmc::BA0Pin)),
574 (("fmc", "BA1"), quote!(crate::fmc::BA1Pin)), 574 (("fmc", "BA1"), quote!(crate::fmc::BA1Pin)),
575 (("timer", "CH1"), quote!(crate::pwm::Channel1Pin)), 575 (("timer", "CH1"), quote!(crate::timer::Channel1Pin)),
576 (("timer", "CH1N"), quote!(crate::pwm::Channel1ComplementaryPin)), 576 (("timer", "CH1N"), quote!(crate::timer::Channel1ComplementaryPin)),
577 (("timer", "CH2"), quote!(crate::pwm::Channel2Pin)), 577 (("timer", "CH2"), quote!(crate::timer::Channel2Pin)),
578 (("timer", "CH2N"), quote!(crate::pwm::Channel2ComplementaryPin)), 578 (("timer", "CH2N"), quote!(crate::timer::Channel2ComplementaryPin)),
579 (("timer", "CH3"), quote!(crate::pwm::Channel3Pin)), 579 (("timer", "CH3"), quote!(crate::timer::Channel3Pin)),
580 (("timer", "CH3N"), quote!(crate::pwm::Channel3ComplementaryPin)), 580 (("timer", "CH3N"), quote!(crate::timer::Channel3ComplementaryPin)),
581 (("timer", "CH4"), quote!(crate::pwm::Channel4Pin)), 581 (("timer", "CH4"), quote!(crate::timer::Channel4Pin)),
582 (("timer", "CH4N"), quote!(crate::pwm::Channel4ComplementaryPin)), 582 (("timer", "CH4N"), quote!(crate::timer::Channel4ComplementaryPin)),
583 (("timer", "ETR"), quote!(crate::pwm::ExternalTriggerPin)), 583 (("timer", "ETR"), quote!(crate::timer::ExternalTriggerPin)),
584 (("timer", "BKIN"), quote!(crate::pwm::BreakInputPin)), 584 (("timer", "BKIN"), quote!(crate::timer::BreakInputPin)),
585 (("timer", "BKIN_COMP1"), quote!(crate::pwm::BreakInputComparator1Pin)), 585 (("timer", "BKIN_COMP1"), quote!(crate::timer::BreakInputComparator1Pin)),
586 (("timer", "BKIN_COMP2"), quote!(crate::pwm::BreakInputComparator2Pin)), 586 (("timer", "BKIN_COMP2"), quote!(crate::timer::BreakInputComparator2Pin)),
587 (("timer", "BKIN2"), quote!(crate::pwm::BreakInput2Pin)), 587 (("timer", "BKIN2"), quote!(crate::timer::BreakInput2Pin)),
588 (("timer", "BKIN2_COMP1"), quote!(crate::pwm::BreakInput2Comparator1Pin)), 588 (("timer", "BKIN2_COMP1"), quote!(crate::timer::BreakInput2Comparator1Pin)),
589 (("timer", "BKIN2_COMP2"), quote!(crate::pwm::BreakInput2Comparator2Pin)), 589 (("timer", "BKIN2_COMP2"), quote!(crate::timer::BreakInput2Comparator2Pin)),
590 (("hrtim", "CHA1"), quote!(crate::hrtim::ChannelAPin)), 590 (("hrtim", "CHA1"), quote!(crate::hrtim::ChannelAPin)),
591 (("hrtim", "CHA2"), quote!(crate::hrtim::ChannelAComplementaryPin)), 591 (("hrtim", "CHA2"), quote!(crate::hrtim::ChannelAComplementaryPin)),
592 (("hrtim", "CHB1"), quote!(crate::hrtim::ChannelBPin)), 592 (("hrtim", "CHB1"), quote!(crate::hrtim::ChannelBPin)),
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 2322204d5..e577ec289 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::into_ref; 1use embassy_hal_internal::into_ref;
2use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
3 3
4use crate::adc::{Adc, AdcPin, Instance, SampleTime}; 4use crate::adc::{Adc, AdcPin, Instance, SampleTime};
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index d9af0c55e..e8245884e 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::into_ref; 1use embassy_hal_internal::into_ref;
2use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
3 3
4use crate::adc::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; 4use crate::adc::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 091c1d447..9a7acea53 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::into_ref; 1use embassy_hal_internal::into_ref;
2use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
3 3
4use super::InternalChannel; 4use super::InternalChannel;
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 3a6e58cf6..821cc7f6a 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::into_ref; 1use embassy_hal_internal::into_ref;
2use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
3 3
4use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; 4use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index c51c6840f..64d0f0c75 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -226,7 +226,7 @@ impl Prescaler {
226 226
227impl<'d, T: Instance> Adc<'d, T> { 227impl<'d, T: Instance> Adc<'d, T> {
228 pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self { 228 pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
229 embassy_hal_common::into_ref!(adc); 229 embassy_hal_internal::into_ref!(adc);
230 T::enable(); 230 T::enable();
231 T::reset(); 231 T::reset();
232 232
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index 5a0153464..1d0fdd532 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -6,7 +6,7 @@ use core::task::Poll;
6 6
7pub use bxcan; 7pub use bxcan;
8use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; 8use bxcan::{Data, ExtendedId, Frame, Id, StandardId};
9use embassy_hal_common::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
10use futures::FutureExt; 10use futures::FutureExt;
11 11
12use crate::gpio::sealed::AFType; 12use crate::gpio::sealed::AFType;
@@ -77,6 +77,7 @@ pub struct Can<'d, T: Instance> {
77} 77}
78 78
79#[derive(Debug)] 79#[derive(Debug)]
80#[cfg_attr(feature = "defmt", derive(defmt::Format))]
80pub enum BusError { 81pub enum BusError {
81 Stuff, 82 Stuff,
82 Form, 83 Form,
@@ -90,6 +91,22 @@ pub enum BusError {
90 BusWarning, 91 BusWarning,
91} 92}
92 93
94#[derive(Debug)]
95#[cfg_attr(feature = "defmt", derive(defmt::Format))]
96pub enum TryReadError {
97 /// Bus error
98 BusError(BusError),
99 /// Receive buffer is empty
100 Empty,
101}
102
103#[derive(Debug)]
104#[cfg_attr(feature = "defmt", derive(defmt::Format))]
105pub enum TryWriteError {
106 /// All transmit mailboxes are full
107 Full,
108}
109
93impl<'d, T: Instance> Can<'d, T> { 110impl<'d, T: Instance> Can<'d, T> {
94 /// Creates a new Bxcan instance, keeping the peripheral in sleep mode. 111 /// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
95 /// You must call [Can::enable_non_blocking] to use the peripheral. 112 /// You must call [Can::enable_non_blocking] to use the peripheral.
@@ -161,58 +178,60 @@ impl<'d, T: Instance> Can<'d, T> {
161 .leave_disabled(); 178 .leave_disabled();
162 } 179 }
163 180
181 /// Enables the peripheral and synchronizes with the bus.
182 ///
183 /// This will wait for 11 consecutive recessive bits (bus idle state).
184 /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting.
185 pub async fn enable(&mut self) {
186 while self.borrow_mut().enable_non_blocking().is_err() {
187 // SCE interrupt is only generated for entering sleep mode, but not leaving.
188 // Yield to allow other tasks to execute while can bus is initializing.
189 embassy_futures::yield_now().await;
190 }
191 }
192
164 /// Queues the message to be sent but exerts backpressure 193 /// Queues the message to be sent but exerts backpressure
165 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { 194 pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
166 poll_fn(|cx| { 195 CanTx { can: &self.can }.write(frame).await
167 T::state().tx_waker.register(cx.waker()); 196 }
168 if let Ok(status) = self.can.borrow_mut().transmit(frame) {
169 return Poll::Ready(status);
170 }
171 197
172 Poll::Pending 198 /// Attempts to transmit a frame without blocking.
173 }) 199 ///
174 .await 200 /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full.
201 pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> {
202 CanTx { can: &self.can }.try_write(frame)
175 } 203 }
176 204
205 /// Waits for a specific transmit mailbox to become empty
177 pub async fn flush(&self, mb: bxcan::Mailbox) { 206 pub async fn flush(&self, mb: bxcan::Mailbox) {
178 poll_fn(|cx| { 207 CanTx { can: &self.can }.flush(mb).await
179 T::state().tx_waker.register(cx.waker()); 208 }
180 if T::regs().tsr().read().tme(mb.index()) {
181 return Poll::Ready(());
182 }
183 209
184 Poll::Pending 210 /// Waits until any of the transmit mailboxes become empty
185 }) 211 pub async fn flush_any(&self) {
186 .await; 212 CanTx { can: &self.can }.flush_any().await
213 }
214
215 /// Waits until all of the transmit mailboxes become empty
216 pub async fn flush_all(&self) {
217 CanTx { can: &self.can }.flush_all().await
187 } 218 }
188 219
189 /// Returns a tuple of the time the message was received and the message frame 220 /// Returns a tuple of the time the message was received and the message frame
190 pub async fn read(&mut self) -> Result<(u16, bxcan::Frame), BusError> { 221 pub async fn read(&mut self) -> Result<(u16, bxcan::Frame), BusError> {
191 poll_fn(|cx| { 222 CanRx { can: &self.can }.read().await
192 T::state().err_waker.register(cx.waker()); 223 }
193 if let Poll::Ready((time, frame)) = T::state().rx_queue.recv().poll_unpin(cx) {
194 return Poll::Ready(Ok((time, frame)));
195 } else if let Some(err) = self.curr_error() {
196 return Poll::Ready(Err(err));
197 }
198 224
199 Poll::Pending 225 /// Attempts to read a can frame without blocking.
200 }) 226 ///
201 .await 227 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
228 pub fn try_read(&mut self) -> Result<(u16, bxcan::Frame), TryReadError> {
229 CanRx { can: &self.can }.try_read()
202 } 230 }
203 231
204 fn curr_error(&self) -> Option<BusError> { 232 /// Waits while receive queue is empty.
205 let err = { T::regs().esr().read() }; 233 pub async fn wait_not_empty(&mut self) {
206 if err.boff() { 234 CanRx { can: &self.can }.wait_not_empty().await
207 return Some(BusError::BusOff);
208 } else if err.epvf() {
209 return Some(BusError::BusPassive);
210 } else if err.ewgf() {
211 return Some(BusError::BusWarning);
212 } else if let Some(err) = err.lec().into_bus_err() {
213 return Some(err);
214 }
215 None
216 } 235 }
217 236
218 unsafe fn receive_fifo(fifo: RxFifo) { 237 unsafe fn receive_fifo(fifo: RxFifo) {
@@ -374,6 +393,14 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
374 .await 393 .await
375 } 394 }
376 395
396 /// Attempts to transmit a frame without blocking.
397 ///
398 /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full.
399 pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> {
400 self.can.borrow_mut().transmit(frame).map_err(|_| TryWriteError::Full)
401 }
402
403 /// Waits for a specific transmit mailbox to become empty
377 pub async fn flush(&self, mb: bxcan::Mailbox) { 404 pub async fn flush(&self, mb: bxcan::Mailbox) {
378 poll_fn(|cx| { 405 poll_fn(|cx| {
379 T::state().tx_waker.register(cx.waker()); 406 T::state().tx_waker.register(cx.waker());
@@ -385,6 +412,42 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
385 }) 412 })
386 .await; 413 .await;
387 } 414 }
415
416 /// Waits until any of the transmit mailboxes become empty
417 pub async fn flush_any(&self) {
418 poll_fn(|cx| {
419 T::state().tx_waker.register(cx.waker());
420
421 let tsr = T::regs().tsr().read();
422 if tsr.tme(bxcan::Mailbox::Mailbox0.index())
423 || tsr.tme(bxcan::Mailbox::Mailbox1.index())
424 || tsr.tme(bxcan::Mailbox::Mailbox2.index())
425 {
426 return Poll::Ready(());
427 }
428
429 Poll::Pending
430 })
431 .await;
432 }
433
434 /// Waits until all of the transmit mailboxes become empty
435 pub async fn flush_all(&self) {
436 poll_fn(|cx| {
437 T::state().tx_waker.register(cx.waker());
438
439 let tsr = T::regs().tsr().read();
440 if tsr.tme(bxcan::Mailbox::Mailbox0.index())
441 && tsr.tme(bxcan::Mailbox::Mailbox1.index())
442 && tsr.tme(bxcan::Mailbox::Mailbox2.index())
443 {
444 return Poll::Ready(());
445 }
446
447 Poll::Pending
448 })
449 .await;
450 }
388} 451}
389 452
390#[allow(dead_code)] 453#[allow(dead_code)]
@@ -407,6 +470,33 @@ impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> {
407 .await 470 .await
408 } 471 }
409 472
473 /// Attempts to read a CAN frame without blocking.
474 ///
475 /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
476 pub fn try_read(&mut self) -> Result<(u16, bxcan::Frame), TryReadError> {
477 if let Ok(envelope) = T::state().rx_queue.try_recv() {
478 return Ok(envelope);
479 }
480
481 if let Some(err) = self.curr_error() {
482 return Err(TryReadError::BusError(err));
483 }
484
485 Err(TryReadError::Empty)
486 }
487
488 /// Waits while receive queue is empty.
489 pub async fn wait_not_empty(&mut self) {
490 poll_fn(|cx| {
491 if T::state().rx_queue.poll_ready_to_receive(cx) {
492 Poll::Ready(())
493 } else {
494 Poll::Pending
495 }
496 })
497 .await
498 }
499
410 fn curr_error(&self) -> Option<BusError> { 500 fn curr_error(&self) -> Option<BusError> {
411 let err = { T::regs().esr().read() }; 501 let err = { T::regs().esr().read() };
412 if err.boff() { 502 if err.boff() {
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index c31a7fc63..f77788db3 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -1,5 +1,5 @@
1pub use bxcan; 1pub use bxcan;
2use embassy_hal_common::PeripheralRef; 2use embassy_hal_internal::PeripheralRef;
3 3
4use crate::peripherals; 4use crate::peripherals;
5 5
diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs
index 3946a2d47..154f2eb91 100644
--- a/embassy-stm32/src/crc/v1.rs
+++ b/embassy-stm32/src/crc/v1.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::{into_ref, PeripheralRef}; 1use embassy_hal_internal::{into_ref, PeripheralRef};
2 2
3use crate::pac::CRC as PAC_CRC; 3use crate::pac::CRC as PAC_CRC;
4use crate::peripherals::CRC; 4use crate::peripherals::CRC;
diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs
index f337055a7..de0c08755 100644
--- a/embassy-stm32/src/crc/v2v3.rs
+++ b/embassy-stm32/src/crc/v2v3.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::{into_ref, PeripheralRef}; 1use embassy_hal_internal::{into_ref, PeripheralRef};
2 2
3use crate::pac::crc::vals; 3use crate::pac::crc::vals;
4use crate::pac::CRC as PAC_CRC; 4use crate::pac::CRC as PAC_CRC;
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs
index 3d58914b3..a2040b857 100644
--- a/embassy-stm32/src/dac/mod.rs
+++ b/embassy-stm32/src/dac/mod.rs
@@ -3,7 +3,7 @@
3//! Provide access to the STM32 digital-to-analog converter (DAC). 3//! Provide access to the STM32 digital-to-analog converter (DAC).
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5 5
6use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
7 7
8use crate::pac::dac; 8use crate::pac::dac;
9use crate::rcc::RccPeripheral; 9use crate::rcc::RccPeripheral;
@@ -38,11 +38,30 @@ impl Channel {
38#[cfg_attr(feature = "defmt", derive(defmt::Format))] 38#[cfg_attr(feature = "defmt", derive(defmt::Format))]
39/// Trigger sources for CH1 39/// Trigger sources for CH1
40pub enum Ch1Trigger { 40pub enum Ch1Trigger {
41 Tim6, 41 #[cfg(dac_v3)]
42 Tim1,
43 Tim2,
44 #[cfg(not(dac_v3))]
42 Tim3, 45 Tim3,
46 #[cfg(dac_v3)]
47 Tim4,
48 #[cfg(dac_v3)]
49 Tim5,
50 Tim6,
43 Tim7, 51 Tim7,
52 #[cfg(dac_v3)]
53 Tim8,
44 Tim15, 54 Tim15,
45 Tim2, 55 #[cfg(dac_v3)]
56 Hrtim1Dactrg1,
57 #[cfg(dac_v3)]
58 Hrtim1Dactrg2,
59 #[cfg(dac_v3)]
60 Lptim1,
61 #[cfg(dac_v3)]
62 Lptim2,
63 #[cfg(dac_v3)]
64 Lptim3,
46 Exti9, 65 Exti9,
47 Software, 66 Software,
48} 67}
@@ -50,14 +69,30 @@ pub enum Ch1Trigger {
50impl Ch1Trigger { 69impl Ch1Trigger {
51 fn tsel(&self) -> dac::vals::Tsel1 { 70 fn tsel(&self) -> dac::vals::Tsel1 {
52 match self { 71 match self {
53 Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO, 72 #[cfg(dac_v3)]
73 Ch1Trigger::Tim1 => dac::vals::Tsel1::TIM1_TRGO,
74 Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_TRGO,
54 #[cfg(not(dac_v3))] 75 #[cfg(not(dac_v3))]
55 Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM3_TRGO, 76 Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM3_TRGO,
56 #[cfg(dac_v3)] 77 #[cfg(dac_v3)]
57 Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM1_TRGO, 78 Ch1Trigger::Tim4 => dac::vals::Tsel1::TIM4_TRGO,
79 #[cfg(dac_v3)]
80 Ch1Trigger::Tim5 => dac::vals::Tsel1::TIM5_TRGO,
81 Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO,
58 Ch1Trigger::Tim7 => dac::vals::Tsel1::TIM7_TRGO, 82 Ch1Trigger::Tim7 => dac::vals::Tsel1::TIM7_TRGO,
83 #[cfg(dac_v3)]
84 Ch1Trigger::Tim8 => dac::vals::Tsel1::TIM8_TRGO,
59 Ch1Trigger::Tim15 => dac::vals::Tsel1::TIM15_TRGO, 85 Ch1Trigger::Tim15 => dac::vals::Tsel1::TIM15_TRGO,
60 Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_TRGO, 86 #[cfg(dac_v3)]
87 Ch1Trigger::Hrtim1Dactrg1 => dac::vals::Tsel1::HRTIM1_DACTRG1,
88 #[cfg(dac_v3)]
89 Ch1Trigger::Hrtim1Dactrg2 => dac::vals::Tsel1::HRTIM1_DACTRG2,
90 #[cfg(dac_v3)]
91 Ch1Trigger::Lptim1 => dac::vals::Tsel1::LPTIM1_OUT,
92 #[cfg(dac_v3)]
93 Ch1Trigger::Lptim2 => dac::vals::Tsel1::LPTIM2_OUT,
94 #[cfg(dac_v3)]
95 Ch1Trigger::Lptim3 => dac::vals::Tsel1::LPTIM3_OUT,
61 Ch1Trigger::Exti9 => dac::vals::Tsel1::EXTI9, 96 Ch1Trigger::Exti9 => dac::vals::Tsel1::EXTI9,
62 Ch1Trigger::Software => dac::vals::Tsel1::SOFTWARE, 97 Ch1Trigger::Software => dac::vals::Tsel1::SOFTWARE,
63 } 98 }
@@ -129,7 +164,7 @@ pub trait DacChannel<T: Instance, Tx> {
129 } 164 }
130 165
131 /// Set mode register of the given channel 166 /// Set mode register of the given channel
132 #[cfg(dac_v2)] 167 #[cfg(any(dac_v2, dac_v3))]
133 fn set_channel_mode(&mut self, val: u8) -> Result<(), Error> { 168 fn set_channel_mode(&mut self, val: u8) -> Result<(), Error> {
134 T::regs().mcr().modify(|reg| { 169 T::regs().mcr().modify(|reg| {
135 reg.set_mode(Self::CHANNEL.index(), val); 170 reg.set_mode(Self::CHANNEL.index(), val);
@@ -216,8 +251,9 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> {
216 pub fn new( 251 pub fn new(
217 peri: impl Peripheral<P = T> + 'd, 252 peri: impl Peripheral<P = T> + 'd,
218 dma: impl Peripheral<P = Tx> + 'd, 253 dma: impl Peripheral<P = Tx> + 'd,
219 _pin: impl Peripheral<P = impl DacPin<T, 1>> + 'd, 254 pin: impl Peripheral<P = impl DacPin<T, 1>> + crate::gpio::sealed::Pin + 'd,
220 ) -> Self { 255 ) -> Self {
256 pin.set_as_analog();
221 into_ref!(peri, dma); 257 into_ref!(peri, dma);
222 T::enable(); 258 T::enable();
223 T::reset(); 259 T::reset();
@@ -226,7 +262,7 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> {
226 262
227 // Configure each activated channel. All results can be `unwrap`ed since they 263 // Configure each activated channel. All results can be `unwrap`ed since they
228 // will only error if the channel is not configured (i.e. ch1, ch2 are false) 264 // will only error if the channel is not configured (i.e. ch1, ch2 are false)
229 #[cfg(dac_v2)] 265 #[cfg(any(dac_v2, dac_v3))]
230 dac.set_channel_mode(0).unwrap(); 266 dac.set_channel_mode(0).unwrap();
231 dac.enable_channel().unwrap(); 267 dac.enable_channel().unwrap();
232 dac.set_trigger_enable(true).unwrap(); 268 dac.set_trigger_enable(true).unwrap();
@@ -252,7 +288,6 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> {
252 /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. 288 /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled.
253 /// 289 ///
254 /// **Important:** Channel 1 has to be configured for the DAC instance! 290 /// **Important:** Channel 1 has to be configured for the DAC instance!
255 #[cfg(all(bdma, not(dma)))] // It currently only works with BDMA-only chips (DMA should theoretically work though)
256 pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> 291 pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error>
257 where 292 where
258 Tx: DmaCh1<T>, 293 Tx: DmaCh1<T>,
@@ -327,8 +362,9 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> {
327 pub fn new( 362 pub fn new(
328 _peri: impl Peripheral<P = T> + 'd, 363 _peri: impl Peripheral<P = T> + 'd,
329 dma: impl Peripheral<P = Tx> + 'd, 364 dma: impl Peripheral<P = Tx> + 'd,
330 _pin: impl Peripheral<P = impl DacPin<T, 2>> + 'd, 365 pin: impl Peripheral<P = impl DacPin<T, 2>> + crate::gpio::sealed::Pin + 'd,
331 ) -> Self { 366 ) -> Self {
367 pin.set_as_analog();
332 into_ref!(_peri, dma); 368 into_ref!(_peri, dma);
333 T::enable(); 369 T::enable();
334 T::reset(); 370 T::reset();
@@ -340,7 +376,7 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> {
340 376
341 // Configure each activated channel. All results can be `unwrap`ed since they 377 // Configure each activated channel. All results can be `unwrap`ed since they
342 // will only error if the channel is not configured (i.e. ch1, ch2 are false) 378 // will only error if the channel is not configured (i.e. ch1, ch2 are false)
343 #[cfg(dac_v2)] 379 #[cfg(any(dac_v2, dac_v3))]
344 dac.set_channel_mode(0).unwrap(); 380 dac.set_channel_mode(0).unwrap();
345 dac.enable_channel().unwrap(); 381 dac.enable_channel().unwrap();
346 dac.set_trigger_enable(true).unwrap(); 382 dac.set_trigger_enable(true).unwrap();
@@ -364,7 +400,6 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> {
364 /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled. 400 /// Note that for performance reasons in circular mode the transfer complete interrupt is disabled.
365 /// 401 ///
366 /// **Important:** Channel 2 has to be configured for the DAC instance! 402 /// **Important:** Channel 2 has to be configured for the DAC instance!
367 #[cfg(all(bdma, not(dma)))] // It currently only works with BDMA-only chips (DMA should theoretically work though)
368 pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error> 403 pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error>
369 where 404 where
370 Tx: DmaCh2<T>, 405 Tx: DmaCh2<T>,
@@ -442,9 +477,11 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> {
442 peri: impl Peripheral<P = T> + 'd, 477 peri: impl Peripheral<P = T> + 'd,
443 dma_ch1: impl Peripheral<P = TxCh1> + 'd, 478 dma_ch1: impl Peripheral<P = TxCh1> + 'd,
444 dma_ch2: impl Peripheral<P = TxCh2> + 'd, 479 dma_ch2: impl Peripheral<P = TxCh2> + 'd,
445 _pin_ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd, 480 pin_ch1: impl Peripheral<P = impl DacPin<T, 1>> + crate::gpio::sealed::Pin + 'd,
446 _pin_ch2: impl Peripheral<P = impl DacPin<T, 2>> + 'd, 481 pin_ch2: impl Peripheral<P = impl DacPin<T, 2>> + crate::gpio::sealed::Pin + 'd,
447 ) -> Self { 482 ) -> Self {
483 pin_ch1.set_as_analog();
484 pin_ch2.set_as_analog();
448 into_ref!(peri, dma_ch1, dma_ch2); 485 into_ref!(peri, dma_ch1, dma_ch2);
449 T::enable(); 486 T::enable();
450 T::reset(); 487 T::reset();
@@ -461,12 +498,12 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> {
461 498
462 // Configure each activated channel. All results can be `unwrap`ed since they 499 // Configure each activated channel. All results can be `unwrap`ed since they
463 // will only error if the channel is not configured (i.e. ch1, ch2 are false) 500 // will only error if the channel is not configured (i.e. ch1, ch2 are false)
464 #[cfg(dac_v2)] 501 #[cfg(any(dac_v2, dac_v3))]
465 dac_ch1.set_channel_mode(0).unwrap(); 502 dac_ch1.set_channel_mode(0).unwrap();
466 dac_ch1.enable_channel().unwrap(); 503 dac_ch1.enable_channel().unwrap();
467 dac_ch1.set_trigger_enable(true).unwrap(); 504 dac_ch1.set_trigger_enable(true).unwrap();
468 505
469 #[cfg(dac_v2)] 506 #[cfg(any(dac_v2, dac_v3))]
470 dac_ch2.set_channel_mode(0).unwrap(); 507 dac_ch2.set_channel_mode(0).unwrap();
471 dac_ch2.enable_channel().unwrap(); 508 dac_ch2.enable_channel().unwrap();
472 dac_ch2.set_trigger_enable(true).unwrap(); 509 dac_ch2.set_trigger_enable(true).unwrap();
diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs
index 78b026cb6..7497f4aaa 100644
--- a/embassy-stm32/src/dcmi.rs
+++ b/embassy-stm32/src/dcmi.rs
@@ -2,7 +2,7 @@ use core::future::poll_fn;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_common::{into_ref, PeripheralRef}; 5use embassy_hal_internal::{into_ref, PeripheralRef};
6use embassy_sync::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
7 7
8use crate::dma::Transfer; 8use crate::dma::Transfer;
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index 5a87888b7..d956047d5 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -6,7 +6,7 @@ use core::sync::atomic::{fence, Ordering};
6use core::task::{Context, Poll, Waker}; 6use core::task::{Context, Poll, Waker};
7 7
8use atomic_polyfill::AtomicUsize; 8use atomic_polyfill::AtomicUsize;
9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 9use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; 12use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError};
@@ -466,15 +466,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
466 self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); 466 self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow()));
467 } 467 }
468 468
469 /// Read bytes from the ring buffer 469 /// Read elements from the ring buffer
470 /// Return a tuple of the length read and the length remaining in the buffer 470 /// Return a tuple of the length read and the length remaining in the buffer
471 /// If not all of the bytes were read, then there will be some bytes in the buffer remaining 471 /// If not all of the elements were read, then there will be some elements in the buffer remaining
472 /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read 472 /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
473 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. 473 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
474 pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { 474 pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
475 self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) 475 self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf)
476 } 476 }
477 477
478 /// Read an exact number of elements from the ringbuffer.
479 ///
480 /// Returns the remaining number of elements available for immediate reading.
481 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
482 ///
483 /// Async/Wake Behavior:
484 /// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point,
485 /// and when it wraps around. This means that when called with a buffer of length 'M', when this
486 /// ring buffer was created with a buffer of size 'N':
487 /// - If M equals N/2 or N/2 divides evenly into M, this function will return every N/2 elements read on the DMA source.
488 /// - Otherwise, this function may need up to N/2 extra elements to arrive before returning.
489 pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result<usize, OverrunError> {
490 use core::future::poll_fn;
491 use core::sync::atomic::compiler_fence;
492
493 let mut read_data = 0;
494 let buffer_len = buffer.len();
495
496 poll_fn(|cx| {
497 self.set_waker(cx.waker());
498
499 compiler_fence(Ordering::SeqCst);
500
501 match self.read(&mut buffer[read_data..buffer_len]) {
502 Ok((len, remaining)) => {
503 read_data += len;
504 if read_data == buffer_len {
505 Poll::Ready(Ok(remaining))
506 } else {
507 Poll::Pending
508 }
509 }
510 Err(e) => Poll::Ready(Err(e)),
511 }
512 })
513 .await
514 }
515
478 /// The capacity of the ringbuffer 516 /// The capacity of the ringbuffer
479 pub fn cap(&self) -> usize { 517 pub fn cap(&self) -> usize {
480 self.ringbuf.cap() 518 self.ringbuf.cap()
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index 58d438af8..219ef2eb0 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -4,7 +4,7 @@ use core::pin::Pin;
4use core::sync::atomic::{fence, AtomicUsize, Ordering}; 4use core::sync::atomic::{fence, AtomicUsize, Ordering};
5use core::task::{Context, Poll, Waker}; 5use core::task::{Context, Poll, Waker};
6 6
7use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 7use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; 10use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError};
@@ -28,6 +28,12 @@ pub struct TransferOptions {
28 pub flow_ctrl: FlowControl, 28 pub flow_ctrl: FlowControl,
29 /// FIFO threshold for DMA FIFO mode. If none, direct mode is used. 29 /// FIFO threshold for DMA FIFO mode. If none, direct mode is used.
30 pub fifo_threshold: Option<FifoThreshold>, 30 pub fifo_threshold: Option<FifoThreshold>,
31 /// Enable circular DMA
32 pub circular: bool,
33 /// Enable half transfer interrupt
34 pub half_transfer_ir: bool,
35 /// Enable transfer complete interrupt
36 pub complete_transfer_ir: bool,
31} 37}
32 38
33impl Default for TransferOptions { 39impl Default for TransferOptions {
@@ -37,6 +43,9 @@ impl Default for TransferOptions {
37 mburst: Burst::Single, 43 mburst: Burst::Single,
38 flow_ctrl: FlowControl::Dma, 44 flow_ctrl: FlowControl::Dma,
39 fifo_threshold: None, 45 fifo_threshold: None,
46 circular: false,
47 half_transfer_ir: false,
48 complete_transfer_ir: true,
40 } 49 }
41 } 50 }
42} 51}
@@ -365,7 +374,13 @@ impl<'a, C: Channel> Transfer<'a, C> {
365 }); 374 });
366 w.set_pinc(vals::Inc::FIXED); 375 w.set_pinc(vals::Inc::FIXED);
367 w.set_teie(true); 376 w.set_teie(true);
368 w.set_tcie(true); 377 w.set_tcie(options.complete_transfer_ir);
378 if options.circular {
379 w.set_circ(vals::Circ::ENABLED);
380 debug!("Setting circular mode");
381 } else {
382 w.set_circ(vals::Circ::DISABLED);
383 }
369 #[cfg(dma_v1)] 384 #[cfg(dma_v1)]
370 w.set_trbuff(true); 385 w.set_trbuff(true);
371 386
@@ -646,7 +661,7 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
646 w.set_minc(vals::Inc::INCREMENTED); 661 w.set_minc(vals::Inc::INCREMENTED);
647 w.set_pinc(vals::Inc::FIXED); 662 w.set_pinc(vals::Inc::FIXED);
648 w.set_teie(true); 663 w.set_teie(true);
649 w.set_htie(true); 664 w.set_htie(options.half_transfer_ir);
650 w.set_tcie(true); 665 w.set_tcie(true);
651 w.set_circ(vals::Circ::ENABLED); 666 w.set_circ(vals::Circ::ENABLED);
652 #[cfg(dma_v1)] 667 #[cfg(dma_v1)]
@@ -696,15 +711,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
696 self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); 711 self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow()));
697 } 712 }
698 713
699 /// Read bytes from the ring buffer 714 /// Read elements from the ring buffer
700 /// Return a tuple of the length read and the length remaining in the buffer 715 /// Return a tuple of the length read and the length remaining in the buffer
701 /// If not all of the bytes were read, then there will be some bytes in the buffer remaining 716 /// If not all of the elements were read, then there will be some elements in the buffer remaining
702 /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read 717 /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
703 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. 718 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
704 pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { 719 pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
705 self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) 720 self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf)
706 } 721 }
707 722
723 /// Read an exact number of elements from the ringbuffer.
724 ///
725 /// Returns the remaining number of elements available for immediate reading.
726 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
727 ///
728 /// Async/Wake Behavior:
729 /// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point,
730 /// and when it wraps around. This means that when called with a buffer of length 'M', when this
731 /// ring buffer was created with a buffer of size 'N':
732 /// - If M equals N/2 or N/2 divides evenly into M, this function will return every N/2 elements read on the DMA source.
733 /// - Otherwise, this function may need up to N/2 extra elements to arrive before returning.
734 pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result<usize, OverrunError> {
735 use core::future::poll_fn;
736 use core::sync::atomic::compiler_fence;
737
738 let mut read_data = 0;
739 let buffer_len = buffer.len();
740
741 poll_fn(|cx| {
742 self.set_waker(cx.waker());
743
744 compiler_fence(Ordering::SeqCst);
745
746 match self.read(&mut buffer[read_data..buffer_len]) {
747 Ok((len, remaining)) => {
748 read_data += len;
749 if read_data == buffer_len {
750 Poll::Ready(Ok(remaining))
751 } else {
752 Poll::Pending
753 }
754 }
755 Err(e) => Poll::Ready(Err(e)),
756 }
757 })
758 .await
759 }
760
708 // The capacity of the ringbuffer 761 // The capacity of the ringbuffer
709 pub fn cap(&self) -> usize { 762 pub fn cap(&self) -> usize {
710 self.ringbuf.cap() 763 self.ringbuf.cap()
diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs
index b7bcf7795..97cc200d7 100644
--- a/embassy-stm32/src/dma/gpdma.rs
+++ b/embassy-stm32/src/dma/gpdma.rs
@@ -5,7 +5,7 @@ use core::pin::Pin;
5use core::sync::atomic::{fence, Ordering}; 5use core::sync::atomic::{fence, Ordering};
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 8use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use super::word::{Word, WordSize}; 11use super::word::{Word, WordSize};
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 0858587bd..4f1a58ae2 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -26,7 +26,7 @@ pub mod word;
26 26
27use core::mem; 27use core::mem;
28 28
29use embassy_hal_common::impl_peripheral; 29use embassy_hal_internal::impl_peripheral;
30 30
31#[cfg(dmamux)] 31#[cfg(dmamux)]
32pub use self::dmamux::*; 32pub use self::dmamux::*;
diff --git a/embassy-stm32/src/dma/ringbuffer.rs b/embassy-stm32/src/dma/ringbuffer.rs
index a2bde986f..190793974 100644
--- a/embassy-stm32/src/dma/ringbuffer.rs
+++ b/embassy-stm32/src/dma/ringbuffer.rs
@@ -72,10 +72,10 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
72 self.cap() - remaining_transfers 72 self.cap() - remaining_transfers
73 } 73 }
74 74
75 /// Read bytes from the ring buffer 75 /// Read elements from the ring buffer
76 /// Return a tuple of the length read and the length remaining in the buffer 76 /// Return a tuple of the length read and the length remaining in the buffer
77 /// If not all of the bytes were read, then there will be some bytes in the buffer remaining 77 /// If not all of the elements were read, then there will be some elements in the buffer remaining
78 /// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read 78 /// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
79 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller. 79 /// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
80 pub fn read(&mut self, mut dma: impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> { 80 pub fn read(&mut self, mut dma: impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
81 /* 81 /*
@@ -95,11 +95,11 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
95 */ 95 */
96 let end = self.pos(dma.get_remaining_transfers()); 96 let end = self.pos(dma.get_remaining_transfers());
97 if self.start == end && dma.get_complete_count() == 0 { 97 if self.start == end && dma.get_complete_count() == 0 {
98 // No bytes are available in the buffer 98 // No elements are available in the buffer
99 Ok((0, self.cap())) 99 Ok((0, self.cap()))
100 } else if self.start < end { 100 } else if self.start < end {
101 // The available, unread portion in the ring buffer DOES NOT wrap 101 // The available, unread portion in the ring buffer DOES NOT wrap
102 // Copy out the bytes from the dma buffer 102 // Copy out the elements from the dma buffer
103 let len = self.copy_to(buf, self.start..end); 103 let len = self.copy_to(buf, self.start..end);
104 104
105 compiler_fence(Ordering::SeqCst); 105 compiler_fence(Ordering::SeqCst);
@@ -128,7 +128,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
128 // The DMA writer has wrapped since we last read and is currently 128 // The DMA writer has wrapped since we last read and is currently
129 // writing (or the next byte added will be) in the beginning of the ring buffer. 129 // writing (or the next byte added will be) in the beginning of the ring buffer.
130 130
131 // The provided read buffer is not large enough to include all bytes from the tail of the dma buffer. 131 // The provided read buffer is not large enough to include all elements from the tail of the dma buffer.
132 132
133 // Copy out from the dma buffer 133 // Copy out from the dma buffer
134 let len = self.copy_to(buf, self.start..self.cap()); 134 let len = self.copy_to(buf, self.start..self.cap());
@@ -154,8 +154,8 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
154 // The DMA writer has wrapped since we last read and is currently 154 // The DMA writer has wrapped since we last read and is currently
155 // writing (or the next byte added will be) in the beginning of the ring buffer. 155 // writing (or the next byte added will be) in the beginning of the ring buffer.
156 156
157 // The provided read buffer is large enough to include all bytes from the tail of the dma buffer, 157 // The provided read buffer is large enough to include all elements from the tail of the dma buffer,
158 // so the next read will not have any unread tail bytes in the ring buffer. 158 // so the next read will not have any unread tail elements in the ring buffer.
159 159
160 // Copy out from the dma buffer 160 // Copy out from the dma buffer
161 let tail = self.copy_to(buf, self.start..self.cap()); 161 let tail = self.copy_to(buf, self.start..self.cap());
@@ -180,7 +180,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
180 } 180 }
181 /// Copy from the dma buffer at `data_range` into `buf` 181 /// Copy from the dma buffer at `data_range` into `buf`
182 fn copy_to(&mut self, buf: &mut [W], data_range: Range<usize>) -> usize { 182 fn copy_to(&mut self, buf: &mut [W], data_range: Range<usize>) -> usize {
183 // Limit the number of bytes that can be copied 183 // Limit the number of elements that can be copied
184 let length = usize::min(data_range.len(), buf.len()); 184 let length = usize::min(data_range.len(), buf.len());
185 185
186 // Copy from dma buffer into read buffer 186 // Copy from dma buffer into read buffer
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index 2a6ea35ff..a1e0240c8 100644
--- a/embassy-stm32/src/eth/v1/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -6,7 +6,7 @@ mod tx_desc;
6use core::marker::PhantomData; 6use core::marker::PhantomData;
7use core::sync::atomic::{fence, Ordering}; 7use core::sync::atomic::{fence, Ordering};
8 8
9use embassy_hal_common::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
10use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; 10use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf};
11 11
12pub(crate) use self::rx_desc::{RDes, RDesRing}; 12pub(crate) use self::rx_desc::{RDes, RDesRing};
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index bb681c42b..ada495fdb 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -3,7 +3,7 @@ mod descriptors;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::sync::atomic::{fence, Ordering}; 4use core::sync::atomic::{fence, Ordering};
5 5
6use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
7 7
8pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; 8pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
9use super::*; 9use super::*;
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index 3ff92c9e6..925cf39be 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
3use core::pin::Pin; 3use core::pin::Pin;
4use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
5 5
6use embassy_hal_common::impl_peripheral; 6use embassy_hal_internal::impl_peripheral;
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use crate::gpio::{AnyPin, Input, Pin as GpioPin}; 9use crate::gpio::{AnyPin, Input, Pin as GpioPin};
diff --git a/embassy-stm32/src/flash/asynch.rs b/embassy-stm32/src/flash/asynch.rs
index f175349cd..e966e2a77 100644
--- a/embassy-stm32/src/flash/asynch.rs
+++ b/embassy-stm32/src/flash/asynch.rs
@@ -1,8 +1,8 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2use core::sync::atomic::{fence, Ordering}; 2use core::sync::atomic::{fence, Ordering};
3 3
4use embassy_hal_common::drop::OnDrop; 4use embassy_hal_internal::drop::OnDrop;
5use embassy_hal_common::into_ref; 5use embassy_hal_internal::into_ref;
6use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 6use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
7use embassy_sync::mutex::Mutex; 7use embassy_sync::mutex::Mutex;
8 8
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs
index 2a374733d..16c511295 100644
--- a/embassy-stm32/src/flash/common.rs
+++ b/embassy-stm32/src/flash/common.rs
@@ -1,8 +1,8 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2use core::sync::atomic::{fence, Ordering}; 2use core::sync::atomic::{fence, Ordering};
3 3
4use embassy_hal_common::drop::OnDrop; 4use embassy_hal_internal::drop::OnDrop;
5use embassy_hal_common::{into_ref, PeripheralRef}; 5use embassy_hal_internal::{into_ref, PeripheralRef};
6use stm32_metapac::FLASH_BASE; 6use stm32_metapac::FLASH_BASE;
7 7
8use super::{ 8use super::{
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index 4cb39e033..728f6d604 100644
--- a/embassy-stm32/src/flash/f4.rs
+++ b/embassy-stm32/src/flash/f4.rs
@@ -14,7 +14,7 @@ use crate::pac;
14mod alt_regions { 14mod alt_regions {
15 use core::marker::PhantomData; 15 use core::marker::PhantomData;
16 16
17 use embassy_hal_common::PeripheralRef; 17 use embassy_hal_internal::PeripheralRef;
18 use stm32_metapac::FLASH_SIZE; 18 use stm32_metapac::FLASH_SIZE;
19 19
20 use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION}; 20 use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION};
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs
index 60d7a00ee..177e66a91 100644
--- a/embassy-stm32/src/fmc.rs
+++ b/embassy-stm32/src/fmc.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::into_ref; 3use embassy_hal_internal::into_ref;
4 4
5use crate::gpio::sealed::AFType; 5use crate::gpio::sealed::AFType;
6use crate::gpio::{Pull, Speed}; 6use crate::gpio::{Pull, Speed};
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index af3a8eaca..cda597145 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -1,7 +1,7 @@
1#![macro_use] 1#![macro_use]
2use core::convert::Infallible; 2use core::convert::Infallible;
3 3
4use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 4use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
5 5
6use crate::pac::gpio::{self, vals}; 6use crate::pac::gpio::{self, vals};
7use crate::{pac, peripherals, Peripheral}; 7use crate::{pac, peripherals, Peripheral};
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index aa485cd86..e5254a8cd 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -1,7 +1,7 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_embedded_hal::SetConfig; 3use embassy_embedded_hal::SetConfig;
4use embassy_hal_common::{into_ref, PeripheralRef}; 4use embassy_hal_internal::{into_ref, PeripheralRef};
5 5
6use crate::dma::NoDma; 6use crate::dma::NoDma;
7use crate::gpio::sealed::AFType; 7use crate::gpio::sealed::AFType;
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 208d1527d..eaf980a4d 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -4,8 +4,8 @@ use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_embedded_hal::SetConfig; 6use embassy_embedded_hal::SetConfig;
7use embassy_hal_common::drop::OnDrop; 7use embassy_hal_internal::drop::OnDrop;
8use embassy_hal_common::{into_ref, PeripheralRef}; 8use embassy_hal_internal::{into_ref, PeripheralRef};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::dma::{NoDma, Transfer}; 11use crate::dma::{NoDma, Transfer};
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs
index 62dda69b4..1ccad7328 100644
--- a/embassy-stm32/src/i2s.rs
+++ b/embassy-stm32/src/i2s.rs
@@ -1,4 +1,4 @@
1use embassy_hal_common::into_ref; 1use embassy_hal_internal::into_ref;
2 2
3use crate::gpio::sealed::{AFType, Pin as _}; 3use crate::gpio::sealed::{AFType, Pin as _};
4use crate::gpio::AnyPin; 4use crate::gpio::AnyPin;
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs
index a24cba9f0..e100ca5cc 100644
--- a/embassy-stm32/src/ipcc.rs
+++ b/embassy-stm32/src/ipcc.rs
@@ -265,63 +265,9 @@ pub(crate) mod sealed {
265} 265}
266 266
267fn _configure_pwr() { 267fn _configure_pwr() {
268 // TODO: move this to RCC 268 // TODO: move the rest of this to rcc
269
270 let pwr = crate::pac::PWR;
271 let rcc = crate::pac::RCC; 269 let rcc = crate::pac::RCC;
272 270
273 rcc.cfgr().modify(|w| w.set_stopwuck(true));
274
275 pwr.cr1().modify(|w| w.set_dbp(true));
276 pwr.cr1().modify(|w| w.set_dbp(true));
277
278 // configure LSE
279 rcc.bdcr().modify(|w| w.set_lseon(true));
280
281 // select system clock source = PLL
282 // set PLL coefficients
283 // m: 2,
284 // n: 12,
285 // r: 3,
286 // q: 4,
287 // p: 3,
288 let src_bits = 0b11;
289 let pllp = (3 - 1) & 0b11111;
290 let pllq = (4 - 1) & 0b111;
291 let pllr = (3 - 1) & 0b111;
292 let plln = 12 & 0b1111111;
293 let pllm = (2 - 1) & 0b111;
294 rcc.pllcfgr().modify(|w| {
295 w.set_pllsrc(src_bits);
296 w.set_pllm(pllm);
297 w.set_plln(plln);
298 w.set_pllr(pllr);
299 w.set_pllp(pllp);
300 w.set_pllpen(true);
301 w.set_pllq(pllq);
302 w.set_pllqen(true);
303 });
304 // enable PLL
305 rcc.cr().modify(|w| w.set_pllon(true));
306 rcc.cr().write(|w| w.set_hsion(false));
307 // while !rcc.cr().read().pllrdy() {}
308
309 // configure SYSCLK mux to use PLL clocl
310 rcc.cfgr().modify(|w| w.set_sw(0b11));
311
312 // configure CPU1 & CPU2 dividers
313 rcc.cfgr().modify(|w| w.set_hpre(0)); // not divided
314 rcc.extcfgr().modify(|w| {
315 w.set_c2hpre(0b1000); // div2
316 w.set_shdhpre(0); // not divided
317 });
318
319 // apply APB1 / APB2 values
320 rcc.cfgr().modify(|w| {
321 w.set_ppre1(0b000); // not divided
322 w.set_ppre2(0b000); // not divided
323 });
324
325 // TODO: required 271 // TODO: required
326 // set RF wake-up clock = LSE 272 // set RF wake-up clock = LSE
327 rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); 273 rcc.csr().modify(|w| w.set_rfwkpsel(0b01));
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 8c005bfed..34220fbf5 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -1,6 +1,9 @@
1#![cfg_attr(not(test), no_std)] 1#![cfg_attr(not(test), no_std)]
2#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] 2#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
3 3
4//! ## Feature flags
5#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
6
4// This must go FIRST so that all the other modules see its macros. 7// This must go FIRST so that all the other modules see its macros.
5pub mod fmt; 8pub mod fmt;
6include!(concat!(env!("OUT_DIR"), "/_macros.rs")); 9include!(concat!(env!("OUT_DIR"), "/_macros.rs"));
@@ -44,7 +47,6 @@ pub mod i2c;
44pub mod i2s; 47pub mod i2s;
45#[cfg(stm32wb)] 48#[cfg(stm32wb)]
46pub mod ipcc; 49pub mod ipcc;
47pub mod pwm;
48#[cfg(quadspi)] 50#[cfg(quadspi)]
49pub mod qspi; 51pub mod qspi;
50#[cfg(rng)] 52#[cfg(rng)]
@@ -80,7 +82,7 @@ pub use crate::_generated::interrupt;
80/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) 82/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
81/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to 83/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
82/// prove at compile-time that the right interrupts have been bound. 84/// prove at compile-time that the right interrupts have been bound.
83// developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`. 85// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`.
84#[macro_export] 86#[macro_export]
85macro_rules! bind_interrupts { 87macro_rules! bind_interrupts {
86 ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { 88 ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
@@ -104,7 +106,7 @@ macro_rules! bind_interrupts {
104 106
105// Reexports 107// Reexports
106pub use _generated::{peripherals, Peripherals}; 108pub use _generated::{peripherals, Peripherals};
107pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 109pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
108#[cfg(feature = "unstable-pac")] 110#[cfg(feature = "unstable-pac")]
109pub use stm32_metapac as pac; 111pub use stm32_metapac as pac;
110#[cfg(not(feature = "unstable-pac"))] 112#[cfg(not(feature = "unstable-pac"))]
diff --git a/embassy-stm32/src/pwm/mod.rs b/embassy-stm32/src/pwm/mod.rs
deleted file mode 100644
index 5aba2663e..000000000
--- a/embassy-stm32/src/pwm/mod.rs
+++ /dev/null
@@ -1,269 +0,0 @@
1pub mod complementary_pwm;
2pub mod simple_pwm;
3
4use stm32_metapac::timer::vals::Ckd;
5
6#[cfg(feature = "unstable-pac")]
7pub mod low_level {
8 pub use super::sealed::*;
9}
10
11#[derive(Clone, Copy)]
12pub enum Channel {
13 Ch1,
14 Ch2,
15 Ch3,
16 Ch4,
17}
18
19impl Channel {
20 pub fn raw(&self) -> usize {
21 match self {
22 Channel::Ch1 => 0,
23 Channel::Ch2 => 1,
24 Channel::Ch3 => 2,
25 Channel::Ch4 => 3,
26 }
27 }
28}
29
30#[derive(Clone, Copy)]
31pub enum OutputCompareMode {
32 Frozen,
33 ActiveOnMatch,
34 InactiveOnMatch,
35 Toggle,
36 ForceInactive,
37 ForceActive,
38 PwmMode1,
39 PwmMode2,
40}
41
42impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
43 fn from(mode: OutputCompareMode) -> Self {
44 match mode {
45 OutputCompareMode::Frozen => stm32_metapac::timer::vals::Ocm::FROZEN,
46 OutputCompareMode::ActiveOnMatch => stm32_metapac::timer::vals::Ocm::ACTIVEONMATCH,
47 OutputCompareMode::InactiveOnMatch => stm32_metapac::timer::vals::Ocm::INACTIVEONMATCH,
48 OutputCompareMode::Toggle => stm32_metapac::timer::vals::Ocm::TOGGLE,
49 OutputCompareMode::ForceInactive => stm32_metapac::timer::vals::Ocm::FORCEINACTIVE,
50 OutputCompareMode::ForceActive => stm32_metapac::timer::vals::Ocm::FORCEACTIVE,
51 OutputCompareMode::PwmMode1 => stm32_metapac::timer::vals::Ocm::PWMMODE1,
52 OutputCompareMode::PwmMode2 => stm32_metapac::timer::vals::Ocm::PWMMODE2,
53 }
54 }
55}
56
57pub(crate) mod sealed {
58 use super::*;
59
60 pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance {
61 /// Global output enable. Does not do anything on non-advanced timers.
62 fn enable_outputs(&mut self, enable: bool);
63
64 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
65
66 fn enable_channel(&mut self, channel: Channel, enable: bool);
67
68 fn set_compare_value(&mut self, channel: Channel, value: u16);
69
70 fn get_max_compare_value(&self) -> u16;
71 }
72
73 pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance {
74 fn set_dead_time_clock_division(&mut self, value: Ckd);
75
76 fn set_dead_time_value(&mut self, value: u8);
77
78 fn enable_complementary_channel(&mut self, channel: Channel, enable: bool);
79 }
80
81 pub trait CaptureCompare32bitInstance: crate::timer::sealed::GeneralPurpose32bitInstance {
82 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
83
84 fn enable_channel(&mut self, channel: Channel, enable: bool);
85
86 fn set_compare_value(&mut self, channel: Channel, value: u32);
87
88 fn get_max_compare_value(&self) -> u32;
89 }
90}
91
92pub trait CaptureCompare16bitInstance:
93 sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static
94{
95}
96
97pub trait ComplementaryCaptureCompare16bitInstance:
98 sealed::ComplementaryCaptureCompare16bitInstance + crate::timer::AdvancedControlInstance + 'static
99{
100}
101
102pub trait CaptureCompare32bitInstance:
103 sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + crate::timer::GeneralPurpose32bitInstance + 'static
104{
105}
106
107#[allow(unused)]
108macro_rules! impl_compare_capable_16bit {
109 ($inst:ident) => {
110 impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
111 fn enable_outputs(&mut self, _enable: bool) {}
112
113 fn set_output_compare_mode(&mut self, channel: crate::pwm::Channel, mode: OutputCompareMode) {
114 use crate::timer::sealed::GeneralPurpose16bitInstance;
115 let r = Self::regs_gp16();
116 let raw_channel: usize = channel.raw();
117 r.ccmr_output(raw_channel / 2)
118 .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
119 }
120
121 fn enable_channel(&mut self, channel: Channel, enable: bool) {
122 use crate::timer::sealed::GeneralPurpose16bitInstance;
123 Self::regs_gp16()
124 .ccer()
125 .modify(|w| w.set_cce(channel.raw(), enable));
126 }
127
128 fn set_compare_value(&mut self, channel: Channel, value: u16) {
129 use crate::timer::sealed::GeneralPurpose16bitInstance;
130 Self::regs_gp16().ccr(channel.raw()).modify(|w| w.set_ccr(value));
131 }
132
133 fn get_max_compare_value(&self) -> u16 {
134 use crate::timer::sealed::GeneralPurpose16bitInstance;
135 Self::regs_gp16().arr().read().arr()
136 }
137 }
138 };
139}
140
141foreach_interrupt! {
142 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => {
143 impl_compare_capable_16bit!($inst);
144
145 impl CaptureCompare16bitInstance for crate::peripherals::$inst {
146
147 }
148 };
149
150 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => {
151 impl_compare_capable_16bit!($inst);
152 impl crate::pwm::sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {
153 fn set_output_compare_mode(
154 &mut self,
155 channel: crate::pwm::Channel,
156 mode: OutputCompareMode,
157 ) {
158 use crate::timer::sealed::GeneralPurpose32bitInstance;
159 let raw_channel = channel.raw();
160 Self::regs_gp32().ccmr_output(raw_channel / 2).modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
161 }
162
163 fn enable_channel(&mut self, channel: Channel, enable: bool) {
164 use crate::timer::sealed::GeneralPurpose32bitInstance;
165 Self::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), enable));
166 }
167
168 fn set_compare_value(&mut self, channel: Channel, value: u32) {
169 use crate::timer::sealed::GeneralPurpose32bitInstance;
170 Self::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(value));
171 }
172
173 fn get_max_compare_value(&self) -> u32 {
174 use crate::timer::sealed::GeneralPurpose32bitInstance;
175 Self::regs_gp32().arr().read().arr() as u32
176 }
177 }
178 impl CaptureCompare16bitInstance for crate::peripherals::$inst {
179
180 }
181 impl CaptureCompare32bitInstance for crate::peripherals::$inst {
182
183 }
184 };
185
186 ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => {
187 impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
188 fn enable_outputs(&mut self, enable: bool) {
189 use crate::timer::sealed::AdvancedControlInstance;
190 let r = Self::regs_advanced();
191 r.bdtr().modify(|w| w.set_moe(enable));
192 }
193
194 fn set_output_compare_mode(
195 &mut self,
196 channel: crate::pwm::Channel,
197 mode: OutputCompareMode,
198 ) {
199 use crate::timer::sealed::AdvancedControlInstance;
200 let r = Self::regs_advanced();
201 let raw_channel: usize = channel.raw();
202 r.ccmr_output(raw_channel / 2)
203 .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
204 }
205
206 fn enable_channel(&mut self, channel: Channel, enable: bool) {
207 use crate::timer::sealed::AdvancedControlInstance;
208 Self::regs_advanced()
209 .ccer()
210 .modify(|w| w.set_cce(channel.raw(), enable));
211 }
212
213 fn set_compare_value(&mut self, channel: Channel, value: u16) {
214 use crate::timer::sealed::AdvancedControlInstance;
215 Self::regs_advanced()
216 .ccr(channel.raw())
217 .modify(|w| w.set_ccr(value));
218 }
219
220 fn get_max_compare_value(&self) -> u16 {
221 use crate::timer::sealed::AdvancedControlInstance;
222 Self::regs_advanced().arr().read().arr()
223 }
224 }
225
226 impl CaptureCompare16bitInstance for crate::peripherals::$inst {
227
228 }
229
230 impl crate::pwm::sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {
231 fn set_dead_time_clock_division(&mut self, value: Ckd) {
232 use crate::timer::sealed::AdvancedControlInstance;
233 Self::regs_advanced().cr1().modify(|w| w.set_ckd(value));
234 }
235
236 fn set_dead_time_value(&mut self, value: u8) {
237 use crate::timer::sealed::AdvancedControlInstance;
238 Self::regs_advanced().bdtr().modify(|w| w.set_dtg(value));
239 }
240
241 fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) {
242 use crate::timer::sealed::AdvancedControlInstance;
243 Self::regs_advanced()
244 .ccer()
245 .modify(|w| w.set_ccne(channel.raw(), enable));
246 }
247 }
248
249 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {
250
251 }
252 };
253}
254
255pin_trait!(Channel1Pin, CaptureCompare16bitInstance);
256pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance);
257pin_trait!(Channel2Pin, CaptureCompare16bitInstance);
258pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance);
259pin_trait!(Channel3Pin, CaptureCompare16bitInstance);
260pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance);
261pin_trait!(Channel4Pin, CaptureCompare16bitInstance);
262pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance);
263pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance);
264pin_trait!(BreakInputPin, CaptureCompare16bitInstance);
265pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance);
266pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance);
267pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
268pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
269pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs
index 31b676088..32382fb28 100644
--- a/embassy-stm32/src/qspi/mod.rs
+++ b/embassy-stm32/src/qspi/mod.rs
@@ -2,7 +2,7 @@
2 2
3pub mod enums; 3pub mod enums;
4 4
5use embassy_hal_common::{into_ref, PeripheralRef}; 5use embassy_hal_internal::{into_ref, PeripheralRef};
6use enums::*; 6use enums::*;
7 7
8use crate::dma::Transfer; 8use crate::dma::Transfer;
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs
index b84470440..7aa9f0fd2 100644
--- a/embassy-stm32/src/rcc/f4.rs
+++ b/embassy-stm32/src/rcc/f4.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::into_ref; 3use embassy_hal_internal::into_ref;
4use stm32_metapac::rcc::vals::{Mco1, Mco2, Mcopre}; 4use stm32_metapac::rcc::vals::{Mco1, Mco2, Mcopre};
5 5
6use super::sealed::RccPeripheral; 6use super::sealed::RccPeripheral;
diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs
index 7e5cd0d1a..bbc0e0831 100644
--- a/embassy-stm32/src/rcc/h7.rs
+++ b/embassy-stm32/src/rcc/h7.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::into_ref; 3use embassy_hal_internal::into_ref;
4pub use pll::PllConfig; 4pub use pll::PllConfig;
5use stm32_metapac::rcc::vals::{Mco1, Mco2}; 5use stm32_metapac::rcc::vals::{Mco1, Mco2};
6 6
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs
index 8a9b4adbf..dc5f55d0c 100644
--- a/embassy-stm32/src/rcc/l4.rs
+++ b/embassy-stm32/src/rcc/l4.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::into_ref; 3use embassy_hal_internal::into_ref;
4use stm32_metapac::rcc::regs::Cfgr; 4use stm32_metapac::rcc::regs::Cfgr;
5use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; 5use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel};
6 6
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 886fc0b93..4ae65d3e6 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -78,6 +78,14 @@ pub struct Clocks {
78/// The existence of this value indicates that the clock configuration can no longer be changed 78/// The existence of this value indicates that the clock configuration can no longer be changed
79static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); 79static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit();
80 80
81#[cfg(stm32wb)]
82/// RCC initialization function
83pub(crate) unsafe fn init(config: Config) {
84 set_freqs(compute_clocks(&config));
85
86 configure_clocks(&config);
87}
88
81/// Sets the clock frequencies 89/// Sets the clock frequencies
82/// 90///
83/// Safety: Sets a mutable global. 91/// Safety: Sets a mutable global.
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs
index e6123821a..4322b950a 100644
--- a/embassy-stm32/src/rcc/wb.rs
+++ b/embassy-stm32/src/rcc/wb.rs
@@ -1,6 +1,5 @@
1use crate::pac::RCC; 1use crate::rcc::Clocks;
2use crate::rcc::{set_freqs, Clocks}; 2use crate::time::{khz, mhz, Hertz};
3use crate::time::Hertz;
4 3
5/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, 4/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC,
6/// and with the addition of the init function to configure a system clock. 5/// and with the addition of the init function to configure a system clock.
@@ -13,11 +12,94 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000);
13/// LSI speed 12/// LSI speed
14pub const LSI_FREQ: Hertz = Hertz(32_000); 13pub const LSI_FREQ: Hertz = Hertz(32_000);
15 14
16/// System clock mux source
17#[derive(Clone, Copy)] 15#[derive(Clone, Copy)]
18pub enum ClockSrc { 16pub enum HsePrescaler {
19 HSE(Hertz), 17 NotDivided,
20 HSI16, 18 Div2,
19}
20
21impl From<HsePrescaler> for bool {
22 fn from(value: HsePrescaler) -> Self {
23 match value {
24 HsePrescaler::NotDivided => false,
25 HsePrescaler::Div2 => true,
26 }
27 }
28}
29
30pub struct Hse {
31 pub prediv: HsePrescaler,
32
33 pub frequency: Hertz,
34}
35
36/// System clock mux source
37#[derive(Clone, Copy, PartialEq)]
38pub enum Sysclk {
39 /// MSI selected as sysclk
40 MSI,
41 /// HSI selected as sysclk
42 HSI,
43 /// HSE selected as sysclk
44 HSE,
45 /// PLL selected as sysclk
46 Pll,
47}
48
49impl From<Sysclk> for u8 {
50 fn from(value: Sysclk) -> Self {
51 match value {
52 Sysclk::MSI => 0b00,
53 Sysclk::HSI => 0b01,
54 Sysclk::HSE => 0b10,
55 Sysclk::Pll => 0b11,
56 }
57 }
58}
59
60#[derive(Clone, Copy, PartialEq)]
61pub enum PllSource {
62 Hsi,
63 Msi,
64 Hse,
65}
66
67impl From<PllSource> for u8 {
68 fn from(value: PllSource) -> Self {
69 match value {
70 PllSource::Msi => 0b01,
71 PllSource::Hsi => 0b10,
72 PllSource::Hse => 0b11,
73 }
74 }
75}
76
77pub enum Pll48Source {
78 PllSai,
79 Pll,
80 Msi,
81 Hsi48,
82}
83
84pub struct PllMux {
85 /// Source clock selection.
86 pub source: PllSource,
87
88 /// PLL pre-divider (DIVM). Must be between 1 and 63.
89 pub prediv: u8,
90}
91
92pub struct Pll {
93 /// PLL multiplication factor. Must be between 4 and 512.
94 pub mul: u16,
95
96 /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128.
97 /// On PLL1, it must be even (in particular, it cannot be 1.)
98 pub divp: Option<u16>,
99 /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128.
100 pub divq: Option<u16>,
101 /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128.
102 pub divr: Option<u16>,
21} 103}
22 104
23/// AHB prescaler 105/// AHB prescaler
@@ -84,86 +166,250 @@ impl Into<u8> for AHBPrescaler {
84 166
85/// Clocks configutation 167/// Clocks configutation
86pub struct Config { 168pub struct Config {
87 pub mux: ClockSrc, 169 pub hse: Option<Hse>,
88 pub ahb_pre: AHBPrescaler, 170 pub lse: Option<Hertz>,
171 pub sys: Sysclk,
172 pub mux: Option<PllMux>,
173 pub pll48: Option<Pll48Source>,
174
175 pub pll: Option<Pll>,
176 pub pllsai: Option<Pll>,
177
178 pub ahb1_pre: AHBPrescaler,
179 pub ahb2_pre: AHBPrescaler,
180 pub ahb3_pre: AHBPrescaler,
89 pub apb1_pre: APBPrescaler, 181 pub apb1_pre: APBPrescaler,
90 pub apb2_pre: APBPrescaler, 182 pub apb2_pre: APBPrescaler,
91} 183}
92 184
185pub const WPAN_DEFAULT: Config = Config {
186 hse: Some(Hse {
187 frequency: mhz(32),
188 prediv: HsePrescaler::NotDivided,
189 }),
190 lse: Some(khz(32)),
191 sys: Sysclk::Pll,
192 mux: Some(PllMux {
193 source: PllSource::Hse,
194 prediv: 2,
195 }),
196 pll48: None,
197
198 pll: Some(Pll {
199 mul: 12,
200 divp: Some(3),
201 divq: Some(4),
202 divr: Some(3),
203 }),
204 pllsai: None,
205
206 ahb1_pre: AHBPrescaler::NotDivided,
207 ahb2_pre: AHBPrescaler::Div2,
208 ahb3_pre: AHBPrescaler::NotDivided,
209 apb1_pre: APBPrescaler::NotDivided,
210 apb2_pre: APBPrescaler::NotDivided,
211};
212
93impl Default for Config { 213impl Default for Config {
94 #[inline] 214 #[inline]
95 fn default() -> Config { 215 fn default() -> Config {
96 Config { 216 Config {
97 mux: ClockSrc::HSI16, 217 hse: None,
98 ahb_pre: AHBPrescaler::NotDivided, 218 lse: None,
219 sys: Sysclk::HSI,
220 mux: None,
221 pll48: None,
222 pll: None,
223 pllsai: None,
224
225 ahb1_pre: AHBPrescaler::NotDivided,
226 ahb2_pre: AHBPrescaler::NotDivided,
227 ahb3_pre: AHBPrescaler::NotDivided,
99 apb1_pre: APBPrescaler::NotDivided, 228 apb1_pre: APBPrescaler::NotDivided,
100 apb2_pre: APBPrescaler::NotDivided, 229 apb2_pre: APBPrescaler::NotDivided,
101 } 230 }
102 } 231 }
103} 232}
104 233
105pub(crate) unsafe fn init(config: Config) { 234pub(crate) fn compute_clocks(config: &Config) -> Clocks {
106 let (sys_clk, sw) = match config.mux { 235 let hse_clk = config.hse.as_ref().map(|hse| match hse.prediv {
107 ClockSrc::HSI16 => { 236 HsePrescaler::NotDivided => hse.frequency,
108 // Enable HSI16 237 HsePrescaler::Div2 => hse.frequency / 2u32,
109 RCC.cr().write(|w| w.set_hsion(true)); 238 });
110 while !RCC.cr().read().hsirdy() {}
111 239
112 (HSI_FREQ.0, 0x01) 240 let mux_clk = config.mux.as_ref().map(|pll_mux| {
241 (match pll_mux.source {
242 PllSource::Hse => hse_clk.unwrap(),
243 PllSource::Hsi => HSI_FREQ,
244 _ => unreachable!(),
245 } / pll_mux.prediv)
246 });
247
248 let (pll_r, _pll_q, _pll_p) = match &config.pll {
249 Some(pll) => {
250 let pll_vco = mux_clk.unwrap() * pll.mul as u32;
251
252 (
253 pll.divr.map(|divr| pll_vco / divr),
254 pll.divq.map(|divq| pll_vco / divq),
255 pll.divp.map(|divp| pll_vco / divp),
256 )
113 } 257 }
114 ClockSrc::HSE(freq) => { 258 None => (None, None, None),
115 // Enable HSE 259 };
116 RCC.cr().write(|w| w.set_hseon(true));
117 while !RCC.cr().read().hserdy() {}
118 260
119 (freq.0, 0x02) 261 let sys_clk = match config.sys {
262 Sysclk::HSE => hse_clk.unwrap(),
263 Sysclk::HSI => HSI_FREQ,
264 Sysclk::Pll => pll_r.unwrap(),
265 _ => unreachable!(),
266 };
267
268 let ahb1_clk = match config.ahb1_pre {
269 AHBPrescaler::NotDivided => sys_clk,
270 pre => {
271 let pre: u8 = pre.into();
272 let pre = 1u32 << (pre as u32 - 7);
273 sys_clk / pre
120 } 274 }
121 }; 275 };
122 276
123 RCC.cfgr().modify(|w| { 277 let ahb2_clk = match config.ahb2_pre {
124 w.set_sw(sw.into()); 278 AHBPrescaler::NotDivided => sys_clk,
125 w.set_hpre(config.ahb_pre.into()); 279 pre => {
126 w.set_ppre1(config.apb1_pre.into()); 280 let pre: u8 = pre.into();
127 w.set_ppre2(config.apb2_pre.into()); 281 let pre = 1u32 << (pre as u32 - 7);
128 }); 282 sys_clk / pre
283 }
284 };
129 285
130 let ahb_freq: u32 = match config.ahb_pre { 286 let ahb3_clk = match config.ahb3_pre {
131 AHBPrescaler::NotDivided => sys_clk, 287 AHBPrescaler::NotDivided => sys_clk,
132 pre => { 288 pre => {
133 let pre: u8 = pre.into(); 289 let pre: u8 = pre.into();
134 let pre = 1 << (pre as u32 - 7); 290 let pre = 1u32 << (pre as u32 - 7);
135 sys_clk / pre 291 sys_clk / pre
136 } 292 }
137 }; 293 };
138 294
139 let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { 295 let (apb1_clk, apb1_tim_clk) = match config.apb1_pre {
140 APBPrescaler::NotDivided => (ahb_freq, ahb_freq), 296 APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk),
141 pre => { 297 pre => {
142 let pre: u8 = pre.into(); 298 let pre: u8 = pre.into();
143 let pre: u8 = 1 << (pre - 3); 299 let pre: u8 = 1 << (pre - 3);
144 let freq = ahb_freq / pre as u32; 300 let freq = ahb1_clk / pre as u32;
145 (freq, freq * 2) 301 (freq, freq * 2u32)
146 } 302 }
147 }; 303 };
148 304
149 let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { 305 let (apb2_clk, apb2_tim_clk) = match config.apb2_pre {
150 APBPrescaler::NotDivided => (ahb_freq, ahb_freq), 306 APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk),
151 pre => { 307 pre => {
152 let pre: u8 = pre.into(); 308 let pre: u8 = pre.into();
153 let pre: u8 = 1 << (pre - 3); 309 let pre: u8 = 1 << (pre - 3);
154 let freq = ahb_freq / pre as u32; 310 let freq = ahb1_clk / pre as u32;
155 (freq, freq * 2) 311 (freq, freq * 2u32)
312 }
313 };
314
315 Clocks {
316 sys: sys_clk,
317 ahb1: ahb1_clk,
318 ahb2: ahb2_clk,
319 ahb3: ahb3_clk,
320 apb1: apb1_clk,
321 apb2: apb2_clk,
322 apb1_tim: apb1_tim_clk,
323 apb2_tim: apb2_tim_clk,
324 }
325}
326
327pub(crate) fn configure_clocks(config: &Config) {
328 let pwr = crate::pac::PWR;
329 let rcc = crate::pac::RCC;
330
331 let needs_hsi = if let Some(pll_mux) = &config.mux {
332 pll_mux.source == PllSource::Hsi
333 } else {
334 false
335 };
336
337 if needs_hsi || config.sys == Sysclk::HSI {
338 rcc.cr().modify(|w| {
339 w.set_hsion(true);
340 });
341
342 while !rcc.cr().read().hsirdy() {}
343 }
344
345 match &config.lse {
346 Some(_) => {
347 rcc.cfgr().modify(|w| w.set_stopwuck(true));
348
349 pwr.cr1().modify(|w| w.set_dbp(true));
350 pwr.cr1().modify(|w| w.set_dbp(true));
351
352 rcc.bdcr().modify(|w| w.set_lseon(true));
353 }
354 _ => {}
355 }
356
357 match &config.hse {
358 Some(hse) => {
359 rcc.cr().modify(|w| {
360 w.set_hsepre(hse.prediv.into());
361 w.set_hseon(true);
362 });
363
364 while !rcc.cr().read().hserdy() {}
365 }
366 _ => {}
367 }
368
369 match &config.mux {
370 Some(pll_mux) => {
371 rcc.pllcfgr().modify(|w| {
372 w.set_pllm(pll_mux.prediv);
373 w.set_pllsrc(pll_mux.source.into());
374 });
156 } 375 }
376 _ => {}
157 }; 377 };
158 378
159 set_freqs(Clocks { 379 match &config.pll {
160 sys: Hertz(sys_clk), 380 Some(pll) => {
161 ahb1: Hertz(ahb_freq), 381 rcc.pllcfgr().modify(|w| {
162 ahb2: Hertz(ahb_freq), 382 w.set_plln(pll.mul as u8);
163 ahb3: Hertz(ahb_freq), 383 pll.divp.map(|divp| {
164 apb1: Hertz(apb1_freq), 384 w.set_pllpen(true);
165 apb2: Hertz(apb2_freq), 385 w.set_pllp((divp - 1) as u8)
166 apb1_tim: Hertz(apb1_tim_freq), 386 });
167 apb2_tim: Hertz(apb2_tim_freq), 387 pll.divq.map(|divq| {
388 w.set_pllqen(true);
389 w.set_pllq((divq - 1) as u8)
390 });
391 pll.divr.map(|divr| {
392 // w.set_pllren(true);
393 w.set_pllr((divr - 1) as u8);
394 });
395 });
396
397 rcc.cr().modify(|w| w.set_pllon(true));
398
399 while !rcc.cr().read().pllrdy() {}
400 }
401 _ => {}
402 }
403
404 rcc.cfgr().modify(|w| {
405 w.set_sw(config.sys.into());
406 w.set_hpre(config.ahb1_pre.into());
407 w.set_ppre1(config.apb1_pre.into());
408 w.set_ppre2(config.apb2_pre.into());
409 });
410
411 rcc.extcfgr().modify(|w| {
412 w.set_c2hpre(config.ahb2_pre.into());
413 w.set_shdhpre(config.ahb3_pre.into());
168 }); 414 });
169} 415}
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index b2faec53d..27415c2d7 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -3,7 +3,7 @@
3use core::future::poll_fn; 3use core::future::poll_fn;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{into_ref, PeripheralRef};
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8use rand_core::{CryptoRng, RngCore}; 8use rand_core::{CryptoRng, RngCore};
9 9
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 12a2ac795..323be3187 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -15,7 +15,7 @@ pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
15#[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")] 15#[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")]
16mod _version; 16mod _version;
17pub use _version::*; 17pub use _version::*;
18use embassy_hal_common::Peripheral; 18use embassy_hal_internal::Peripheral;
19 19
20/// Errors that can occur on methods on [RtcClock] 20/// Errors that can occur on methods on [RtcClock]
21#[derive(Clone, Debug, PartialEq, Eq)] 21#[derive(Clone, Debug, PartialEq, Eq)]
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index 698292bff..6b532363c 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -6,8 +6,8 @@ use core::marker::PhantomData;
6use core::ops::{Deref, DerefMut}; 6use core::ops::{Deref, DerefMut};
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_hal_common::drop::OnDrop; 9use embassy_hal_internal::drop::OnDrop;
10use embassy_hal_common::{into_ref, PeripheralRef}; 10use embassy_hal_internal::{into_ref, PeripheralRef};
11use embassy_sync::waitqueue::AtomicWaker; 11use embassy_sync::waitqueue::AtomicWaker;
12use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; 12use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
13 13
@@ -225,6 +225,9 @@ const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOp
225 mburst: crate::dma::Burst::Incr4, 225 mburst: crate::dma::Burst::Incr4,
226 flow_ctrl: crate::dma::FlowControl::Peripheral, 226 flow_ctrl: crate::dma::FlowControl::Peripheral,
227 fifo_threshold: Some(crate::dma::FifoThreshold::Full), 227 fifo_threshold: Some(crate::dma::FifoThreshold::Full),
228 circular: false,
229 half_transfer_ir: false,
230 complete_transfer_ir: true,
228}; 231};
229#[cfg(all(sdmmc_v1, not(dma)))] 232#[cfg(all(sdmmc_v1, not(dma)))]
230const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions { 233const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions {
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index d5f63f84e..bdf3c85b0 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -4,7 +4,7 @@ use core::ptr;
4 4
5use embassy_embedded_hal::SetConfig; 5use embassy_embedded_hal::SetConfig;
6use embassy_futures::join::join; 6use embassy_futures::join::join;
7use embassy_hal_common::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 8pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
9 9
10use crate::dma::{slice_ptr_parts, word, Transfer}; 10use crate::dma::{slice_ptr_parts, word, Transfer};
diff --git a/embassy-stm32/src/pwm/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index 4d64d005c..64bb32c39 100644
--- a/embassy-stm32/src/pwm/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::{into_ref, PeripheralRef}; 3use embassy_hal_internal::{into_ref, PeripheralRef};
4use stm32_metapac::timer::vals::Ckd; 4use stm32_metapac::timer::vals::Ckd;
5 5
6use super::simple_pwm::*; 6use super::simple_pwm::*;
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs
index a92f854ec..286ab556f 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -1,3 +1,6 @@
1pub mod complementary_pwm;
2pub mod simple_pwm;
3
1use stm32_metapac::timer::vals; 4use stm32_metapac::timer::vals;
2 5
3use crate::interrupt; 6use crate::interrupt;
@@ -44,24 +47,122 @@ pub(crate) mod sealed {
44 fn regs_advanced() -> crate::pac::timer::TimAdv; 47 fn regs_advanced() -> crate::pac::timer::TimAdv;
45 } 48 }
46 49
47 #[cfg(hrtim_v1)] 50 pub trait CaptureCompare16bitInstance: GeneralPurpose16bitInstance {
48 pub trait HighResolutionControlInstance: RccPeripheral { 51 /// Global output enable. Does not do anything on non-advanced timers.
49 type Interrupt: interrupt::typelevel::Interrupt; 52 fn enable_outputs(&mut self, enable: bool);
53
54 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
55
56 fn enable_channel(&mut self, channel: Channel, enable: bool);
57
58 fn set_compare_value(&mut self, channel: Channel, value: u16);
59
60 fn get_max_compare_value(&self) -> u16;
61 }
62
63 pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance {
64 fn set_dead_time_clock_division(&mut self, value: vals::Ckd);
65
66 fn set_dead_time_value(&mut self, value: u8);
67
68 fn enable_complementary_channel(&mut self, channel: Channel, enable: bool);
69 }
70
71 pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance {
72 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
73
74 fn enable_channel(&mut self, channel: Channel, enable: bool);
75
76 fn set_compare_value(&mut self, channel: Channel, value: u32);
77
78 fn get_max_compare_value(&self) -> u32;
79 }
80}
81
82#[derive(Clone, Copy)]
83pub enum Channel {
84 Ch1,
85 Ch2,
86 Ch3,
87 Ch4,
88}
89
90impl Channel {
91 pub fn raw(&self) -> usize {
92 match self {
93 Channel::Ch1 => 0,
94 Channel::Ch2 => 1,
95 Channel::Ch3 => 2,
96 Channel::Ch4 => 3,
97 }
98 }
99}
100
101#[derive(Clone, Copy)]
102pub enum OutputCompareMode {
103 Frozen,
104 ActiveOnMatch,
105 InactiveOnMatch,
106 Toggle,
107 ForceInactive,
108 ForceActive,
109 PwmMode1,
110 PwmMode2,
111}
50 112
51 fn regs() -> crate::pac::hrtim::Hrtim; 113impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
114 fn from(mode: OutputCompareMode) -> Self {
115 match mode {
116 OutputCompareMode::Frozen => stm32_metapac::timer::vals::Ocm::FROZEN,
117 OutputCompareMode::ActiveOnMatch => stm32_metapac::timer::vals::Ocm::ACTIVEONMATCH,
118 OutputCompareMode::InactiveOnMatch => stm32_metapac::timer::vals::Ocm::INACTIVEONMATCH,
119 OutputCompareMode::Toggle => stm32_metapac::timer::vals::Ocm::TOGGLE,
120 OutputCompareMode::ForceInactive => stm32_metapac::timer::vals::Ocm::FORCEINACTIVE,
121 OutputCompareMode::ForceActive => stm32_metapac::timer::vals::Ocm::FORCEACTIVE,
122 OutputCompareMode::PwmMode1 => stm32_metapac::timer::vals::Ocm::PWMMODE1,
123 OutputCompareMode::PwmMode2 => stm32_metapac::timer::vals::Ocm::PWMMODE2,
124 }
52 } 125 }
53} 126}
54 127
128pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {}
129
55pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {} 130pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {}
56 131
57pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + 'static {} 132pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + 'static {}
58 133
59pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {} 134pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {}
60 135
61#[cfg(hrtim_v1)] 136pub trait CaptureCompare16bitInstance:
62pub trait HighResolutionControlInstance: sealed::HighResolutionControlInstance + 'static {} 137 sealed::CaptureCompare16bitInstance + GeneralPurpose16bitInstance + 'static
138{
139}
63 140
64pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} 141pub trait ComplementaryCaptureCompare16bitInstance:
142 sealed::ComplementaryCaptureCompare16bitInstance + AdvancedControlInstance + 'static
143{
144}
145
146pub trait CaptureCompare32bitInstance:
147 sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + GeneralPurpose32bitInstance + 'static
148{
149}
150
151pin_trait!(Channel1Pin, CaptureCompare16bitInstance);
152pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance);
153pin_trait!(Channel2Pin, CaptureCompare16bitInstance);
154pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance);
155pin_trait!(Channel3Pin, CaptureCompare16bitInstance);
156pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance);
157pin_trait!(Channel4Pin, CaptureCompare16bitInstance);
158pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance);
159pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance);
160pin_trait!(BreakInputPin, CaptureCompare16bitInstance);
161pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance);
162pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance);
163pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
164pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
165pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
65 166
66#[allow(unused)] 167#[allow(unused)]
67macro_rules! impl_basic_16bit_timer { 168macro_rules! impl_basic_16bit_timer {
@@ -150,33 +251,94 @@ macro_rules! impl_32bit_timer {
150 }; 251 };
151} 252}
152 253
254#[allow(unused)]
255macro_rules! impl_compare_capable_16bit {
256 ($inst:ident) => {
257 impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
258 fn enable_outputs(&mut self, _enable: bool) {}
259
260 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
261 use sealed::GeneralPurpose16bitInstance;
262 let r = Self::regs_gp16();
263 let raw_channel: usize = channel.raw();
264 r.ccmr_output(raw_channel / 2)
265 .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
266 }
267
268 fn enable_channel(&mut self, channel: Channel, enable: bool) {
269 use sealed::GeneralPurpose16bitInstance;
270 Self::regs_gp16()
271 .ccer()
272 .modify(|w| w.set_cce(channel.raw(), enable));
273 }
274
275 fn set_compare_value(&mut self, channel: Channel, value: u16) {
276 use sealed::GeneralPurpose16bitInstance;
277 Self::regs_gp16().ccr(channel.raw()).modify(|w| w.set_ccr(value));
278 }
279
280 fn get_max_compare_value(&self) -> u16 {
281 use sealed::GeneralPurpose16bitInstance;
282 Self::regs_gp16().arr().read().arr()
283 }
284 }
285 };
286}
287
153foreach_interrupt! { 288foreach_interrupt! {
154 ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { 289 ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => {
155 impl_basic_16bit_timer!($inst, $irq); 290 impl_basic_16bit_timer!($inst, $irq);
156 291 impl Basic16bitInstance for crate::peripherals::$inst {}
157 impl Basic16bitInstance for crate::peripherals::$inst {
158 }
159 }; 292 };
160 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { 293 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => {
161 impl_basic_16bit_timer!($inst, $irq); 294 impl_basic_16bit_timer!($inst, $irq);
162 295 impl_compare_capable_16bit!($inst);
163 impl Basic16bitInstance for crate::peripherals::$inst { 296 impl Basic16bitInstance for crate::peripherals::$inst {}
164 } 297 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
298 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
165 299
166 impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { 300 impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst {
167 fn regs_gp16() -> crate::pac::timer::TimGp16 { 301 fn regs_gp16() -> crate::pac::timer::TimGp16 {
168 crate::pac::$inst 302 crate::pac::$inst
169 } 303 }
170 } 304 }
171
172 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {
173 }
174 }; 305 };
175 306
176 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { 307 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => {
177 impl_basic_16bit_timer!($inst, $irq); 308 impl_basic_16bit_timer!($inst, $irq);
309 impl_32bit_timer!($inst);
310 impl_compare_capable_16bit!($inst);
311 impl Basic16bitInstance for crate::peripherals::$inst {}
312 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
313 impl CaptureCompare32bitInstance for crate::peripherals::$inst {}
314 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
315 impl GeneralPurpose32bitInstance for crate::peripherals::$inst {}
316
317 impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {
318 fn set_output_compare_mode(
319 &mut self,
320 channel: Channel,
321 mode: OutputCompareMode,
322 ) {
323 use crate::timer::sealed::GeneralPurpose32bitInstance;
324 let raw_channel = channel.raw();
325 Self::regs_gp32().ccmr_output(raw_channel / 2).modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
326 }
178 327
179 impl Basic16bitInstance for crate::peripherals::$inst { 328 fn enable_channel(&mut self, channel: Channel, enable: bool) {
329 use crate::timer::sealed::GeneralPurpose32bitInstance;
330 Self::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), enable));
331 }
332
333 fn set_compare_value(&mut self, channel: Channel, value: u32) {
334 use crate::timer::sealed::GeneralPurpose32bitInstance;
335 Self::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(value));
336 }
337
338 fn get_max_compare_value(&self) -> u32 {
339 use crate::timer::sealed::GeneralPurpose32bitInstance;
340 Self::regs_gp32().arr().read().arr() as u32
341 }
180 } 342 }
181 343
182 impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { 344 impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst {
@@ -184,21 +346,16 @@ foreach_interrupt! {
184 unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } 346 unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) }
185 } 347 }
186 } 348 }
187
188 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {
189 }
190
191 impl_32bit_timer!($inst);
192
193 impl GeneralPurpose32bitInstance for crate::peripherals::$inst {
194 }
195 }; 349 };
196 350
197 ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { 351 ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => {
198 impl_basic_16bit_timer!($inst, $irq); 352 impl_basic_16bit_timer!($inst, $irq);
199 353
200 impl Basic16bitInstance for crate::peripherals::$inst { 354 impl Basic16bitInstance for crate::peripherals::$inst {}
201 } 355 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {}
356 impl CaptureCompare16bitInstance for crate::peripherals::$inst {}
357 impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {}
358 impl AdvancedControlInstance for crate::peripherals::$inst {}
202 359
203 impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { 360 impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst {
204 fn regs_gp16() -> crate::pac::timer::TimGp16 { 361 fn regs_gp16() -> crate::pac::timer::TimGp16 {
@@ -206,17 +363,71 @@ foreach_interrupt! {
206 } 363 }
207 } 364 }
208 365
209 impl GeneralPurpose16bitInstance for crate::peripherals::$inst {
210 }
211
212 impl sealed::AdvancedControlInstance for crate::peripherals::$inst { 366 impl sealed::AdvancedControlInstance for crate::peripherals::$inst {
213 fn regs_advanced() -> crate::pac::timer::TimAdv { 367 fn regs_advanced() -> crate::pac::timer::TimAdv {
214 crate::pac::$inst 368 crate::pac::$inst
215 } 369 }
216 } 370 }
217 371
218 impl AdvancedControlInstance for crate::peripherals::$inst { 372 impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
373 fn enable_outputs(&mut self, enable: bool) {
374 use crate::timer::sealed::AdvancedControlInstance;
375 let r = Self::regs_advanced();
376 r.bdtr().modify(|w| w.set_moe(enable));
377 }
378
379 fn set_output_compare_mode(
380 &mut self,
381 channel: Channel,
382 mode: OutputCompareMode,
383 ) {
384 use crate::timer::sealed::AdvancedControlInstance;
385 let r = Self::regs_advanced();
386 let raw_channel: usize = channel.raw();
387 r.ccmr_output(raw_channel / 2)
388 .modify(|w| w.set_ocm(raw_channel % 2, mode.into()));
389 }
390
391 fn enable_channel(&mut self, channel: Channel, enable: bool) {
392 use crate::timer::sealed::AdvancedControlInstance;
393 Self::regs_advanced()
394 .ccer()
395 .modify(|w| w.set_cce(channel.raw(), enable));
396 }
397
398 fn set_compare_value(&mut self, channel: Channel, value: u16) {
399 use crate::timer::sealed::AdvancedControlInstance;
400 Self::regs_advanced()
401 .ccr(channel.raw())
402 .modify(|w| w.set_ccr(value));
403 }
404
405 fn get_max_compare_value(&self) -> u16 {
406 use crate::timer::sealed::AdvancedControlInstance;
407 Self::regs_advanced().arr().read().arr()
408 }
409 }
410
411 impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {
412 fn set_dead_time_clock_division(&mut self, value: vals::Ckd) {
413 use crate::timer::sealed::AdvancedControlInstance;
414 Self::regs_advanced().cr1().modify(|w| w.set_ckd(value));
415 }
416
417 fn set_dead_time_value(&mut self, value: u8) {
418 use crate::timer::sealed::AdvancedControlInstance;
419 Self::regs_advanced().bdtr().modify(|w| w.set_dtg(value));
420 }
421
422 fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) {
423 use crate::timer::sealed::AdvancedControlInstance;
424 Self::regs_advanced()
425 .ccer()
426 .modify(|w| w.set_ccne(channel.raw(), enable));
427 }
219 } 428 }
429
430
220 }; 431 };
221 432
222 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { 433 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
diff --git a/embassy-stm32/src/pwm/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index 995f59c23..514796930 100644
--- a/embassy-stm32/src/pwm/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::{into_ref, PeripheralRef}; 3use embassy_hal_internal::{into_ref, PeripheralRef};
4 4
5use super::*; 5use super::*;
6#[allow(unused_imports)] 6#[allow(unused_imports)]
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index 433ad299c..ca117da82 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -2,7 +2,7 @@ use core::future::poll_fn;
2use core::slice; 2use core::slice;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_common::atomic_ring_buffer::RingBuffer; 5use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
6use embassy_sync::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
7 7
8use super::*; 8use super::*;
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index ea8e525ea..d99034bca 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -5,8 +5,8 @@ use core::marker::PhantomData;
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_common::drop::OnDrop; 8use embassy_hal_internal::drop::OnDrop;
9use embassy_hal_common::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
10use futures::future::{select, Either}; 10use futures::future::{select, Either};
11 11
12use crate::dma::{NoDma, Transfer}; 12use crate::dma::{NoDma, Transfer};
@@ -857,7 +857,7 @@ fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx:
857 "Using {} oversampling, desired baudrate: {}, actual baudrate: {}", 857 "Using {} oversampling, desired baudrate: {}, actual baudrate: {}",
858 oversampling, 858 oversampling,
859 config.baudrate, 859 config.baudrate,
860 pclk_freq.0 / div 860 (pclk_freq.0 * mul as u32) / div
861 ); 861 );
862 862
863 r.cr2().write(|w| { 863 r.cr2().write(|w| {
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs
index c74d7e092..80261d048 100644
--- a/embassy-stm32/src/usart/ringbuffered.rs
+++ b/embassy-stm32/src/usart/ringbuffered.rs
@@ -2,7 +2,7 @@ use core::future::poll_fn;
2use core::sync::atomic::{compiler_fence, Ordering}; 2use core::sync::atomic::{compiler_fence, Ordering};
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_common::PeripheralRef; 5use embassy_hal_internal::PeripheralRef;
6use futures::future::{select, Either}; 6use futures::future::{select, Either};
7 7
8use super::{clear_interrupt_flags, rdr, sr, BasicInstance, Error, UartRx}; 8use super::{clear_interrupt_flags, rdr, sr, BasicInstance, Error, UartRx};
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index ecdd1d0b8..cef196355 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -5,7 +5,7 @@ use core::marker::PhantomData;
5use core::sync::atomic::{AtomicBool, Ordering}; 5use core::sync::atomic::{AtomicBool, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_common::into_ref; 8use embassy_hal_internal::into_ref;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use embassy_usb_driver as driver; 10use embassy_usb_driver as driver;
11use embassy_usb_driver::{ 11use embassy_usb_driver::{
diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs
index fd0e22adf..348f0f79d 100644
--- a/embassy-stm32/src/usb_otg/usb.rs
+++ b/embassy-stm32/src/usb_otg/usb.rs
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
3use core::sync::atomic::{AtomicBool, AtomicU16, Ordering}; 3use core::sync::atomic::{AtomicBool, AtomicU16, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_common::{into_ref, Peripheral}; 6use embassy_hal_internal::{into_ref, Peripheral};
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8use embassy_usb_driver::{ 8use embassy_usb_driver::{
9 self, Bus as _, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointIn, EndpointInfo, 9 self, Bus as _, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointIn, EndpointInfo,
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs
index b03e81d6e..eafd03364 100644
--- a/embassy-stm32/src/wdg/mod.rs
+++ b/embassy-stm32/src/wdg/mod.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::{into_ref, Peripheral}; 3use embassy_hal_internal::{into_ref, Peripheral};
4use stm32_metapac::iwdg::vals::{Key, Pr}; 4use stm32_metapac::iwdg::vals::{Key, Pr};
5 5
6use crate::rcc::LSI_FREQ; 6use crate::rcc::LSI_FREQ;
diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml
index 30b67b7b2..068474e7a 100644
--- a/examples/nrf-rtos-trace/Cargo.toml
+++ b/examples/nrf-rtos-trace/Cargo.toml
@@ -34,3 +34,6 @@ log = { version = "0.4.17", optional = true }
34[[bin]] 34[[bin]]
35name = "rtos_trace" 35name = "rtos_trace"
36required-features = ["nightly"] 36required-features = ["nightly"]
37
38[profile.release]
39debug = 2
diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml
index ded3b7db8..715f1ecfe 100644
--- a/examples/nrf52840-rtic/Cargo.toml
+++ b/examples/nrf52840-rtic/Cargo.toml
@@ -19,3 +19,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing
19cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
20panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "0.3", features = ["print-defmt"] }
21futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 21futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
22
23[profile.release]
24debug = 2
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml
index 9b41ec5ab..780aaeac2 100644
--- a/examples/nrf52840/Cargo.toml
+++ b/examples/nrf52840/Cargo.toml
@@ -57,5 +57,5 @@ embedded-hal-async = { version = "0.2.0-alpha.2", optional = true }
57num-integer = { version = "0.1.45", default-features = false } 57num-integer = { version = "0.1.45", default-features = false }
58microfft = "0.5.0" 58microfft = "0.5.0"
59 59
60[patch.crates-io] 60[profile.release]
61lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } 61debug = 2
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml
index f1d45f336..b0e51dcf4 100644
--- a/examples/nrf5340/Cargo.toml
+++ b/examples/nrf5340/Cargo.toml
@@ -53,3 +53,6 @@ rand = { version = "0.8.4", default-features = false }
53embedded-storage = "0.3.0" 53embedded-storage = "0.3.0"
54usbd-hid = "0.6.0" 54usbd-hid = "0.6.0"
55serde = { version = "1.0.136", default-features = false } 55serde = { version = "1.0.136", default-features = false }
56
57[profile.release]
58debug = 2
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index c812cb3ee..8c61dc5e1 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -53,7 +53,4 @@ pio = "0.2.1"
53rand = { version = "0.8.5", default-features = false } 53rand = { version = "0.8.5", default-features = false }
54 54
55[profile.release] 55[profile.release]
56debug = true 56debug = 2
57
58[patch.crates-io]
59lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs
index c001d6440..a6d6144be 100644
--- a/examples/rp/src/bin/pio_async.rs
+++ b/examples/rp/src/bin/pio_async.rs
@@ -8,7 +8,6 @@ use embassy_executor::Spawner;
8use embassy_rp::bind_interrupts; 8use embassy_rp::bind_interrupts;
9use embassy_rp::peripherals::PIO0; 9use embassy_rp::peripherals::PIO0;
10use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; 10use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine};
11use embassy_rp::relocate::RelocatedProgram;
12use fixed::traits::ToFixed; 11use fixed::traits::ToFixed;
13use fixed_macro::types::U56F8; 12use fixed_macro::types::U56F8;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
@@ -29,9 +28,8 @@ fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
29 ".wrap", 28 ".wrap",
30 ); 29 );
31 30
32 let relocated = RelocatedProgram::new(&prg.program);
33 let mut cfg = Config::default(); 31 let mut cfg = Config::default();
34 cfg.use_program(&pio.load_program(&relocated), &[]); 32 cfg.use_program(&pio.load_program(&prg.program), &[]);
35 let out_pin = pio.make_pio_pin(pin); 33 let out_pin = pio.make_pio_pin(pin);
36 cfg.set_out_pins(&[&out_pin]); 34 cfg.set_out_pins(&[&out_pin]);
37 cfg.set_set_pins(&[&out_pin]); 35 cfg.set_set_pins(&[&out_pin]);
@@ -65,9 +63,8 @@ fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
65 ".wrap", 63 ".wrap",
66 ); 64 );
67 65
68 let relocated = RelocatedProgram::new(&prg.program);
69 let mut cfg = Config::default(); 66 let mut cfg = Config::default();
70 cfg.use_program(&pio.load_program(&relocated), &[]); 67 cfg.use_program(&pio.load_program(&prg.program), &[]);
71 cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); 68 cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed();
72 cfg.shift_in.auto_fill = true; 69 cfg.shift_in.auto_fill = true;
73 cfg.shift_in.direction = ShiftDirection::Right; 70 cfg.shift_in.direction = ShiftDirection::Right;
@@ -96,9 +93,8 @@ fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
96 "irq 3 [15]", 93 "irq 3 [15]",
97 ".wrap", 94 ".wrap",
98 ); 95 );
99 let relocated = RelocatedProgram::new(&prg.program);
100 let mut cfg = Config::default(); 96 let mut cfg = Config::default();
101 cfg.use_program(&pio.load_program(&relocated), &[]); 97 cfg.use_program(&pio.load_program(&prg.program), &[]);
102 cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); 98 cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed();
103 sm.set_config(&cfg); 99 sm.set_config(&cfg);
104} 100}
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs
index 9ab72e1f3..86e5017ac 100644
--- a/examples/rp/src/bin/pio_dma.rs
+++ b/examples/rp/src/bin/pio_dma.rs
@@ -8,7 +8,6 @@ use embassy_executor::Spawner;
8use embassy_futures::join::join; 8use embassy_futures::join::join;
9use embassy_rp::peripherals::PIO0; 9use embassy_rp::peripherals::PIO0;
10use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; 10use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection};
11use embassy_rp::relocate::RelocatedProgram;
12use embassy_rp::{bind_interrupts, Peripheral}; 11use embassy_rp::{bind_interrupts, Peripheral};
13use fixed::traits::ToFixed; 12use fixed::traits::ToFixed;
14use fixed_macro::types::U56F8; 13use fixed_macro::types::U56F8;
@@ -46,9 +45,8 @@ async fn main(_spawner: Spawner) {
46 ".wrap", 45 ".wrap",
47 ); 46 );
48 47
49 let relocated = RelocatedProgram::new(&prg.program);
50 let mut cfg = Config::default(); 48 let mut cfg = Config::default();
51 cfg.use_program(&common.load_program(&relocated), &[]); 49 cfg.use_program(&common.load_program(&prg.program), &[]);
52 cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed(); 50 cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed();
53 cfg.shift_in = ShiftConfig { 51 cfg.shift_in = ShiftConfig {
54 auto_fill: true, 52 auto_fill: true,
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs
index 8aedd24b6..d80c5c24b 100644
--- a/examples/rp/src/bin/pio_hd44780.rs
+++ b/examples/rp/src/bin/pio_hd44780.rs
@@ -14,7 +14,6 @@ use embassy_rp::pio::{
14 Config, Direction, FifoJoin, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, 14 Config, Direction, FifoJoin, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
15}; 15};
16use embassy_rp::pwm::{self, Pwm}; 16use embassy_rp::pwm::{self, Pwm};
17use embassy_rp::relocate::RelocatedProgram;
18use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef}; 17use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef};
19use embassy_time::{Duration, Instant, Timer}; 18use embassy_time::{Duration, Instant, Timer};
20use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
@@ -127,9 +126,8 @@ impl<'l> HD44780<'l> {
127 126
128 sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]); 127 sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]);
129 128
130 let relocated = RelocatedProgram::new(&prg.program);
131 let mut cfg = Config::default(); 129 let mut cfg = Config::default();
132 cfg.use_program(&common.load_program(&relocated), &[&e]); 130 cfg.use_program(&common.load_program(&prg.program), &[&e]);
133 cfg.clock_divider = 125u8.into(); 131 cfg.clock_divider = 125u8.into();
134 cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); 132 cfg.set_out_pins(&[&db4, &db5, &db6, &db7]);
135 cfg.shift_out = ShiftConfig { 133 cfg.shift_out = ShiftConfig {
@@ -201,9 +199,8 @@ impl<'l> HD44780<'l> {
201 "# 199 "#
202 ); 200 );
203 201
204 let relocated = RelocatedProgram::new(&prg.program);
205 let mut cfg = Config::default(); 202 let mut cfg = Config::default();
206 cfg.use_program(&common.load_program(&relocated), &[&e]); 203 cfg.use_program(&common.load_program(&prg.program), &[&e]);
207 cfg.clock_divider = 8u8.into(); // ~64ns/insn 204 cfg.clock_divider = 8u8.into(); // ~64ns/insn
208 cfg.set_jmp_pin(&db7); 205 cfg.set_jmp_pin(&db7);
209 cfg.set_set_pins(&[&rs, &rw]); 206 cfg.set_set_pins(&[&rs, &rw]);
diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs
new file mode 100644
index 000000000..5fddbe292
--- /dev/null
+++ b/examples/rp/src/bin/pio_uart.rs
@@ -0,0 +1,392 @@
1//! This example shows how to use the PIO module in the RP2040 chip to implement a duplex UART.
2//! The PIO module is a very powerful peripheral that can be used to implement many different
3//! protocols. It is a very flexible state machine that can be programmed to do almost anything.
4//!
5//! This example opens up a USB device that implements a CDC ACM serial port. It then uses the
6//! PIO module to implement a UART that is connected to the USB serial port. This allows you to
7//! communicate with a device connected to the RP2040 over USB serial.
8
9#![no_std]
10#![no_main]
11#![feature(type_alias_impl_trait)]
12#![feature(async_fn_in_trait)]
13
14use defmt::{info, panic, trace};
15use embassy_executor::Spawner;
16use embassy_futures::join::{join, join3};
17use embassy_rp::bind_interrupts;
18use embassy_rp::peripherals::{PIO0, USB};
19use embassy_rp::pio::InterruptHandler as PioInterruptHandler;
20use embassy_rp::usb::{Driver, Instance, InterruptHandler};
21use embassy_sync::blocking_mutex::raw::NoopRawMutex;
22use embassy_sync::pipe::Pipe;
23use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State};
24use embassy_usb::driver::EndpointError;
25use embassy_usb::{Builder, Config};
26use embedded_io::asynch::{Read, Write};
27use {defmt_rtt as _, panic_probe as _};
28
29use crate::uart::PioUart;
30use crate::uart_rx::PioUartRx;
31use crate::uart_tx::PioUartTx;
32
33bind_interrupts!(struct Irqs {
34 USBCTRL_IRQ => InterruptHandler<USB>;
35 PIO0_IRQ_0 => PioInterruptHandler<PIO0>;
36});
37
38#[embassy_executor::main]
39async fn main(_spawner: Spawner) {
40 info!("Hello there!");
41
42 let p = embassy_rp::init(Default::default());
43
44 // Create the driver, from the HAL.
45 let driver = Driver::new(p.USB, Irqs);
46
47 // Create embassy-usb Config
48 let mut config = Config::new(0xc0de, 0xcafe);
49 config.manufacturer = Some("Embassy");
50 config.product = Some("PIO UART example");
51 config.serial_number = Some("12345678");
52 config.max_power = 100;
53 config.max_packet_size_0 = 64;
54
55 // Required for windows compatibility.
56 // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help
57 config.device_class = 0xEF;
58 config.device_sub_class = 0x02;
59 config.device_protocol = 0x01;
60 config.composite_with_iads = true;
61
62 // Create embassy-usb DeviceBuilder using the driver and config.
63 // It needs some buffers for building the descriptors.
64 let mut device_descriptor = [0; 256];
65 let mut config_descriptor = [0; 256];
66 let mut bos_descriptor = [0; 256];
67 let mut control_buf = [0; 64];
68
69 let mut state = State::new();
70
71 let mut builder = Builder::new(
72 driver,
73 config,
74 &mut device_descriptor,
75 &mut config_descriptor,
76 &mut bos_descriptor,
77 &mut control_buf,
78 );
79
80 // Create classes on the builder.
81 let class = CdcAcmClass::new(&mut builder, &mut state, 64);
82
83 // Build the builder.
84 let mut usb = builder.build();
85
86 // Run the USB device.
87 let usb_fut = usb.run();
88
89 // PIO UART setup
90 let uart = PioUart::new(9600, p.PIO0, p.PIN_4, p.PIN_5);
91 let (mut uart_tx, mut uart_rx) = uart.split();
92
93 // Pipe setup
94 let usb_pipe: Pipe<NoopRawMutex, 20> = Pipe::new();
95 let mut usb_pipe_writer = usb_pipe.writer();
96 let mut usb_pipe_reader = usb_pipe.reader();
97
98 let uart_pipe: Pipe<NoopRawMutex, 20> = Pipe::new();
99 let mut uart_pipe_writer = uart_pipe.writer();
100 let mut uart_pipe_reader = uart_pipe.reader();
101
102 let (mut usb_tx, mut usb_rx) = class.split();
103
104 // Read + write from USB
105 let usb_future = async {
106 loop {
107 info!("Wait for USB connection");
108 usb_rx.wait_connection().await;
109 info!("Connected");
110 let _ = join(
111 usb_read(&mut usb_rx, &mut uart_pipe_writer),
112 usb_write(&mut usb_tx, &mut usb_pipe_reader),
113 )
114 .await;
115 info!("Disconnected");
116 }
117 };
118
119 // Read + write from UART
120 let uart_future = join(
121 uart_read(&mut uart_rx, &mut usb_pipe_writer),
122 uart_write(&mut uart_tx, &mut uart_pipe_reader),
123 );
124
125 // Run everything concurrently.
126 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
127 join3(usb_fut, usb_future, uart_future).await;
128}
129
130struct Disconnected {}
131
132impl From<EndpointError> for Disconnected {
133 fn from(val: EndpointError) -> Self {
134 match val {
135 EndpointError::BufferOverflow => panic!("Buffer overflow"),
136 EndpointError::Disabled => Disconnected {},
137 }
138 }
139}
140
141/// Read from the USB and write it to the UART TX pipe
142async fn usb_read<'d, T: Instance + 'd>(
143 usb_rx: &mut Receiver<'d, Driver<'d, T>>,
144 uart_pipe_writer: &mut embassy_sync::pipe::Writer<'_, NoopRawMutex, 20>,
145) -> Result<(), Disconnected> {
146 let mut buf = [0; 64];
147 loop {
148 let n = usb_rx.read_packet(&mut buf).await?;
149 let data = &buf[..n];
150 trace!("USB IN: {:x}", data);
151 uart_pipe_writer.write(data).await;
152 }
153}
154
155/// Read from the USB TX pipe and write it to the USB
156async fn usb_write<'d, T: Instance + 'd>(
157 usb_tx: &mut Sender<'d, Driver<'d, T>>,
158 usb_pipe_reader: &mut embassy_sync::pipe::Reader<'_, NoopRawMutex, 20>,
159) -> Result<(), Disconnected> {
160 let mut buf = [0; 64];
161 loop {
162 let n = usb_pipe_reader.read(&mut buf).await;
163 let data = &buf[..n];
164 trace!("USB OUT: {:x}", data);
165 usb_tx.write_packet(&data).await?;
166 }
167}
168
169/// Read from the UART and write it to the USB TX pipe
170async fn uart_read(
171 uart_rx: &mut PioUartRx<'_>,
172 usb_pipe_writer: &mut embassy_sync::pipe::Writer<'_, NoopRawMutex, 20>,
173) -> ! {
174 let mut buf = [0; 64];
175 loop {
176 let n = uart_rx.read(&mut buf).await.expect("UART read error");
177 if n == 0 {
178 continue;
179 }
180 let data = &buf[..n];
181 trace!("UART IN: {:x}", buf);
182 usb_pipe_writer.write(data).await;
183 }
184}
185
186/// Read from the UART TX pipe and write it to the UART
187async fn uart_write(
188 uart_tx: &mut PioUartTx<'_>,
189 uart_pipe_reader: &mut embassy_sync::pipe::Reader<'_, NoopRawMutex, 20>,
190) -> ! {
191 let mut buf = [0; 64];
192 loop {
193 let n = uart_pipe_reader.read(&mut buf).await;
194 let data = &buf[..n];
195 trace!("UART OUT: {:x}", data);
196 let _ = uart_tx.write(&data).await;
197 }
198}
199
200mod uart {
201 use embassy_rp::peripherals::PIO0;
202 use embassy_rp::pio::{Pio, PioPin};
203 use embassy_rp::Peripheral;
204
205 use crate::uart_rx::PioUartRx;
206 use crate::uart_tx::PioUartTx;
207 use crate::Irqs;
208
209 pub struct PioUart<'a> {
210 tx: PioUartTx<'a>,
211 rx: PioUartRx<'a>,
212 }
213
214 impl<'a> PioUart<'a> {
215 pub fn new(
216 baud: u64,
217 pio: impl Peripheral<P = PIO0> + 'a,
218 tx_pin: impl PioPin,
219 rx_pin: impl PioPin,
220 ) -> PioUart<'a> {
221 let Pio {
222 mut common, sm0, sm1, ..
223 } = Pio::new(pio, Irqs);
224
225 let tx = PioUartTx::new(&mut common, sm0, tx_pin, baud);
226 let rx = PioUartRx::new(&mut common, sm1, rx_pin, baud);
227
228 PioUart { tx, rx }
229 }
230
231 pub fn split(self) -> (PioUartTx<'a>, PioUartRx<'a>) {
232 (self.tx, self.rx)
233 }
234 }
235}
236
237mod uart_tx {
238 use core::convert::Infallible;
239
240 use embassy_rp::gpio::Level;
241 use embassy_rp::peripherals::PIO0;
242 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
243 use embedded_io::asynch::Write;
244 use embedded_io::Io;
245 use fixed::traits::ToFixed;
246 use fixed_macro::types::U56F8;
247
248 pub struct PioUartTx<'a> {
249 sm_tx: StateMachine<'a, PIO0, 0>,
250 }
251
252 impl<'a> PioUartTx<'a> {
253 pub fn new(
254 common: &mut Common<'a, PIO0>,
255 mut sm_tx: StateMachine<'a, PIO0, 0>,
256 tx_pin: impl PioPin,
257 baud: u64,
258 ) -> Self {
259 let prg = pio_proc::pio_asm!(
260 r#"
261 .side_set 1 opt
262
263 ; An 8n1 UART transmit program.
264 ; OUT pin 0 and side-set pin 0 are both mapped to UART TX pin.
265
266 pull side 1 [7] ; Assert stop bit, or stall with line in idle state
267 set x, 7 side 0 [7] ; Preload bit counter, assert start bit for 8 clocks
268 bitloop: ; This loop will run 8 times (8n1 UART)
269 out pins, 1 ; Shift 1 bit from OSR to the first OUT pin
270 jmp x-- bitloop [6] ; Each loop iteration is 8 cycles.
271 "#
272 );
273 let tx_pin = common.make_pio_pin(tx_pin);
274 sm_tx.set_pins(Level::High, &[&tx_pin]);
275 sm_tx.set_pin_dirs(Direction::Out, &[&tx_pin]);
276
277 let mut cfg = Config::default();
278
279 cfg.set_out_pins(&[&tx_pin]);
280 cfg.use_program(&common.load_program(&prg.program), &[&tx_pin]);
281 cfg.shift_out.auto_fill = false;
282 cfg.shift_out.direction = ShiftDirection::Right;
283 cfg.fifo_join = FifoJoin::TxOnly;
284 cfg.clock_divider = (U56F8!(125_000_000) / (8 * baud)).to_fixed();
285 sm_tx.set_config(&cfg);
286 sm_tx.set_enable(true);
287
288 Self { sm_tx }
289 }
290
291 pub async fn write_u8(&mut self, data: u8) {
292 self.sm_tx.tx().wait_push(data as u32).await;
293 }
294 }
295
296 impl Io for PioUartTx<'_> {
297 type Error = Infallible;
298 }
299
300 impl Write for PioUartTx<'_> {
301 async fn write(&mut self, buf: &[u8]) -> Result<usize, Infallible> {
302 for byte in buf {
303 self.write_u8(*byte).await;
304 }
305 Ok(buf.len())
306 }
307 }
308}
309
310mod uart_rx {
311 use core::convert::Infallible;
312
313 use embassy_rp::gpio::Level;
314 use embassy_rp::peripherals::PIO0;
315 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
316 use embedded_io::asynch::Read;
317 use embedded_io::Io;
318 use fixed::traits::ToFixed;
319 use fixed_macro::types::U56F8;
320
321 pub struct PioUartRx<'a> {
322 sm_rx: StateMachine<'a, PIO0, 1>,
323 }
324
325 impl<'a> PioUartRx<'a> {
326 pub fn new(
327 common: &mut Common<'a, PIO0>,
328 mut sm_rx: StateMachine<'a, PIO0, 1>,
329 rx_pin: impl PioPin,
330 baud: u64,
331 ) -> Self {
332 let prg = pio_proc::pio_asm!(
333 r#"
334 ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
335 ; break conditions more gracefully.
336 ; IN pin 0 and JMP pin are both mapped to the GPIO used as UART RX.
337
338 start:
339 wait 0 pin 0 ; Stall until start bit is asserted
340 set x, 7 [10] ; Preload bit counter, then delay until halfway through
341 rx_bitloop: ; the first data bit (12 cycles incl wait, set).
342 in pins, 1 ; Shift data bit into ISR
343 jmp x-- rx_bitloop [6] ; Loop 8 times, each loop iteration is 8 cycles
344 jmp pin good_rx_stop ; Check stop bit (should be high)
345
346 irq 4 rel ; Either a framing error or a break. Set a sticky flag,
347 wait 1 pin 0 ; and wait for line to return to idle state.
348 jmp start ; Don't push data if we didn't see good framing.
349
350 good_rx_stop: ; No delay before returning to start; a little slack is
351 push ; important in case the TX clock is slightly too fast.
352 "#
353 );
354 let mut cfg = Config::default();
355 cfg.use_program(&common.load_program(&prg.program), &[]);
356
357 let rx_pin = common.make_pio_pin(rx_pin);
358 sm_rx.set_pins(Level::High, &[&rx_pin]);
359 cfg.set_in_pins(&[&rx_pin]);
360 cfg.set_jmp_pin(&rx_pin);
361 sm_rx.set_pin_dirs(Direction::In, &[&rx_pin]);
362
363 cfg.clock_divider = (U56F8!(125_000_000) / (8 * baud)).to_fixed();
364 cfg.shift_out.auto_fill = false;
365 cfg.shift_out.direction = ShiftDirection::Right;
366 cfg.fifo_join = FifoJoin::RxOnly;
367 sm_rx.set_config(&cfg);
368 sm_rx.set_enable(true);
369
370 Self { sm_rx }
371 }
372
373 pub async fn read_u8(&mut self) -> u8 {
374 self.sm_rx.rx().wait_pull().await as u8
375 }
376 }
377
378 impl Io for PioUartRx<'_> {
379 type Error = Infallible;
380 }
381
382 impl Read for PioUartRx<'_> {
383 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Infallible> {
384 let mut i = 0;
385 while i < buf.len() {
386 buf[i] = self.read_u8().await;
387 i += 1;
388 }
389 Ok(i)
390 }
391 }
392}
diff --git a/examples/rp/src/bin/pio_ws2812.rs b/examples/rp/src/bin/pio_ws2812.rs
index 3de2bd48d..bc87016ec 100644
--- a/examples/rp/src/bin/pio_ws2812.rs
+++ b/examples/rp/src/bin/pio_ws2812.rs
@@ -12,7 +12,6 @@ use embassy_rp::peripherals::PIO0;
12use embassy_rp::pio::{ 12use embassy_rp::pio::{
13 Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, 13 Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
14}; 14};
15use embassy_rp::relocate::RelocatedProgram;
16use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; 15use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef};
17use embassy_time::{Duration, Timer}; 16use embassy_time::{Duration, Timer};
18use fixed::types::U24F8; 17use fixed::types::U24F8;
@@ -73,8 +72,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> Ws2812<'d, P, S, N> {
73 cfg.set_out_pins(&[&out_pin]); 72 cfg.set_out_pins(&[&out_pin]);
74 cfg.set_set_pins(&[&out_pin]); 73 cfg.set_set_pins(&[&out_pin]);
75 74
76 let relocated = RelocatedProgram::new(&prg); 75 cfg.use_program(&pio.load_program(&prg), &[&out_pin]);
77 cfg.use_program(&pio.load_program(&relocated), &[&out_pin]);
78 76
79 // Clock config, measured in kHz to avoid overflows 77 // Clock config, measured in kHz to avoid overflows
80 // TODO CLOCK_FREQ should come from embassy_rp 78 // TODO CLOCK_FREQ should come from embassy_rp
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index 92933ab50..42adede10 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -23,3 +23,6 @@ clap = { version = "3.0.0-beta.5", features = ["derive"] }
23rand_core = { version = "0.6.3", features = ["std"] } 23rand_core = { version = "0.6.3", features = ["std"] }
24heapless = { version = "0.7.5", default-features = false } 24heapless = { version = "0.7.5", default-features = false }
25static_cell = { version = "1.1", features = ["nightly"]} 25static_cell = { version = "1.1", features = ["nightly"]}
26
27[profile.release]
28debug = 2
diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml
index 26837abef..8534921ab 100644
--- a/examples/stm32c0/Cargo.toml
+++ b/examples/stm32c0/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32c031c6 to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] }
12 13
13defmt = "0.3" 14defmt = "0.3"
14defmt-rtt = "0.4" 15defmt-rtt = "0.4"
@@ -19,3 +20,6 @@ embedded-hal = "0.2.6"
19panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "0.3", features = ["print-defmt"] }
20futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 21futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
21heapless = { version = "0.7.5", default-features = false } 22heapless = { version = "0.7.5", default-features = false }
23
24[profile.release]
25debug = 2
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml
index b7b5eaa99..46b6db45c 100644
--- a/examples/stm32f0/Cargo.toml
+++ b/examples/stm32f0/Cargo.toml
@@ -7,6 +7,8 @@ license = "MIT OR Apache-2.0"
7# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 8
9[dependencies] 9[dependencies]
10# Change stm32f091rc to your chip name, if necessary.
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "memory-x", "stm32f091rc", "time-driver-any", "exti", "unstable-pac"] }
10cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 12cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
11cortex-m-rt = "0.7.0" 13cortex-m-rt = "0.7.0"
12defmt = "0.3" 14defmt = "0.3"
@@ -15,5 +17,7 @@ panic-probe = "0.3"
15embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 17embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
16embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 18embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
17embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 19embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
18embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "memory-x", "stm32f091rc", "time-driver-any", "exti", "unstable-pac"] }
19static_cell = { version = "1.1", features = ["nightly"]} 20static_cell = { version = "1.1", features = ["nightly"]}
21
22[profile.release]
23debug = 2
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml
index 29cad5b67..5d32992cd 100644
--- a/examples/stm32f1/Cargo.toml
+++ b/examples/stm32f1/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32f103c8 to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any", "unstable-traits" ] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any", "unstable-traits" ] }
12embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
14 15
@@ -25,3 +26,6 @@ nb = "1.0.0"
25 26
26[profile.dev] 27[profile.dev]
27opt-level = "s" 28opt-level = "s"
29
30[profile.release]
31debug = 2
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml
index 652210c7f..9857fb631 100644
--- a/examples/stm32f2/Cargo.toml
+++ b/examples/stm32f2/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32f207zg to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
12 13
13defmt = "0.3" 14defmt = "0.3"
14defmt-rtt = "0.4" 15defmt-rtt = "0.4"
@@ -20,3 +21,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
20futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 21futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
21heapless = { version = "0.7.5", default-features = false } 22heapless = { version = "0.7.5", default-features = false }
22nb = "1.0.0" 23nb = "1.0.0"
24
25[profile.release]
26debug = 2
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml
index 489d0ff4c..bd594d16a 100644
--- a/examples/stm32f3/Cargo.toml
+++ b/examples/stm32f3/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32f303ze to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
12embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
14 15
@@ -24,3 +25,6 @@ heapless = { version = "0.7.5", default-features = false }
24nb = "1.0.0" 25nb = "1.0.0"
25embedded-storage = "0.3.0" 26embedded-storage = "0.3.0"
26static_cell = { version = "1.1", features = ["nightly"]} 27static_cell = { version = "1.1", features = ["nightly"]}
28
29[profile.release]
30debug = 2
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index c1c821364..fdd3b7d4f 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32f429zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers", "arch-cortex-m", "executor-thread", "executor-interrupt"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] }
12embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
13embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } 14embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] }
14 15
diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs
index 08bed88db..f84f74d30 100644
--- a/examples/stm32f4/src/bin/can.rs
+++ b/examples/stm32f4/src/bin/can.rs
@@ -40,10 +40,13 @@ async fn main(_spawner: Spawner) {
40 40
41 can.as_mut() 41 can.as_mut()
42 .modify_config() 42 .modify_config()
43 .set_bit_timing(0x001c0003) // http://www.bittiming.can-wiki.info/
44 .set_loopback(true) // Receive own frames 43 .set_loopback(true) // Receive own frames
45 .set_silent(true) 44 .set_silent(true)
46 .enable(); 45 .leave_disabled();
46
47 can.set_bitrate(1_000_000);
48
49 can.enable().await;
47 50
48 let mut i: u8 = 0; 51 let mut i: u8 = 0;
49 loop { 52 loop {
diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs
index 3a6216712..aaedcfecc 100644
--- a/examples/stm32f4/src/bin/dac.rs
+++ b/examples/stm32f4/src/bin/dac.rs
@@ -14,11 +14,11 @@ async fn main(_spawner: Spawner) -> ! {
14 info!("Hello World, dude!"); 14 info!("Hello World, dude!");
15 15
16 let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4); 16 let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4);
17 unwrap!(dac.set_trigger_enable(false));
17 18
18 loop { 19 loop {
19 for v in 0..=255 { 20 for v in 0..=255 {
20 unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); 21 unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
21 dac.trigger();
22 } 22 }
23 } 23 }
24} 24}
diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs
index 7c5902052..4f130c26b 100644
--- a/examples/stm32f4/src/bin/pwm.rs
+++ b/examples/stm32f4/src/bin/pwm.rs
@@ -4,9 +4,9 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
8use embassy_stm32::pwm::Channel;
9use embassy_stm32::time::khz; 7use embassy_stm32::time::khz;
8use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
9use embassy_stm32::timer::Channel;
10use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
11use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
12 12
diff --git a/examples/stm32f4/src/bin/pwm_complementary.rs b/examples/stm32f4/src/bin/pwm_complementary.rs
index a8a68ed6e..8cc2a4117 100644
--- a/examples/stm32f4/src/bin/pwm_complementary.rs
+++ b/examples/stm32f4/src/bin/pwm_complementary.rs
@@ -4,10 +4,10 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::pwm::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
8use embassy_stm32::pwm::simple_pwm::PwmPin;
9use embassy_stm32::pwm::Channel;
10use embassy_stm32::time::khz; 7use embassy_stm32::time::khz;
8use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
9use embassy_stm32::timer::simple_pwm::PwmPin;
10use embassy_stm32::timer::Channel;
11use embassy_time::{Duration, Timer}; 11use embassy_time::{Duration, Timer};
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index 84d7b79c5..a379cbbe3 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32f767zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] }
12embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } 13embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] }
13embedded-io = { version = "0.4.0", features = ["async"] } 14embedded-io = { version = "0.4.0", features = ["async"] }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
@@ -27,3 +28,6 @@ rand_core = "0.6.3"
27critical-section = "1.1" 28critical-section = "1.1"
28embedded-storage = "0.3.0" 29embedded-storage = "0.3.0"
29static_cell = { version = "1.1", features = ["nightly"]} 30static_cell = { version = "1.1", features = ["nightly"]}
31
32[profile.release]
33debug = 2
diff --git a/examples/stm32f7/build.rs b/examples/stm32f7/build.rs
index 2b5d412a9..8cd32d7ed 100644
--- a/examples/stm32f7/build.rs
+++ b/examples/stm32f7/build.rs
@@ -1,43 +1,5 @@
1//! adapted from https://github.com/stm32-rs/stm32f7xx-hal/blob/master/build.rs 1fn main() {
2use std::fs::File;
3use std::io::prelude::*;
4use std::path::PathBuf;
5use std::{env, io};
6
7#[derive(Debug)]
8enum Error {
9 Env(env::VarError),
10 Io(io::Error),
11}
12
13impl From<env::VarError> for Error {
14 fn from(error: env::VarError) -> Self {
15 Self::Env(error)
16 }
17}
18
19impl From<io::Error> for Error {
20 fn from(error: io::Error) -> Self {
21 Self::Io(error)
22 }
23}
24
25fn main() -> Result<(), Error> {
26 println!("cargo:rerun-if-changed=build.rs");
27 println!("cargo:rerun-if-changed=memory.x");
28
29 let out_dir = env::var("OUT_DIR")?;
30 let out_dir = PathBuf::from(out_dir);
31
32 let memory_x = include_bytes!("memory.x").as_ref();
33 File::create(out_dir.join("memory.x"))?.write_all(memory_x)?;
34
35 // Tell Cargo where to find the file.
36 println!("cargo:rustc-link-search={}", out_dir.display());
37
38 println!("cargo:rustc-link-arg-bins=--nmagic"); 2 println!("cargo:rustc-link-arg-bins=--nmagic");
39 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 3 println!("cargo:rustc-link-arg-bins=-Tlink.x");
40 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 4 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
41
42 Ok(())
43} 5}
diff --git a/examples/stm32f7/memory.x b/examples/stm32f7/memory.x
deleted file mode 100644
index 899f7a4b8..000000000
--- a/examples/stm32f7/memory.x
+++ /dev/null
@@ -1,12 +0,0 @@
1/* For STM32F765,767,768,769,777,778,779 devices */
2MEMORY
3{
4 /* NOTE K = KiBi = 1024 bytes */
5 FLASH : ORIGIN = 0x08000000, LENGTH = 2M
6 RAM : ORIGIN = 0x20000000, LENGTH = 368K + 16K
7}
8
9/* This is where the call stack will be allocated. */
10/* The stack is of the full descending type. */
11/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
12_stack_start = ORIGIN(RAM) + LENGTH(RAM);
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml
index c88282d91..b4dfe3c6b 100644
--- a/examples/stm32g0/Cargo.toml
+++ b/examples/stm32g0/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32g071rb to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] }
12 13
13defmt = "0.3" 14defmt = "0.3"
14defmt-rtt = "0.4" 15defmt-rtt = "0.4"
@@ -19,3 +20,6 @@ embedded-hal = "0.2.6"
19panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "0.3", features = ["print-defmt"] }
20futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 21futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
21heapless = { version = "0.7.5", default-features = false } 22heapless = { version = "0.7.5", default-features = false }
23
24[profile.release]
25debug = 2
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml
index 18bd03c39..cf3e2ce9b 100644
--- a/examples/stm32g4/Cargo.toml
+++ b/examples/stm32g4/Cargo.toml
@@ -5,11 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32g491re to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] }
12embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
14 14
15defmt = "0.3" 15defmt = "0.3"
@@ -21,3 +21,6 @@ embedded-hal = "0.2.6"
21panic-probe = { version = "0.3", features = ["print-defmt"] } 21panic-probe = { version = "0.3", features = ["print-defmt"] }
22futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 22futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
23heapless = { version = "0.7.5", default-features = false } 23heapless = { version = "0.7.5", default-features = false }
24
25[profile.release]
26debug = 2
diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs
index 8f7842ed7..b5a9b9952 100644
--- a/examples/stm32g4/src/bin/pwm.rs
+++ b/examples/stm32g4/src/bin/pwm.rs
@@ -4,9 +4,9 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
8use embassy_stm32::pwm::Channel;
9use embassy_stm32::time::khz; 7use embassy_stm32::time::khz;
8use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
9use embassy_stm32::timer::Channel;
10use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
11use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
12 12
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml
index 227bc28b4..51d3bad1f 100644
--- a/examples/stm32h5/Cargo.toml
+++ b/examples/stm32h5/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32h563zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h563zi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
12embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits", "proto-ipv6"] } 13embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits", "proto-ipv6"] }
13embedded-io = { version = "0.4.0", features = ["async"] } 14embedded-io = { version = "0.4.0", features = ["async"] }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32h5/memory.x b/examples/stm32h5/memory.x
deleted file mode 100644
index 456061509..000000000
--- a/examples/stm32h5/memory.x
+++ /dev/null
@@ -1,5 +0,0 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x08000000, LENGTH = 0x200000
4 RAM : ORIGIN = 0x20000000, LENGTH = 0x50000
5}
diff --git a/examples/stm32h7/.cargo/config.toml b/examples/stm32h7/.cargo/config.toml
index 5f680dbce..4160bf855 100644
--- a/examples/stm32h7/.cargo/config.toml
+++ b/examples/stm32h7/.cargo/config.toml
@@ -1,5 +1,5 @@
1[target.thumbv7em-none-eabihf] 1[target.thumbv7em-none-eabihf]
2runner = 'probe-rs run --chip STM32H743ZITx' 2runner = 'probe-rs run --chip STM32H7A3ZITxQ'
3 3
4[build] 4[build]
5target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) 5target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 768702fa9..3c1232e67 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32h743bi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "unstable-traits"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
12embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits", "proto-ipv6"] } 13embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits", "proto-ipv6"] }
13embedded-io = { version = "0.4.0", features = ["async"] } 14embedded-io = { version = "0.4.0", features = ["async"] }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32h7/memory.x b/examples/stm32h7/memory.x
deleted file mode 100644
index 026b14b9b..000000000
--- a/examples/stm32h7/memory.x
+++ /dev/null
@@ -1,5 +0,0 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x8000000, LENGTH = 1024K
4 RAM : ORIGIN = 0x24000000, LENGTH = 384K
5}
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs
index 586b4154b..ee078286b 100644
--- a/examples/stm32h7/src/bin/dac.rs
+++ b/examples/stm32h7/src/bin/dac.rs
@@ -21,11 +21,11 @@ fn main() -> ! {
21 let p = embassy_stm32::init(config); 21 let p = embassy_stm32::init(config);
22 22
23 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); 23 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4);
24 unwrap!(dac.set_trigger_enable(false));
24 25
25 loop { 26 loop {
26 for v in 0..=255 { 27 for v in 0..=255 {
27 unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); 28 unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
28 dac.trigger();
29 } 29 }
30 } 30 }
31} 31}
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs
new file mode 100644
index 000000000..a9cb5d1ed
--- /dev/null
+++ b/examples/stm32h7/src/bin/dac_dma.rs
@@ -0,0 +1,140 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_stm32::dac::{DacChannel, ValueArray};
8use embassy_stm32::pac::timer::vals::{Mms, Opm};
9use embassy_stm32::peripherals::{TIM6, TIM7};
10use embassy_stm32::rcc::low_level::RccPeripheral;
11use embassy_stm32::time::{mhz, Hertz};
12use embassy_stm32::timer::low_level::Basic16bitInstance;
13use micromath::F32Ext;
14use {defmt_rtt as _, panic_probe as _};
15
16pub type Dac1Type =
17 embassy_stm32::dac::DacCh1<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH3>;
18
19pub type Dac2Type =
20 embassy_stm32::dac::DacCh2<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH4>;
21
22#[embassy_executor::main]
23async fn main(spawner: Spawner) {
24 let mut config = embassy_stm32::Config::default();
25 config.rcc.sys_ck = Some(mhz(400));
26 config.rcc.hclk = Some(mhz(100));
27 config.rcc.pll1.q_ck = Some(mhz(100));
28
29 // Initialize the board and obtain a Peripherals instance
30 let p: embassy_stm32::Peripherals = embassy_stm32::init(config);
31
32 // Obtain two independent channels (p.DAC1 can only be consumed once, though!)
33 let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split();
34
35 spawner.spawn(dac_task1(dac_ch1)).ok();
36 spawner.spawn(dac_task2(dac_ch2)).ok();
37}
38
39#[embassy_executor::task]
40async fn dac_task1(mut dac: Dac1Type) {
41 let data: &[u8; 256] = &calculate_array::<256>();
42
43 info!("TIM6 frequency is {}", TIM6::frequency());
44 const FREQUENCY: Hertz = Hertz::hz(200);
45
46 // Compute the reload value such that we obtain the FREQUENCY for the sine
47 let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32;
48
49 // Depends on your clock and on the specific chip used, you may need higher or lower values here
50 if reload < 10 {
51 error!("Reload value {} below threshold!", reload);
52 }
53
54 dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap();
55 dac.enable_channel().unwrap();
56
57 TIM6::enable();
58 TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1));
59 TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE));
60 TIM6::regs().cr1().modify(|w| {
61 w.set_opm(Opm::DISABLED);
62 w.set_cen(true);
63 });
64
65 debug!(
66 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
67 TIM6::frequency(),
68 FREQUENCY,
69 reload,
70 reload as u16,
71 data.len()
72 );
73
74 // Loop technically not necessary if DMA circular mode is enabled
75 loop {
76 info!("Loop DAC1");
77 if let Err(e) = dac.write(ValueArray::Bit8(data), true).await {
78 error!("Could not write to dac: {}", e);
79 }
80 }
81}
82
83#[embassy_executor::task]
84async fn dac_task2(mut dac: Dac2Type) {
85 let data: &[u8; 256] = &calculate_array::<256>();
86
87 info!("TIM7 frequency is {}", TIM7::frequency());
88
89 const FREQUENCY: Hertz = Hertz::hz(600);
90 let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32;
91
92 if reload < 10 {
93 error!("Reload value {} below threshold!", reload);
94 }
95
96 TIM7::enable();
97 TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1));
98 TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE));
99 TIM7::regs().cr1().modify(|w| {
100 w.set_opm(Opm::DISABLED);
101 w.set_cen(true);
102 });
103
104 dac.select_trigger(embassy_stm32::dac::Ch2Trigger::Tim7).unwrap();
105
106 debug!(
107 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
108 TIM7::frequency(),
109 FREQUENCY,
110 reload,
111 reload as u16,
112 data.len()
113 );
114
115 if let Err(e) = dac.write(ValueArray::Bit8(data), true).await {
116 error!("Could not write to dac: {}", e);
117 }
118}
119
120fn to_sine_wave(v: u8) -> u8 {
121 if v >= 128 {
122 // top half
123 let r = 3.14 * ((v - 128) as f32 / 128.0);
124 (r.sin() * 128.0 + 127.0) as u8
125 } else {
126 // bottom half
127 let r = 3.14 + 3.14 * (v as f32 / 128.0);
128 (r.sin() * 128.0 + 127.0) as u8
129 }
130}
131
132fn calculate_array<const N: usize>() -> [u8; N] {
133 let mut res = [0; N];
134 let mut i = 0;
135 while i < N {
136 res[i] = to_sine_wave(i as u8);
137 i += 1;
138 }
139 res
140}
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index d360df085..45b0872b5 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -6,8 +6,8 @@ use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::gpio::low_level::AFType; 7use embassy_stm32::gpio::low_level::AFType;
8use embassy_stm32::gpio::Speed; 8use embassy_stm32::gpio::Speed;
9use embassy_stm32::pwm::*;
10use embassy_stm32::time::{khz, mhz, Hertz}; 9use embassy_stm32::time::{khz, mhz, Hertz};
10use embassy_stm32::timer::*;
11use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; 11use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef};
12use embassy_time::{Duration, Timer}; 12use embassy_time::{Duration, Timer};
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs
index c5c0dd290..adf2ea9ce 100644
--- a/examples/stm32h7/src/bin/pwm.rs
+++ b/examples/stm32h7/src/bin/pwm.rs
@@ -4,9 +4,9 @@
4 4
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm};
8use embassy_stm32::pwm::Channel;
9use embassy_stm32::time::{khz, mhz}; 7use embassy_stm32::time::{khz, mhz};
8use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
9use embassy_stm32::timer::Channel;
10use embassy_stm32::Config; 10use embassy_stm32::Config;
11use embassy_time::{Duration, Timer}; 11use embassy_time::{Duration, Timer};
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index 747cec7bf..c325751c6 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -10,10 +10,11 @@ nightly = ["embassy-stm32/nightly", "embassy-time/nightly", "embassy-time/unstab
10 "embassy-lora", "lora-phy", "lorawan-device", "lorawan", "embedded-io/async"] 10 "embassy-lora", "lora-phy", "lorawan-device", "lorawan", "embedded-io/async"]
11 11
12[dependencies] 12[dependencies]
13# Change stm32l072cz to your chip name, if necessary.
14embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
13embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 15embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
14embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 16embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
15embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 17embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
16embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
17embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["time", "defmt"], optional = true } 18embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["time", "defmt"], optional = true }
18lora-phy = { version = "1", optional = true } 19lora-phy = { version = "1", optional = true }
19lorawan-device = { version = "0.10.0", default-features = false, features = ["async", "external-lora-phy"], optional = true } 20lorawan-device = { version = "0.10.0", default-features = false, features = ["async", "external-lora-phy"], optional = true }
@@ -33,5 +34,5 @@ heapless = { version = "0.7.5", default-features = false }
33embedded-hal = "0.2.6" 34embedded-hal = "0.2.6"
34static_cell = "1.1" 35static_cell = "1.1"
35 36
36[patch.crates-io] 37[profile.release]
37lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } 38debug = 2
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml
index dcca1cc3d..329d44cac 100644
--- a/examples/stm32l1/Cargo.toml
+++ b/examples/stm32l1/Cargo.toml
@@ -20,3 +20,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
20futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 20futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
21heapless = { version = "0.7.5", default-features = false } 21heapless = { version = "0.7.5", default-features = false }
22embedded-storage = "0.3.0" 22embedded-storage = "0.3.0"
23
24[profile.release]
25debug = 2
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index c55558518..3b27d8e81 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -5,11 +5,12 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32l4s5vi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "memory-x", "time-driver-any", "exti", "unstable-traits", "chrono"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
12embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits", "chrono"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
14 15
15defmt = "0.3" 16defmt = "0.3"
@@ -26,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false }
26chrono = { version = "^0.4", default-features = false } 27chrono = { version = "^0.4", default-features = false }
27 28
28micromath = "2.0.0" 29micromath = "2.0.0"
30
31[profile.release]
32debug = 2
diff --git a/examples/stm32l4/build.rs b/examples/stm32l4/build.rs
index 30691aa97..8cd32d7ed 100644
--- a/examples/stm32l4/build.rs
+++ b/examples/stm32l4/build.rs
@@ -1,34 +1,4 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() { 1fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic"); 2 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 3 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 4 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
diff --git a/examples/stm32l4/memory.x b/examples/stm32l4/memory.x
deleted file mode 100644
index eb87d1b54..000000000
--- a/examples/stm32l4/memory.x
+++ /dev/null
@@ -1,7 +0,0 @@
1MEMORY
2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 /* These values correspond to the STM32L4S5 */
5 FLASH : ORIGIN = 0x08000000, LENGTH = 1024K
6 RAM : ORIGIN = 0x20000000, LENGTH = 128K
7}
diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs
index ade43eb35..0193a248e 100644
--- a/examples/stm32l4/src/bin/dac.rs
+++ b/examples/stm32l4/src/bin/dac.rs
@@ -13,11 +13,11 @@ fn main() -> ! {
13 info!("Hello World!"); 13 info!("Hello World!");
14 14
15 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); 15 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4);
16 unwrap!(dac.set_trigger_enable(false));
16 17
17 loop { 18 loop {
18 for v in 0..=255 { 19 for v in 0..=255 {
19 unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); 20 unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
20 dac.trigger();
21 } 21 }
22 } 22 }
23} 23}
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index 54911482e..1afd00398 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32l552ze to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
12embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
13embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } 14embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
@@ -26,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false }
26rand_core = { version = "0.6.3", default-features = false } 27rand_core = { version = "0.6.3", default-features = false }
27embedded-io = { version = "0.4.0", features = ["async"] } 28embedded-io = { version = "0.4.0", features = ["async"] }
28static_cell = { version = "1.1", features = ["nightly"]} 29static_cell = { version = "1.1", features = ["nightly"]}
30
31[profile.release]
32debug = 2
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml
index 835e32940..db251eafe 100644
--- a/examples/stm32u5/Cargo.toml
+++ b/examples/stm32u5/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32u585ai to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] }
12embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
13 14
14defmt = "0.3" 15defmt = "0.3"
@@ -22,3 +23,6 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
22heapless = { version = "0.7.5", default-features = false } 23heapless = { version = "0.7.5", default-features = false }
23 24
24micromath = "2.0.0" 25micromath = "2.0.0"
26
27[profile.release]
28debug = 2
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index 7c0b83e65..1a5aff352 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -5,11 +5,12 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32wb55rg to your chip name in both dependencies, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] }
10embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 11embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 12embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 13embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] }
12embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] }
13embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "udp", "medium-ieee802154", "nightly"], optional=true } 14embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "udp", "medium-ieee802154", "nightly"], optional=true }
14 15
15defmt = "0.3" 16defmt = "0.3"
@@ -50,4 +51,7 @@ required-features = ["ble"]
50 51
51[[bin]] 52[[bin]]
52name = "gatt_server" 53name = "gatt_server"
53required-features = ["ble"] \ No newline at end of file 54required-features = ["ble"]
55
56[profile.release]
57debug = 2
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml
index e2c66f456..48b69c8d0 100644
--- a/examples/stm32wl/Cargo.toml
+++ b/examples/stm32wl/Cargo.toml
@@ -5,10 +5,11 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32wl55jc-cm4 to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] }
8embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
13embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time", "defmt"] } 14embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time", "defmt"] }
14lora-phy = { version = "1" } 15lora-phy = { version = "1" }
@@ -27,5 +28,5 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
27heapless = { version = "0.7.5", default-features = false } 28heapless = { version = "0.7.5", default-features = false }
28chrono = { version = "^0.4", default-features = false } 29chrono = { version = "^0.4", default-features = false }
29 30
30[patch.crates-io] 31[profile.release]
31lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } 32debug = 2
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index 3679e3857..2791cc341 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -17,3 +17,6 @@ wasm-bindgen = "0.2"
17web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] } 17web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] }
18log = "0.4.11" 18log = "0.4.11"
19critical-section = { version = "1.1", features = ["std"] } 19critical-section = { version = "1.1", features = ["std"] }
20
21[profile.release]
22debug = 2
diff --git a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
index 398ab9d27..e2adfe0be 100644
--- a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
+++ b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
@@ -118,9 +118,9 @@ const WIFI_NETWORK: &str = "EmbassyTest";
118const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; 118const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
119 119
120const TEST_DURATION: usize = 10; 120const TEST_DURATION: usize = 10;
121const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 150; 121const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 50;
122const TEST_EXPECTED_UPLOAD_KBPS: usize = 150; 122const TEST_EXPECTED_UPLOAD_KBPS: usize = 50;
123const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 150; 123const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 50;
124const RX_BUFFER_SIZE: usize = 4096; 124const RX_BUFFER_SIZE: usize = 4096;
125const TX_BUFFER_SIZE: usize = 4096; 125const TX_BUFFER_SIZE: usize = 4096;
126const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2); 126const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2);
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs
index bc127e2e5..fffdabc9b 100644
--- a/tests/rp/src/bin/cyw43-perf.rs
+++ b/tests/rp/src/bin/cyw43-perf.rs
@@ -48,9 +48,9 @@ async fn main(spawner: Spawner) {
48 } 48 }
49 49
50 // cyw43 firmware needs to be flashed manually: 50 // cyw43 firmware needs to be flashed manually:
51 // probe-rs download 43439A0.bin --format bin --chip RP2040 --base-address 0x101c0000 51 // probe-rs download 43439A0.bin --format bin --chip RP2040 --base-address 0x101b0000
52 // probe-rs download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x101f8000 52 // probe-rs download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x101f8000
53 let fw = unsafe { core::slice::from_raw_parts(0x101c0000 as *const u8, 224190) }; 53 let fw = unsafe { core::slice::from_raw_parts(0x101b0000 as *const u8, 230321) };
54 let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 4752) }; 54 let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 4752) };
55 55
56 let pwr = Output::new(p.PIN_23, Level::Low); 56 let pwr = Output::new(p.PIN_23, Level::Low);
diff --git a/tests/rp/src/bin/pio_irq.rs b/tests/rp/src/bin/pio_irq.rs
index 45004424a..bdea63eaa 100644
--- a/tests/rp/src/bin/pio_irq.rs
+++ b/tests/rp/src/bin/pio_irq.rs
@@ -9,7 +9,6 @@ use embassy_executor::Spawner;
9use embassy_rp::bind_interrupts; 9use embassy_rp::bind_interrupts;
10use embassy_rp::peripherals::PIO0; 10use embassy_rp::peripherals::PIO0;
11use embassy_rp::pio::{Config, InterruptHandler, Pio}; 11use embassy_rp::pio::{Config, InterruptHandler, Pio};
12use embassy_rp::relocate::RelocatedProgram;
13use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
14 13
15bind_interrupts!(struct Irqs { 14bind_interrupts!(struct Irqs {
@@ -35,9 +34,8 @@ async fn main(_spawner: Spawner) {
35 "irq wait 1", 34 "irq wait 1",
36 ); 35 );
37 36
38 let relocated = RelocatedProgram::new(&prg.program);
39 let mut cfg = Config::default(); 37 let mut cfg = Config::default();
40 cfg.use_program(&common.load_program(&relocated), &[]); 38 cfg.use_program(&common.load_program(&prg.program), &[]);
41 sm.set_config(&cfg); 39 sm.set_config(&cfg);
42 sm.set_enable(true); 40 sm.set_enable(true);
43 41
diff --git a/tests/rp/src/bin/pio_multi_load.rs b/tests/rp/src/bin/pio_multi_load.rs
new file mode 100644
index 000000000..356f16795
--- /dev/null
+++ b/tests/rp/src/bin/pio_multi_load.rs
@@ -0,0 +1,126 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4#[path = "../common.rs"]
5mod common;
6
7use defmt::info;
8use embassy_executor::Spawner;
9use embassy_rp::bind_interrupts;
10use embassy_rp::peripherals::PIO0;
11use embassy_rp::pio::{Config, InterruptHandler, LoadError, Pio};
12use {defmt_rtt as _, panic_probe as _};
13
14bind_interrupts!(struct Irqs {
15 PIO0_IRQ_0 => InterruptHandler<PIO0>;
16});
17
18#[embassy_executor::main]
19async fn main(_spawner: Spawner) {
20 let p = embassy_rp::init(Default::default());
21 let pio = p.PIO0;
22 let Pio {
23 mut common,
24 mut sm0,
25 mut sm1,
26 mut sm2,
27 irq_flags,
28 ..
29 } = Pio::new(pio, Irqs);
30
31 // load with explicit origin works
32 let prg1 = pio_proc::pio_asm!(
33 ".origin 4"
34 "nop",
35 "nop",
36 "nop",
37 "nop",
38 "nop",
39 "nop",
40 "nop",
41 "irq 0",
42 "nop",
43 "nop",
44 );
45 let loaded1 = common.load_program(&prg1.program);
46 assert_eq!(loaded1.origin, 4);
47 assert_eq!(loaded1.wrap.source, 13);
48 assert_eq!(loaded1.wrap.target, 4);
49
50 // load without origin chooses a free space
51 let prg2 = pio_proc::pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 1", "nop", "nop",);
52 let loaded2 = common.load_program(&prg2.program);
53 assert_eq!(loaded2.origin, 14);
54 assert_eq!(loaded2.wrap.source, 23);
55 assert_eq!(loaded2.wrap.target, 14);
56
57 // wrapping around the end of program space automatically works
58 let prg3 =
59 pio_proc::pio_asm!("nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "irq 2",);
60 let loaded3 = common.load_program(&prg3.program);
61 assert_eq!(loaded3.origin, 24);
62 assert_eq!(loaded3.wrap.source, 3);
63 assert_eq!(loaded3.wrap.target, 24);
64
65 // check that the programs actually work
66 {
67 let mut cfg = Config::default();
68 cfg.use_program(&loaded1, &[]);
69 sm0.set_config(&cfg);
70 sm0.set_enable(true);
71 while !irq_flags.check(0) {}
72 sm0.set_enable(false);
73 }
74 {
75 let mut cfg = Config::default();
76 cfg.use_program(&loaded2, &[]);
77 sm1.set_config(&cfg);
78 sm1.set_enable(true);
79 while !irq_flags.check(1) {}
80 sm1.set_enable(false);
81 }
82 {
83 let mut cfg = Config::default();
84 cfg.use_program(&loaded3, &[]);
85 sm2.set_config(&cfg);
86 sm2.set_enable(true);
87 while !irq_flags.check(2) {}
88 sm2.set_enable(false);
89 }
90
91 // instruction memory is full now. all loads should fail.
92 {
93 let prg = pio_proc::pio_asm!(".origin 0", "nop");
94 match common.try_load_program(&prg.program) {
95 Err(LoadError::AddressInUse(0)) => (),
96 _ => panic!("program loaded when it shouldn't"),
97 };
98
99 let prg = pio_proc::pio_asm!("nop");
100 match common.try_load_program(&prg.program) {
101 Err(LoadError::InsufficientSpace) => (),
102 _ => panic!("program loaded when it shouldn't"),
103 };
104 }
105
106 // freeing some memory should allow further loads though.
107 unsafe {
108 common.free_instr(loaded3.used_memory);
109 }
110 {
111 let prg = pio_proc::pio_asm!(".origin 0", "nop");
112 match common.try_load_program(&prg.program) {
113 Ok(_) => (),
114 _ => panic!("program didn't loaded when it shouldn"),
115 };
116
117 let prg = pio_proc::pio_asm!("nop");
118 match common.try_load_program(&prg.program) {
119 Ok(_) => (),
120 _ => panic!("program didn't loaded when it shouldn"),
121 };
122 }
123
124 info!("Test OK");
125 cortex_m::asm::bkpt();
126}
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 3007cd1e6..17320649e 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -7,11 +7,11 @@ autobins = false
7 7
8[features] 8[features]
9stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill 9stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill
10stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "can", "not-gpdma"] # Nucleo "sdmmc" 10stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc"
11stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma"] # Nucleo 11stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo
12stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo 12stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo
13stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo 13stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo
14stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma"] # Nucleo 14stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma", "dac-adc-pin"] # Nucleo
15stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo 15stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo
16stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo 16stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo
17stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board 17stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board
@@ -23,6 +23,7 @@ ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"]
23mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] 23mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"]
24embassy-stm32-wpan = [] 24embassy-stm32-wpan = []
25not-gpdma = [] 25not-gpdma = []
26dac-adc-pin = []
26 27
27[dependencies] 28[dependencies]
28teleprobe-meta = "1" 29teleprobe-meta = "1"
@@ -42,6 +43,7 @@ cortex-m-rt = "0.7.0"
42embedded-hal = "0.2.6" 43embedded-hal = "0.2.6"
43embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } 44embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" }
44embedded-hal-async = { version = "=0.2.0-alpha.2" } 45embedded-hal-async = { version = "=0.2.0-alpha.2" }
46micromath = "2.0.0"
45panic-probe = { version = "0.3.0", features = ["print-defmt"] } 47panic-probe = { version = "0.3.0", features = ["print-defmt"] }
46rand_core = { version = "0.6", default-features = false } 48rand_core = { version = "0.6", default-features = false }
47rand_chacha = { version = "0.3", default-features = false } 49rand_chacha = { version = "0.3", default-features = false }
@@ -56,6 +58,11 @@ path = "src/bin/can.rs"
56required-features = [ "can",] 58required-features = [ "can",]
57 59
58[[bin]] 60[[bin]]
61name = "dac"
62path = "src/bin/dac.rs"
63required-features = [ "dac-adc-pin",]
64
65[[bin]]
59name = "gpio" 66name = "gpio"
60path = "src/bin/gpio.rs" 67path = "src/bin/gpio.rs"
61required-features = [] 68required-features = []
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs
new file mode 100644
index 000000000..67a7d5b59
--- /dev/null
+++ b/tests/stm32/src/bin/dac.rs
@@ -0,0 +1,81 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5// required-features: dac-adc-pin
6
7#[path = "../common.rs"]
8mod common;
9use common::*;
10use defmt::assert;
11use embassy_executor::Spawner;
12use embassy_stm32::adc::Adc;
13use embassy_stm32::dac::{DacCh1, DacChannel, Value};
14use embassy_stm32::dma::NoDma;
15use embassy_time::{Delay, Duration, Timer};
16use {defmt_rtt as _, panic_probe as _};
17
18#[embassy_executor::main]
19async fn main(_spawner: Spawner) {
20 // Initialize the board and obtain a Peripherals instance
21 let p: embassy_stm32::Peripherals = embassy_stm32::init(config());
22
23 #[cfg(feature = "stm32f429zi")]
24 let dac_peripheral = p.DAC;
25
26 #[cfg(any(feature = "stm32h755zi", feature = "stm32g071rb"))]
27 let dac_peripheral = p.DAC1;
28
29 let mut dac: DacCh1<'_, _, NoDma> = DacCh1::new(dac_peripheral, NoDma, p.PA4);
30 unwrap!(dac.set_trigger_enable(false));
31
32 let mut adc = Adc::new(p.ADC1, &mut Delay);
33
34 #[cfg(feature = "stm32h755zi")]
35 let normalization_factor = 256;
36 #[cfg(any(feature = "stm32f429zi", feature = "stm32g071rb"))]
37 let normalization_factor: i32 = 16;
38
39 unwrap!(dac.set(Value::Bit8(0)));
40 // Now wait a little to obtain a stable value
41 Timer::after(Duration::from_millis(30)).await;
42 let offset = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4);
43
44 for v in 0..=255 {
45 // First set the DAC output value
46 let dac_output_val = to_sine_wave(v);
47 unwrap!(dac.set(Value::Bit8(dac_output_val)));
48
49 // Now wait a little to obtain a stable value
50 Timer::after(Duration::from_millis(30)).await;
51
52 // Need to steal the peripherals here because PA4 is obviously in use already
53 let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4);
54 // Calibrate and normalize the measurement to get close to the dac_output_val
55 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16;
56
57 info!("value / measured: {} / {}", dac_output_val, measured_normalized);
58
59 // The deviations are quite enormous but that does not matter since this is only a quick test
60 assert!((dac_output_val as i16 - measured_normalized).abs() < 15);
61 }
62
63 info!("Test OK");
64 cortex_m::asm::bkpt();
65}
66
67use core::f32::consts::PI;
68
69use micromath::F32Ext;
70
71fn to_sine_wave(v: u8) -> u8 {
72 if v >= 128 {
73 // top half
74 let r = PI * ((v - 128) as f32 / 128.0);
75 (r.sin() * 128.0 + 127.0) as u8
76 } else {
77 // bottom half
78 let r = PI + PI * (v as f32 / 128.0);
79 (r.sin() * 128.0 + 127.0) as u8
80 }
81}
diff --git a/tests/stm32/src/bin/wpan_ble.rs b/tests/stm32/src/bin/wpan_ble.rs
index 3ad8aca4e..452da77a4 100644
--- a/tests/stm32/src/bin/wpan_ble.rs
+++ b/tests/stm32/src/bin/wpan_ble.rs
@@ -12,6 +12,7 @@ use common::*;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::bind_interrupts; 13use embassy_stm32::bind_interrupts;
14use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 14use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
15use embassy_stm32::rcc::WPAN_DEFAULT;
15use embassy_stm32_wpan::hci::host::uart::UartHci; 16use embassy_stm32_wpan::hci::host::uart::UartHci;
16use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; 17use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
17use embassy_stm32_wpan::hci::types::AdvertisingType; 18use embassy_stm32_wpan::hci::types::AdvertisingType;
@@ -40,7 +41,10 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) {
40 41
41#[embassy_executor::main] 42#[embassy_executor::main]
42async fn main(spawner: Spawner) { 43async fn main(spawner: Spawner) {
43 let p = embassy_stm32::init(config()); 44 let mut config = config();
45 config.rcc = WPAN_DEFAULT;
46
47 let p = embassy_stm32::init(config);
44 info!("Hello World!"); 48 info!("Hello World!");
45 49
46 let config = Config::default(); 50 let config = Config::default();
diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs
index b04a19ee9..7eab2fd38 100644
--- a/tests/stm32/src/bin/wpan_mac.rs
+++ b/tests/stm32/src/bin/wpan_mac.rs
@@ -10,6 +10,7 @@ use common::*;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_stm32::bind_interrupts; 11use embassy_stm32::bind_interrupts;
12use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 12use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
13use embassy_stm32::rcc::WPAN_DEFAULT;
13use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest}; 14use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest};
14use embassy_stm32_wpan::mac::event::MacEvent; 15use embassy_stm32_wpan::mac::event::MacEvent;
15use embassy_stm32_wpan::mac::typedefs::{ 16use embassy_stm32_wpan::mac::typedefs::{
@@ -31,7 +32,10 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) {
31 32
32#[embassy_executor::main] 33#[embassy_executor::main]
33async fn main(spawner: Spawner) { 34async fn main(spawner: Spawner) {
34 let p = embassy_stm32::init(config()); 35 let mut config = config();
36 config.rcc = WPAN_DEFAULT;
37
38 let p = embassy_stm32::init(config);
35 info!("Hello World!"); 39 info!("Hello World!");
36 40
37 let config = Config::default(); 41 let config = Config::default();
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 3d2a9b8ef..ca5cb43ac 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -33,6 +33,7 @@ pub fn config() -> Config {
33 { 33 {
34 config.rcc.sys_ck = Some(Hertz(400_000_000)); 34 config.rcc.sys_ck = Some(Hertz(400_000_000));
35 config.rcc.pll1.q_ck = Some(Hertz(100_000_000)); 35 config.rcc.pll1.q_ck = Some(Hertz(100_000_000));
36 config.rcc.adc_clock_source = embassy_stm32::rcc::AdcClockSource::PerCk;
36 } 37 }
37 38
38 #[cfg(feature = "stm32u585ai")] 39 #[cfg(feature = "stm32u585ai")]